1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1985 Wayne A. Christopher
5 1992 Stephen R. Whiteley
6 ****************************************************************************/
7
8 #include "spice.h"
9 #include "ftedefs.h"
10 #include "spfteext.h"
11
12 /* Interpolate all the vectors in a plot to a linear time scale, which
13 * we determine by looking at the transient parameters in the CKT struct.
14 */
15
16 #ifdef __STDC__
17 static void lincopy(struct dvec*,double*,int,struct dvec*);
18 #else
19 static void lincopy();
20 #endif
21
22
23 void
com_linearize(wl)24 com_linearize(wl)
25
26 wordlist *wl;
27 {
28 double tstart, tstop, tstep, d;
29 struct plot *new, *old;
30 struct dvec *newtime, *v;
31 struct dvec *oldtime;
32 wordlist *wl0, *tl;
33 int len, i;
34 char buf[BSIZE_SP];
35
36 if (!plot_cur || !plot_cur->pl_scale) {
37 fprintf(cp_err, "Error: no current plot or no scale\n");
38 return;
39 }
40 if (!isreal(plot_cur->pl_scale)) {
41 fprintf(cp_err, "Error: non-real time scale for %s\n",
42 plot_cur->pl_typename);
43 return;
44 }
45 if (!ciprefix("tran", plot_cur->pl_typename)) {
46 fprintf(cp_err, "Error: plot must be a transient analysis\n");
47 return;
48 }
49
50 tstart = plot_cur->pl_start;
51 tstop = plot_cur->pl_stop;
52 tstep = plot_cur->pl_step;
53
54 if (((tstop - tstart) * tstep <= 0.0) || ((tstop - tstart) < tstep)) {
55 fprintf(cp_err,
56 "Error: bad parameters -- start = %G, stop = %G, step = %G\n",
57 tstart, tstop, tstep);
58 return;
59 }
60
61 old = plot_cur;
62 oldtime = old->pl_scale;
63 new = plot_alloc("transient");
64 (void) sprintf(buf, "%s (linearized)", old->pl_name);
65 new->pl_name = copy(buf);
66 new->pl_title = copy(old->pl_title);
67 new->pl_date = copy(old->pl_date);
68 new->pl_next = plot_list;
69 new->pl_start = tstart;
70 new->pl_stop = tstop;
71 new->pl_step = tstep;
72 plot_new(new);
73 plot_setcur(new->pl_typename);
74 plot_list = new;
75 len = (tstop - tstart) / tstep + 1.5;
76 newtime = alloc(struct dvec);
77 newtime->v_name = copy(oldtime->v_name);
78 newtime->v_type = oldtime->v_type;
79 newtime->v_flags = oldtime->v_flags;
80 newtime->v_length = len;
81 newtime->v_plot = new;
82 newtime->v_realdata = (double *) tmalloc(len * sizeof (double));
83 for (i = 0, d = tstart; i < len; i++, d += tstep)
84 newtime->v_realdata[i] = d;
85 vec_newperm(newtime); /* set to scale */
86
87 if (wl && !cieq(wl->wl_word,"all")) {
88 while (wl) {
89 v = vec_fromplot(wl->wl_word, old);
90 if (!v) {
91 fprintf(cp_err, "Error: no such vector %s\n",
92 wl->wl_word);
93 continue;
94 }
95 lincopy(v, newtime->v_realdata, len, oldtime);
96 wl = wl->wl_next;
97 }
98 }
99 else {
100 wl0 = (wordlist*)htab_list(old->pl_hashtab);
101 for (tl = wl0; tl; tl = tl->wl_next) {
102 v = (struct dvec *)((char**)tl->wl_word)[1];
103 if (v == old->pl_scale)
104 continue;
105 lincopy(v, newtime->v_realdata, len, oldtime);
106 }
107 wl_free(wl0);
108 }
109 return;
110 }
111
112
113 static void
lincopy(ov,newscale,newlen,oldscale)114 lincopy(ov, newscale, newlen, oldscale)
115
116 struct dvec *ov, *oldscale;
117 double *newscale;
118 int newlen;
119 {
120 struct dvec *v;
121 double *nd;
122
123 if (!isreal(ov)) {
124 fprintf(cp_err, "Warning: %s is not real\n", ov->v_name);
125 return;
126 }
127 if (ov->v_length < oldscale->v_length) {
128 fprintf(cp_err, "Warning: %s is too short\n", ov->v_name);
129 return;
130 }
131 v = alloc(struct dvec);
132 v->v_name = copy(ov->v_name);
133 v->v_type = ov->v_type;
134 v->v_flags = ov->v_flags;
135 v->v_length = newlen;
136
137 nd = (double *) tmalloc(newlen * sizeof (double));
138 if (!ft_interpolate(ov->v_realdata, nd, oldscale->v_realdata,
139 oldscale->v_length, newscale, newlen, 1)) {
140 fprintf(cp_err, "Error: can't interpolate %s\n", ov->v_name);
141 return;
142 }
143 v->v_realdata = nd;
144 vec_newperm(v);
145 return;
146 }
147