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