Exemplo n.º 1
0
int CalcDelay<T>::gcc(const typename CDEVector<T>::Type &X,
                      const typename CDEVector<T>::Type &Y, int maxdelay, int filter)
{
  assert( X.length() == Y.length() );

  typename CDEVector<T>::Type tmp( X.length() );

  int fftsize = 2*(X.length()-1);

  // multiplication in frequency domain
  for(int i=1; i<=X.length(); ++i)
    tmp(i) = conj( X(i) ) * Y(i);

  // calc phase transform if needed
  if( filter == 1 )
  {
    for(int i=1; i<=X.length(); ++i)
      if( std::abs(tmp(i)) != 0) tmp(i) = tmp(i) / std::abs(tmp(i));
  }

  // calc crosscorr with IFFT
  typename DEVector<T>::Type crosscorr;
  irfft(tmp,crosscorr);

  // calc delay
  for(int i=1; i<=fftsize; ++i)
    crosscorr(i) = std::abs( crosscorr(i) );
  int mdelay = (fftsize < maxdelay) ? fftsize : maxdelay;

  int delay = (int) ( std::max_element( crosscorr.data(),
                                        crosscorr.data()+mdelay )
                      - crosscorr.data() );

//   cout << crosscorr << "fftsize:" << fftsize << ",mdelay:" << mdelay 
//        << "maxdelay;" << maxdelay << endl;

  return delay;
}
Exemplo n.º 2
0
const Field3D DDZ(const Field3D &f, CELL_LOC outloc, DIFF_METHOD method, bool inc_xbndry)
{
    deriv_func func = fDDZ; // Set to default function
    DiffLookup *table = FirstDerivTable;

    CELL_LOC inloc = f.getLocation(); // Input location
    CELL_LOC diffloc = inloc; // Location of differential result

    if(StaggerGrids && (outloc == CELL_DEFAULT)) {
        // Take care of CELL_DEFAULT case
        outloc = diffloc; // No shift (i.e. same as no stagger case)
    }

    if(StaggerGrids && (outloc != inloc)) {
        // Shifting to a new location

        if(((inloc == CELL_CENTRE) && (outloc == CELL_ZLOW)) ||
                ((inloc == CELL_ZLOW) && (outloc == CELL_CENTRE))) {
            // Shifting in Z. Centre -> Zlow, or Zlow -> Centre

            func = sfDDZ; // Set default
            table = FirstStagDerivTable; // Set table for others
            diffloc = (inloc == CELL_CENTRE) ? CELL_ZLOW : CELL_CENTRE;

        } else {
            // A more complicated shift. Get a result at cell centre, then shift.
            if(inloc == CELL_ZLOW) {
                // Shifting

                func = sfDDZ; // Set default
                table = FirstStagDerivTable; // Set table for others
                diffloc = CELL_CENTRE;

            } else if(inloc != CELL_CENTRE) {
                // Interpolate then (centre -> centre) then interpolate
                return DDZ(interp_to(f, CELL_CENTRE), outloc, method);
            }
        }
    }

    if(method != DIFF_DEFAULT) {
        // Lookup function
        func = lookupFunc(table, method);
    }

    Field3D result;

    if(func == NULL) {
        // Use FFT

        real shift = 0.; // Shifting result in Z?
        if(StaggerGrids) {
            if((inloc == CELL_CENTRE) && (diffloc == CELL_ZLOW)) {
                // Shifting down - multiply by exp(-0.5*i*k*dz)
                shift = -1.;
            } else if((inloc == CELL_ZLOW) && (diffloc == CELL_CENTRE)) {
                // Shifting up
                shift = 1.;
            }
        }

        result.Allocate(); // Make sure data allocated

        static dcomplex *cv = (dcomplex*) NULL;
        int jx, jy, jz;
        real kwave;
        real flt;

        int xge = MXG, xlt = ngx-MXG;
        if(inc_xbndry) { // Include x boundary region (for mixed XZ derivatives)
            xge = 0;
            xlt = ngx;
        }

        if(cv == (dcomplex*) NULL)
            cv = new dcomplex[ncz/2 + 1];

        for(jx=xge; jx<xlt; jx++) {
            for(jy=0; jy<ngy; jy++) {

                rfft(f[jx][jy], ncz, cv); // Forward FFT

                for(jz=0; jz<=ncz/2; jz++) {
                    kwave=jz*2.0*PI/zlength; // wave number is 1/[rad]

                    if (jz>0.4*ncz) flt=1e-10;
                    else flt=1.0;
                    cv[jz] *= dcomplex(0.0, kwave) * flt;
                    if(StaggerGrids)
                        cv[jz] *= exp(Im * (shift * kwave * dz));
                }

                irfft(cv, ncz, result[jx][jy]); // Reverse FFT

                result[jx][jy][ncz] = result[jx][jy][0];

            }
        }

#ifdef CHECK
        // Mark boundaries as invalid
        result.bndry_xin = result.bndry_xout = result.bndry_yup = result.bndry_ydown = false;
#endif

    } else {
        // All other (non-FFT) functions
        result = applyZdiff(f, func, dz);
    }

    result.setLocation(diffloc);

    return interp_to(result, outloc);
}
Exemplo n.º 3
0
int main(int argc, char **argv)
{
    int	i;
    int	N, M, L;
    FILE	*fp;

    M = 128;	/* kernel size */
    N = 2*M;	/* input sub-section length (fft size) */
    L = N - M + 1;	/* number of "good" points per section */

    if ( argc != 2 || isatty(fileno(stdin)) || isatty(fileno(stdout)) ) {
	bu_exit(1, "Usage: dconv filter < doubles > doubles\nXXX Warning: kernal size must be 2^i - 1\n" );
    }

#ifdef never
    /* prepare the kernel(!) */
    /* this is either the direct complex response,
     *  or the FT(impulse resp)
     */
    for ( i = 0; i < N; i++ ) {
	if ( i <= N/2 )
	    ibuf[i] = 1.0;	/* Real part */
	else
	    ibuf[i] = 0.0;	/* Imag part */
    }
#endif /* never */

    if ( (fp = fopen( argv[1], "r" )) == NULL ) {
	bu_exit(2, "dconv: can't open \"%s\"\n", argv[1] );
    }
    if ( (M = fread( ibuf, sizeof(*ibuf), 2*MAXM, fp )) == 0 ) {
	bu_exit(3, "dconv: problem reading filter file\n" );
    }
    fclose( fp );
    if ( M > MAXM ) {
	bu_exit(4, "dconv: only compiled for up to %d sized filter kernels\n", MAXM );
    }
/*XXX HACK HACK HACK HACK XXX*/
/* Assume M = 2^i - 1 */
    M += 1;
    N = 2*M;	/* input sub-section length (fft size) */
    L = N - M + 1;	/* number of "good" points per section */

    if ( N == 256 )
	rfft256( ibuf );
    else
	rfft( ibuf, N );

    while ( (i = fread(&xbuf[M-1], sizeof(*xbuf), L, stdin)) > 0 ) {
	if ( i < L ) {
	    /* pad the end with zero's */
	    memset((char *)&xbuf[M-1+i], 0, (L-i)*sizeof(*savebuffer));
	}
	memcpy(xbuf, savebuffer, (M-1)*sizeof(*savebuffer));
	memcpy(savebuffer, &xbuf[L], (M-1)*sizeof(*savebuffer));

	/*xform( xbuf, N );*/
	if ( N == 256 )
	    rfft256( xbuf );
	else
	    rfft( xbuf, N );

	/* Mult */
	mult( xbuf, ibuf, N );

	/*invxform( xbuf, N );*/
	if ( N == 256 )
	    irfft256( xbuf );
	else
	    irfft( xbuf, N );

	fwrite( &xbuf[M-1], sizeof(*xbuf), L, stdout );
    }

    return 0;
}