void dft(double *jr, double *ji, int n, int iflag) { fftw_plan plan; int i; double ninv; FFTW_COMPLEX *cbuf; static int wisdom_inited=0; char *ram_cache_wisdom; int plan_flags; if(!wisdom_inited) { wisdom_inited=1; wisdom_file=getenv("GRACE_FFTW_WISDOM_FILE"); ram_cache_wisdom=getenv("GRACE_FFTW_RAM_WISDOM"); if(ram_cache_wisdom) sscanf(ram_cache_wisdom, "%d", &using_wisdom); /* turn on wisdom if it is requested even without persistent storage */ if(wisdom_file && wisdom_file[0] ) { /* if a file was specified in GRACE_FFTW_WISDOM_FILE, try to read it */ FILE *wf; fftw_status fstat; wf=fopen(wisdom_file,"r"); if(wf) { fstat=fftw_import_wisdom_from_file(wf); fclose(wf); initial_wisdom=fftw_export_wisdom_to_string(); } else initial_wisdom=0; atexit(save_wisdom); using_wisdom=1; /* if a file is specified, always use wisdom */ } } plan_flags=using_wisdom? (FFTW_USE_WISDOM | FFTW_MEASURE) : FFTW_ESTIMATE; plan=fftw_create_plan(n, iflag?FFTW_BACKWARD:FFTW_FORWARD, plan_flags | FFTW_IN_PLACE); cbuf=xcalloc(n, sizeof(*cbuf)); if(!cbuf) return; for(i=0; i<n; i++) { cbuf[i].re=jr[i]; cbuf[i].im=ji[i]; } fftw(plan, 1, cbuf, 1, 1, 0, 1, 1); fftw_destroy_plan(plan); if(!iflag) { ninv=1.0/n; for(i=0; i<n; i++) { jr[i]=cbuf[i].re*ninv; ji[i]=cbuf[i].im*ninv; } } else { for(i=0; i<n; i++) { jr[i]=cbuf[i].re; ji[i]=cbuf[i].im; } } XCFREE(cbuf); }
/* DFT by definition */ void dft(double *jr, double *ji, int n, int iflag) { int i, j, sgn; double sumr, sumi, tpi, w, *xr, *xi, on = 1.0 / n; double *cov, *siv, co, si; int iwrap; sgn = iflag ? -1 : 1; tpi = 2.0 * M_PI; xr = (double *)xcalloc(n, sizeof(double)); xi = (double *)xcalloc(n, sizeof(double)); cov = (double *)xcalloc(n, sizeof(double)); siv = (double *)xcalloc(n, sizeof(double)); if (xr == NULL || xi == NULL || cov == NULL || siv == NULL) { XCFREE(xr); XCFREE(xi); XCFREE(cov); XCFREE(siv); return; } for (i = 0; i < n; i++) { w = tpi * i * on; cov[i] = cos(w); siv[i] = sin(w)*sgn; xr[i] = jr[i]; xi[i] = ji[i]; } for (j = 0; j < n; j++) { sumr = 0.0; sumi = 0.0; for (i = 0, iwrap=0; i < n; i++, iwrap += j) { if(iwrap >= n) iwrap -= n; co = cov[iwrap]; si = siv[iwrap]; sumr = sumr + xr[i] * co + sgn * xi[i] * si; sumi = sumi + xi[i] * co - sgn * xr[i] * si; } jr[j] = sumr; ji[j] = sumi; } if (sgn == 1) { on = 1.0 * on; } else { on = 1.0; } for (i = 0; i < n; i++) { jr[i] = jr[i] * on; ji[i] = ji[i] * on; } XCFREE(xr); XCFREE(xi); XCFREE(cov); XCFREE(siv); }
static int leval_aac_cb(void *data) { int i, nscols, type; double start, stop; int npts; char *formula[MAX_SET_COLS]; Quark *pset, *gr; GVar *t; Leval_ui *ui = (Leval_ui *) data; Grace *grace; gr = ui->gr; type = GetOptionChoice(ui->set_type); nscols = settype_cols(type); if (xv_evalexpr(ui->start, &start) != RETURN_SUCCESS) { errmsg("Start item undefined"); return RETURN_FAILURE; } if (xv_evalexpr(ui->stop, &stop) != RETURN_SUCCESS) { errmsg("Stop item undefined"); return RETURN_FAILURE; } if (xv_evalexpri(ui->npts, &npts) != RETURN_SUCCESS) { errmsg("Number of points undefined"); return RETURN_FAILURE; } TableCommitEdit(ui->mw, FALSE); for (i = 0; i < nscols; i++) { formula[i] = TableGetCell(ui->mw, i, 0); } pset = gapp_set_new(gr); set_set_type(pset, type); grace = grace_from_quark(pset); t = graal_get_var(grace_get_graal(grace), "$t", TRUE); if (t == NULL) { errmsg("Internal error"); return RETURN_FAILURE; } #if 0 if (t->length != 0) { xfree(t->data); t->length = 0; } t->data = allocate_mesh(start, stop, npts); if (t->data == NULL) { return RETURN_FAILURE; } t->length = npts; if (set_set_length(pset, npts) != RETURN_SUCCESS) { quark_free(pset); XCFREE(t->data); t->length = 0; return RETURN_FAILURE; } #endif for (i = 0; i < nscols; i++) { char buf[32], *expr; int res; /* preparing the expression */ sprintf(buf, "%s = ", dataset_col_name(grace, i)); expr = copy_string(NULL, buf); expr = concat_strings(expr, formula[i]); /* evaluate the expression */ res = graal_parse_line(grace_get_graal(grace), expr, NULL); xfree(expr); if (res != RETURN_SUCCESS) { quark_free(pset); return RETURN_FAILURE; } } #if 0 XCFREE(t->data); t->length = 0; #endif update_set_lists(gr); return RETURN_SUCCESS; }
void fft(double *real_data, double *imag_data, int n_pts, int nu, int inv) { int n2, i, ib ,mm, k; int sgn, tstep; double tr, ti, arg; /* intermediate values in calcs. */ double c, s; /* cosine & sine components of Fourier trans. */ static double *sintab = NULL; static int last_n = 0; n2 = n_pts / 2; if(n_pts==0) { if(sintab) XCFREE(sintab); sintab=NULL; last_n=0; return; /* just deallocate memory if called with zero points */ } else if (n_pts != last_n) { /* allocate new sin table */ arg=2*M_PI/n_pts; last_n=0; if(sintab) XCFREE(sintab); sintab=(double *) xcalloc(n_pts,sizeof(double)); if(sintab == NULL) return; /* out of memory! */ for(i=0; i<n_pts; i++) sintab[i] = sin(arg*i); last_n=n_pts; } /* * sign change for inverse transform */ sgn = inv ? -1 : 1; /* do bit reversal of data in advance */ for (k = 0; k != n_pts; k++) { ib = bit_swap(k, nu); if (ib > k) { fswap((real_data + k), (real_data + ib)); fswap((imag_data + k), (imag_data + ib)); } } /* * Calculate the componets of the Fourier series of the function */ tstep=n2; for (mm = 1; mm < n_pts; mm*=2) { int sinidx=0, cosidx=n_pts/4; for(k=0; k<mm; k++) { c = sintab[cosidx]; s = sgn * sintab[sinidx]; sinidx += tstep; cosidx += tstep; if(sinidx >= n_pts) sinidx -= n_pts; if(cosidx >= n_pts) cosidx -= n_pts; for (i = k; i < n_pts; i+=mm*2) { double re1, re2, im1, im2; re1=real_data[i]; re2=real_data[i+mm]; im1=imag_data[i]; im2=imag_data[i+mm]; tr = re2 * c + im2 * s; ti = im2 * c - re2 * s; real_data[i+mm] = re1 - tr; imag_data[i+mm] = im1 - ti; real_data[i] = re1 + tr; imag_data[i] = im1 + ti; } } tstep /= 2; } /* * If calculating the inverse transform, must divide the data by the number of * data points. */ if (inv) { double fac = 1.0 / n_pts; for (k = 0; k != n_pts; k++) { *(real_data + k) *= fac; *(imag_data + k) *= fac; } } }