Jspice3
ptfuncs.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1987 Wayne A. Christopher
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * All the functions used in the parse tree. These functions return HUGE
10  * if their argument is out of range.
11  */
12 
13 #include "spice.h"
14 #include <stdio.h>
15 #include <math.h>
16 #include "inpptree.h"
17 
18 /* These should be in math.h */
19 extern double asinh(), acosh(), atanh();
20 
21 #ifdef __STDC__
22 static double PTtPulse(INPparseNode*,double*);
23 static double PTtPwl(INPparseNode*,double*);
24 static double PTtSin(INPparseNode*,double*);
25 static double PTtSpulse(INPparseNode*,double*);
26 static double PTtExp(INPparseNode*,double*);
27 static double PTtSffm(INPparseNode*,double*);
28 static double PTabs(double);
29 static double PTsgn(double);
30 static double PTplus(double,double);
31 static double PTminus(double,double);
32 static double PTtimes(double,double);
33 static double PTdivide(double,double);
34 static double PTpower(double,double);
35 static double PTacos(double);
36 static double PTasin(double);
37 static double PTatan(double);
38 #ifdef HAVE_ACOSH
39 static double PTacosh(double);
40 static double PTasinh(double);
41 static double PTatanh(double);
42 #endif /* HAVE_ACOSH */
43 static double PTcos(double);
44 static double PTcosh(double);
45 static double PTexp(double);
46 static double PTln(double);
47 static double PTlog(double);
48 static double PTsin(double);
49 static double PTsinh(double);
50 static double PTsqrt(double);
51 static double PTtan(double);
52 static double PTtanh(double);
53 static double PTuminus(double);
54 #else
55 static double PTtPulse();
56 static double PTtPwl();
57 static double PTtSin();
58 static double PTtSpulse();
59 static double PTtExp();
60 static double PTtSffm();
61 static double PTabs();
62 static double PTsgn();
63 static double PTplus();
64 static double PTminus();
65 static double PTtimes();
66 static double PTdivide();
67 static double PTpower();
68 static double PTacos();
69 static double PTasin();
70 static double PTatan();
71 #ifdef HAVE_ACOSH
72 static double PTacosh();
73 static double PTasinh();
74 static double PTatanh();
75 #endif /* HAVE_ACOSH */
76 static double PTcos();
77 static double PTcosh();
78 static double PTexp();
79 static double PTln();
80 static double PTlog();
81 static double PTsin();
82 static double PTsinh();
83 static double PTsqrt();
84 static double PTtan();
85 static double PTtanh();
86 static double PTuminus();
87 #endif
88 
89 
91 
92 #define MODULUS(NUM,LIMIT) ((NUM) - ((int) ((NUM) / (LIMIT))) * (LIMIT))
93 
94 
95 /* Tables that the parser uses. */
96 
97 struct sPTop PTops[] = {
98  { PT_COMMA, ",", NULL } ,
99  { PT_PLUS, "+", PTplus } ,
100  { PT_MINUS, "-", PTminus } ,
101  { PT_TIMES, "*", PTtimes } ,
102  { PT_DIVIDE, "/", PTdivide },
103  { PT_POWER, "^", PTpower },
104  { PT_PLACEHOLDER, NULL, (double(*)())NULL }
105 };
106 
107 struct sPTfunc PTfuncs[] = {
108  { "abs", PTF_ABS, PTabs } ,
109  { "acos", PTF_ACOS, PTacos } ,
110  { "asin", PTF_ASIN, PTasin } ,
111  { "atan", PTF_ATAN, PTatan } ,
112 #ifdef HAVE_ACOSH
113  { "acosh", PTF_ACOSH, PTacosh } ,
114  { "asinh", PTF_ASINH, PTasinh } ,
115  { "atanh", PTF_ATANH, PTatanh } ,
116 #endif /* HAVE_ACOSH */
117  { "cos", PTF_COS, PTcos } ,
118  { "cosh", PTF_COSH, PTcosh } ,
119  { "exp", PTF_EXP, PTexp } ,
120  { "ln", PTF_LN, PTln } ,
121  { "log", PTF_LOG, PTlog } ,
122  { "sgn", PTF_SGN, PTsgn } ,
123  { "sin", PTF_SIN, PTsin } ,
124  { "sinh", PTF_SINH, PTsinh } ,
125  { "sqrt", PTF_SQRT, PTsqrt } ,
126  { "tan", PTF_TAN, PTtan } ,
127  { "tanh", PTF_TANH, PTtanh } ,
128  { "-", PTF_UMINUS, PTuminus },
129  { NULL, 0, (double(*)())NULL }
130 };
131 
132 struct sPTfunc PTtFuncs[] = {
133  { "pulse", PTF_tPULSE, PTtPulse } ,
134  { "pwl", PTF_tPWL, PTtPwl } ,
135  { "sin", PTF_tSIN, PTtSin } ,
136  { "spulse", PTF_tSPULSE,PTtSpulse } ,
137  { "exp", PTF_tEXP, PTtExp } ,
138  { "sffm", PTF_tSFFM, PTtSffm } ,
139  { NULL, 0, (double(*)())NULL }
140 };
141 
142 #define V1 p->tranparms[0]
143 #define V2 p->tranparms[1]
144 #define TD p->tranparms[2]
145 #define TR p->tranparms[3]
146 #define TF p->tranparms[4]
147 #define PW p->tranparms[5]
148 #define PER p->tranparms[6]
149 
150 #define SPER p->tranparms[2]
151 #define SDEL p->tranparms[3]
152 
153 #define VO p->tranparms[0]
154 #define VA p->tranparms[1]
155 #define FREQ p->tranparms[2]
156 #define TDL p->tranparms[3]
157 #define THETA p->tranparms[4]
158 
159 #define TD1 p->tranparms[2]
160 #define TAU1 p->tranparms[3]
161 #define TD2 p->tranparms[4]
162 #define TAU2 p->tranparms[5]
163 
164 #define FC p->tranparms[2]
165 #define MDI p->tranparms[3]
166 #define FS p->tranparms[4]
167 
168 /* evaluate the tran functions */
169 
170 static double
172 
173 INPparseNode *p;
174 double *t;
175 {
176  double time, basetime, value;
177  double pw = TR + PW;
178  int i;
179 
180  time = *t - TD;
181  if (time > PER) {
182  /* repeating signal - figure out where we are in period */
183  basetime = PER * (int)(time/PER);
184  time -= basetime;
185  }
186  if (time < TR || time >= pw + TF) {
187  value = V1;
188  if (time > 0 && time < TR)
189  value += time* *p->trancache;
190  }
191  else {
192  value = V2;
193  if (time > pw)
194  value += (time - pw)* *(p->trancache+1);
195  }
196 
197  /* new feature: additional entries are added as in
198  * pulse(V1 V2 TD ...) + pulse(0 V2-V1 TD1 ...) + ...
199  * extra entries have offset subtracted
200  */
201  for (i = 7; i < p->numtrancoeffs; i++) {
202  time = *t - p->trancoeffs[i];
203  if (time > PER) {
204  /* repeating signal - figure out where we are in period */
205  basetime = PER * (int)(time/PER);
206  time -= basetime;
207  }
208  if (time < TR || time >= pw + TF) {
209  if (time > 0 && time < TR)
210  value += time* *p->trancache;
211  }
212  else {
213  value += (V2-V1);
214  if (time > pw)
215  value += (time - pw)* *(p->trancache+1);
216  }
217  }
218  return (value);
219 }
220 
221 
222 static double
224 
225 INPparseNode *p;
226 double *t;
227 {
228  if (*t >= (*p->trancoeffs+p->numtrancoeffs-2))
229  return (*(p->trancoeffs+p->numtrancoeffs-1));
230  if (p->pwlindex + 2 < p->numtrancoeffs) {
231  for (;;) {
232  if (*t <= *(p->trancoeffs+p->pwlindex+2)) break;
233  p->pwlindex += 2;
234  if (p->pwlindex >= p->numtrancoeffs) break;
235  }
236  }
237  for (;;) {
238  if (*t < *(p->trancoeffs+p->pwlindex) && p->pwlindex)
239  p->pwlindex -= 2;
240  else break;
241  }
242  if (!p->pwlindex && *t <= *(p->trancoeffs)) {
243  return (*(p->trancoeffs+1));
244  }
245  if (p->pwlindex >= p->numtrancoeffs) {
246  return (*(p->trancoeffs+p->numtrancoeffs-1));
247  }
248  return ( *(p->trancoeffs+p->pwlindex+1) +
249  *(p->trancache + (p->pwlindex >> 1)) *
250  (*t - *(p->trancoeffs+p->pwlindex)) );
251 }
252 
253 
254 static double
256 
257 INPparseNode *p;
258 double *t;
259 {
260  double time, value;
261 
262  time = *t - TDL;
263  if (time <= 0)
264  return (VO);
265  return (VO + VA*sin(FREQ * time * 2*M_PI)*exp(-time*THETA));
266 }
267 
268 
269 static double
271 
272 INPparseNode *p;
273 double *t;
274 {
275  double time;
276 
277  time = *t - SDEL;
278  if (time <= 0)
279  return (V1);
280  return (V1 +
281  (V2-V1)*( 1 - cos(2*M_PI*time/SPER)*exp(-time*THETA) )/2);
282 }
283 
284 
285 static double
287 
288 INPparseNode *p;
289 double *t;
290 {
291  double value;
292 
293  value = V1;
294  if (*t <= TD1)
295  return (value);
296  value += (V2-V1)*(1-exp(-(*t-TD1)/TAU1));
297  if (*t <= TD2)
298  return (value);
299  value += (V1-V2)*(1-exp(-(*t-TD2)/TAU2));
300  return (value);
301 }
302 
303 
304 static double
306 
307 INPparseNode *p;
308 double *t;
309 {
310  return (VO + VA*sin((2*M_PI * FC * *t) +
311  MDI * sin(2*M_PI * FS * *t)));
312 }
313 
314 
315 /* evaluate the math functions */
316 
317 static double
318 PTabs(arg)
319 
320 double arg;
321 { return arg >= 0.0 ? arg : -arg; }
322 
323 
324 static double
325 PTsgn(arg)
326 
327 double arg;
328 { return arg > 0.0 ? 1.0 : arg < 0.0 ? -1.0 : 0.0; }
329 
330 
331 static double
332 PTplus(arg1, arg2)
333 
334 double arg1, arg2;
335 { return (arg1 + arg2); }
336 
337 
338 static double
339 PTminus(arg1, arg2)
340 
341 double arg1, arg2;
342 { return (arg1 - arg2); }
343 
344 
345 static double
346 PTtimes(arg1, arg2)
347 
348 double arg1, arg2;
349 { return (arg1 * arg2); }
350 
351 
352 static double
353 PTdivide(arg1, arg2)
354 
355 double arg1, arg2;
356 {
357  if (arg2 >= 0.0)
358  arg2 += PTfudge_factor;
359  else
360  arg2 -= PTfudge_factor;
361 
362  if (arg2 == 0.0)
363  return (HUGE);
364 
365  return (arg1 / arg2);
366 }
367 
368 
369 static double
370 PTpower(arg1, arg2)
371 
372 double arg1, arg2;
373 { return (pow(arg1, arg2)); }
374 
375 
376 static double
377 PTacos(arg)
378 
379 double arg;
380 { return (acos(arg)); }
381 
382 
383 static double
384 PTasin(arg)
385 
386 double arg;
387 { return (asin(arg)); }
388 
389 
390 static double
391 PTatan(arg)
392 
393 double arg;
394 { return (atan(arg)); }
395 
396 
397 #ifdef HAVE_ACOSH
398 
399 static double
400 PTacosh(arg)
401 
402 double arg;
403 { return (acosh(arg)); }
404 
405 
406 static double
407 PTasinh(arg)
408 
409 double arg;
410 { return (asinh(arg)); }
411 
412 
413 static double
414 PTatanh(arg)
415 
416 double arg;
417 { return (atanh(arg)); }
418 
419 #endif /* HAVE_ACOSH */
420 
421 
422 static double
423 PTcos(arg)
424 
425 double arg;
426 { return (cos(MODULUS(arg, 2 * M_PI))); }
427 
428 
429 static double
430 PTcosh(arg)
431 
432 double arg;
433 { return (cosh(arg)); }
434 
435 
436 static double
437 PTexp(arg)
438 
439 double arg;
440 { return (exp(arg)); }
441 
442 
443 static double
444 PTln(arg)
445 
446 double arg;
447 {
448  if (arg < 0.0)
449  arg = -arg;
450  return (log(arg));
451 }
452 
453 
454 static double
455 PTlog(arg)
456 
457 double arg;
458 {
459  if (arg < 0.0)
460  arg = -arg;
461  return (log10(arg));
462 }
463 
464 
465 static double
466 PTsin(arg)
467 
468 double arg;
469 { return (sin(MODULUS(arg, 2 * M_PI))); }
470 
471 
472 static double
473 PTsinh(arg)
474 
475 double arg;
476 { return (sinh(arg)); }
477 
478 
479 static double
480 PTsqrt(arg)
481 
482 double arg;
483 {
484  if (arg < 0.0)
485  arg = -arg;
486  return (sqrt(arg));
487 }
488 
489 
490 static double
491 PTtan(arg)
492 
493 double arg;
494 { return (tan(MODULUS(arg, M_PI))); }
495 
496 
497 static double
498 PTtanh(arg)
499 
500 double arg;
501 { return (tanh(arg)); }
502 
503 
504 static double
506 
507 double arg;
508 { return (- arg); }
509 
static double PTtPulse()
#define PTF_SQRT
Definition: inpptree.h:97
#define PTF_tPULSE
Definition: inpptree.h:106
double asinh()
#define MDI
Definition: ptfuncs.c:165
#define PT_DIVIDE
Definition: inpptree.h:72
#define TDL
Definition: ptfuncs.c:156
#define PT_PLACEHOLDER
Definition: inpptree.h:68
#define VA
Definition: ptfuncs.c:154
static double PTexp()
#define PTF_ACOS
Definition: inpptree.h:84
#define PTF_tSIN
Definition: inpptree.h:108
#define TAU1
Definition: ptfuncs.c:160
#define V2
Definition: ptfuncs.c:143
#define PTF_COS
Definition: inpptree.h:90
static double PTsin()
#define PW
Definition: ptfuncs.c:147
#define M_PI
Definition: spice.h:132
#define V1
Definition: ptfuncs.c:142
struct sPTop PTops[]
Definition: ptfuncs.c:97
#define PTF_TANH
Definition: inpptree.h:99
#define THETA
Definition: ptfuncs.c:157
#define PER
Definition: ptfuncs.c:148
#define PTF_COSH
Definition: inpptree.h:91
Definition: cddefs.h:215
#define TD
Definition: ptfuncs.c:144
#define TD1
Definition: ptfuncs.c:159
static double PTabs()
static double PTtanh()
struct sPTfunc PTfuncs[]
Definition: ptfuncs.c:107
static double PTatan()
#define PTF_tSFFM
Definition: inpptree.h:111
#define TF
Definition: ptfuncs.c:146
#define FREQ
Definition: ptfuncs.c:155
#define PTF_EXP
Definition: inpptree.h:92
static double PTtSin()
double PTfudge_factor
Definition: ptfuncs.c:90
static double PTln()
#define VO
Definition: ptfuncs.c:153
struct sPTfunc PTtFuncs[]
Definition: ptfuncs.c:132
#define PTF_SIN
Definition: inpptree.h:95
double acosh()
static double PTsinh()
#define SPER
Definition: ptfuncs.c:150
static double PTtan()
static double PTtExp()
static double PTtPwl()
#define NULL
Definition: spdefs.h:121
static double PTpower()
#define PT_PLUS
Definition: inpptree.h:69
#define PT_MINUS
Definition: inpptree.h:70
static double PTcosh()
double cos()
#define PTF_ATANH
Definition: inpptree.h:89
#define SDEL
Definition: ptfuncs.c:151
static double PTasin()
double atanh()
static double PTuminus()
#define PTF_ASINH
Definition: inpptree.h:87
#define PT_COMMA
Definition: inpptree.h:78
static double PTtSpulse()
double sin()
#define PTF_UMINUS
Definition: inpptree.h:100
static double PTdivide()
#define TR
Definition: ptfuncs.c:145
#define MODULUS(NUM, LIMIT)
Definition: ptfuncs.c:92
#define PTF_ASIN
Definition: inpptree.h:86
static double PTsgn()
#define TD2
Definition: ptfuncs.c:161
static double PTsqrt()
#define PTF_LN
Definition: inpptree.h:93
static double PTacos()
static double PTtSffm()
#define PTF_ABS
Definition: inpptree.h:101
#define FC
Definition: ptfuncs.c:164
#define PTF_tPWL
Definition: inpptree.h:107
static double PTtimes()
#define PT_POWER
Definition: inpptree.h:73
#define PTF_LOG
Definition: inpptree.h:94
#define PTF_tEXP
Definition: inpptree.h:110
static double PTlog()
#define FS
Definition: ptfuncs.c:166
static double PTplus()
#define PTF_SINH
Definition: inpptree.h:96
#define PTF_ACOSH
Definition: inpptree.h:85
#define PTF_ATAN
Definition: inpptree.h:88
#define PTF_SGN
Definition: inpptree.h:102
#define PTF_TAN
Definition: inpptree.h:98
#define PTF_tSPULSE
Definition: inpptree.h:109
Definition: cddefs.h:192
#define TAU2
Definition: ptfuncs.c:162
#define PT_TIMES
Definition: inpptree.h:71
static double PTcos()
static double PTminus()
#define HUGE
Definition: spice.h:128