Esempio n. 1
0
void addtoavgenergy(t_complex *list, real *result, int size, int tsteps)
{
    int i;
    for (i = 0; i < size; i++)
    {
        result[i] += cabs2(list[i])/tsteps;
    }

}
Esempio n. 2
0
dmat *psd1d(const dmat *v, /**<[in] The data sequence*/
	    long nseg      /**<[in] Number of overlapping segments*/
    ){
    long nx;
    long ncol;
    if(v->nx==1){
	nx=v->ny;
	ncol=1;
    }else{
	nx=v->nx;
	ncol=v->ny;
    }
    if(nseg<=1) nseg=1;
    const int lseg2=nx/(nseg+1);
    const int lseg=lseg2*2;
    dmat *psd=dnew(lseg2+1, ncol);
    cmat *hat=cnew(lseg, 1);
    //cfft2plan(hat, -1);
    for(long icol=0; icol<ncol; icol++){
	double *ppsd=psd->p+icol*(lseg2+1);
	for(int iseg=0; iseg<nseg; iseg++){
	    double* p=v->p+icol*nx+iseg*lseg2;
	    for(int ix=0; ix<lseg; ix++){
		hat->p[ix]=p[ix]*W_J(ix, lseg2);
	    }
	    cfft2(hat, -1);
	    ppsd[0]+=cabs2(hat->p[0]);
	    for(int ix=1; ix<lseg2; ix++){
		ppsd[ix]+=cabs2(hat->p[ix])+cabs2(hat->p[lseg-ix]);
	    }
	    ppsd[lseg2]+=cabs2(hat->p[lseg2]);
	}
    }
    double sumwt=0;
    for(int ix=0; ix<lseg; ix++){
	sumwt+=pow(W_J(ix, lseg2), 2);
    }
    sumwt*=lseg*nseg;
    dscale(psd, 1./sumwt);
    cfree(hat);
    return psd;
}
Esempio n. 3
0
// HIGHPASS
pzkContainer * t2hp(pzkContainer * pzk, real w0) {
	pzkContainer * f = createPzkContainer(pzk->nextPole, pzk->nextZero);
	uint i;
	complex tmp;
	
	f->amp = pzk->amp * pow(w0,(real)pzk->no_wz);
	f->no_wz = -pzk->no_wz;

	for( i = 0; i < pzk->nextPole; i++ ) {
		tmp.re = w0;
		tmp.im = 0;
		f->no_wz++;
		if( cisreal(pzk->poles[i]) ) {
			f->amp /= -pzk->poles[i].re;
			tmp.re /= pzk->poles[i].re;
		} else {
			tmp = cdiv(tmp, pzk->poles[i]);
			f->amp /= cabs2(pzk->poles[i]);
			f->no_wz++;
		}
		addPole(f, tmp);
	}
	
	for( i = 0; i < pzk->nextZero; i++ ) {
		tmp.re = w0;
		tmp.im = 0;
		f->no_wz--;	
		if( cisreal(pzk->zeros[i]) ) {
			f->amp *= -pzk->zeros[i].re;
			tmp.re /= pzk->zeros[i].re;
		} else {
			tmp = cdiv(tmp, pzk->zeros[i]);
			f->amp *= cabs2(pzk->zeros[i]);
			f->no_wz--;
		}
		addZero(f, tmp);
	}
	
	f->type = highpass;
	return f;
	
}
Esempio n. 4
0
File: perf.c Progetto: pkofod/julia
int mandel(double complex z) {
    int maxiter = 80;
    double complex c = z;
    for (int n = 0; n < maxiter; ++n) {
        if (cabs2(z) > 4.0) {
            return n;
        }
        z = z*z+c;
    }
    return maxiter;
}
Esempio n. 5
0
static int mandel(double cre, double cim, int MAX_ITER)
{
   const float Z_MAX2 = 4.0;
   double zre = cre, zim = cim;
   int iter;

   for (iter = 0; iter < MAX_ITER; iter++) {
      double z1re, z1im;
      z1re = zre * zre - zim * zim;
      z1im = 2 * zre * zim;
      z1re += cre;
      z1im += cim;
      if (cabs2(z1re, z1im) > Z_MAX2) {
         return iter + 1;  /* outside set */
      }
      zre = z1re;
      zim = z1im;
   }

   return 0;               /* inside set */
}
Esempio n. 6
0
int PSDCalculator::calculatePowerSpectrum(
  double *input, int inputLen, 
  double *output, int outputLen, 
  bool removeMean, bool interpolateHoles,
  bool average, int averageLen, 
  bool apodize, ApodizeFunction apodizeFxn, double gaussianSigma,
  PSDType outputType, double inputSamplingFreq) {

  if (outputLen != calculateOutputVectorLength(inputLen, average, averageLen)) {
    KstDebug::self()->log(QObject::tr("in PSDCalculator::calculatePowerSpectrum: received output array with wrong length."), KstDebug::Error);

    return -1;
  }

  if (outputLen != _prevOutputLen) {
    delete[] _a;
    delete[] _w;

    _awLen = outputLen*2;
    _prevOutputLen = outputLen;

    _a = new double[_awLen];
    _w = new double[_awLen];

    updateWindowFxn(apodizeFxn, gaussianSigma);
  }

  if ( (_prevApodizeFxn != apodizeFxn) || (_prevGaussianSigma != gaussianSigma) ) {
    updateWindowFxn(apodizeFxn, gaussianSigma);
  }

  int currentCopyLen, nsamples = 0;
  int i_samp, i_subset, ioffset;

  memset(output, 0, sizeof(double) * outputLen);

  bool done = false;
  for (i_subset = 0; !done; i_subset++) {
    //
    // overlapping average => i_subset*outputLen...
    //

    ioffset = i_subset * outputLen;

    //
    // only zero pad if we really have to.  
    //  It is better to adjust the last chunk's overlap...
    //

    if (ioffset + _awLen*5/4 < inputLen) {
      currentCopyLen = _awLen; // will copy a complete window.
    } else if (_awLen<inputLen) {  // count the last one from the end.
      ioffset = inputLen-_awLen - 1;
      currentCopyLen = _awLen; // will copy a complete window.
      done = true;
    } else {
      currentCopyLen = inputLen - ioffset; // will copy a partial window.
      memset(&_a[currentCopyLen], 0, sizeof(double)*(_awLen - currentCopyLen)); // zero the leftovers.
      done = true;
    }

    double mean = 0.0;

    if (removeMean) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        mean += input[i_samp + ioffset];
      }
      mean /= (double)currentCopyLen;
    }

    //
    // apply the PSD options (removeMean, apodize, etc.)
    // separate cases for speed- although this shouldn't really matter - 
    //  the rdft should be the most time consuming step by far for any large data set...
    //

    if (removeMean && apodize && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = (kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen) - mean)*_w[i_samp];
      }
    } else if (removeMean && apodize) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = (input[i_samp + ioffset] - mean)*_w[i_samp];
      }
    } else if (removeMean && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen) - mean;
      }
    } else if (apodize && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen)*_w[i_samp];
      }
    } else if (removeMean) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset] - mean;
      }
    } else if (apodize) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset]*_w[i_samp];
      }
    } else if (interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen);
      }
    } else {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset];
      }
    }

    nsamples += currentCopyLen;

    //
    // real discrete fourier transorm on _a.
    //

    rdft(_awLen, 1, _a); 

    output[0] += _a[0] * _a[0];
    output[outputLen-1] += _a[1] * _a[1];
    for (i_samp = 1; i_samp < outputLen - 1; i_samp++) {
      output[i_samp] += cabs2(_a[i_samp * 2], _a[i_samp * 2 + 1]);
    }
  }

  double frequencyStep = 2.0*(double)inputSamplingFreq/(double)nsamples;
  double norm = 2.0/(double)nsamples*2.0/(double)nsamples;

  switch (outputType) {
    default:
    case PSDAmplitudeSpectralDensity: // amplitude spectral density (default) [V/Hz^1/2]
      norm /= frequencyStep;
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] = sqrt(output[i_samp]*norm);
      }
      break;

    case PSDPowerSpectralDensity: // power spectral density [V^2/Hz]
      norm /= frequencyStep;
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] *= norm;
      }
      break;

    case PSDAmplitudeSpectrum: // amplitude spectrum [V]
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] = sqrt(output[i_samp]*norm);
      }
      break;

    case PSDPowerSpectrum: // power spectrum [V^2]
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] *= norm;
      }
      break;
  }

  return 0;
}
Esempio n. 7
0
// BANDSTOP
pzkContainer * t2bs(pzkContainer * pzk, real w0, real dw) {
	uint nop, noz, i;
	pzkContainer * f;
	const real w02 = w0*w0;
	complex tmp, beta, gamma, cw0, cdwp2;

	cw0.re = w0;
	cw0.im = 0;

	cdwp2.re = dw / 2;
	cdwp2.im = 0;
	
	noz = 2*pzk->nextZero;
	nop = 2*pzk->nextPole;
	
	if( pzk->no_wz > 0 ) {
		noz += pzk->no_wz;
	}
	if( pzk->no_wz < 0 ) {
		nop -= pzk->no_wz;
	}
	
	f = createPzkContainer(nop, noz);
	
	f->wz = w0;
	f->no_wz = -pzk->no_wz;
	f->amp = pzk->amp * pow(dw, (real)(pzk->no_wz));
		
	gamma.re = 0;
	gamma.im = 0;
	if( pzk->no_wz > 0 ) {
		for( i = 0; i < pzk->no_wz; i++ ) {
			addZero(f, gamma);
		}
	}
	if( pzk->no_wz < 0 ) {
		for( i = 0; i < -pzk->no_wz; i++ ) {
			addPole(f, gamma);
		}
	}

	for( i = 0; i < pzk->nextPole; i++ ) {
		if( cisreal(pzk->poles[i]) ) {
			beta.re = cdwp2.re / pzk->poles[i].re;
			tmp.re = 1 - ( w02/(beta.re*beta.re) );

			if( tmp.re >= 0 ) {
				tmp.re = sqrt( tmp.re );
				gamma.im = 0;
				gamma.re = beta.re * (1 + tmp.re);
				addPole(f, gamma);
				gamma.re = beta.re * (1 - tmp.re);
				addPole(f, gamma);
			} else {
				tmp.im = sqrt( -tmp.re );
				tmp.re = 1;
				gamma = cmul2( beta.re, tmp );
				addPole(f, gamma);
			}

			f->amp /= -pzk->poles[i].re;
			f->no_wz++;
		}
		else {
			beta = cdiv(cdwp2, pzk->poles[i]);	
			tmp = cdiv(cw0, beta);
			tmp = csqrt( csub2(1, cmlt(tmp, tmp)) );

			gamma = cmlt(beta, cadd2(1, tmp));
			addPole(f, gamma);
			gamma = cmlt(beta, csub2(1, tmp));
			addPole(f, gamma);

			f->amp /= cabs2(pzk->poles[i]);
			f->no_wz += 2;
		}
	}
	
	for( i = 0; i < pzk->nextZero; i++ ) {
		if( cisreal(pzk->zeros[i]) ) {
			beta.re = cdwp2.re / pzk->zeros[i].re;
			tmp.re = 1 - ( w02/(beta.re*beta.re) );

			if( tmp.re >= 0 ) {
				tmp.re = sqrt( tmp.re );
				gamma.im = 0;
				gamma.re = beta.re * (1 + tmp.re);
				addZero(f, gamma);
				gamma.re = beta.re * (1 - tmp.re);
				addZero(f, gamma);
			} else {
				tmp.im = sqrt( -tmp.re );
				tmp.re = 1;
				gamma = cmul2( beta.re, tmp );
				addZero(f, gamma);
			}

			f->amp *= -pzk->zeros[i].re;
			f->no_wz--;
		}
		else {
			beta = cdiv(cdwp2, pzk->zeros[i]);	
			tmp = cdiv(cw0, beta);
			tmp = csqrt( csub2(1, cmlt(tmp, tmp)) );

			gamma = cmlt(beta, cadd2(1, tmp));
			addZero(f, gamma);
			gamma = cmlt(beta, csub2(1, tmp));
			addZero(f, gamma);

			f->amp *= cabs2(pzk->zeros[i]);
			f->no_wz -= 2;
		}
	}
	
	return f;	
}
Esempio n. 8
0
double *bayestar_sky_map_toa_phoa_snr(
    long *npix, /* Input: number of HEALPix pixels. */
    double gmst, /* Greenwich mean sidereal time in radians. */
    int nifos, /* Input: number of detectors. */
    const float (**responses)[3], /* Pointers to detector responses. */
    const double **locations, /* Pointers to locations of detectors in Cartesian geographic coordinates. */
    const double *toas, /* Input: array of times of arrival with arbitrary relative offset. (Make toas[0] == 0.) */
    const double *phoas, /* Input: array of phases of arrival with arbitrary relative offset. (Make phoas[0] == 0.) */
    const double *snrs, /* Input: array of SNRs. */
    const double *w_toas, /* Input: sum-of-squares weights, (1/TOA variance)^2. */
    const double *w1s, /* Input: first moments of angular frequency. */
    const double *w2s, /* Input: second moments of angular frequency. */
    const double *horizons, /* Distances at which a source would produce an SNR of 1 in each detector. */
    double min_distance,
    double max_distance,
    int prior_distance_power) /* Use a prior of (distance)^(prior_distance_power) */
{
    long nside;
    long maxpix;
    long i;
    double d1[nifos];
    double *P;
    gsl_permutation *pix_perm;
    double complex exp_i_phoas[nifos];

    /* Hold GSL return values for any thread that fails. */
    int gsl_errno = GSL_SUCCESS;

    /* Storage for old GSL error handler. */
    gsl_error_handler_t *old_handler;

    /* Maximum number of subdivisions for adaptive integration. */
    static const size_t subdivision_limit = 64;

    /* Subdivide radial integral where likelihood is this fraction of the maximum,
     * will be used in solving the quadratic to find the breakpoints */
    static const double eta = 0.01;

    /* Use this many integration steps in 2*psi  */
    static const int ntwopsi = 16;

    /* Number of integration steps in cos(inclination) */
    static const int nu = 16;

    /* Number of integration steps in arrival time */
    static const int nt = 16;

    /* Rescale distances so that furthest horizon distance is 1. */
    {
        double d1max;
        memcpy(d1, horizons, sizeof(d1));
        for (d1max = d1[0], i = 1; i < nifos; i ++)
            if (d1[i] > d1max)
                d1max = d1[i];
        for (i = 0; i < nifos; i ++)
            d1[i] /= d1max;
        min_distance /= d1max;
        max_distance /= d1max;
    }

    (void)w2s; /* FIXME: remove unused parameter */

    for (i = 0; i < nifos; i ++)
        exp_i_phoas[i] = exp_i(phoas[i]);

    /* Evaluate posterior term only first. */
    P = bayestar_sky_map_toa_adapt_resolution(&pix_perm, &maxpix, npix, gmst, nifos, locations, toas, w_toas, autoresolution_count_pix_toa_phoa_snr);
    if (!P)
        return NULL;

    /* Determine the lateral HEALPix resolution. */
    nside = npix2nside(*npix);

    /* Zero all pixels that didn't meet the TDOA cut. */
    for (i = maxpix; i < *npix; i ++)
    {
        long ipix = gsl_permutation_get(pix_perm, i);
        P[ipix] = -INFINITY;
    }

    /* Use our own error handler while in parallel section to avoid concurrent
     * calls to the GSL error handler, which if provided by the user may not
     * be threadsafe. */
    old_handler = gsl_set_error_handler(my_gsl_error);

    /* Compute posterior factor for amplitude consistency. */
    #pragma omp parallel for firstprivate(gsl_errno) lastprivate(gsl_errno)
    for (i = 0; i < maxpix; i ++)
    {
       /* Cancel further computation if a GSL error condition has occurred.
        *
        * Note: if one thread sets gsl_errno, not necessarily all thread will
        * get the updated value. That's OK, because most failure modes will
        * cause GSL error conditions on all threads. If we cared to have any
        * failure on any thread terminate all of the other threads as quickly
        * as possible, then we would want to insert the following pragma here:
        *
        *     #pragma omp flush(gsl_errno)
        *
        * and likewise before any point where we set gsl_errno.
        */

        if (gsl_errno != GSL_SUCCESS)
            goto skip;

        {
            long ipix = gsl_permutation_get(pix_perm, i);
            double complex F[nifos];
            double theta, phi;
            int itwopsi, iu, it, iifo;
            double accum = -INFINITY;
            double complex exp_i_toaphoa[nifos];
            double dtau[nifos], mean_dtau;

            /* Prepare workspace for adaptive integrator. */
            gsl_integration_workspace *workspace = gsl_integration_workspace_alloc(subdivision_limit);

            /* If the workspace could not be allocated, then record the GSL
             * error value for later reporting when we leave the parallel
             * section. Then, skip to the next loop iteration. */
            if (!workspace)
            {
               gsl_errno = GSL_ENOMEM;
               goto skip;
            }

            /* Look up polar coordinates of this pixel */
            pix2ang_ring(nside, ipix, &theta, &phi);

            toa_errors(dtau, theta, phi, gmst, nifos, locations, toas);
            for (iifo = 0; iifo < nifos; iifo ++)
                exp_i_toaphoa[iifo] = exp_i_phoas[iifo] * exp_i(w1s[iifo] * dtau[iifo]);

            /* Find mean arrival time error */
            mean_dtau = gsl_stats_wmean(w_toas, 1, dtau, 1, nifos);

            /* Look up antenna factors */
            for (iifo = 0; iifo < nifos; iifo++)
            {
                XLALComputeDetAMResponse(
                    (double *)&F[iifo],     /* Type-punned real part */
                    1 + (double *)&F[iifo], /* Type-punned imag part */
                    responses[iifo], phi, M_PI_2 - theta, 0, gmst);
                F[iifo] *= d1[iifo];
            }

            /* Integrate over 2*psi */
            for (itwopsi = 0; itwopsi < ntwopsi; itwopsi++)
            {
                const double twopsi = (2 * M_PI / ntwopsi) * itwopsi;
                const double complex exp_i_twopsi = exp_i(twopsi);

                /* Integrate over u from u=-1 to u=1. */
                for (iu = -nu; iu <= nu; iu++)
                {
                    const double u = (double)iu / nu;
                    const double u2 = gsl_pow_2(u);

                    double A = 0, B = 0;
                    double breakpoints[5];
                    int num_breakpoints = 0;
                    double log_offset = -INFINITY;

                    /* The log-likelihood is quadratic in the estimated and true
                     * values of the SNR, and in 1/r. It is of the form A/r^2 + B/r,
                     * where A depends only on the true values of the SNR and is
                     * strictly negative and B depends on both the true values and
                     * the estimates and is strictly positive.
                     *
                     * The middle breakpoint is at the maximum of the log-likelihood,
                     * occurring at 1/r=-B/2A. The lower and upper breakpoints occur
                     * when the likelihood becomes eta times its maximum value. This
                     * occurs when
                     *
                     *   A/r^2 + B/r = log(eta) - B^2/4A.
                     *
                     */

                    /* Perform arrival time integral */
                    double accum1 = -INFINITY;
                    for (it = -nt/2; it <= nt/2; it++)
                    {
                        const double t = mean_dtau + LAL_REARTH_SI / LAL_C_SI * it / nt;
                        double complex i0arg_complex = 0;
                        for (iifo = 0; iifo < nifos; iifo++)
                        {
                            const double complex tmp = F[iifo] * exp_i_twopsi;
                            /* FIXME: could use - sign here to avoid conj below, but
                             * this probably just sets our sign convention relative to
                             * detection pipeline */
                            double complex phase_rhotimesr = 0.5 * (1 + u2) * creal(tmp) + I * u * cimag(tmp);
                            const double abs_rhotimesr_2 = cabs2(phase_rhotimesr);
                            const double abs_rhotimesr = sqrt(abs_rhotimesr_2);
                            phase_rhotimesr /= abs_rhotimesr;
                            i0arg_complex += exp_i_toaphoa[iifo] * exp_i(-w1s[iifo] * t) * phase_rhotimesr * gsl_pow_2(snrs[iifo]);
                        }
                        const double i0arg = cabs(i0arg_complex);
                        accum1 = logaddexp(accum1, log(gsl_sf_bessel_I0_scaled(i0arg)) + i0arg - 0.5 * gsl_stats_wtss_m(w_toas, 1, dtau, 1, nifos, t));
                    }

                    /* Loop over detectors */
                    for (iifo = 0; iifo < nifos; iifo++)
                    {
                        const double complex tmp = F[iifo] * exp_i_twopsi;
                        /* FIXME: could use - sign here to avoid conj below, but
                         * this probably just sets our sign convention relative to
                         * detection pipeline */
                        double complex phase_rhotimesr = 0.5 * (1 + u2) * creal(tmp) + I * u * cimag(tmp);
                        const double abs_rhotimesr_2 = cabs2(phase_rhotimesr);
                        const double abs_rhotimesr = sqrt(abs_rhotimesr_2);

                        A += abs_rhotimesr_2;
                        B += abs_rhotimesr * snrs[iifo];
                    }
                    A *= -0.5;

                    {
                        const double middle_breakpoint = -2 * A / B;
                        const double lower_breakpoint = 1 / (1 / middle_breakpoint + sqrt(log(eta) / A));
                        const double upper_breakpoint = 1 / (1 / middle_breakpoint - sqrt(log(eta) / A));
                        breakpoints[num_breakpoints++] = min_distance;
                        if(lower_breakpoint > breakpoints[num_breakpoints-1] && lower_breakpoint < max_distance)
                            breakpoints[num_breakpoints++] = lower_breakpoint;
                        if(middle_breakpoint > breakpoints[num_breakpoints-1] && middle_breakpoint < max_distance)
                            breakpoints[num_breakpoints++] = middle_breakpoint;
                        if(upper_breakpoint > breakpoints[num_breakpoints-1] && upper_breakpoint < max_distance)
                            breakpoints[num_breakpoints++] = upper_breakpoint;
                        breakpoints[num_breakpoints++] = max_distance;
                    }

                    {
                        /*
                         * Set log_offset to the maximum of the logarithm of the
                         * radial integrand evaluated at all of the breakpoints. */
                        int ibreakpoint;
                        for (ibreakpoint = 0; ibreakpoint < num_breakpoints; ibreakpoint++)
                        {
                            const double new_log_offset = log_radial_integrand(
                                breakpoints[ibreakpoint], A, B, prior_distance_power);
                            if (new_log_offset < INFINITY && new_log_offset > log_offset)
                                log_offset = new_log_offset;
                        }
                    }

                    {
                        /* Perform adaptive integration. Stop when a relative
                         * accuracy of 0.05 has been reached. */
                        inner_integrand_params integrand_params = {A, B, log_offset, prior_distance_power};
                        const gsl_function func = {radial_integrand, &integrand_params};
                        double result, abserr;
                        int ret = gsl_integration_qagp(&func, &breakpoints[0], num_breakpoints, DBL_MIN, 0.05, subdivision_limit, workspace, &result, &abserr);

                        /* If the integrator failed, then record the GSL error
                         * value for later reporting when we leave the parallel
                         * section. Then, break out of the loop. */
                        if (ret != GSL_SUCCESS)
                        {
                            gsl_errno = ret;
                            gsl_integration_workspace_free(workspace);
                            goto skip;
                        }

                        /* Take the logarithm and put the log-normalization back in. */
                        result = log(result) + integrand_params.log_offset + accum1;

                        /* Accumulate result. */
                        accum = logaddexp(accum, result);
                    }
                }
            }
            /* Discard workspace for adaptive integrator. */
            gsl_integration_workspace_free(workspace);

            /* Store log posterior. */
            P[ipix] = accum;
        }

        skip: /* this statement intentionally left blank */;
    }

    /* Restore old error handler. */
    gsl_set_error_handler(old_handler);

    /* Free permutation. */
    gsl_permutation_free(pix_perm);

    /* Check if there was an error in any thread evaluating any pixel. If there
     * was, raise the error and return. */
    if (gsl_errno != GSL_SUCCESS)
    {
        free(P);
        GSL_ERROR_NULL(gsl_strerror(gsl_errno), gsl_errno);
    }

    /* Exponentiate and normalize posterior. */
    pix_perm = get_pixel_ranks(*npix, P);
    if (!pix_perm)
    {
        free(P);
        return NULL;
    }
    exp_normalize(*npix, P, pix_perm);
    gsl_permutation_free(pix_perm);

    return P;
}
Esempio n. 9
0
double bayestar_log_posterior_toa_phoa_snr(
    double ra,
    double sin_dec,
    double distance,
    double u,
    double twopsi,
    double t,
    double gmst, /* Greenwich mean sidereal time in radians. */
    int nifos, /* Input: number of detectors. */
    const float (**responses)[3], /* Pointers to detector responses. */
    const double **locations, /* Pointers to locations of detectors in Cartesian geographic coordinates. */
    const double *toas, /* Input: array of times of arrival with arbitrary relative offset. (Make toas[0] == 0.) */
    const double *phoas, /* Input: array of times of arrival with arbitrary relative offset. (Make toas[0] == 0.) */
    const double *snrs, /* Input: array of SNRs. */
    const double *w_toas, /* Input: sum-of-squares weights, (1/TOA variance)^2. */
    const double *w1s, /* Input: first moments of angular frequency. */
    const double *w2s, /* Input: second moments of angular frequency. */
    const double *horizons, /* Distances at which a source would produce an SNR of 1 in each detector. */
    int prior_distance_power) /* Use a prior of (distance)^(prior_distance_power) */
{
    int iifo;
    const double dec = asin(sin_dec);
    const double u2 = gsl_pow_2(u);
    const double complex exp_i_twopsi = exp_i(twopsi);

    (void)w2s; /* FIXME: remove unused parameter */

    /* Compute time of arrival errors */
    double dt[nifos];
    toa_errors(dt, M_PI_2 - dec, ra, gmst, nifos, locations, toas);

    {
        double mean_dt = gsl_stats_wmean(w_toas, 1, dt, 1, nifos);
        for (iifo = 0; iifo < nifos; iifo++)
            dt[iifo] += t - mean_dt;
    }

    /* Rescale distances so that furthest horizon distance is 1. */
    double d1[nifos];
    {
        const double d1max = gsl_stats_max(horizons, 1, nifos);
        for (iifo = 0; iifo < nifos; iifo ++)
            d1[iifo] = horizons[iifo] / d1max;
        distance /= d1max;
    }

    double logp = 0;
    double complex i0arg_complex = 0;
    double A = 0;
    double B = 0;

    /* Loop over detectors */
    for (iifo = 0; iifo < nifos; iifo++)
    {
        double complex F;
        XLALComputeDetAMResponse(
            (double *)&F,     /* Type-punned real part */
            1 + (double *)&F, /* Type-punned imag part */
            responses[iifo], ra, dec, 0, gmst);
        F *= d1[iifo];

        const double complex tmp = F * exp_i_twopsi;
        double complex phase_rhotimesr = 0.5 * (1 + u2) * creal(tmp) + I * u * cimag(tmp);
        const double abs_rhotimesr_2 = cabs2(phase_rhotimesr);
        const double abs_rhotimesr = sqrt(abs_rhotimesr_2);
        phase_rhotimesr /= abs_rhotimesr;
        i0arg_complex += exp_i(phoas[iifo] + w1s[iifo] * dt[iifo]) * phase_rhotimesr * gsl_pow_2(snrs[iifo]);
        logp += -0.5 * w_toas[iifo] * gsl_pow_2(dt[iifo]);

        A += abs_rhotimesr_2;
        B += abs_rhotimesr * snrs[iifo];
    }
    A *= -0.5;

    const double i0arg = cabs(i0arg_complex);

    /* Should be equivalent to, but more accurate than:
         logp += log(gsl_sf_bessel_I0(i0arg))
     */
    logp += log(gsl_sf_bessel_I0_scaled(i0arg)) + i0arg;

    logp += log_radial_integrand(distance, A, B, prior_distance_power);

    return logp;
}
int PSDCalculator::calculatePowerSpectrum(
  double *input, int inputLen, 
  double *output, int outputLen, 
  bool removeMean, bool interpolateHoles,
  bool average, int averageLen, 
  bool apodize, ApodizeFunction apodizeFxn, double gaussianSigma,
  PSDType outputType, double inputSamplingFreq) {

  if (outputLen != calculateOutputVectorLength(inputLen, average, averageLen)) {
    Kst::Debug::self()->log(i18n("in PSDCalculator::calculatePowerSpectrum: received output array with wrong length."), Kst::Debug::Error);
    return -1;
  }

  if (outputLen != _prevOutputLen) {
    delete[] _a;
    delete[] _w;

    _awLen = outputLen*2;
    _prevOutputLen = outputLen;

    _a = new double[_awLen];
    _w = new double[_awLen];

    updateWindowFxn(apodizeFxn, gaussianSigma);
  }

  if ( (_prevApodizeFxn != apodizeFxn) || (_prevGaussianSigma != gaussianSigma) ) {
    updateWindowFxn(apodizeFxn, gaussianSigma);
  }

  int currentCopyLen, nsamples = 0;
  int i_samp, i_subset, ioffset;

  memset(output, 0, sizeof(double)*outputLen); // initialize output.

  // Mingw build could be 10 times slower (Gaussian apod, mostly 0 then?)
  //MeasureTime time_in_rfdt("rdft()");

  bool done = false;
  for (i_subset = 0; !done; i_subset++) {
    ioffset = i_subset*outputLen; //overlapping average => i_subset*outputLen

    // only zero pad if we really have to.  It is better to adjust the last chunk's
    // overlap.
    if (ioffset + _awLen*5/4 < inputLen) {
      currentCopyLen = _awLen; //will copy a complete window.
    } else if (_awLen<inputLen) {  // count the last one from the end.
      ioffset = inputLen-_awLen - 1;
      currentCopyLen = _awLen; //will copy a complete window.
      done = true;
    } else {
      currentCopyLen = inputLen - ioffset; //will copy a partial window.
      memset(&_a[currentCopyLen], 0, sizeof(double)*(_awLen - currentCopyLen)); //zero the leftovers.
      done = true;
    }

    double mean = 0.0;

    if (removeMean) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        mean += input[i_samp + ioffset];
      }
      mean /= (double)currentCopyLen;
    }

    // apply the PSD options (removeMean, apodize, etc.)
    // separate cases for speed- although this shouldn't really matter- the rdft should be the most time consuming step by far for any large data set.
    if (removeMean && apodize && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = (Kst::kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen) - mean)*_w[i_samp];
      }
    } else if (removeMean && apodize) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = (input[i_samp + ioffset] - mean)*_w[i_samp];
      }
    } else if (removeMean && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = Kst::kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen) - mean;
      }
    } else if (apodize && interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = Kst::kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen)*_w[i_samp];
      }
    } else if (removeMean) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset] - mean;
      }
    } else if (apodize) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset]*_w[i_samp];
      }
    } else if (interpolateHoles) {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = Kst::kstInterpolateNoHoles(input, inputLen, i_samp + ioffset, inputLen);
      }
    } else {
      for (i_samp = 0; i_samp < currentCopyLen; i_samp++) {
        _a[i_samp] = input[i_samp + ioffset];
      }
    }

    nsamples += currentCopyLen;

#if !defined(__QNX__)
    rdft(_awLen, 1, _a); //real discrete fourier transorm on _a.
#else
    Q_ASSERT(0); // there is a linking problem when not compling with pch. . .
#endif

    output[0] += _a[0] * _a[0];
    output[outputLen-1] += _a[1] * _a[1];
    for (i_samp = 1; i_samp < outputLen - 1; i_samp++) {
      output[i_samp] += cabs2(_a[i_samp * 2], _a[i_samp * 2 + 1]);
    }
  }

  // FIXME: NORMALIZATION. 
  /* This normalization doesn't give the same results as the original KstPSD.

  double frequencyStep = .5*(double)inputSamplingFreq/(double)(outputLen-1);

  //normalization factors which were left out earlier for speed. 
  //    - 2.0 for the negative frequencies which were neglected by the rdft //FIXME: double check.
  //    - /(_awLen*_awLen) for the constant Wss from numerical recipes in C. (ensure that the window function agrees with this.)
  //    - /i_subset to average the powers in all the subsets.
  double norm = 2.0/(double)_awLen/(double)_awLen/(double)i_subset;
  */

  // original normalization
  double frequencyStep = 2.0*(double)inputSamplingFreq/(double)nsamples; //OLD value for frequencyStep.
  double norm = 2.0/(double)nsamples*2.0/(double)nsamples; //OLD value for norm.

  switch (outputType) {
  default:
    case PSDAmplitudeSpectralDensity: // amplitude spectral density (default) [V/Hz^1/2]
      norm /= frequencyStep;
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] = sqrt(output[i_samp]*norm);
      }
    break;

    case PSDPowerSpectralDensity: // power spectral density [V^2/Hz]
      norm /= frequencyStep;
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] *= norm;
      }
    break;

    case PSDAmplitudeSpectrum: // amplitude spectrum [V]
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] = sqrt(output[i_samp]*norm);
      }
    break;

    case PSDPowerSpectrum: // power spectrum [V^2]
      for (i_samp = 0; i_samp < outputLen; i_samp++) {
        output[i_samp] *= norm;
      }
    break;
  }

  return 0;
}
Esempio n. 11
0
void KstPSDGenerator::updateNow() {

  int i_subset, i_samp;
  int n_subsets;
  int v_len;
  int copyLen;
  QValueVector<double> psd, f;
  double mean;
  double nf;
  bool done;
  
  adjustLengths();
  
  v_len = _inputVector->size();
  n_subsets = v_len/_PSDLen+1;
  if (v_len%_PSDLen==0) n_subsets--;

  // always update when asked
  _last_n_new = _inputVector->size();

  for (i_samp = 0; i_samp < _PSDLen; i_samp++) {
    (*_powerVector)[i_samp] = 0;
    (*_frequencyVector)[i_samp] = i_samp*0.5*_Freq/( _PSDLen-1 );
  }
  _frequencyVectorStep = 0.5*_Freq/(_PSDLen - 1);

  nf = 0;
  done = false;
  for (i_subset = 0; !done; i_subset++) {
    // copy each chunk into a[] and find mean
    if (i_subset*_PSDLen + _ALen < v_len) {
      copyLen = _ALen;
    } else {
      copyLen = v_len - i_subset*_PSDLen;
      done = true;
    }

    mean = 0;
    for (i_samp = 0; i_samp < copyLen; i_samp++) {
      mean += (
        _a[i_samp] =
        _inputVector->at(i_samp + i_subset*_PSDLen)
        );
    }
    if (copyLen > 1) {
      mean /= (double)copyLen;
    }

    if (apodize()) {
      GenW(copyLen);
    }
     
    // remove mean and apodize
    if (removeMean() && apodize()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        _a[i_samp]= (_a[i_samp]-mean)*_w[i_samp];
      }
    } else if (removeMean()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        _a[i_samp] -= mean;
      }
    } else if (apodize()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        _a[i_samp] *= _w[i_samp];
      }
    }
    nf += copyLen;


    for (;i_samp < _ALen; i_samp++) {
      _a[i_samp] = 0.0;
    }
    // fft a
    rdft(_ALen, 1, _a);
    (*_powerVector)[0] += _a[0]*_a[0];
    (*_powerVector)[_PSDLen-1] += _a[1]*_a[1];
    for (i_samp=1; i_samp<_PSDLen-1; i_samp++) {
      (*_powerVector)[i_samp]+= cabs2(_a[i_samp*2], _a[i_samp*2+1]);
    }
  }

  _last_f0 = 0;
  _last_n_subsets = n_subsets;
  _last_n_new = 0;
  nf = 1.0/(double(_Freq)*double(nf/2.0));
  for ( i_samp = 0; i_samp<_PSDLen; i_samp++ ) {
    (*_powerVector)[i_samp] = sqrt((*_powerVector)[i_samp]*nf);
  }
  if (_Freq <= 0.0) {
    _Freq = 1.0;
  }
}