diff --git a/src/frontend/fourier.c b/src/frontend/fourier.c index d66efe3ee..5754700a3 100644 --- a/src/frontend/fourier.c +++ b/src/frontend/fourier.c @@ -23,7 +23,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group static char *pnum(double num); -static int CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Value, +static int CKTfour(int ndata, int numFreq, int numPeriod, double *thd, double *Time, double *Value, double FundFreq, double *Freq, double *Mag, double *Phase, double *nMag, double *nPhase); @@ -32,8 +32,8 @@ static int CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Va #define DEF_FOURGRIDSIZE 200 -/* CKTfour(ndata, numFreq, thd, Time, Value, FundFreq, Freq, Mag, Phase, nMag, nPhase) - * len 10 ? inp inp inp out out out out out +/* CKTfour(ndata, numFreq, numPeriod, thd, Time, Value, FundFreq, Freq, Mag, Phase, nMag, nPhase) + * len 10 1 ? inp inp inp out out out out out */ int @@ -42,7 +42,7 @@ fourier(wordlist *wl, struct plot *current_plot) struct dvec *time, *vec; struct pnode *pn, *names; double fundfreq, *data = NULL; - int nfreqs, fourgridsize, polydegree; + int nfreqs, nperiods, fourgridsize, polydegree; double *freq, *mag, *phase, *nmag, *nphase; /* Outputs from CKTfour */ double thd, *timescale = NULL; char *s; @@ -68,6 +68,8 @@ fourier(wordlist *wl, struct plot *current_plot) if (!cp_getvar("nfreqs", CP_NUM, &nfreqs, 0) || nfreqs < 1) nfreqs = 10; + if (!cp_getvar("nperiods", CP_NUM, &nperiods, 0) || nperiods < 1) + nperiods = 1; if (!cp_getvar("polydegree", CP_NUM, &polydegree, 0) || polydegree < 0) polydegree = 1; if (!cp_getvar("fourgridsize", CP_NUM, &fourgridsize, 0) || fourgridsize < 1) @@ -112,14 +114,16 @@ fourier(wordlist *wl, struct plot *current_plot) if (polydegree) { double *dp, d; + /* Get fourgridsize points per period */ + fourgridsize = fourgridsize * nperiods; /* 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... */ + d = nperiods / fundfreq; /* The wavelength... */ if (dp[1] - dp[0] < d) { - fprintf(cp_err, "Error: wavelength longer than time span\n"); + fprintf(cp_err, "Error: (%d * wavelength) longer than time span\n", nperiods); goto done; } else if (dp[1] - dp[0] > d) { dp[0] = dp[1] - d; @@ -143,7 +147,7 @@ fourier(wordlist *wl, struct plot *current_plot) timescale = time->v_realdata; } - err = CKTfour(fourgridsize, nfreqs, &thd, timescale, + err = CKTfour(fourgridsize, nfreqs, nperiods, &thd, timescale, data, fundfreq, freq, mag, phase, nmag, nphase); if (err != OK) { @@ -153,9 +157,10 @@ fourier(wordlist *wl, struct plot *current_plot) 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", + " No. Harmonics: %d, THD: %g %%, Gridsize: %d, Interpolation Degree: %d," + " No. Periods: %d\n\n", nfreqs, thd, fourgridsize, - polydegree); + polydegree, nperiods); /* Each field will have width cp_numdgt + 6 (or 7 * with HP-UX) + 1 if there is a - sign. */ @@ -288,6 +293,7 @@ static int CKTfour(int ndata, /* number of entries in the Time and Value arrays */ int numFreq, /* number of harmonics to calculate */ + int numPeriod, /* number of periods for detection */ double *thd, /* total harmonic distortion (percent) to be returned */ double *Time, /* times at which the voltage/current @@ -313,10 +319,10 @@ CKTfour(int ndata, /* number of entries in the Time and * The arrays must all be allocated by the caller. * The Time and Value array must be reasonably distributed over at * least one full period of the fundamental Frequency for the - * fourier transform to be useful. The function will take the - * last period of the frequency as data for the transform. + * fourier transform to be useful. The function will take + * numPeriod periods of the frequency as data for the transform. * - * We are assuming that the caller has provided exactly one period + * We are assuming that the caller has provided exactly numPeriod periods * of the fundamental frequency. */ int i; int j; @@ -331,10 +337,10 @@ CKTfour(int ndata, /* number of entries in the Time and Phase[i] = 0; } - for (i = 0; i < ndata; i++) + for (i = 0; i < ndata ; i++) for (j = 0; j < numFreq; j++) { - Mag[j] += Value[i] * sin(j*2.0*M_PI*i/((double)ndata)); - Phase[j] += Value[i] * cos(j*2.0*M_PI*i/((double)ndata)); + Mag[j] += Value[i] * sin(j*2.0*M_PI*numPeriod*i/((double)ndata)); + Phase[j] += Value[i] * cos(j*2.0*M_PI*numPeriod*i/((double)ndata)); } Mag[0] = Phase[0]/ndata;