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)
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
21 *------------------------------------------------------------------
22 * SPICE compatible SIN
24 //testing=script,complete 2005.10.07
27 #include "l_denoise.h"
29 /*--------------------------------------------------------------------------*/
31 /*--------------------------------------------------------------------------*/
34 /*--------------------------------------------------------------------------*/
35 const double _default_offset (0);
36 const double _default_amplitude (1);
37 const double _default_frequency (NOT_INPUT
);
38 const double _default_delay (0);
39 const double _default_damping (0);
40 const double _default_samples (4);
41 const bool _default_zero (false);
42 const bool _default_peak (false);
43 /*--------------------------------------------------------------------------*/
44 class EVAL_BM_SIN
: public EVAL_BM_ACTION_BASE
{
46 PARAMETER
<double> _offset
;
47 PARAMETER
<double> _amplitude
;
48 PARAMETER
<double> _frequency
;
49 PARAMETER
<double> _delay
;
50 PARAMETER
<double> _damping
;
51 PARAMETER
<double> _end
;
52 PARAMETER
<double> _samples
;
53 PARAMETER
<bool> _zero
;
54 PARAMETER
<bool> _peak
;
55 void set_param_by_name(string Name
, string Value
);
57 mutable double _actual_frequency
;
58 static std::map
<string
, PARA_BASE
EVAL_BM_SIN::*> _param_dict
;
59 explicit EVAL_BM_SIN(const EVAL_BM_SIN
& p
);
61 explicit EVAL_BM_SIN(int c
=0);
63 int param_count()const {return 8 + EVAL_BM_ACTION_BASE::param_count();}
64 string
param_name(int i
)const;
65 string
param_name(int i
,int)const{return param_name(i
);}
66 string
param_value(int)const;
67 bool param_is_printable(int i
)const;
68 private: // override vitrual
69 bool operator==(const COMMON_COMPONENT
&)const;
70 COMMON_COMPONENT
* clone()const {return new EVAL_BM_SIN(*this);}
71 void print_common_obsolete_callback(OMSTREAM
&, LANGUAGE
*)const;
72 bool use_obsolete_callback_print()const {return false;}
74 void precalc_last(const CARD_LIST
*);
75 void tr_eval(ELEMENT
*)const;
76 TIME_PAIR
tr_review(COMPONENT
*)const;
77 std::string
name()const {return "sin";}
78 bool ac_too()const {return false;}
79 bool parse_numlist(CS
&);
80 bool parse_params_obsolete_callback(CS
&);
82 /*--------------------------------------------------------------------------*/
83 /*--------------------------------------------------------------------------*/
84 EVAL_BM_SIN::EVAL_BM_SIN(int c
)
85 :EVAL_BM_ACTION_BASE(c
),
86 _offset(_default_offset
),
87 _amplitude(_default_amplitude
),
88 _frequency(_default_frequency
),
89 _delay(_default_delay
),
90 _damping(_default_damping
),
92 _samples(_default_samples
),
98 /*--------------------------------------------------------------------------*/
99 EVAL_BM_SIN::EVAL_BM_SIN(const EVAL_BM_SIN
& p
)
100 :EVAL_BM_ACTION_BASE(p
),
102 _amplitude(p
._amplitude
),
103 _frequency(p
._frequency
),
105 _damping(p
._damping
),
107 _samples(p
._samples
),
110 _actual_frequency(p
._actual_frequency
)
113 /*--------------------------------------------------------------------------*/
114 bool EVAL_BM_SIN::operator==(const COMMON_COMPONENT
& x
)const
116 const EVAL_BM_SIN
* p
= dynamic_cast<const EVAL_BM_SIN
*>(&x
);
118 && _offset
== p
->_offset
119 && _amplitude
== p
->_amplitude
120 && _frequency
== p
->_frequency
121 && _delay
== p
->_delay
122 && _damping
== p
->_damping
123 && _samples
== p
->_samples
126 && EVAL_BM_ACTION_BASE::operator==(x
);
129 /*--------------------------------------------------------------------------*/
130 void EVAL_BM_SIN::print_common_obsolete_callback(OMSTREAM
& o
, LANGUAGE
* lang
)const
134 print_pair(o
, lang
, "offset", _offset
);
135 print_pair(o
, lang
, "amplitude", _amplitude
);
136 print_pair(o
, lang
, "frequency", _frequency
);
137 print_pair(o
, lang
, "delay", _delay
, _delay
.has_hard_value());
138 print_pair(o
, lang
, "damping", _damping
, _damping
.has_hard_value());
139 print_pair(o
, lang
, "samples", _samples
, _samples
.has_hard_value());
140 print_pair(o
, lang
, "zero", _zero
, _zero
.has_hard_value());
141 print_pair(o
, lang
, "peak", _peak
, _peak
.has_hard_value());
142 EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o
, lang
);
144 /*--------------------------------------------------------------------------*/
145 void EVAL_BM_SIN::precalc_last(const CARD_LIST
* Scope
)
148 EVAL_BM_ACTION_BASE::precalc_last(Scope
);
149 _offset
.e_val(_default_offset
, Scope
);
150 _amplitude
.e_val(_default_amplitude
, Scope
);
151 _frequency
.e_val(_default_frequency
, Scope
);
152 _delay
.e_val(_default_delay
, Scope
);
153 _damping
.e_val(_default_damping
, Scope
);
154 _samples
.e_val(_default_samples
, Scope
);
155 _zero
.e_val(_default_zero
, Scope
);
156 _peak
.e_val(_default_peak
, Scope
);
158 /*--------------------------------------------------------------------------*/
159 void EVAL_BM_SIN::tr_eval(ELEMENT
* d
)const
161 if (!_frequency
.has_hard_value()) {
162 _actual_frequency
= d
->_sim
->_freq
;
164 _actual_frequency
= _frequency
;
167 double reltime
= ioffset(d
->_sim
->_time0
);
169 if (reltime
> _delay
) {
170 double x
=_amplitude
*fixzero(sin(M_TWO_PI
*_actual_frequency
*(reltime
-_delay
)),1.);
171 if (_damping
!= 0.) {
172 x
*= exp(-(reltime
-_delay
)*_damping
);
178 tr_finish_tdv(d
, ev
);
180 /*--------------------------------------------------------------------------*/
181 TIME_PAIR
EVAL_BM_SIN::tr_review(COMPONENT
* d
)const
183 double eps
= d
->_sim
->_dtmin
* .01;
184 double time
= ioffset(d
->_sim
->_time0
);
185 double reltime
= time
+ eps
;
186 ELEMENT
* e
= prechecked_cast
<ELEMENT
*>(d
);
189 if (reltime
> _delay
) {
190 if (_peak
&& _zero
) {
191 d
->_time_by
.min_event(floor(reltime
* 4 * _actual_frequency
+ 1) / (4 * _actual_frequency
));
193 d
->_time_by
.min_event((floor(reltime
*2*_actual_frequency
+.5) + .5) / (2*_actual_frequency
));
195 d
->_time_by
.min_event(floor(reltime
* 2 * _actual_frequency
+ 1) / (2 * _actual_frequency
));
198 d
->_time_by
.min_error_estimate(d
->_sim
->_time0
+ 1. / (_samples
* _actual_frequency
));
199 if (time
< _delay
+eps
) {
200 e
->_discont
|= disSECOND
;
204 d
->_time_by
.min_event(_delay
);
209 /*--------------------------------------------------------------------------*/
210 bool EVAL_BM_SIN::parse_numlist(CS
& cmd
)
212 unsigned start
= cmd
.cursor();
213 unsigned here
= cmd
.cursor();
214 for (PARAMETER
<double>* i
= &_offset
; i
< &_end
; ++i
) {
215 PARAMETER
<double> val(NOT_VALID
);
217 if (cmd
.stuck(&here
)) {
223 return cmd
.gotit(start
);
225 /*--------------------------------------------------------------------------*/
226 bool EVAL_BM_SIN::parse_params_obsolete_callback(CS
& cmd
)
229 || Get(cmd
, "o{ffset}", &_offset
)
230 || Get(cmd
, "a{mplitude}", &_amplitude
)
231 || Get(cmd
, "f{requency}", &_frequency
)
232 || Get(cmd
, "de{lay}", &_delay
)
233 || Get(cmd
, "da{mping}", &_damping
)
234 || Get(cmd
, "sa{mples}", &_samples
)
235 || Get(cmd
, "ze{ro}", &_zero
)
236 || Get(cmd
, "pe{ak}", &_peak
)
237 || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd
)
240 /*--------------------------------------------------------------------------*/
241 bool EVAL_BM_SIN::param_is_printable(int i
)const
243 switch (EVAL_BM_SIN::param_count() - 1 - i
) { untested();
244 case 0: return (true);
245 case 1: return (true);
246 case 2: return (true);
247 case 3: return _delay
.has_hard_value();
248 case 4: return _damping
.has_hard_value();
249 case 5: return _samples
.has_hard_value();
250 case 6: return _zero
.has_hard_value();
251 case 7: return _peak
.has_hard_value();
252 default: return EVAL_BM_ACTION_BASE::param_is_printable(i
);
255 /*--------------------------------------------------------------------------*/
256 string
EVAL_BM_SIN::param_name(int i
)const
258 switch (EVAL_BM_SIN::param_count() - 1 - i
) { untested();
259 case 0: return "offset";
260 case 1: return "amplitude";
261 case 2: return "frequency";
262 case 3: return "delay";
263 case 4: return "damping";
264 case 5: return "samples";
265 case 6: return "zero";
266 case 7: return "peak";
267 default: return EVAL_BM_ACTION_BASE::param_name(i
);
270 /*--------------------------------------------------------------------------*/
271 string
EVAL_BM_SIN::param_value(int i
)const
273 switch (EVAL_BM_SIN::param_count() - 1 - i
) { untested();
274 case 0: return _offset
.string();
275 case 1: return _amplitude
.string();
276 case 2: return _frequency
.string();
277 case 3: return _delay
.string();
278 case 4: return _damping
.string();
279 case 5: return _samples
.string();
280 case 6: return _zero
.string();
281 case 7: return _peak
.string();
282 default: return EVAL_BM_ACTION_BASE::param_value(i
);
285 /*--------------------------------------------------------------------------*/
286 map
<string
, PARA_BASE
EVAL_BM_SIN::*> EVAL_BM_SIN::_param_dict
=
287 boost::assign::map_list_of
288 ("offset", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_offset
)
289 ("o", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_offset
)
290 ("amplitude",(PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_amplitude
)
291 ("a", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_amplitude
)
292 ("frequency",(PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_frequency
)
293 ("f", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_frequency
)
294 ("delay", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_delay
)
295 ("de", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_delay
)
296 ("damping", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_damping
)
297 ("da", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_damping
)
298 ("samples", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_samples
)
299 ("sa", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_samples
)
300 ("zero", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_zero
)
301 ("ze", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_zero
)
302 ("peak", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_peak
)
303 ("pe", (PARA_BASE
EVAL_BM_SIN::*) &EVAL_BM_SIN::_peak
);
304 /*--------------------------------------------------------------------------*/
305 void EVAL_BM_SIN::set_param_by_name(std::string Name
, std::string Value
)
307 PARA_BASE
EVAL_BM_SIN::* x
= (_param_dict
[Name
]);
309 PARA_BASE
* p
= &(this->*x
);
312 EVAL_BM_ACTION_BASE::set_param_by_name(Name
, Value
);
315 /*--------------------------------------------------------------------------*/
316 /*--------------------------------------------------------------------------*/
317 EVAL_BM_SIN
p1(CC_STATIC
);
318 DISPATCHER
<COMMON_COMPONENT
>::INSTALL
d1(&bm_dispatcher
, "sin|sine", &p1
);
320 /*--------------------------------------------------------------------------*/
321 /*--------------------------------------------------------------------------*/
322 // vim:ts=8:sw=2:noet: