⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evaluate.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
    int len, i, j;    bool rev = FALSE;    v = ft_evaluate(arg1);    ind = ft_evaluate(arg2);    if (!v || !ind)        return (NULL);    scale = v->v_scale;    if (!scale)        scale = v->v_plot->pl_scale;    if (!scale) {        fprintf(cp_err, "Error: no scale for vector %s\n", v->v_name);        return (NULL);    }    if (ind->v_length != 1) {        fprintf(cp_err, "Error: strange range specification\n");        return (NULL);    }    if (isreal(ind)) {        up = low = *ind->v_realdata;    } else {        up = imagpart(ind->v_compdata);        low = realpart(ind->v_compdata);    }    if (up < low) {        td = up;        up = low;        low = td;        rev = TRUE;    }    for (i = len = 0; i < scale->v_length; i++) {        td = isreal(scale) ? scale->v_realdata[i] :                realpart(&scale->v_compdata[i]);        if ((td <= up) && (td >= low))            len++;    }    res = alloc(struct dvec);    ZERO(res,struct dvec);    res->v_name = mkcname('R', v->v_name, ind->v_name);    res->v_type = v->v_type;    res->v_flags = v->v_flags;    res->v_gridtype = v->v_gridtype;    res->v_plottype = v->v_plottype;    res->v_defcolor = v->v_defcolor;    res->v_length = len;    res->v_scale = /* nscale; */ scale;    /* Dave says get rid of this    res->v_numdims = v->v_numdims;    for (i = 0; i < v->v_numdims; i++)        res->v_dims[i] = v->v_dims[i];    */    res->v_numdims = 1;    res->v_dims[0] = len;    if (isreal(res))        res->v_realdata = (double *) tmalloc(sizeof (double) * len);    else        res->v_compdata = (complex *) tmalloc(sizeof (complex) * len);    /* Toss in the data */    j = 0;    for (i = (rev ? v->v_length - 1 : 0); i != (rev ? -1 : v->v_length);            rev ? i-- : i++) {        td = isreal(scale) ? scale->v_realdata[i] :                realpart(&scale->v_compdata[i]);        if ((td <= up) && (td >= low)) {            if (isreal(res)) {                res->v_realdata[j] = v->v_realdata[i];            } else {                realpart(&res->v_compdata[j]) =                        realpart(&v->v_compdata[i]);                imagpart(&res->v_compdata[j]) =                        imagpart(&v->v_compdata[i]);            }            j++;        }    }    if (j != len)        fprintf(cp_err, "Error: something funny..\n");    /* Note that we DON'T do a vec_new, since we want this vector to be     * invisible to everybody except the result of this operation.     * Doing this will cause a lot of core leaks, though. XXX     */    vec_new(res);    /* va: garbage collection */    if (arg1->pn_value==NULL && v!=NULL) vec_free(v);    if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind);    return (res);}/* This is another operation we do specially -- if the argument is a vector of * dimension n, n > 0, the result will be either a vector of dimension n - 1, * or a vector of dimension n with only a certain range of vectors present. */struct dvec *op_ind(struct pnode *arg1, struct pnode *arg2){    struct dvec *v, *ind, *res;    int length, newdim, i, j, k, up, down;    int majsize, blocksize;    bool rev = FALSE;    v = ft_evaluate(arg1);    ind = ft_evaluate(arg2);    if (!v || !ind)        return (NULL);    /* First let's check to make sure that the vector is consistent */    if (v->v_numdims > 1) {        for (i = 0, j = 1; i < v->v_numdims; i++)            j *= v->v_dims[i];        if (v->v_length != j) {            fprintf(cp_err,                "op_ind: Internal Error: len %d should be %d\n",                v->v_length, j);            return (NULL);        }    } else {        /* Just in case we were sloppy */        v->v_numdims = 1;        v->v_dims[0] = v->v_length;        if (v->v_length <= 1) {            fprintf(cp_err, "Error: nostrchring on a scalar (%s)\n",                    v->v_name);            return (NULL);        }    }    if (ind->v_length != 1) {        fprintf(cp_err, "Error:strchr %s is not of length 1\n",                ind->v_name);        return (NULL);    }    majsize = v->v_dims[0];    blocksize = v->v_length / majsize;    /* Now figure out if we should put the dim down by one.  Because of the     * way we parse thestrchr, we figure that if the value is complex     * (e.g, "[1,2]"), the guy meant a range.  This is sort of bad though.     */    if (isreal(ind)) {        newdim = v->v_numdims - 1;        down = up = ind->v_realdata[0];    } else {        newdim = v->v_numdims;        down = realpart(&ind->v_compdata[0]);        up = imagpart(&ind->v_compdata[0]);    }    if (up < down) {        i = up;        up = down;        down = i;        rev = TRUE;    }    if (up < 0) {        fprintf(cp_err, "Warning: upper limit %d should be 0\n", up);        up = 0;    }    if (up >= majsize) {        fprintf(cp_err, "Warning: upper limit %d should be %d\n", up,                majsize - 1);        up = majsize - 1;    }    if (down < 0) {        fprintf(cp_err, "Warning: lower limit %d should be 0\n", down);        down = 0;    }    if (down >= majsize) {        fprintf(cp_err, "Warning: lower limit %d should be %d\n", down,                majsize - 1);        down = majsize - 1;    }    if (up == down)        length = blocksize;    else        length = blocksize * (up - down + 1);    /* Make up the new vector. */    res = alloc(struct dvec);    ZERO(res,struct dvec);    res->v_name = mkcname('[', v->v_name, ind->v_name);    res->v_type = v->v_type;    res->v_flags = v->v_flags;    res->v_defcolor = v->v_defcolor;    res->v_gridtype = v->v_gridtype;    res->v_plottype = v->v_plottype;    res->v_length = length;    res->v_numdims = newdim;    if (up != down) {	for (i = 0; i < newdim; i++)	    res->v_dims[i] = v->v_dims[i];        res->v_dims[0] = up - down + 1;    } else {	for (i = 0; i < newdim; i++)	    res->v_dims[i] = v->v_dims[i + 1];    }    if (isreal(res))        res->v_realdata = (double *) tmalloc(sizeof (double) * length);    else        res->v_compdata = (complex *) tmalloc(sizeof (complex) * length);    /* And toss in the new data */    for (j = 0; j < up - down + 1; j++) {        if (rev)            k = (up - down) - j;        else            k = j;        for (i = 0; i < blocksize; i++)            if (isreal(res))                res->v_realdata[k * blocksize + i] =                    v->v_realdata[(down + j) * blocksize + i];            else {                realpart(&res->v_compdata[k * blocksize + i]) =                    realpart(&v->v_compdata[(down + j) * blocksize + i]);                imagpart(&res->v_compdata[k * blocksize + i]) =                    imagpart(&v->v_compdata[(down + j) * blocksize + i]);            }    }    /* This is a problem -- the old scale will be no good.  I guess we     * should make an altered copy of the old scale also.     */    /* Even though the old scale is no good and we should somehow decide     * on a new scale, using the vector as its own scale is not the     * solution.     */    /*     * res->v_scale = res;     */    vec_new(res);    /* va: garbage collection */    if (arg1->pn_value==NULL && v!=NULL) vec_free(v);    if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind);    return (res);}/* Apply a function to an argument. Complex functions are called as follows: *  cx_something(data, type, length, &newlength, &newtype), *  and returns a char * that is cast to complex or double. */static struct dvec *apply_func(struct func *func, struct pnode *arg){    struct dvec *v, *t, *newv = NULL, *end = NULL;    int len, i;    short type;    char *data, buf[BSIZE_SP];    /* Special case. This is not good -- happens when vm(), etc are used     * and it gets caught as a user-definable function.  Usually v()     * is caught in the parser.     */    if (!func->fu_func) {        if (!arg->pn_value /* || (arg->pn_value->v_length != 1) XXX */) {            fprintf(cp_err, "Error: bad v() syntax\n");            return (NULL);        }        (void) sprintf(buf, "v(%s)", arg->pn_value->v_name);        t = vec_fromplot(buf, plot_cur);        if (!t) {            fprintf(cp_err, "Error: no such vector %s\n", buf);            return (NULL);        }        t = vec_copy(t);        vec_new(t);        return (t);    }    v = ft_evaluate(arg);    if (v == NULL)        return (NULL);    for (; v; v = v->v_link2) {        /* Some of the math routines generate SIGILL if the argument is         * out of range.  Catch this here.         */        if (SETJMP(matherrbuf, 1)) {
            (void) signal(SIGILL, SIG_DFL);            return (NULL);        }        (void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);        if (eq(func->fu_name, "interpolate")            || eq(func->fu_name, "deriv"))       /* Ack */	{	    void *(*f)(void *data, short int type, int length,                       int *newlength, short int *newtype, ...)=func->fu_func;            data = ((*f) ((isreal(v) ? (void *) v->v_realdata : (void *) v->v_compdata),		          (short) (isreal(v) ? VF_REAL : VF_COMPLEX),		          v->v_length, &len, &type,		          v->v_plot, plot_cur, v->v_dims[0]));        } else {            data = ((*func->fu_func) ((isreal(v) ? (void *)				       v->v_realdata :				       (void *) v->v_compdata),				      (short) (isreal(v) ? VF_REAL :					       VF_COMPLEX),				      v->v_length, &len, &type));	}        /* Back to normal */        (void) signal(SIGILL, SIG_DFL);        if (!data)            return (NULL);        t = alloc(struct dvec);	ZERO(t,struct dvec);        t->v_flags = (v->v_flags & ~VF_COMPLEX & ~VF_REAL &                ~VF_PERMANENT & ~VF_MINGIVEN & ~VF_MAXGIVEN);        t->v_flags |= type;#ifdef FTEDEBUG        if (ft_evdb)            fprintf(cp_err,                "apply_func: func %s to %s len %d, type %d\n",                    func->fu_name, v->v_name, len, type);#endif	if (isreal(t))	    t->v_realdata = (double *) data;	else	    t->v_compdata = (complex *) data;	if (eq(func->fu_name, "minus"))	    t->v_name = mkcname('a', func->fu_name, v->v_name);	else if (eq(func->fu_name, "not"))	    t->v_name = mkcname('c', func->fu_name, v->v_name);	else	    t->v_name = mkcname('b', v->v_name, (char *) NULL);	t->v_type = v->v_type; /* This is strange too. */	t->v_length = len;	t->v_scale = v->v_scale;	/* Copy a few useful things */	t->v_defcolor = v->v_defcolor;	t->v_gridtype = v->v_gridtype;	t->v_plottype = v->v_plottype;	t->v_numdims = v->v_numdims;	for (i = 0; i < t->v_numdims; i++)	    t->v_dims[i] = v->v_dims[i];	vec_new(t);	if (end)	    end->v_link2 = t;	else	    newv = t;	end = t;    }    /* va: garbage collection */    if (arg->pn_value==NULL && v!=NULL) vec_free(v);    return (newv);}/* The unary minus operation. */struct dvec *op_uminus(struct pnode *arg){    return (apply_func(&func_uminus, arg));}struct dvec *op_not(struct pnode *arg){    return (apply_func(&func_not, arg));}/* Create a reasonable name for the result of a function application, etc. * The what values 'a' and 'b' mean "make a function name" and "make a * unary minus", respectively. */static char *mkcname(char what, char *v1, char *v2){    char buf[BSIZE_SP], *s;    if (what == 'a')	(void) sprintf(buf, "%s(%s)", v1, v2);    else if (what == 'b')	(void) sprintf(buf, "-(%s)", v1);    else if (what == 'c')	(void) sprintf(buf, "~(%s)", v1);    else if (what == '[')	(void) sprintf(buf, "%s[%s]", v1, v2);    else if (what == 'R')	(void) sprintf(buf, "%s[[%s]]", v1, v2);    else	(void) sprintf(buf, "(%s)%c(%s)", v1, what, v2);    s = copy(buf);    return (s);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -