viminfo
[gnucap-felix.git] / apps / bm_posy.cc
blobea42d5869081b5544d62b8f50d17f55f4f0ff329
1 /*$Id: bm_posy.cc,v 26.137 2010/04/10 02:37:05 al Exp $ -*- 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 "globals.h"
27 #include "u_lang.h"
28 #include "e_elemnt.h"
29 #include "bm.h"
30 /*--------------------------------------------------------------------------*/
31 namespace {
32 /*--------------------------------------------------------------------------*/
33 const double _default_max(BIGBIG);
34 const double _default_min(-BIGBIG);
35 const bool _default_abs(false);
36 const bool _default_odd(false);
37 const bool _default_even(false);
38 /*--------------------------------------------------------------------------*/
39 class EVAL_BM_POSY : public EVAL_BM_ACTION_BASE {
40 private:
41 PARAMETER<double> _min;
42 PARAMETER<double> _max;
43 PARAMETER<bool> _abs;
44 PARAMETER<bool> _odd;
45 PARAMETER<bool> _even;
46 std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > > _table;
47 explicit EVAL_BM_POSY(const EVAL_BM_POSY& p);
48 public:
49 explicit EVAL_BM_POSY(int c=0);
50 ~EVAL_BM_POSY() {}
51 private: // override vitrual
52 bool operator==(const COMMON_COMPONENT&)const;
53 COMMON_COMPONENT* clone()const {return new EVAL_BM_POSY(*this);}
54 void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const;
56 void precalc_first(const CARD_LIST*);
57 void tr_eval(ELEMENT*)const;
58 std::string name()const {return "posy";}
59 bool ac_too()const {untested();return false;}
60 bool parse_numlist(CS&);
61 bool parse_params_obsolete_callback(CS&);
63 /*--------------------------------------------------------------------------*/
64 /*--------------------------------------------------------------------------*/
65 EVAL_BM_POSY::EVAL_BM_POSY(int c)
66 :EVAL_BM_ACTION_BASE(c),
67 _min(_default_min),
68 _max(_default_max),
69 _abs(_default_abs),
70 _odd(_default_odd),
71 _even(_default_even),
72 _table()
75 /*--------------------------------------------------------------------------*/
76 EVAL_BM_POSY::EVAL_BM_POSY(const EVAL_BM_POSY& p)
77 :EVAL_BM_ACTION_BASE(p),
78 _min(p._min),
79 _max(p._max),
80 _abs(p._abs),
81 _odd(p._odd),
82 _even(p._even),
83 _table(p._table)
86 /*--------------------------------------------------------------------------*/
87 bool EVAL_BM_POSY::operator==(const COMMON_COMPONENT& x)const
89 const EVAL_BM_POSY* p = dynamic_cast<const EVAL_BM_POSY*>(&x);
90 bool rv = p
91 && _min == p->_min
92 && _max == p->_max
93 && _abs == p->_abs
94 && _odd == p->_odd
95 && _even == p->_even
96 && _table == p->_table
97 && EVAL_BM_ACTION_BASE::operator==(x);
98 if (rv) {
99 untested();
101 return rv;
103 /*--------------------------------------------------------------------------*/
104 void EVAL_BM_POSY::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const
106 assert(lang);
107 o << name() << '(';
108 for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
109 const_iterator p = _table.begin(); p != _table.end(); ++p) {
110 o << p->second << ',' << p->first << ' ';
112 o << ')';
113 print_pair(o, lang, "min", _min, _min.has_hard_value());
114 print_pair(o, lang, "max", _max, _max.has_hard_value());
115 print_pair(o, lang, "abs", _abs, _abs.has_hard_value());
116 print_pair(o, lang, "odd", _odd, _odd.has_hard_value());
117 print_pair(o, lang, "even",_even,_even.has_hard_value());
118 EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang);
120 /*--------------------------------------------------------------------------*/
121 void EVAL_BM_POSY::precalc_first(const CARD_LIST* Scope)
123 assert(Scope);
124 EVAL_BM_ACTION_BASE::precalc_first(Scope);
125 _min.e_val(_default_min, Scope);
126 _max.e_val(_default_max, Scope);
127 _abs.e_val(_default_abs, Scope);
128 _odd.e_val(_default_odd, Scope);
129 _even.e_val(_default_even, Scope);
130 for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
131 iterator p = _table.begin(); p != _table.end(); ++p) {
132 p->first.e_val(0, Scope);
133 p->second.e_val(0, Scope);
136 /*--------------------------------------------------------------------------*/
137 void EVAL_BM_POSY::tr_eval(ELEMENT* d)const
139 double x_raw = ioffset(d->_y[0].x);
140 trace1("before", x_raw);
141 double x = (x_raw < 0)
142 ? ((_odd || _even) ? -x_raw : 0.)
143 : x_raw;
144 assert(x >= 0);
145 trace1("rev", x);
147 double f0 = 0.;
148 double f1 = 0.;
149 if (x > 0) {
150 for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
151 const_iterator p = _table.begin(); p != _table.end(); ++p) {
152 double coeff = p->second * pow(x, p->first-1);
153 f1 += coeff * p->first;
154 f0 += coeff * x;
156 }else{
157 assert(x == 0);
158 for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
159 const_iterator p = _table.begin(); p != _table.end(); ++p) {
160 if (p->first == 0.) {
161 f0 += 1;
162 untested();
167 trace3("", x, f0, f1);
169 if (_odd && x_raw < 0) {
170 f0 = -f0;
172 if (_even && x_raw < 0) {
173 f1 = -f1;
174 untested();
176 trace3("after", x, f0, f1);
178 if (_abs && f0 < 0) {
179 f0 = -f0;
180 f1 = -f1;
181 untested();
184 if (f0 > _max) {
185 f0 = _max;
186 f1 = 0;
187 untested();
188 }else if (f0 < _min) {
189 f0 = _min;
190 f1 = 0;
191 untested();
194 d->_y[0] = FPOLY1(x_raw, f0, f1);
195 tr_final_adjust(&(d->_y[0]), d->f_is_value());
196 trace3("fa", d->_y[0].x, d->_y[0].f0, d->_y[0].f1);
198 /*--------------------------------------------------------------------------*/
199 bool EVAL_BM_POSY::parse_numlist(CS& cmd)
201 unsigned start = cmd.cursor();
202 unsigned here = cmd.cursor();
203 for (;;) {
204 unsigned start_of_pair = here;
205 std::pair<PARAMETER<double>, PARAMETER<double> > p;
206 cmd >> p.second; // value
207 if (cmd.stuck(&here)) {
208 // no more, graceful finish
209 break;
210 }else{
211 cmd >> p.first; // key
212 if (cmd.stuck(&here)) {
213 // ran out, but already have half of the pair
214 // back up one, hoping somebody else knows what to do with it
215 cmd.reset(start_of_pair);
216 break;
217 }else{
218 _table.push_back(p);
222 if (cmd.gotit(start)) {
223 }else{
224 untested();
226 return cmd.gotit(start);
228 /*--------------------------------------------------------------------------*/
229 bool EVAL_BM_POSY::parse_params_obsolete_callback(CS& cmd)
231 return ONE_OF
232 || Get(cmd, "min", &_min)
233 || Get(cmd, "max", &_max)
234 || Get(cmd, "abs", &_abs)
235 || Get(cmd, "odd", &_odd)
236 || Get(cmd, "even", &_even)
237 || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd)
240 /*--------------------------------------------------------------------------*/
241 /*--------------------------------------------------------------------------*/
242 EVAL_BM_POSY p1(CC_STATIC);
243 DISPATCHER<COMMON_COMPONENT>::INSTALL d1(&bm_dispatcher, "posy", &p1);
245 /*--------------------------------------------------------------------------*/
246 /*--------------------------------------------------------------------------*/
247 // vim:ts=8:sw=2:noet: