Merge branch 'testing-uf' into master-uf
[gnucap-felix.git] / apps / bm_posy.cc
blobd4804ba68d391ba4fd00df1b2d704d0b6c5b897f
1 /* -*- C++ -*-
2 * Copyright (C) 2001 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *------------------------------------------------------------------
22 * behavioral modeling - posynomial (non-integer powers)
23 * pair ... first is key, second is value
25 //testing=script 2005.10.06
26 #include "u_lang.h"
27 #include "e_elemnt.h"
28 #include "bm.h"
29 /*--------------------------------------------------------------------------*/
30 namespace {
31 /*--------------------------------------------------------------------------*/
32 const double _default_max(BIGBIG);
33 const double _default_min(-BIGBIG);
34 const bool _default_abs(false);
35 const bool _default_odd(false);
36 const bool _default_even(false);
37 /*--------------------------------------------------------------------------*/
38 class EVAL_BM_POSY : public EVAL_BM_ACTION_BASE {
39 private:
40 PARAMETER<double> _min;
41 PARAMETER<double> _max;
42 PARAMETER<bool> _abs;
43 PARAMETER<bool> _odd;
44 PARAMETER<bool> _even;
45 std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > > _table;
46 explicit EVAL_BM_POSY(const EVAL_BM_POSY& p);
47 public:
48 explicit EVAL_BM_POSY(int c=0);
49 ~EVAL_BM_POSY() {}
50 private: // override vitrual
51 bool operator==(const COMMON_COMPONENT&)const;
52 COMMON_COMPONENT* clone()const {return new EVAL_BM_POSY(*this);}
53 void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const;
55 void precalc_last(const CARD_LIST*);
56 void tr_eval(ELEMENT*)const;
57 std::string name()const {return "posy";}
58 bool ac_too()const {untested();return false;}
59 bool parse_numlist(CS&);
60 bool parse_params_obsolete_callback(CS&);
62 /*--------------------------------------------------------------------------*/
63 /*--------------------------------------------------------------------------*/
64 EVAL_BM_POSY::EVAL_BM_POSY(int c)
65 :EVAL_BM_ACTION_BASE(c),
66 _min(_default_min),
67 _max(_default_max),
68 _abs(_default_abs),
69 _odd(_default_odd),
70 _even(_default_even),
71 _table()
74 /*--------------------------------------------------------------------------*/
75 EVAL_BM_POSY::EVAL_BM_POSY(const EVAL_BM_POSY& p)
76 :EVAL_BM_ACTION_BASE(p),
77 _min(p._min),
78 _max(p._max),
79 _abs(p._abs),
80 _odd(p._odd),
81 _even(p._even),
82 _table(p._table)
85 /*--------------------------------------------------------------------------*/
86 bool EVAL_BM_POSY::operator==(const COMMON_COMPONENT& x)const
88 const EVAL_BM_POSY* p = dynamic_cast<const EVAL_BM_POSY*>(&x);
89 bool rv = p
90 && _min == p->_min
91 && _max == p->_max
92 && _abs == p->_abs
93 && _odd == p->_odd
94 && _even == p->_even
95 && _table == p->_table
96 && EVAL_BM_ACTION_BASE::operator==(x);
97 return rv;
99 /*--------------------------------------------------------------------------*/
100 void EVAL_BM_POSY::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const
102 assert(lang);
103 o << name() << '(';
104 for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
105 const_iterator p = _table.begin(); p != _table.end(); ++p) {
106 o << p->second << ',' << p->first << ' ';
108 o << ')';
109 print_pair(o, lang, "min", _min, _min.has_hard_value());
110 print_pair(o, lang, "max", _max, _max.has_hard_value());
111 print_pair(o, lang, "abs", _abs, _abs.has_hard_value());
112 print_pair(o, lang, "odd", _odd, _odd.has_hard_value());
113 print_pair(o, lang, "even",_even,_even.has_hard_value());
114 EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang);
116 /*--------------------------------------------------------------------------*/
117 void EVAL_BM_POSY::precalc_last(const CARD_LIST* Scope)
119 assert(Scope);
120 EVAL_BM_ACTION_BASE::precalc_last(Scope);
121 _min.e_val(_default_min, Scope);
122 _max.e_val(_default_max, Scope);
123 _abs.e_val(_default_abs, Scope);
124 _odd.e_val(_default_odd, Scope);
125 _even.e_val(_default_even, Scope);
126 for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
127 iterator p = _table.begin(); p != _table.end(); ++p) {
128 p->first.e_val(0, Scope);
129 p->second.e_val(0, Scope);
132 /*--------------------------------------------------------------------------*/
133 void EVAL_BM_POSY::tr_eval(ELEMENT* d)const
135 double x_raw = ioffset(d->_y[0].x);
136 trace1("before", x_raw);
137 double x = (x_raw < 0)
138 ? ((_odd || _even) ? -x_raw : 0.)
139 : x_raw;
140 assert(x >= 0);
141 trace1("rev", x);
143 double f0 = 0.;
144 double f1 = 0.;
145 if (x > 0) {
146 for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
147 const_iterator p = _table.begin(); p != _table.end(); ++p) {
148 double coeff = p->second * pow(x, p->first-1);
149 f1 += coeff * p->first;
150 f0 += coeff * x;
152 }else{
153 assert(x == 0);
154 for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
155 const_iterator p = _table.begin(); p != _table.end(); ++p) {
156 if (p->first == 0.) {
157 f0 += 1;
158 untested();
163 trace3("", x, f0, f1);
165 if (_odd && x_raw < 0) {
166 f0 = -f0;
168 if (_even && x_raw < 0) {
169 f1 = -f1;
170 untested();
172 trace3("after", x, f0, f1);
174 if (_abs && f0 < 0) {
175 f0 = -f0;
176 f1 = -f1;
177 untested();
180 if (f0 > _max) {
181 f0 = _max;
182 f1 = 0;
183 untested();
184 }else if (f0 < _min) {
185 f0 = _min;
186 f1 = 0;
187 untested();
190 d->_y[0] = FPOLY1(x_raw, f0, f1);
191 tr_final_adjust(&(d->_y[0]), d->f_is_value());
192 trace3("fa", d->_y[0].x, d->_y[0].f0, d->_y[0].f1);
194 /*--------------------------------------------------------------------------*/
195 bool EVAL_BM_POSY::parse_numlist(CS& cmd)
197 unsigned start = cmd.cursor();
198 unsigned here = cmd.cursor();
199 for (;;) {
200 unsigned start_of_pair = here;
201 std::pair<PARAMETER<double>, PARAMETER<double> > p;
202 cmd >> p.second; // value
203 if (cmd.stuck(&here)) {
204 // no more, graceful finish
205 break;
206 }else{
207 cmd >> p.first; // key
208 if (cmd.stuck(&here)) {
209 // ran out, but already have half of the pair
210 // back up one, hoping somebody else knows what to do with it
211 cmd.reset(start_of_pair);
212 break;
213 }else{
214 _table.push_back(p);
218 if (cmd.gotit(start)) {
219 }else{
220 untested();
222 return cmd.gotit(start);
224 /*--------------------------------------------------------------------------*/
225 bool EVAL_BM_POSY::parse_params_obsolete_callback(CS& cmd)
227 return ONE_OF
228 || Get(cmd, "min", &_min)
229 || Get(cmd, "max", &_max)
230 || Get(cmd, "abs", &_abs)
231 || Get(cmd, "odd", &_odd)
232 || Get(cmd, "even", &_even)
233 || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd)
236 /*--------------------------------------------------------------------------*/
237 /*--------------------------------------------------------------------------*/
238 EVAL_BM_POSY p1(CC_STATIC);
239 DISPATCHER<COMMON_COMPONENT>::INSTALL d1(&bm_dispatcher, "posy", &p1);
241 /*--------------------------------------------------------------------------*/
242 /*--------------------------------------------------------------------------*/
243 // vim:ts=8:sw=2:noet: