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);
}
Example #3
0
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;
        }
    }
}