void cr2dfft(complex *cdata, REAL *rdata, int nr, int nc, int ldc, int ldr, int sign) { #if defined(HAVE_LIBSCS) static int nr_prev=0, nc_prev=0; int isys=0, ntable, nwork, zero=0; int ld1, j; static float *work, *table; float scale=1.0; #else int i, j, nf; complex *tmp; #endif #if defined(HAVE_LIBSCS) if (nr != nr_prev || nc != nc_prev) { nwork = nr*nc; ntable = 15+nr+2*(15+nc); if (work) free (work); if (table) free (table); work = (float *)malloc(nwork*sizeof(float)); table = (float *)malloc(ntable*sizeof(float)); csfft2d_(&zero,&nr,&nc,&scale,cdata,&ldc,rdata,&ldr,table,work,&isys); nr_prev = nr; nc_prev = nc; } ld1 = 2*ldc; csfft2d_(sign,&nr,&nc,&scale,cdata,&ldc,cdata,&ld1,table,work,&isys); for (j=0; j<nc; j++) { memcpy((float *)&rdata[j*ldr], (float *)&cdata[j*ldc].r, sizeof(float)*nr); } #else tmp = (complex *)malloc(nc*sizeof(complex)); nf = (nr+2)/2; for (i=0; i<nf; i++) { for (j=0; j<nc; j++) tmp[j] = cdata[j*ldc+i]; cc1fft(tmp, nc, sign); for (j=0; j<nc; j++) cdata[j*ldc+i] = tmp[j]; } free (tmp); crmfft(cdata, rdata, nr, nc, ldc, ldr, sign); #endif return; }
void ncrmfft(complex *cdata, REAL *rdata, int *n1, int *n2, int *ldc, int *ldr, int *sign) { crmfft(cdata, rdata, *n1, *n2, *ldc, *ldr, *sign); return; }
void convolhom(float *data1, float *data2, float *con, int nrec, int nsam, float dt, int shift, float rho, int mode) { int i, j, n, optn, nfreq, sign; float df, dw, om, tau, scl; float *qr, *qi, *p1r, *p1i, *p2r, *p2i, *rdata1, *rdata2; complex *cdata1, *cdata2, *ccon, tmp; optn = optncr(nsam); nfreq = optn/2+1; cdata1 = (complex *)malloc(nfreq*nrec*sizeof(complex)); if (cdata1 == NULL) verr("memory allocation error for cdata1"); cdata2 = (complex *)malloc(nfreq*nrec*sizeof(complex)); if (cdata2 == NULL) verr("memory allocation error for cdata2"); ccon = (complex *)malloc(nfreq*nrec*sizeof(complex)); if (ccon == NULL) verr("memory allocation error for ccov"); rdata1 = (float *)malloc(optn*nrec*sizeof(float)); if (rdata1 == NULL) verr("memory allocation error for rdata1"); rdata2 = (float *)malloc(optn*nrec*sizeof(float)); if (rdata2 == NULL) verr("memory allocation error for rdata2"); /* pad zeroes until Fourier length is reached */ pad_data(data1, nsam, nrec, optn, rdata1); pad_data(data2, nsam, nrec, optn, rdata2); /* forward time-frequency FFT */ sign = -1; rcmfft(&rdata1[0], &cdata1[0], optn, nrec, optn, nfreq, sign); rcmfft(&rdata2[0], &cdata2[0], optn, nrec, optn, nfreq, sign); /* apply convolution */ p1r = (float *) &cdata1[0]; p2r = (float *) &cdata2[0]; qr = (float *) &ccon[0].r; p1i = p1r + 1; p2i = p2r + 1; qi = qr + 1; n = nrec*nfreq; for (j = 0; j < n; j++) { *qr = (*p2r**p1r-*p2i**p1i); *qi = (*p2r**p1i+*p2i**p1r); qr += 2; qi += 2; p1r += 2; p1i += 2; p2r += 2; p2i += 2; } free(cdata1); free(cdata2); if (shift) { df = 1.0/(dt*optn); dw = 2*PI*df; tau = dt*(nsam/2); for (j = 0; j < nrec; j++) { om = 0.0; for (i = 0; i < nfreq; i++) { tmp.r = ccon[j*nfreq+i].r*cos(om*tau) + ccon[j*nfreq+i].i*sin(om*tau); tmp.i = ccon[j*nfreq+i].i*cos(om*tau) - ccon[j*nfreq+i].r*sin(om*tau); ccon[j*nfreq+i] = tmp; om += dw; } } } /* Scaling for the homogeneous equation */ if (mode==0) {//single source df = 1.0/(dt*optn); dw = 2.0*(M_PI)*df; for (i=0; i<nrec; i++) { j=0; ccon[i*nfreq+j].r *= 0.0; ccon[i*nfreq+j].i *= 0.0; for (j=1; j<nfreq; j++) { ccon[i*nfreq+j].r *= (4.0/(rho*dw*j)); ccon[i*nfreq+j].i *= (4.0/(rho*dw*j)); } } } else {//multiple sources df = 1.0/(dt*optn); dw = 2.0*(M_PI)*df; for (i=0; i<nrec; i++) { j=0; ccon[i*nfreq+j].r *= 0.0; ccon[i*nfreq+j].i *= 0.0; for (j=1; j<nfreq; j++) { tmp.r = (2.0/(rho*dw*j))*ccon[i*nfreq+j].i; tmp.i = (2.0/(rho*dw*j))*ccon[i*nfreq+j].r; ccon[i*nfreq+j]=tmp; } } } /* inverse frequency-time FFT and scale result */ sign = 1; scl = 1.0/((float)(optn)); crmfft(&ccon[0], &rdata1[0], optn, nrec, nfreq, optn, sign); scl_data(rdata1,optn,nrec,scl,con,nsam); free(ccon); free(rdata1); free(rdata2); return; }