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

📄 vectors.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
    nv->v_name = copy(v->v_name);    nv->v_type = v->v_type;    nv->v_flags = v->v_flags & ~VF_PERMANENT;    if (isreal(v)) {        nv->v_realdata = (double *) tmalloc(sizeof (double) *                v->v_length);        bcopy((char *) v->v_realdata, (char *) nv->v_realdata,                 sizeof (double) * v->v_length);        nv->v_compdata = NULL;    } else {        nv->v_realdata = NULL;        nv->v_compdata = (complex *) tmalloc(sizeof (complex) *                v->v_length);        bcopy((char *) v->v_compdata, (char *) nv->v_compdata,                 sizeof (complex) * v->v_length);    }    nv->v_minsignal = v->v_minsignal;    nv->v_maxsignal = v->v_maxsignal;    nv->v_gridtype = v->v_gridtype;    nv->v_plottype = v->v_plottype;    nv->v_length = v->v_length;    nv->v_rlength = 0; /*XXX???*/    nv->v_outindex = 0; /*XXX???*/    nv->v_linestyle = 0; /*XXX???*/    nv->v_color = 0; /*XXX???*/    nv->v_defcolor = v->v_defcolor;    nv->v_numdims = v->v_numdims;    for (i = 0; i < v->v_numdims; i++)        nv->v_dims[i] = v->v_dims[i];    nv->v_plot = v->v_plot;    nv->v_next = NULL;    nv->v_link2 = NULL;    nv->v_scale = v->v_scale;    return (nv);}/* Create a new plot structure. This just fills in the typename and sets up * the ccom struct. */struct plot *plot_alloc(char *name){    struct plot *pl = alloc(struct plot), *tp;    char *s;    char buf[BSIZE_SP];    ZERO(pl, struct plot);    if (!(s = ft_plotabbrev(name)))        s = "unknown";    do {        (void) sprintf(buf, "%s%d", s, plot_num);        for (tp = plot_list; tp; tp = tp->pl_next)            if (cieq(tp->pl_typename, buf)) {                plot_num++;                break;            }    } while (tp);    pl->pl_typename = copy(buf);    cp_addkword(CT_PLOT, buf);    /* va: create a new, empty keyword tree for class CT_VECTOR, s=old tree */    s = cp_kwswitch(CT_VECTOR, (char *) NULL);    cp_addkword(CT_VECTOR, "all");    pl->pl_ccom = cp_kwswitch(CT_VECTOR, s);    /* va: keyword tree is old tree again, new tree is linked to pl->pl_ccom */    return (pl);}/* Stick a new vector in the proper place in the plot list. */voidvec_new(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(void){    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_x(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) {        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 (v->v_realdata) tfree(v->v_realdata);    if (v->v_compdata) 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(struct dvec *v1, struct dvec *v2){    char *s1, *s2;    bool rtn;    if (v1->v_plot != v2->v_plot)        return (FALSE);        s1 = vec_basename(v1);    s2 = vec_basename(v2);    if (cieq(s1, s2))        rtn = TRUE;    else        rtn = FALSE;    tfree(s1);    tfree(s2);    return rtn;}/* 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(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));}/* Make a plot the current one.  This gets called by cp_usrset() when one * does a 'set curplot = name'. * va: ATTENTION: has unlinked old keyword-class-tree from keywords[CT_VECTOR]  *                (potentially memory leak) */voidplot_setcur(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;    }/* va: we skip cp_kwswitch, because it confuses the keyword-tree management for  *     repeated op-commands. When however cp_kwswitch is necessary for other  *     reasons, we should hold the original keyword table pointer in an  *     permanent variable, since it will lost here, and can never tfree'd.    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(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(struct dvec *v){    int dim0, dim1, nummatrices;    int i, j, k, joffset, koffset, blocksize;    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(struct dvec *v){    int size, numvecs, i, j, count[MAXDIMS];    int totalsize;    struct dvec *vecs, *d;    char buf[BSIZE_SP], buf2[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) {    	indexstring(count, v->v_numdims - 1, buf2);	(void) sprintf(buf, "%s%s", v->v_name, buf2);        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(char *pre, char *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 + -