Jspice3
compose.c File Reference
#include "spice.h"
#include "ftedefs.h"
Include dependency graph for compose.c:

Go to the source code of this file.

Data Structures

struct  sCompose
 

Functions

static void dimxpand ()
 
static bool cmp_values ()
 
static bool cmp_parse ()
 
static bool cmp_linsweep ()
 
static bool cmp_logsweep ()
 
static bool cmp_random ()
 
static bool cmp_gauss ()
 
void com_compose (wordlist *wl)
 
static void dimxpand (struct dvec *v, int *newdims, double *data)
 
static bool cmp_values (wordlist *wl, int *length, double **datap, complex **cdatap, bool *realflag)
 
static bool cmp_parse (wordlist *wl, struct sCompose *sc)
 
static bool cmp_linsweep (struct sCompose *sc, int *length, double **datap)
 
static bool cmp_logsweep (struct sCompose *sc, int *length, double **datap)
 
static bool cmp_random (struct sCompose *sc, int *length, double **datap)
 
static bool cmp_gauss (struct sCompose *sc, int *length, double **datap)
 
double xrandom ()
 
double xgauss ()
 

Function Documentation

static bool cmp_gauss ( )
static
static bool cmp_gauss ( struct sCompose sc,
int *  length,
double **  datap 
)
static

Definition at line 605 of file compose.c.

611 {
612  double *data;
613  int i;
614 
615  if (!sc->meangiven) {
616  sc->mean = 0;
617  sc->meangiven = true;
618  }
619  if (!sc->sdgiven) {
620  sc->sd = 1.0;
621  sc->sdgiven = true;
622  }
623 
624  data = (double *) tmalloc(sizeof (double) * sc->gauss);
625  for (i = 0; i < sc->gauss; i++)
626  data[i] = xgauss()*sc->sd + sc->mean;
627  *length = sc->gauss;
628  *datap = data;
629  return (false);
630 }
bool sdgiven
Definition: compose.c:37
int gauss
Definition: compose.c:27
bool meangiven
Definition: compose.c:36
double sd
Definition: compose.c:24
char * tmalloc()
double xgauss()
Definition: compose.c:643
double mean
Definition: compose.c:23
static bool cmp_linsweep ( )
static
static bool cmp_linsweep ( struct sCompose sc,
int *  length,
double **  datap 
)
static

Definition at line 509 of file compose.c.

515 {
516  double *data, tt;
517  int i;
518 
519 
520  data = (double *) tmalloc(sizeof (double) * sc->lin);
521 
522  if (sc->stepgiven && sc->startgiven && sc->stopgiven) {
523  if (sc->step !=
524  (sc->stop - sc->start) / sc->lin * (sc->reverse ? -1 : 1)) {
525  fprintf(cp_err, "Warning: bad step -- should be %lg\n",
526  (sc->stop - sc->start) / sc->lin * (sc->reverse ? -1 : 1));
527  sc->stepgiven = false;
528  }
529  }
530  if (!sc->startgiven) {
531  if (sc->stopgiven && sc->stepgiven) {
532  sc->start = sc->stop - sc->step * sc->lin;
533  }
534  else if (sc->stopgiven) {
535  sc->start = sc->stop - sc->lin;
536  }
537  else {
538  sc->start = 0;
539  }
540  sc->startgiven = true;
541  }
542  if (!sc->stopgiven) {
543  if (sc->stepgiven)
544  sc->stop = sc->start + sc->lin * sc->step;
545  else
546  sc->stop = sc->start + sc->lin;
547  sc->stopgiven = true;
548  }
549  if (!sc->stepgiven) {
550  sc->step = (sc->stop - sc->start) / sc->lin;
551  }
552  if (sc->reverse)
553  for (i = 0, tt = sc->stop; i < sc->lin; i++, tt -= sc->step)
554  data[i] = tt;
555  else
556  for (i = 0, tt = sc->start; i < sc->lin; i++, tt += sc->step)
557  data[i] = tt;
558  *length = sc->lin;
559  *datap = data;
560  return (false);
561 }
bool startgiven
Definition: compose.c:30
Definition: xforms.c:16
double start
Definition: compose.c:17
bool stopgiven
Definition: compose.c:31
FILE * cp_err
Definition: help.c:101
char * tmalloc()
bool reverse
Definition: compose.c:43
double lin
Definition: compose.c:20
bool stepgiven
Definition: compose.c:32
double stop
Definition: compose.c:18
double step
Definition: compose.c:19
static bool cmp_logsweep ( )
static
static bool cmp_logsweep ( struct sCompose sc,
int *  length,
double **  datap 
)
static

Definition at line 565 of file compose.c.

571 {
572  return (false);
573 }
static bool cmp_parse ( )
static
static bool cmp_parse ( wordlist wl,
struct sCompose sc 
)
static

Definition at line 352 of file compose.c.

356 {
357  char *s, *var, *val;
358  double *td;
359 
360  /* Parse the line... */
361  while (wl) {
362  if ((s = strchr(wl->wl_word, '=')) && s[1]) {
363  /* This is var=val. */
364  *s = '\0';
365  var = wl->wl_word;
366  val = s + 1;
367  wl = wl->wl_next;
368  }
369  else if (strchr(wl->wl_word, '=')) {
370  /* This is var= val. */
371  *s = '\0';
372  var = wl->wl_word;
373  wl = wl->wl_next;
374  if (wl) {
375  val = wl->wl_word;
376  wl = wl->wl_next;
377  }
378  else {
379  fprintf(cp_err, "Error: bad syntax\n");
380  return (true);
381  }
382  }
383  else {
384  /* This is var =val or var = val. */
385  var = wl->wl_word;
386  wl = wl->wl_next;
387  if (wl) {
388  val = wl->wl_word;
389  if (*val != '=') {
390  fprintf(cp_err,"Error: bad syntax\n");
391  return (true);
392  }
393  val++;
394  if (!*val) {
395  wl = wl->wl_next;
396  if (wl) {
397  val = wl->wl_word;
398  }
399  else {
400  fprintf(cp_err,"Error: bad syntax\n");
401  return (true);
402  }
403  }
404  wl = wl->wl_next;
405  }
406  else {
407  fprintf(cp_err, "Error: bad syntax\n");
408  return (true);
409  }
410  }
411 
412  if (cieq(var, "start")) {
413  sc->startgiven = true;
414  if (!(td = ft_numparse(&val, false))) {
415  goto bad;
416  }
417  sc->start = *td;
418  }
419  else if (cieq(var, "stop")) {
420  sc->stopgiven = true;
421  if (!(td = ft_numparse(&val, false))) {
422  goto bad;
423  }
424  sc->stop = *td;
425  }
426  else if (cieq(var, "step")) {
427  sc->stepgiven = true;
428  if (!(td = ft_numparse(&val, false))) {
429  goto bad;
430  }
431  sc->step = *td;
432  }
433  else if (cieq(var, "center")) {
434  sc->centergiven = true;
435  if (!(td = ft_numparse(&val, false))) {
436  goto bad;
437  }
438  sc->center = *td;
439  }
440  else if (cieq(var, "span")) {
441  sc->spangiven = true;
442  if (!(td = ft_numparse(&val, false))) {
443  goto bad;
444  }
445  sc->span = *td;
446  }
447  else if (cieq(var, "mean")) {
448  sc->meangiven = true;
449  if (!(td = ft_numparse(&val, false))) {
450  goto bad;
451  }
452  sc->mean = *td;
453  }
454  else if (cieq(var, "sd")) {
455  sc->sdgiven = true;
456  if (!(td = ft_numparse(&val, false))) {
457  goto bad;
458  }
459  sc->sd = *td;
460  }
461  else if (cieq(var, "lin")) {
462  sc->lingiven = true;
463  if (!(td = ft_numparse(&val, false))) {
464  goto bad;
465  }
466  sc->lin = *td;
467  }
468  else if (cieq(var, "log")) {
469  sc->loggiven = true;
470  if (!(td = ft_numparse(&val, false))) {
471  goto bad;
472  }
473  sc->log = *td;
474  }
475  else if (cieq(var, "dec")) {
476  sc->decgiven = true;
477  if (!(td = ft_numparse(&val, false))) {
478  goto bad;
479  }
480  sc->dec = *td;
481  }
482  else if (cieq(var, "gauss")) {
483  sc->gaussgiven = true;
484  if (!(td = ft_numparse(&val, false))) {
485  goto bad;
486  }
487  sc->gauss = *td;
488  }
489  else if (cieq(var, "random")) {
490  sc->randmgiven = true;
491  if (!(td = ft_numparse(&val, false))) {
492  goto bad;
493  }
494  sc->randm = *td;
495  }
496  else if (cieq(var, "pool")) {
497  sc->poolgiven = true;
498  sc->pool = val;
499  }
500  }
501  return (false);
502 bad:
503  fprintf(cp_err,"Error: bad parm %s = %s\n", var, val);
504  return (true);
505 }
bool sdgiven
Definition: compose.c:37
bool spangiven
Definition: compose.c:35
int cieq()
bool startgiven
Definition: compose.c:30
int gauss
Definition: compose.c:27
bool poolgiven
Definition: compose.c:42
bool loggiven
Definition: compose.c:38
Definition: cddefs.h:119
char * pool
Definition: compose.c:29
double * ft_numparse()
double start
Definition: compose.c:17
bool lingiven
Definition: compose.c:33
bool centergiven
Definition: compose.c:34
bool stopgiven
Definition: compose.c:31
bool meangiven
Definition: compose.c:36
double sd
Definition: compose.c:24
FILE * cp_err
Definition: help.c:101
int dec
Definition: compose.c:26
bool randmgiven
Definition: compose.c:41
bool gaussgiven
Definition: compose.c:40
double lin
Definition: compose.c:20
bool stepgiven
Definition: compose.c:32
int log
Definition: compose.c:25
double stop
Definition: compose.c:18
double step
Definition: compose.c:19
struct wordlist * wl_next
Definition: cpstd.h:23
char * wl_word
Definition: cpstd.h:22
double span
Definition: compose.c:22
bool decgiven
Definition: compose.c:39
int randm
Definition: compose.c:28
double center
Definition: compose.c:21
double mean
Definition: compose.c:23
static bool cmp_random ( )
static
static bool cmp_random ( struct sCompose sc,
int *  length,
double **  datap 
)
static

Definition at line 577 of file compose.c.

583 {
584  double *data;
585  int i;
586 
587  if (!sc->centergiven) {
588  sc->center = 0.0;
589  sc->centergiven = true;
590  }
591  if (!sc->spangiven) {
592  sc->span = 2.0;
593  sc->spangiven = true;
594  }
595  data = (double *) tmalloc(sizeof (double) * sc->randm);
596  for (i = 0; i < sc->randm; i++)
597  data[i] = (xrandom() - 0.5)*sc->span + sc->center;
598  *length = sc->randm;
599  *datap = data;
600  return (false);
601 }
bool spangiven
Definition: compose.c:35
bool centergiven
Definition: compose.c:34
char * tmalloc()
double xrandom()
Definition: compose.c:634
double span
Definition: compose.c:22
int randm
Definition: compose.c:28
double center
Definition: compose.c:21
static bool cmp_values ( )
static
static bool cmp_values ( wordlist wl,
int *  length,
double **  datap,
complex **  cdatap,
bool realflag 
)
static

Definition at line 241 of file compose.c.

248 {
249  struct pnode *pn;
250  struct dvec *vec, *v;
251  int i, j, len, dim, blocksize, dims[MAXDIMS];
252  bool rflg = true;
253  double *data;
254  complex *cdata;
255  struct dvlist *dl, *dl0;
256 
257  if ((pn = ft_getpnames(wl, true)) == NULL)
258  return (true);
259  if ((dl0 = ft_dvlist(pn)) == NULL)
260  return (true);
261 
262  /* Now make sure these are all of the same dimensionality. We
263  * can coerce the sizes...
264  */
265  dim = dl0->dl_dvec->v_numdims;
266  if (dim < 2)
267  dim = 0;
268  if (dim >= MAXDIMS) {
269  fprintf(cp_err, "Error: max dimensionality is %d\n", MAXDIMS);
270  vec_dlfree(dl0);
271  return (true);
272  }
273  len = dim ? 1 : dl0->dl_dvec->v_length;
274  if (iscomplex(dl0->dl_dvec))
275  rflg = false;
276 
277  for (dl = dl0->dl_next; dl; dl = dl->dl_next) {
278  v = dl->dl_dvec;
279  i = v->v_numdims;
280  if (i < 2) {
281  i = 0;
282  len += v->v_length;
283  }
284  else
285  len++;
286  if (i != dim) {
287  fprintf(cp_err,
288  "Error: all vectors must be of the same dimensionality\n");
289  vec_dlfree(dl0);
290  return (true);
291  }
292  if (iscomplex(v))
293  rflg = false;
294  }
295  for (i = 0; i < dim; i++) {
296  dims[i] = dl0->dl_dvec->v_dims[i];
297  for (dl = dl0->dl_next; dl; dl = dl->dl_next) {
298  v = dl->dl_dvec;
299  if (v->v_dims[i] > dims[i])
300  dims[i] = v->v_dims[i];
301  }
302  }
303  dim++;
304  dims[dim - 1] = len;
305  for (i = 0, blocksize = 1; i < dim - 1; i++)
306  blocksize *= dims[i];
307  if (rflg)
308  data = (double *) tmalloc(sizeof (double) * len * blocksize);
309  else
310  cdata = (complex *) tmalloc(sizeof (complex) * len * blocksize);
311 
312  /* Now copy all the data over... If the sizes are too small
313  * then the extra elements are left as 0.
314  */
315  for (i = 0, dl = dl0; dl; dl = dl->dl_next) {
316  v = dl->dl_dvec;
317  if (dim == 1) {
318  for (j = 0; j < v->v_length; j++) {
319  if (rflg && isreal(v))
320  data[i] = v->v_realdata[j];
321  else if (isreal(v)) {
322  realpart(&cdata[i]) = v->v_realdata[j];
323  imagpart(&cdata[i]) = 0.0;
324  }
325  else {
326  realpart(&cdata[i]) =
327  realpart(&v->v_compdata[j]);
328  imagpart(&cdata[i]) =
329  imagpart(&v->v_compdata[j]);
330  }
331  i++;
332  }
333  continue;
334  }
335  dimxpand(v, dims, (rflg ? (data + i * blocksize) :
336  (double *) (cdata + i * blocksize)));
337  i++;
338  }
339  len *= blocksize;
340  *length = len;
341  *realflag = rflg;
342  if (rflg)
343  *datap = data;
344  else
345  *cdatap = cdata;
346  vec_dlfree(dl0);
347  return (false);
348 }
struct dvlist * ft_dvlist()
if(TDesc==NULL)
Definition: cd.c:1326
Definition: ftedata.h:49
struct pnode * ft_getpnames()
static void dimxpand()
Definition: cpstd.h:29
int v_dims[MAXDIMS]
Definition: ftedata.h:41
complex * v_compdata
Definition: ftedata.h:29
struct dvlist * dl_next
Definition: ftedata.h:51
FILE * cp_err
Definition: help.c:101
char * tmalloc()
#define MAXDIMS
Definition: ftedata.h:22
#define NULL
Definition: spdefs.h:121
#define isreal(v)
Definition: ftedata.h:54
Definition: ftedata.h:24
struct dvec * dl_dvec
Definition: ftedata.h:50
#define imagpart(cval)
Definition: cpstd.h:36
#define iscomplex(v)
Definition: ftedata.h:55
void vec_dlfree()
int v_numdims
Definition: ftedata.h:40
int v_length
Definition: ftedata.h:34
double * v_realdata
Definition: ftedata.h:28
#define realpart(cval)
Definition: cpstd.h:35
Definition: fteparse.h:16
void com_compose ( wordlist wl)

Definition at line 90 of file compose.c.

93 {
94  struct sCompose sc;
95  struct dvec *result;
96  complex *cdata;
97  double *data;
98  double tt;
99  int length;
100  bool realflag = true;
101  char *resname;
102 
103  bzero(&sc,sizeof(struct sCompose));
104 
105  resname = wl->wl_word;
106  vec_remove(resname);
107  wl = wl->wl_next;
108 
109  if (eq(wl->wl_word, "values")) {
110  if (cmp_values(wl->wl_next,&length,&data,&cdata,&realflag))
111  return;
112  }
113  else {
114  if (cmp_parse(wl,&sc))
115  return;
116 
117  /* Now see what we have... start and stop are pretty much
118  * compatible with everything...
119  */
120  if (sc.stepgiven && (sc.step == 0.0)) {
121  fprintf(cp_err, "Error: step cannot = 0.0\n");
122  return;
123  }
124  if (sc.startgiven && sc.stopgiven && (sc.start > sc.stop)) {
125  tt = sc.start;
126  sc.start = sc.stop;
127  sc.stop = tt;
128  sc.reverse = true;
129  }
130  if (sc.lingiven + sc.loggiven + sc.decgiven +
131  sc.randmgiven + sc.gaussgiven > 1) {
132  fprintf(cp_err,
133  "Error: can have at most one of (lin, log, dec, random, gauss)\n");
134  return;
135  }
136  else if (sc.lingiven + sc.loggiven + sc.decgiven + sc.randmgiven +
137  sc.gaussgiven == 0) {
138  /* Hmm, if we have a start, stop, and step we're ok. */
139  if (sc.startgiven && sc.stopgiven && sc.stepgiven) {
140  sc.lingiven = true;
141  sc.lin = (sc.stop - sc.start) / sc.step + 1;
142  sc.stepgiven = false; /* Problems below... */
143  }
144  else {
145  fprintf(cp_err,
146 "Error: either one of (lin, log, dec, random, gauss) must be given, or all\n");
147  fprintf(cp_err,
148  "\tof (start, stop, and step) must be given.\n");
149  return;
150  }
151  }
152 
153  if (sc.lingiven) {
154  if (cmp_linsweep(&sc,&length,&data))
155  return;
156  }
157  else if (sc.loggiven || sc.decgiven) {
158  if (cmp_logsweep(&sc,&length,&data))
159  return;
160  }
161  else if (sc.randmgiven) {
162  if (cmp_random(&sc,&length,&data))
163  return;
164  }
165  else if (sc.gaussgiven) {
166  if (cmp_gauss(&sc,&length,&data))
167  return;
168  }
169  }
170  result = alloc(struct dvec);
171  result->v_name = copy(resname);
172  result->v_type = SV_NOTYPE;
173  result->v_flags = (realflag ? VF_REAL : VF_COMPLEX);
174  if (realflag)
175  result->v_realdata = data;
176  else
177  result->v_compdata = cdata;
178  result->v_length = length;
179  result->v_numdims = 1;
180  vec_newperm(result);
181  return;
182 }
#define eq(a, b)
Definition: misc.h:29
#define VF_REAL
Definition: fteconst.h:39
void vec_remove()
static bool cmp_parse()
Definition: xforms.c:16
Definition: cpstd.h:29
#define alloc(type)
Definition: cdmacs.h:21
int bzero(char *ptr, int num)
Definition: string.c:357
complex * v_compdata
Definition: ftedata.h:29
char * copy()
static bool cmp_random()
FILE * cp_err
Definition: help.c:101
void vec_newperm()
static bool cmp_gauss()
Definition: ftedata.h:24
char * v_name
Definition: ftedata.h:25
static bool cmp_values()
int v_type
Definition: ftedata.h:26
static bool cmp_linsweep()
struct wordlist * wl_next
Definition: cpstd.h:23
int v_numdims
Definition: ftedata.h:40
static bool cmp_logsweep()
char * wl_word
Definition: cpstd.h:22
int v_length
Definition: ftedata.h:34
short v_flags
Definition: ftedata.h:27
double * v_realdata
Definition: ftedata.h:28
#define VF_COMPLEX
Definition: fteconst.h:40
#define SV_NOTYPE
Definition: fteconst.h:11
static void dimxpand ( )
static
static void dimxpand ( struct dvec v,
int *  newdims,
double *  data 
)
static

Definition at line 186 of file compose.c.

192 {
193  complex *cdata = (complex *) data;
194  bool realflag = isreal(v);
195  int i, j, o, n, t, u;
196  int ncount[MAXDIMS], ocount[MAXDIMS];
197  int dims;
198 
199  dims = v->v_numdims;
200  if (dims == 0)
201  dims = 1;
202 
203  for (i = 0; i < MAXDIMS; i++)
204  ncount[i] = ocount[i] = 0;
205 
206  for (;;) {
207  for (o = n = i = 0; i < dims; i++) {
208  for (j = i, t = u = 1; j < dims; j++) {
209  t *= v->v_dims[j];
210  u *= newdims[j];
211  }
212  o += ocount[i] * t;
213  n += ncount[i] * u;
214  }
215 
216  if (realflag) {
217  data[n] = v->v_realdata[o];
218  }
219  else {
220  realpart(&cdata[n]) = realpart(&v->v_compdata[o]);
221  imagpart(&cdata[n]) = imagpart(&v->v_compdata[o]);
222  }
223  /* Now find the next index element... */
224  for (i = dims - 1; i >= 0; i--) {
225  if ((ocount[i] < v->v_dims[i] - 1) &&
226  (ncount[i] < newdims[i] - 1)) {
227  ocount[i]++;
228  ncount[i]++;
229  break;
230  }
231  else
232  ocount[i] = ncount[i] = 0;
233  }
234  if (i < 0)
235  break;
236  }
237 }
Definition: cpstd.h:29
int v_dims[MAXDIMS]
Definition: ftedata.h:41
complex * v_compdata
Definition: ftedata.h:29
#define MAXDIMS
Definition: ftedata.h:22
#define isreal(v)
Definition: ftedata.h:54
#define imagpart(cval)
Definition: cpstd.h:36
Definition: cddefs.h:142
int v_numdims
Definition: ftedata.h:40
double * v_realdata
Definition: ftedata.h:28
Definition: cddefs.h:192
#define realpart(cval)
Definition: cpstd.h:35
double xgauss ( )

Definition at line 643 of file compose.c.

649 {
650  static bool iset;
651  static double gset;
652  double fac, r, v1, v2;
653  /* xrandom() returns uniform deviate [0-1] */
654 
655  if (!iset) {
656  do {
657  v1 = 2.0*xrandom() - 1.0;
658  v2 = 2.0*xrandom() - 1.0;
659  r = v1*v1 + v2*v2;
660  } while (r >= 1.0);
661  fac = sqrt(-2.0*log(r)/r);
662  gset = v1*fac;
663  iset = true;
664  return (v2*fac);
665  }
666  iset = false;
667  return (gset);
668 }
double xrandom()
Definition: compose.c:634
Definition: cddefs.h:162
double xrandom ( )

Definition at line 634 of file compose.c.

637 {
638  return ((random() & 0x7fffffff)/(0x7fffffff + 1.0));
639 }