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

📄 evaluate.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
        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);    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(func, arg)    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) {#ifdef HAS_SIGS_AND_LJMP        /* Some of the math routines generate SIGILL if the argument is         * out of range.  Catch this here.         */        if (setjmp(matherrbuf)) {            (void) signal(SIGILL, SIG_DFL);            return (NULL);        }        (void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);#endif        if (eq(func->fu_name, "interpolate")            || eq(func->fu_name, "deriv"))       /* Ack */	{            data = (char *) ((*func->fu_func) ((isreal(v) ? (char *)                v->v_realdata : (char *) 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 = (char *) ((*func->fu_func) ((isreal(v) ? (char *)                v->v_realdata : (char *) v->v_compdata),                (short) (isreal(v) ? VF_REAL : VF_COMPLEX),                v->v_length, &len, &type));	}#ifdef HAS_SIGS_AND_LJMP        /* Back to normal */        (void) signal(SIGILL, SIG_DFL);#endif        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;    }    return (newv);}/* The unary minus operation. */struct dvec *op_uminus(arg)    struct pnode *arg;{    return (apply_func(&func_uminus, arg));}struct dvec *op_not(arg)    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(what, v1, v2)    char what;    char *v1, *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);}/* Operate on two vectors, and return a third with the data, length, and flags * fields filled in. Add it to the current plot and get rid of the two args. */static struct dvec *doop(what, func, arg1, arg2)    char what;    char *(*func)();    struct pnode *arg1, *arg2;{    struct dvec *v1, *v2, *res;    complex *c1, *c2, lc;    double *d1, *d2, ld;    int length, i;    char *data;    bool free1 = false, free2 = false, relflag = false;    v1 = ft_evaluate(arg1);    v2 = ft_evaluate(arg2);    if (!v1 || !v2)	return (NULL);    /* Now the question is, what do we do when one or both of these     * has more than one vector?  This is definitely not a good     * thing.  For the time being don't do anything.     */    if (v1->v_link2 || v2->v_link2) {	fprintf(cp_err, "Warning: no operations on wildcards yet.\n");	if (v1->v_link2 && v2->v_link2)	    fprintf(cp_err, "\t(You couldn't do that one anyway)\n");	return (NULL);    }    /* How do we handle operations on multi-dimensional vectors?     * For now, we only allow operations between one-D vectors,     * equivalently shaped multi-D vectors, or a multi-D vector and     * a one-D vector.  It's not at all clear what to do in the other cases.     * So only check shape requirement if its an operation between two multi-D     * arrays.     */    if ((v1->v_numdims > 1) && (v2->v_numdims > 1)) {	if (v1->v_numdims != v2->v_numdims) {	    fprintf(cp_err,		"Warning: operands %s and %s have incompatible shapes.\n",		v1->v_name, v2->v_name);	    return (NULL);	}	for (i = 1; i < v1->v_numdims; i++) {	    if ((v1->v_dims[i] != v2->v_dims[i])) {		fprintf(cp_err,		    "Warning: operands %s and %s have incompatible shapes.\n",		    v1->v_name, v2->v_name);		return (NULL);	    }	}    }    /* This is a bad way to do this. */    switch (what) {	case '=':	case '>':	case '<':	case 'G':	case 'L':	case 'N':	case '&':	case '|':	case '~':	    relflag = true;    }    /* Don't bother to do type checking.  Maybe this should go in at     * some point.     */    /* Make sure we have data of the same length. */    length = ((v1->v_length > v2->v_length) ? v1->v_length : v2->v_length);    if (v1->v_length < length) {	free1 = true;	if (isreal(v1)) {	    ld = 0.0;	    d1 = (double *) tmalloc(length * sizeof (double));	    for (i = 0; i < v1->v_length; i++)		d1[i] = v1->v_realdata[i];	    if (length > 0)		ld = v1->v_realdata[v1->v_length - 1];	    for ( ; i < length; i++)		d1[i] = ld;	} else {	    realpart(&lc) = 0.0;	    imagpart(&lc) = 0.0;	    c1 = (complex *) tmalloc(length * sizeof (complex));	    for (i = 0; i < v1->v_length; i++)		c1[i] = v1->v_compdata[i];	    if (length > 0)		lc = v1->v_compdata[v1->v_length - 1];	    for ( ; i < length; i++)		c1[i] = lc;	}    } else	if (isreal(v1))	    d1 = v1->v_realdata;	else	    c1 = v1->v_compdata;    if (v2->v_length < length) {	free2 = true;	if (isreal(v2)) {	    ld = 0.0;	    d2 = (double *) tmalloc(length * sizeof (double));	    for (i = 0; i < v2->v_length; i++)		d2[i] = v2->v_realdata[i];	    if (length > 0)		ld = v2->v_realdata[v2->v_length - 1];	    for ( ; i < length; i++)		d2[i] = ld;	} else {	    realpart(&lc) = 0.0;	    imagpart(&lc) = 0.0;	    c2 = (complex *) tmalloc(length * sizeof (complex));	    for (i = 0; i < v2->v_length; i++)		c2[i] = v2->v_compdata[i];	    if (length > 0)		lc = v2->v_compdata[v1->v_length - 1];	    for ( ; i < length; i++)		c2[i] = lc;	}    } else	if (isreal(v2))	    d2 = v2->v_realdata;	else	    c2 = v2->v_compdata;#ifdef HAS_SIGS_AND_LJMP    /* Some of the math routines generate SIGILL if the argument is     * out of range.  Catch this here.     */    if (setjmp(matherrbuf)) {        return (NULL);    }    (void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);#endif    /* Now pass the vectors to the appropriate function. */    data = (char *) ((*func) ((isreal(v1) ? (char *) d1 : (char *) c1),                  (isreal(v2) ? (char *) d2 : (char *) c2),                  (isreal(v1) ? VF_REAL : VF_COMPLEX),                  (isreal(v2) ? VF_REAL : VF_COMPLEX),                  length));#ifdef HAS_SIGS_AND_LJMP    /* Back to normal */    (void) signal(SIGILL, SIG_DFL);#endif    if (!data)	return (NULL);    /* Make up the new vector. */    res = alloc(struct dvec);    ZERO(res,struct dvec);    if (relflag || (isreal(v1) && isreal(v2) && (func != cx_comma))) {        res->v_flags = (v1->v_flags | v2->v_flags |                        VF_REAL) & ~ VF_COMPLEX;        res->v_realdata = (double *) data;    } else {        res->v_flags = (v1->v_flags | v2->v_flags |                        VF_COMPLEX) & ~ VF_REAL;        res->v_compdata = (complex *) data;    }    res->v_name = mkcname(what, v1->v_name, v2->v_name);    res->v_length = length;    /* This is a non-obvious thing */    if (v1->v_scale != v2->v_scale) {        fprintf(cp_err, "Warning: scales of %s and %s are different.\n",                v1->v_name, v2->v_name);        res->v_scale = NULL;    } else        res->v_scale = v1->v_scale;    /* Copy a few useful things */    res->v_defcolor = v1->v_defcolor;    res->v_gridtype = v1->v_gridtype;    res->v_plottype = v1->v_plottype;    /* Copy dimensions. */    if (v1->v_numdims > v2->v_numdims) {	res->v_numdims = v1->v_numdims;	for (i = 0; i < v1->v_numdims; i++)	    res->v_dims[i] = v1->v_dims[i];    } else {	res->v_numdims = v2->v_numdims;	for (i = 0; i < v2->v_numdims; i++)	    res->v_dims[i] = v2->v_dims[i];    }    /* This depends somewhat on what the operation is.  XXX Should fix */    res->v_type = v1->v_type;    vec_new(res);    /* Free the temporary data areas we used, if we allocated any. */    if (free1) {        if (isreal(v1)) {            tfree(d1);        } else {            tfree(c1);        }    }    if (free2) {        if (isreal(v2)) {            tfree(d2);        } else {            tfree(c2);        }    }    return (res);}

⌨️ 快捷键说明

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