📄 com_compose.c
字号:
/* The 'compose' command. This is a more powerful and convenient form * of the 'let' command. */#include <ngspice.h>#include <complex.h>#include <dvec.h>#include <bool.h>#include <sim.h>#include <pnode.h>#include <fteext.h>#include <cpextern.h>#include "quote.h"#include "com_compose.h"#include "completion.h"/* Copy the data from a vector into a buffer with larger dimensions. */static voiddimxpand(struct dvec *v, int *newdims, double *data){ complex *cdata = (complex *) data; bool realflag = isreal(v); int i, j, o, n, t, u; int ncount[MAXDIMS], ocount[MAXDIMS]; for (i = 0; i < MAXDIMS; i++) ncount[i] = ocount[i] = 0; for (;;) { for (o = n = i = 0; i < v->v_numdims; i++) { for (j = i, t = u = 1; j < v->v_numdims; j++) { t *= v->v_dims[j]; u *= newdims[j]; } o += ocount[i] * t; n += ncount[i] * u; } if (realflag) { data[n] = v->v_realdata[o]; } else { realpart(&cdata[n]) = realpart(&v->v_compdata[o]); imagpart(&cdata[n]) = imagpart(&v->v_compdata[o]); } /* Now find the nextstrchr element... */ for (i = v->v_numdims - 1; i >= 0; i--) { if ((ocount[i] < v->v_dims[i] - 1) && (ncount[i] < newdims[i] - 1)) { ocount[i]++; ncount[i]++; break; } else ocount[i] = ncount[i] = 0; } if (i < 0) break; } return;}/* The general syntax is 'compose name parm = val ...' * The possible parms are: * start The value at which the vector should start. * stop The value at which the vector should end. * step The difference between sucessive elements. * lin The number of points, linearly spaced. * log The number of points, logarithmically spaced. * dec The number of points per decade, logarithmically spaced. * center Where to center the range of points. * span The size of the range of points. * unif ?? * gauss The number of points in the gaussian distribution. * mean The mean value for the gass. dist. * sd The standard deviation for the gauss. dist. * random The number of randomly selected points. * pool The name of a vector (must be already defined) to get * random values -- default is 'unitvec(npoints)' * * The case 'compose name values val val ...' takes the values and creates a * new vector -- the vals may be arbitrary expressions. * * NOTE: most of this doesn't work -- there will be plenty of unused variable * lint messages... */voidcom_compose(wordlist *wl){ double start = 0.0; double stop = 0.0; double step = 0.0; double lin = 0.0; double center; double span; double mean, sd; bool startgiven = FALSE, stopgiven = FALSE, stepgiven = FALSE; bool lingiven = FALSE; bool loggiven = FALSE, decgiven = FALSE, gaussgiven = FALSE; bool randmgiven = FALSE; bool spangiven = FALSE; bool centergiven = FALSE; bool meangiven = FALSE; bool poolgiven = FALSE; bool sdgiven = FALSE; int log, dec, gauss, randm; char *pool; int i; char *resname, *s, *var, *val; double *td, tt; double *data = NULL; complex *cdata = NULL; int length = 0; int dim, type = SV_NOTYPE, blocksize; bool realflag = TRUE; int dims[MAXDIMS]; struct dvec *result, *vecs = NULL, *v, *lv = NULL; struct pnode *pn, *first_pn=NULL; bool reverse = FALSE; resname = cp_unquote(wl->wl_word); vec_remove(resname); wl = wl->wl_next; if (eq(wl->wl_word, "values")) { /* Build up the vector from the rest of the line... */ wl = wl->wl_next; if (!(pn = ft_getpnames(wl, TRUE))) return; first_pn = pn; while (pn) { if (!(v = ft_evaluate(pn))) return; if (!vecs) vecs = lv = v; else lv->v_link2 = v; for (lv = v; lv->v_link2; lv = lv->v_link2) ; pn = pn->pn_next; } /* Now make sure these are all of the same dimensionality. We * can coerce the sizes... */ dim = vecs->v_numdims; if (dim < 2) dim = (vecs->v_length > 1) ? 1 : 0; if (dim == MAXDIMS) { fprintf(cp_err, "Error: max dimensionality is %d\n", MAXDIMS); return; } for (v = vecs; v; v = v->v_link2) if (v->v_numdims < 2) v->v_dims[0] = v->v_length; for (v = vecs->v_link2, length = 1; v; v = v->v_link2) { i = v->v_numdims; if (i < 2) i = (v->v_length > 1) ? 1 : 0; if (i != dim) { fprintf(cp_err, "Error: all vectors must be of the same dimensionality\n"); return; } length++; if (iscomplex(v)) realflag = FALSE; } for (i = 0; i < dim; i++) { dims[i] = vecs->v_dims[i]; for (v = vecs->v_link2; v; v = v->v_link2) if (v->v_dims[i] > dims[i]) dims[i] = v->v_dims[i]; } dim++; dims[dim - 1] = length; for (i = 0, blocksize = 1; i < dim - 1; i++) blocksize *= dims[i]; if (realflag) data = (double *) tmalloc(sizeof (double) * length * blocksize); else cdata = (complex *) tmalloc(sizeof (complex) * length * blocksize); /* Now copy all the data over... If the sizes are too small * then the extra elements are left as 0. */ for (v = vecs, i = 0; v; v = v->v_link2) { if (dim == 1) { if (realflag && isreal(v)) data[i] = v->v_realdata[0]; else if (isreal(v)) { realpart(&cdata[i]) = realpart(&v->v_compdata[0]); imagpart(&cdata[i]) = 0.0; } else { realpart(&cdata[i]) = realpart(&v->v_compdata[0]); imagpart(&cdata[i]) = imagpart(&v->v_compdata[0]); } i++; continue; } dimxpand(v, dims, (realflag ? (data + i * blocksize) : (double *) (cdata + i * blocksize))); } length *= blocksize; } else { /* Parse the line... */ while (wl) { if ((s =strchr(wl->wl_word, '=')) && s[1]) { /* This is var=val. */ *s = '\0'; var = wl->wl_word; val = s + 1; wl = wl->wl_next; } else if (index(wl->wl_word, '=')) { /* This is var= val. */ *s = '\0'; var = wl->wl_word; wl = wl->wl_next; if (wl) { val = wl->wl_word; wl = wl->wl_next; } else { fprintf(cp_err, "Error: bad syntax\n"); return; } } else { /* This is var =val or var = val. */ var = wl->wl_word; wl = wl->wl_next; if (wl) { val = wl->wl_word; if (*val != '=') { fprintf(cp_err, "Error: bad syntax\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -