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

📄 vectors.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    return (pl);}/* Stick a new vector in the proper place in the plot list. */voidvec_new(d)    struct dvec *d;{#ifdef FTEDEBUG    if (ft_vecdb)        fprintf(cp_err, "new vector %s\n", d->v_name);#endif    /* Note that this can't happen. */    if (plot_cur == NULL) {        fprintf(cp_err, "vec_new: Internal Error: no cur plot\n");    }    if ((d->v_flags & VF_PERMANENT) && (plot_cur->pl_scale == NULL))        plot_cur->pl_scale = d;    if (!d->v_plot)        d->v_plot = plot_cur;    if (d->v_numdims < 1) {        d->v_numdims = 1;        d->v_dims[0] = d->v_length;    }    d->v_next = d->v_plot->pl_dvecs;    d->v_plot->pl_dvecs = d;    return;}/* Because of the way that all vectors, including temporary vectors, * are linked together under the current plot, they can often be * left lying around. This gets rid of all vectors that don't have * the permanent flag set. Also, for the remaining vectors, it * clears the v_link2 pointer. */voidvec_gc(){    struct dvec *d, *nd;    struct plot *pl;    for (pl = plot_list; pl; pl = pl->pl_next)        for (d = pl->pl_dvecs; d; d = nd) {            nd = d->v_next;            if (!(d->v_flags & VF_PERMANENT)) {                if (ft_vecdb)                    fprintf(cp_err,                         "vec_gc: throwing away %s.%s\n",                        pl->pl_typename, d->v_name);                vec_free(d);            }        }    for (pl = plot_list; pl; pl = pl->pl_next)        for (d = pl->pl_dvecs; d; d = d->v_next)            d->v_link2 = NULL;    return;}/* Free a dvector. This is sort of a pain because we also have to make sure * that it has been unlinked from its plot structure. If the name of the * vector is NULL, then we have already freed it so don't try again. (This * situation can happen with user-defined functions.) Note that this depends * on our having tfree set its argument to NULL. Note that if all the vectors * in a plot are gone it stays around... */voidvec_free(v)    struct dvec *v;{    struct plot *pl;    struct dvec *lv;    if ((v == NULL) || (v->v_name == NULL))        return;    pl = v->v_plot;    /* Now we have to take this dvec out of the plot list. */    if (pl == NULL)        fprintf(cp_err, "vec_free: Internal Error: plot ptr is 0\n");    if (pl->pl_dvecs == v)        pl->pl_dvecs = v->v_next;    else {        for (lv = pl->pl_dvecs; lv->v_next; lv = lv->v_next)            if (lv->v_next == v)                break;        if (lv->v_next == NULL)            fprintf(cp_err,                 "vec_free: Internal Error: %s not in plot\n",                    v->v_name);        lv->v_next = v->v_next;    }    if (pl->pl_scale == v) {        if (pl->pl_dvecs)            pl->pl_scale = pl->pl_dvecs;    /* Random one... */        else            pl->pl_scale = NULL;    }    tfree(v->v_name);    if (isreal(v)) {        tfree(v->v_realdata);    } else {        tfree(v->v_compdata);    }    tfree(v);    return;}/* This is something we do in a few places...  Since vectors get copied a lot, * we can't just compare pointers to tell if two vectors are 'really' the same. */boolvec_eq(v1, v2)    struct dvec *v1, *v2;{    char *s1, *s2;    if (v1->v_plot != v2->v_plot)        return (false);        s1 = vec_basename(v1);    s2 = vec_basename(v2);    if (cieq(s1, s2))        return (true);    else        return (false);}/* Return the name of the vector with the plot prefix stripped off.  This * is no longer trivial since '.' doesn't always mean 'plot prefix'. */char *vec_basename(v)    struct dvec *v;{    char buf[BSIZE_SP], *t, *s;    int i;    if (index(v->v_name, '.')) {        for (t = v->v_name, i = 0; *t; t++)            buf[i++] = *t;        buf[i] = '\0';        if (cieq(v->v_plot->pl_typename, buf))            (void) strcpy(buf, t + 1);        else            (void) strcpy(buf, v->v_name);    } else        (void) strcpy(buf, v->v_name);        for (t = buf; *t; t++)        if (isupper(*t))            *t = tolower(*t);    for (t = buf; isspace(*t); t++)        ;    s = t;    for (t = s; *t; t++)        ;    while ((t > s) && isspace(t[-1]))        *--t = '\0';    return (copy(s));}/* Sort all the vectors in d, first by plot name and then by vector name. * Do the right thing with numbers. */static struct dvec *sortvecs(d)    struct dvec *d;{    struct dvec **array, *t;    int i, j;    for (t = d, i = 0; t; t = t->v_link2)        i++;    if (i < 2)        return (d);    array = (struct dvec **) tmalloc(i * sizeof (struct dvec *));    for (t = d, i = 0; t; t = t->v_link2)        array[i++] = t;        qsort((char *) array, i, sizeof (struct dvec *), veccmp);    /* Now string everything back together... */    for (j = 0; j < i - 1; j++)        array[j]->v_link2 = array[j + 1];    array[j]->v_link2 = NULL;    d = array[0];    tfree(array);    return (d);}static intveccmp(d1, d2)    struct dvec **d1, **d2;{    int i;    if ((i = namecmp((*d1)->v_plot->pl_typename,            (*d2)->v_plot->pl_typename)) != 0)        return (i);    return (namecmp((*d1)->v_name, (*d2)->v_name));}/* If there are imbedded numeric strings, compare them numerically, not * alphabetically. */static intnamecmp(s, t)    char *s, *t;{    int i, j;    for (;;) {        while ((*s == *t) && !isdigit(*s) && *s)            s++, t++;        if (!*s)            return (0);        if ((*s != *t) && (!isdigit(*s) || !isdigit(*t)))            return (*s - *t);                /* The beginning of a number... Grab the two numbers          * and then compare them...         */        for (i = 0; isdigit(*s); s++)            i = i * 10 + *s - '0';        for (j = 0; isdigit(*t); t++)            j = j * 10 + *t - '0';                if (i != j)            return (i - j);    }}/* Make a plot the current one.  This gets called by cp_usrset() when one * does a 'set curplot = name'. */voidplot_setcur(name)    char *name;{    struct plot *pl;    if (cieq(name, "new")) {        pl = plot_alloc("unknown");        pl->pl_title = copy("Anonymous");        pl->pl_name = copy("unknown");        pl->pl_date = copy(datestring( ));        plot_new(pl);        plot_cur = pl;        return;    }    for (pl = plot_list; pl; pl = pl->pl_next)        if (plot_prefix(name, pl->pl_typename))            break;    if (!pl) {        fprintf(cp_err, "Error: no such plot named %s\n", name);        return;    }    if (plot_cur)        plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom);    plot_cur = pl;    return;}/* Add a plot to the plot list. This is different from plot_add() in that * all this does is update the list and the variable $plots. */voidplot_new(pl)    struct plot *pl;{    pl->pl_next = plot_list;    plot_list = pl;    return;}/* This routine takes a multi-dimensional vector, treats it as a * group of 2-dimensional matrices and transposes each matrix. * The data array is replaced with a new one that has the elements * in the proper order.  Otherwise the transposition is done in place. */voidvec_transpose(v)    struct dvec *v;{    int dim0, dim1, nummatrices;    int i, j, k, joffset, koffset, blocksize;    struct dvec *d;    double *newreal, *oldreal;    complex *newcomp, *oldcomp;    if (v->v_numdims < 2 || v->v_length <= 1)        return;    dim0 = v->v_dims[v->v_numdims-1];    dim1 = v->v_dims[v->v_numdims-2];    v->v_dims[v->v_numdims-1] = dim1;    v->v_dims[v->v_numdims-2] = dim0;    /* Assume length is a multiple of each dimension size.     * This may not be safe, in which case a test should be     * made that the length is the product of all the dimensions.     */    blocksize = dim0*dim1;    nummatrices = v->v_length / blocksize;    /* Note:     *   olda[i,j] is at data[i*dim0+j]     *   newa[j,i] is at data[j*dim1+i]     *   where j is in [0, dim0-1]  and  i is in [0, dim1-1]     * Since contiguous data in the old array is scattered in the new array     * we can't use bcopy :(.  There is probably a BLAS2 function for this     * though.  The formulation below gathers scattered old data into     * consecutive new data.     */    if (isreal(v)) {	newreal = (double *) tmalloc(sizeof (double) * v->v_length);	oldreal = v->v_realdata;	koffset = 0;	for ( k=0; k < nummatrices; k++ ) {	    joffset = 0;	    for ( j=0; j < dim0; j++ ) {		for ( i=0; i < dim1; i++ ) {		  newreal[ koffset + joffset + i ] =		    oldreal[ koffset + i*dim0 + j ];		}		joffset += dim1;  /* joffset = j*dim0 */	    }	    koffset += blocksize; /* koffset = k*blocksize = k*dim0*dim1 */	}	tfree(oldreal);	v->v_realdata = newreal;    } else {	newcomp = (complex *) tmalloc(sizeof (complex) * v->v_length);	oldcomp = v->v_compdata;	koffset = 0;	for ( k=0; k < nummatrices; k++ ) {	    joffset = 0;	    for ( j=0; j < dim0; j++ ) {		for ( i=0; i < dim1; i++ ) {		  realpart(&newcomp[ koffset + joffset + i ]) =		    realpart(&oldcomp[ koffset + i*dim0 + j ]);		  imagpart(&newcomp[ koffset + joffset + i ]) =		    imagpart(&oldcomp[ koffset + i*dim0 + j ]);		}		joffset += dim1;  /* joffset = j*dim0 */	    }	    koffset += blocksize; /* koffset = k*blocksize = k*dim0*dim1 */	}	tfree(oldcomp);	v->v_compdata = newcomp;    }}/* This routine takes a multi-dimensional vector and turns it into a family * of 1-d vectors, linked together with v_link2.  It is here so that plot * can do intelligent things. */struct dvec *vec_mkfamily(v)    struct dvec *v;{    int size, numvecs, i, j, count[MAXDIMS];    int totalsize;    struct dvec *vecs, *d;    char buf[BSIZE_SP];    if (v->v_numdims < 2)        return (v);    size = v->v_dims[v->v_numdims - 1];    for (i = 0, numvecs = 1; i < v->v_numdims - 1; i++)        numvecs *= v->v_dims[i];    for (i = 0, vecs = d = NULL; i < numvecs; i++) {        if (vecs) {            d = d->v_link2 = alloc(struct dvec);	    ZERO(d, struct dvec);        } else {            d = vecs = alloc(struct dvec);	    ZERO(d, struct dvec);	}    }    for (i = 0; i < MAXDIMS; i++)        count[i] = 0;    for (d = vecs, j = 0; d; j++, d = d->v_link2) {	(void) sprintf(buf, "%s%s", v->v_name,		indexstring(count, v->v_numdims - 1));        d->v_name = copy(buf);        d->v_type = v->v_type;        d->v_flags = v->v_flags;        d->v_minsignal = v->v_minsignal;        d->v_maxsignal = v->v_maxsignal;        d->v_gridtype = v->v_gridtype;        d->v_plottype = v->v_plottype;        d->v_scale = v->v_scale;        /* Don't copy the default color, since there will be many         * of these things...         */        d->v_numdims = 1;        d->v_length = size;        if (isreal(v)) {	    totalsize = sizeof (double) * size;            d->v_realdata = (double *) tmalloc(totalsize);            bcopy((char *) v->v_realdata + totalsize * j,                    (char *) d->v_realdata, totalsize);        } else {	    totalsize = sizeof (complex) * size;            d->v_realdata = (double *) tmalloc(totalsize);            bcopy((char *) v->v_compdata + totalsize * j,                    (char *) d->v_compdata, totalsize);        }	/* Add one to the counter. */	(void) incindex(count, v->v_numdims - 1, v->v_dims, v->v_numdims);    }    for (d = vecs; d; d = d->v_link2)        vec_new(d);    return (vecs);}/* This function will match "op" with "op1", but not "op1" with "op12". */boolplot_prefix(pre, str)    char *pre, *str;{    if (!*pre)        return (true);    while (*pre && *str) {        if (*pre != *str)            break;        pre++; str++;    }    if (*pre || (*str && isdigit(pre[-1])))        return (false);    else        return (true);}

⌨️ 快捷键说明

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