struct pnode * PP_mknnode(double number) { struct pnode *p; struct dvec *v; /* We don't use printnum because it screws up PP_mkfnode above. We have * to be careful to deal properly with node numbers that are quite * large... */ v = dvec_alloc(number < MAXPOSINT ? tprintf("%d", (int) number) : tprintf("%G", number), SV_NOTYPE, VF_REAL, 1, NULL); v->v_realdata[0] = number; vec_new(v); p = alloc_pnode(); p->pn_value = v; return (p); }
struct dvec * vec_copy(struct dvec *v) { struct dvec *nv; int i; if (!v) return (NULL); nv = dvec_alloc(copy(v->v_name), v->v_type, v->v_flags & ~VF_PERMANENT, v->v_length, NULL); if (isreal(v)) bcopy(v->v_realdata, nv->v_realdata, sizeof(double) * (size_t) v->v_length); else bcopy(v->v_compdata, nv->v_compdata, sizeof(ngcomplex_t) * (size_t) 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; /* Modified to copy the rlength of origin to destination vecor * instead of always putting it to 0. * As when it comes to make a print does not leave M1 @ @ M1 = 0.0, * to do so in the event that rlength = 0 not print anything on screen * nv-> v_rlength = 0; * Default -> v_rlength = 0 and only if you come from a print or M1 @ * @ M1 [all] rlength = 1, after control is one of * if (v-> v_rlength == 0) com_print (wordlist * wl) */ nv->v_rlength = v->v_rlength; 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); }
struct pnode * PP_mksnode(const char *string) { struct dvec *v, *nv, *vs, *newv = NULL, *end = NULL; struct pnode *p; p = alloc_pnode(); v = vec_get(string); if (v == NULL) { nv = dvec_alloc(copy(string), SV_NOTYPE, 0, 0, NULL); p->pn_value = nv; return (p); } /* It's not obvious that we should be doing this, but... */ for (vs = v; vs; vs = vs->v_link2) { nv = vec_copy(vs); vec_new(nv); if (end) end->v_link2 = nv; else newv = end = nv; end = nv; } p->pn_value = newv; /* va: tfree v in case of @xxx[par], because vec_get created a new vec and nobody will free it elsewhere */ /*if (v && v->v_name && *v->v_name == '@' && isreal(v) && v->v_realdata) { vec_free(v); } */ /* The two lines above have been commented out to prevent deletion of @xxx[par] after execution of only a single command like plot @xxx[par] or write. We need to monitor if this will lead to excessive memory usage. h_vogt 090221 */ return (p); }
static struct plot * oldread(char *name) { struct plot *pl; char buf[BSIZE_SP]; struct dvec *v, *end = NULL; short nv; /* # vars */ long np; /* # points/var. */ long i, j; short a; /* The magic number. */ float f1, f2; FILE *fp; if (!(fp = fopen(name, "r"))) { perror(name); return (NULL); } pl = alloc(struct plot); tfread(buf, 1, 80, fp); buf[80] = '\0'; for (i = (int) strlen(buf) - 1; (i > 1) && (buf[i] == ' '); i--) ; buf[i + 1] = '\0'; pl->pl_title = copy(buf); tfread(buf, 1, 16, fp); buf[16] = '\0'; pl->pl_date = copy(fixdate(buf)); tfread(&nv, sizeof (short), 1, fp); tfread(&a, sizeof (short), 1, fp); if (a != 4) fprintf(cp_err, "Warning: magic number 4 is wrong...\n"); for (i = 0; i < nv; i++) { v = dvec_alloc(NULL, SV_NOTYPE, 0, 0, NULL); if (end) end->v_next = v; else pl->pl_scale = pl->pl_dvecs = v; end = v; tfread(buf, 1, 8, fp); buf[8] = '\0'; v->v_name = copy(buf); } for (v = pl->pl_dvecs; v; v = v->v_next) { tfread(&a, sizeof (short), 1, fp); v->v_type = a; } /* If the first output variable is type FREQ then there is complex * data, otherwise the data is real. */ i = pl->pl_dvecs->v_type; if ((i == SV_FREQUENCY) || (i == SV_POLE) || (i == SV_ZERO)) for (v = pl->pl_dvecs; v; v = v->v_next) v->v_flags |= VF_COMPLEX; else for (v = pl->pl_dvecs; v; v = v->v_next) v->v_flags |= VF_REAL; /* Check the node indices -- this shouldn't be a problem ever. */ for (i = 0; i < nv; i++) { tfread(&a, sizeof(short), 1, fp); if (a != i + 1) fprintf(cp_err, "Warning: output %d should be %ld\n", a, i); } tfread(buf, 1, 24, fp); buf[24] = '\0'; pl->pl_name = copy(buf); /* Now to figure out how many points of data there are left in * the file. */ i = ftell(fp); (void) fseek(fp, 0L, SEEK_END); j = ftell(fp); (void) fseek(fp, i, SEEK_SET); i = j - i; if (i % 8) { /* Data points are always 8 bytes... */ fprintf(cp_err, "Error: alignment error in data\n"); (void) fclose(fp); return (NULL); } i = i / 8; if (i % nv) { fprintf(cp_err, "Error: alignment error in data\n"); (void) fclose(fp); return (NULL); } np = i / nv; for (v = pl->pl_dvecs; v; v = v->v_next) { dvec_realloc(v, (int) np, NULL); } for (i = 0; i < np; i++) { /* Read in the output vector for point i. If the type is * complex it will be float and we want double. */ for (v = pl->pl_dvecs; v; v = v->v_next) { if (v->v_flags & VF_REAL) { tfread(&v->v_realdata[i], sizeof (double), 1, fp); } else { tfread(&f1, sizeof (float), 1, fp); tfread(&f2, sizeof (float), 1, fp); realpart(v->v_compdata[i]) = f1; imagpart(v->v_compdata[i]) = f2; } } } (void) fclose(fp); return (pl); }
struct dvec * vec_get(const char *vec_name) { struct dvec *d, *end = NULL, *newv = NULL; struct plot *pl; char buf[BSIZE_SP], *s, *wd, *word, *whole, *name = NULL, *param; int i = 0; struct variable *vv; wd = word = copy(vec_name); /* Gets mangled below... */ if (strchr(word, '.')) { /* Snag the plot... */ for (i = 0, s = word; *s != '.'; i++, s++) buf[i] = *s; buf[i] = '\0'; if (cieq(buf, "all")) { word = ++s; pl = NULL; /* NULL pl signifies a wildcard. */ } else { for (pl = plot_list; pl && !plot_prefix(buf, pl->pl_typename); pl = pl->pl_next) ; if (pl) { word = ++s; } else { /* This used to be an error... */ pl = plot_cur; } } } else { pl = plot_cur; } if (pl) { d = vec_fromplot(word, pl); if (!d) d = vec_fromplot(word, &constantplot); } else { for (pl = plot_list; pl; pl = pl->pl_next) { if (cieq(pl->pl_typename, "const")) continue; d = vec_fromplot(word, pl); if (d) { if (end) end->v_link2 = d; else newv = d; for (end = d; end->v_link2; end = end->v_link2) ; } } d = newv; if (!d) { fprintf(cp_err, "Error: plot wildcard (name %s) matches nothing\n", word); tfree(wd); /* MW. I don't want core leaks here */ return (NULL); } } if (!d && (*word == SPECCHAR)) { /* This is a special quantity... */ if (ft_nutmeg) { fprintf(cp_err, "Error: circuit parameters only available with spice\n"); tfree(wd); /* MW. Memory leak fixed again */ return (NULL); /* va: use NULL */ } whole = copy(word); name = ++word; for (param = name; *param && (*param != '['); param++) ; if (*param) { *param++ = '\0'; for (s = param; *s && *s != ']'; s++) ; *s = '\0'; } else { param = NULL; } if (ft_curckt) { /* * This is what is done in case of "alter r1 resistance = 1234" * r1 resistance, 0 * if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model); */ /* vv = if_getparam (ft_curckt->ci_ckt, &name, param, 0, 0); */ vv = if_getparam(ft_curckt->ci_ckt, &name, param, 0, 0); if (!vv) { tfree(whole); tfree(wd); return (NULL); } } else { fprintf(cp_err, "Error: No circuit loaded.\n"); tfree(whole); tfree(wd); return (NULL); } d = dvec_alloc(copy(whole), /* MW. The same as word before */ SV_NOTYPE, VF_REAL, /* No complex values yet... */ 1, NULL); /* In case the represented variable is a REAL vector this takes * the actual value of the first element of the linked list which * does not make sense. * This is an error. */ /* This will copy the contents of the structure vv in another structure * dvec (FTEDATA.H) that do not have INTEGER so that those parameters * defined as IF_INTEGER are not given their value when using * print @pot[pos_node] * To fix this, it is necessary to define: * OPU( "pos_node", POT_QUEST_POS_NODE, IF_REAL,"Positive node of potenciometer"), * int POTnegNode; // number of negative node of potenciometer (Nodo_3) * case POT_QUEST_POS_NODE: * value->rValue = (double)fast->POTposNode; * return (OK); * Works but with the format 1.00000E0 */ /* We must make a change in format between the data that carries a variable to * put in a dvec. */ /* * #define va_bool va_V.vV_bool * #define va_num va_V.vV_num * #define va_real va_V.vV_real * #define va_string va_V.vV_string * #define va_vlist va_V.vV_list * enum cp_types { * CP_BOOL, * CP_NUM, * CP_REAL, * CP_STRING, * CP_LIST ° }; */ /* The variable is a vector */ if (vv->va_type == CP_LIST) { /* Compute the length of the vector, * used with the parameters of isrc and vsrc */ struct variable *nv; i = 0; for (nv = vv->va_vlist; nv; nv = nv->va_next) i++; dvec_realloc(d, i, NULL); i = 0; for (nv = vv->va_vlist; nv; nv = nv->va_next) d->v_realdata[i++] = nv->va_real; /* To be able to identify the vector to represent * belongs to a special "conunto" and should be printed in a * special way. */ d->v_dims[1] = 1; } else if (vv->va_type == CP_NUM) { /* Variable is an integer */ *d->v_realdata = (double) vv->va_num; } else if (vv->va_type == CP_REAL) { /* Variable is a real */ if (!(vv->va_next)) { /* Only a real data * usually normal */ *d->v_realdata = vv->va_real; } else { /* Real data set * When you print a model @ [all] * Just print numerical values, not the string */ struct variable *nv; /* We go to print the list of values * nv->va_name = Parameter description * nv->va_string = Parameter * nv->va_real= Value */ nv = vv; for (i = 1; ; i++) { switch (nv->va_type) { case CP_REAL: fprintf(stdout, "%s=%g\n", nv->va_name, nv->va_real); break; case CP_STRING: fprintf(stdout, "%s=%s\n", nv->va_name, nv->va_string); break; case CP_NUM: fprintf(stdout, "%s=%d\n", nv->va_name, nv->va_num); break; default: { fprintf(stderr, "ERROR: enumeration value `CP_BOOL' or `CP_LIST' not handled in vec_get\nAborting...\n"); controlled_exit(EXIT_FAILURE); } } nv = nv->va_next; if (!nv) break; } /* To distinguish those does not take anything for print screen to * make a print or M1 @ @ M1 [all] leaving only the correct data * and not the last */ d->v_rlength = 1; } } tfree(vv->va_name); tfree(vv); /* va: tfree vv->va_name and vv (avoid memory leakages) */ tfree(wd); vec_new(d); tfree(whole); return (d); } tfree(wd); return (sortvecs(d)); }
int fourier(wordlist *wl, struct plot *current_plot) { struct dvec *time, *vec; struct pnode *pn, *names; double *ff, fundfreq, *data = NULL; int nfreqs, fourgridsize, polydegree; double *freq, *mag, *phase, *nmag, *nphase; /* Outputs from CKTfour */ double thd, *timescale = NULL; char *s; int i, err, fw; char xbuf[20]; int shift; int rv = 1; struct dvec *n; int newveccount = 1; static int callstof = 1; if (!current_plot) return 1; sprintf(xbuf, "%1.1e", 0.0); shift = (int) strlen(xbuf) - 7; if (!current_plot || !current_plot->pl_scale) { fprintf(cp_err, "Error: no vectors loaded.\n"); return 1; } if (!cp_getvar("nfreqs", CP_NUM, &nfreqs, 0) || nfreqs < 1) nfreqs = 10; if (!cp_getvar("polydegree", CP_NUM, &polydegree, 0) || polydegree < 0) polydegree = 1; if (!cp_getvar("fourgridsize", CP_NUM, &fourgridsize, 0) || fourgridsize < 1) fourgridsize = DEF_FOURGRIDSIZE; time = current_plot->pl_scale; if (!isreal(time)) { fprintf(cp_err, "Error: fourier needs real time scale\n"); return 1; } s = wl->wl_word; if ((ff = ft_numparse(&s, FALSE)) == NULL || (*ff <= 0.0)) { fprintf(cp_err, "Error: bad fund freq %s\n", wl->wl_word); return 1; } fundfreq = *ff; freq = TMALLOC(double, nfreqs); mag = TMALLOC(double, nfreqs); phase = TMALLOC(double, nfreqs); nmag = TMALLOC(double, nfreqs); nphase = TMALLOC(double, nfreqs); wl = wl->wl_next; names = ft_getpnames(wl, TRUE); for (pn = names; pn; pn = pn->pn_next) { vec = ft_evaluate(pn); for (; vec; vec = vec->v_link2) { if (vec->v_length != time->v_length) { fprintf(cp_err, "Error: lengths don't match: %d, %d\n", vec->v_length, time->v_length); continue; } if (!isreal(vec)) { fprintf(cp_err, "Error: %s isn't real!\n", vec->v_name); continue; } if (polydegree) { double *dp, d; /* Build the grid... */ timescale = TMALLOC(double, fourgridsize); data = TMALLOC(double, fourgridsize); dp = ft_minmax(time, TRUE); /* Now get the last fund freq... */ d = 1 / fundfreq; /* The wavelength... */ if (dp[1] - dp[0] < d) { fprintf(cp_err, "Error: wavelength longer than time span\n"); goto done; } else if (dp[1] - dp[0] > d) { dp[0] = dp[1] - d; } d = (dp[1] - dp[0]) / fourgridsize; for (i = 0; i < fourgridsize; i++) timescale[i] = dp[0] + i * d; /* Now interpolate the data... */ if (!ft_interpolate(vec->v_realdata, data, time->v_realdata, vec->v_length, timescale, fourgridsize, polydegree)) { fprintf(cp_err, "Error: can't interpolate\n"); goto done; } } else { fourgridsize = vec->v_length; data = vec->v_realdata; timescale = time->v_realdata; } err = CKTfour(fourgridsize, nfreqs, &thd, timescale, data, fundfreq, freq, mag, phase, nmag, nphase); if (err != OK) { ft_sperror(err, "fourier"); goto done; } fprintf(cp_out, "Fourier analysis for %s:\n", vec->v_name); fprintf(cp_out, " No. Harmonics: %d, THD: %g %%, Gridsize: %d, Interpolation Degree: %d\n\n", nfreqs, thd, fourgridsize, polydegree); /* Each field will have width cp_numdgt + 6 (or 7 * with HP-UX) + 1 if there is a - sign. */ fw = ((cp_numdgt > 0) ? cp_numdgt : 6) + 5 + shift; fprintf(cp_out, "Harmonic %-*s %-*s %-*s %-*s %-*s\n", fw, "Frequency", fw, "Magnitude", fw, "Phase", fw, "Norm. Mag", fw, "Norm. Phase"); fprintf(cp_out, "-------- %-*s %-*s %-*s %-*s %-*s\n", fw, "---------", fw, "---------", fw, "-----", fw, "---------", fw, "-----------"); for (i = 0; i < nfreqs; i++) { char *pnumfr, *pnumma, *pnumph, *pnumnm, *pnumnp; pnumfr = pnum(freq[i]); pnumma = pnum(mag[i]); pnumph = pnum(phase[i]); pnumnm = pnum(nmag[i]); pnumnp = pnum(nphase[i]); fprintf(cp_out, " %-4d %-*s %-*s %-*s %-*s %-*s\n", i, fw, pnumfr, fw, pnumma, fw, pnumph, fw, pnumnm, fw, pnumnp); tfree(pnumfr); tfree(pnumma); tfree(pnumph); tfree(pnumnm); tfree(pnumnp); } fputs("\n", cp_out); /* create and assign a new vector n */ /* with size 3 * nfreqs in current plot */ /* generate name for new vector, using vec->name */ n = dvec_alloc(tprintf("fourier%d%d", callstof, newveccount), SV_NOTYPE, VF_REAL | VF_PERMANENT, 3 * nfreqs, NULL); n->v_numdims = 2; n->v_dims[0] = 3; n->v_dims[1] = nfreqs; vec_new(n); /* store data in vector: freq, mag, phase */ for (i = 0; i < nfreqs; i++) { n->v_realdata[i] = freq[i]; n->v_realdata[i + nfreqs] = mag[i]; n->v_realdata[i + 2 * nfreqs] = phase[i]; } newveccount++; if (polydegree) { tfree(timescale); tfree(data); } timescale = NULL; data = NULL; } }