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

📄 evaluate.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    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(dvec);    res->v_flags = v->v_flags;    res->v_name = mkcname('[', v->v_name, ind->v_name);    res->v_defcolor = v->v_defcolor;    res->v_gridtype = v->v_gridtype;    res->v_plottype = v->v_plottype;    res->v_type = v->v_type;    res->v_length = length;    res->v_numdims = newdim;    for (i = 0; i < newdim; i++)        res->v_dims[i] = v->v_dims[i];        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...     */    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];    /* 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)) {            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) {        t = alloc(dvec);#ifdef BSD        /* 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, sig_matherr);#endif        if (eq(func->fu_name, "interpolate"))       /* 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));        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 BSD        /* Back to normal... */        (void) signal(SIGILL, SIG_DFL);#endif        if (!data)            return (NULL);        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], *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);    }        /* 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 BSD    /* 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, 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 BSD    /* Back to normal... */    (void) signal(SIGILL, SIG_DFL);#endif    /* Make up the new vector. */    res = alloc(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;    /* This depends somewhat on what the operation is... 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 + -