def shift_sum(v1, shifts, bins): real_type = real_same_precision_as(v1) shifts = numpy.array(shifts, dtype=real_type) bins = numpy.array(bins, dtype=numpy.uint32) blen = len(bins) - 1 # pylint:disable=unused-variable v1 = numpy.array(v1.data, copy=False) slen = len(v1) # pylint:disable=unused-variable if v1.dtype.name == 'complex64': code = point_chisq_code_single else: code = point_chisq_code_double n = int(len(shifts)) # Create some output memory chisq = numpy.zeros(n, dtype=real_type) inline(code, ['v1', 'n', 'chisq', 'slen', 'shifts', 'bins', 'blen'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs ) return chisq
def inner_inline_real(self, other): x = _np.array(self._data, copy=False) # pylint:disable=unused-variable y = _np.array(other, copy=False) # pylint:disable=unused-variable total = _np.array([0.], dtype=float64) N = len(self) # pylint:disable=unused-variable inline(inner_code, ['x', 'y', 'total', 'N'], libraries=omp_libs, extra_compile_args=code_flags) return total[0]
def batch_correlate_execute(self, y): num_vectors = self.num_vectors # pylint:disable=unused-variable size = self.size # pylint:disable=unused-variable x = numpy.array(self.x.data, copy=False) # pylint:disable=unused-variable z = numpy.array(self.z.data, copy=False) # pylint:disable=unused-variable y = numpy.array(y.data, copy=False) inline(batch_correlator_code, ['x', 'y', 'z', 'size', 'num_vectors'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs)
def batch_correlate_execute(self, y): num_vectors = self.num_vectors # pylint:disable=unused-variable size = self.size # pylint:disable=unused-variable x = numpy.array(self.x.data, copy=False) # pylint:disable=unused-variable z = numpy.array(self.z.data, copy=False) # pylint:disable=unused-variable y = numpy.array(y.data, copy=False) inline(batch_correlator_code, ['x', 'y', 'z', 'size', 'num_vectors'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs)
def correlate(self): htilde = self.x # pylint:disable=unused-variable stilde = self.y # pylint:disable=unused-variable qtilde = self.z # pylint:disable=unused-variable arrlen = self.arrlen # pylint:disable=unused-variable segsize = self.segsize # pylint:disable=unused-variable inline(self.code, ['htilde', 'stilde', 'qtilde', 'arrlen', 'segsize'], extra_compile_args = [WEAVE_FLAGS] + omp_flags, #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'] + omp_flags, #extra_compile_args = ['-msse3 -O3 -w'] + omp_flags, libraries = omp_libs, support_code = self.support, auto_downcast = 1)
def abs_arg_max(self): if self.kind == 'real': return _np.argmax(abs(self.data)) else: data = _np.array(self._data, # pylint:disable=unused-variable copy=False).view(real_same_precision_as(self)) loc = _np.array([0]) N = len(self) # pylint:disable=unused-variable inline(code_abs_arg_max, ['data', 'loc', 'N'], libraries=omp_libs, extra_compile_args=code_flags) return loc[0]
def execute(self): inarr = self.inarr # pylint:disable=unused-variable mval = self.mval # pylint:disable=unused-variable norm = self.norm # pylint:disable=unused-variable mloc = self.mloc # pylint:disable=unused-variable nstart = self.nstart # pylint:disable=unused-variable howmany = self.howmany # pylint:disable=unused-variable inline(self.code, ['inarr', 'mval', 'norm', 'mloc', 'nstart', 'howmany'], extra_compile_args = [WEAVE_FLAGS], #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'], #extra_compile_args = ['-msse4.1 -O3 -w'], support_code = self.support, auto_downcast = 1, verbose = self.verbose)
def correlate_simd(ht, st, qt): htilde = _np.array(ht.data, copy=False).view(dtype=float32) stilde = _np.array(st.data, copy=False).view(dtype=float32) # pylint:disable=unused-variable qtilde = _np.array(qt.data, copy=False).view(dtype=float32) # pylint:disable=unused-variable arrlen = len(htilde) # pylint:disable=unused-variable inline( corr_simd_code, ['htilde', 'stilde', 'qtilde', 'arrlen'], extra_compile_args=[WEAVE_FLAGS], #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'], #extra_compile_args = ['-msse3 -O3 -w'], support_code=corr_support, auto_downcast=1)
def execute(self): inarr = self.inarr # pylint:disable=unused-variable arrlen = self.arrlen # pylint:disable=unused-variable cvals = self.cvals # pylint:disable=unused-variable norms = self.norms # pylint:disable=unused-variable locs = self.locs # pylint:disable=unused-variable winsize = self.winsize # pylint:disable=unused-variable startoffset = self.startoffset # pylint:disable=unused-variable inline(self.code, ['inarr', 'arrlen', 'cvals', 'norms', 'locs', 'winsize', 'startoffset'], extra_compile_args = [WEAVE_FLAGS], #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'], #extra_compile_args = ['-msse4.1 -O3 -w'], support_code = self.support, auto_downcast = 1, verbose = self.verbose)
def threshold_inline(series, value): arr = numpy.array(series.data.view(dtype=numpy.float32), copy=False) # pylint:disable=unused-variable global outl, outv, count if outl is None or len(outl) < len(series): outl = numpy.zeros(len(series), dtype=numpy.uint32) outv = numpy.zeros(len(series), dtype=numpy.complex64) count = numpy.zeros(1, dtype=numpy.uint32) N = len(series) # pylint:disable=unused-variable threshold = value**2.0 # pylint:disable=unused-variable code = """ float v = threshold; unsigned int num_parallel_regions = 16; unsigned int t=0; #pragma omp parallel for ordered shared(t) for (unsigned int p=0; p<num_parallel_regions; p++){ unsigned int start = (N * p) / num_parallel_regions; unsigned int end = (N * (p+1)) / num_parallel_regions; unsigned int c = 0; for (unsigned int i=start; i<end; i++){ float r = arr[i*2]; float im = arr[i*2+1]; if ((r * r + im * im) > v){ outl[c+start] = i; outv[c+start] = std::complex<float>(r, im); c++; } } #pragma omp ordered { t+=c; } memmove(outl+t-c, outl+start, sizeof(unsigned int)*c); memmove(outv+t-c, outv+start, sizeof(std::complex<float>)*c); } count[0] = t; """ inline(code, ['N', 'arr', 'outv', 'outl', 'count', 'threshold'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs ) num = count[0] if num > 0: return outl[0:num], outv[0:num] else: return numpy.array([], numpy.uint32), numpy.array([], numpy.float32)
def threshold_inline(series, value): arr = numpy.array(series.data.view(dtype=numpy.float32), copy=False) # pylint:disable=unused-variable global outl, outv, count if outl is None or len(outl) < len(series): outl = numpy.zeros(len(series), dtype=numpy.uint32) outv = numpy.zeros(len(series), dtype=numpy.complex64) count = numpy.zeros(1, dtype=numpy.uint32) N = len(series) # pylint:disable=unused-variable threshold = value**2.0 # pylint:disable=unused-variable code = """ float v = threshold; unsigned int num_parallel_regions = 16; unsigned int t=0; #pragma omp parallel for ordered shared(t) for (unsigned int p=0; p<num_parallel_regions; p++){ unsigned int start = (N * p) / num_parallel_regions; unsigned int end = (N * (p+1)) / num_parallel_regions; unsigned int c = 0; for (unsigned int i=start; i<end; i++){ float r = arr[i*2]; float im = arr[i*2+1]; if ((r * r + im * im) > v){ outl[c+start] = i; outv[c+start] = std::complex<float>(r, im); c++; } } #pragma omp ordered { t+=c; } memmove(outl+t-c, outl+start, sizeof(unsigned int)*c); memmove(outv+t-c, outv+start, sizeof(std::complex<float>)*c); } count[0] = t; """ inline(code, ['N', 'arr', 'outv', 'outl', 'count', 'threshold'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs ) num = count[0] if num > 0: return outl[0:num], outv[0:num] else: return numpy.array([], numpy.uint32), numpy.array([], numpy.float32)
def correlate_batch_inline(x, y, z): if z.precision == 'single': the_code = single_codeb else: the_code = double_codeb za = numpy.array(z.ptr, copy=False) # pylint:disable=unused-variable xa = numpy.array(x.ptr, copy=False) # pylint:disable=unused-variable ya = numpy.array(y.ptr, copy=False) # pylint:disable=unused-variable N = len(x) # pylint:disable=unused-variable inline(the_code, ['xa', 'ya', 'za', 'N'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, support_code=support, libraries=omp_libs)
def chisq_accum_bin_inline(chisq, q): chisq = numpy.array(chisq.data, copy=False) q = numpy.array(q.data, copy=False) N = len(chisq) # pylint:disable=unused-variable code = """ #pragma omp parallel for for (int i=0; i<N; i++){ chisq[i] += q[i].real()*q[i].real()+q[i].imag()*q[i].imag(); } """ inline(code, ['chisq', 'q', 'N'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs)
def correlate(self): htilde = self.x # pylint:disable=unused-variable stilde = self.y # pylint:disable=unused-variable qtilde = self.z # pylint:disable=unused-variable arrlen = self.arrlen # pylint:disable=unused-variable segsize = self.segsize # pylint:disable=unused-variable inline( self.code, ['htilde', 'stilde', 'qtilde', 'arrlen', 'segsize'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'] + omp_flags, #extra_compile_args = ['-msse3 -O3 -w'] + omp_flags, libraries=omp_libs, support_code=self.support, auto_downcast=1)
def chisq_accum_bin_inline(chisq, q): chisq = numpy.array(chisq.data, copy=False) q = numpy.array(q.data, copy=False) N = len(chisq) # pylint:disable=unused-variable code = """ #pragma omp parallel for for (int i=0; i<N; i++){ chisq[i] += q[i].real()*q[i].real()+q[i].imag()*q[i].imag(); } """ inline(code, ['chisq', 'q', 'N'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs )
def correlate_parallel(ht, st, qt): htilde = _np.array(ht.data, copy=False) stilde = _np.array(st.data, copy=False) # pylint:disable=unused-variable qtilde = _np.array(qt.data, copy=False) # pylint:disable=unused-variable arrlen = len(htilde) # pylint:disable=unused-variable segsize = default_segsize # pylint:disable=unused-variable inline( corr_parallel_code, ['htilde', 'stilde', 'qtilde', 'arrlen', 'segsize'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs, #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'], #extra_compile_args = ['-msse3 -O3 -w'], support_code=corr_support, auto_downcast=1)
def correlate_batch_inline(x, y, z): if z.precision == 'single': the_code = single_codeb else: the_code = double_codeb za = numpy.array(z.ptr, copy=False) # pylint:disable=unused-variable xa = numpy.array(x.ptr, copy=False) # pylint:disable=unused-variable ya = numpy.array(y.ptr, copy=False) # pylint:disable=unused-variable N = len(x) # pylint:disable=unused-variable inline(the_code, ['xa', 'ya', 'za', 'N'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, support_code = support, libraries=omp_libs )
def execute(self, thresh): series = self.series # pylint:disable=unused-variable slen = self.slen # pylint:disable=unused-variable values = self.values # pylint:disable=unused-variable locs = self.locs # pylint:disable=unused-variable window = self.window # pylint:disable=unused-variable segsize = self.segsize # pylint:disable=unused-variable nthr = inline( self.code, [ 'series', 'slen', 'values', 'locs', 'thresh', 'window', 'segsize' ], extra_compile_args=[WEAVE_FLAGS] + omp_flags, #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'], #extra_compile_args = ['-msse4.1 -O3 -w'], support_code=self.support, libraries=omp_libs, auto_downcast=1, verbose=self.verbose) if nthr > 0: return self.values[0:nthr], self.locs[0:nthr] else: return _np.array([], dtype=complex64), _np.array([], dtype=_np.uint32)
def apply_fseries_time_shift(htilde, dt, kmin=0, copy=True): """Shifts a frequency domain waveform in time. The waveform is assumed to be sampled at equal frequency intervals. """ out = numpy.array(htilde.data, copy=copy) phi = -2 * numpy.pi * dt * htilde.delta_f # pylint:disable=unused-variable kmax = len(htilde) # pylint:disable=unused-variable if htilde.precision == 'single': code = _apply_shift_code32 else: code = _apply_shift_code inline(code, ['out', 'phi', 'kmin', 'kmax'], extra_compile_args=[WEAVE_FLAGS]+omp_flags, libraries=omp_libs) if copy: htilde = FrequencySeries(out, delta_f=htilde.delta_f, epoch=htilde.epoch, copy=False) return htilde
def apply_fseries_time_shift(htilde, dt, kmin=0, copy=True): """Shifts a frequency domain waveform in time. The waveform is assumed to be sampled at equal frequency intervals. """ out = numpy.array(htilde.data, copy=copy) phi = -2 * numpy.pi * dt * htilde.delta_f # pylint:disable=unused-variable kmax = len(htilde) # pylint:disable=unused-variable if htilde.precision == 'single': code = _apply_shift_code32 else: code = _apply_shift_code inline(code, ['out', 'phi', 'kmin', 'kmax'], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs) if copy: htilde = FrequencySeries(out, delta_f=htilde.delta_f, epoch=htilde.epoch, copy=False) return htilde
def inline_linear_interp(amp, phase, sample_frequencies, output, df, f_lower, imin, start_index): # The CPU code does not reference f_lower, but GPU needs it if output.precision == 'single': code = _linear_decompress_code32 else: code = _linear_decompress_code sample_frequencies = numpy.array(sample_frequencies) amp = numpy.array(amp) phase = numpy.array(phase) sflen = len(sample_frequencies) # pylint:disable=unused-variable h = numpy.array(output.data, copy=False) # pylint:disable=unused-variable hlen = len(output) # pylint:disable=unused-variable delta_f = float(df) # pylint:disable=unused-variable inline(code, [ 'h', 'hlen', 'sflen', 'delta_f', 'sample_frequencies', 'amp', 'phase', 'start_index', 'imin' ], extra_compile_args=[WEAVE_FLAGS] + omp_flags, libraries=omp_libs) return output
def threshold_and_cluster(self, threshold, window): series = self.series # pylint:disable=unused-variable slen = self.slen # pylint:disable=unused-variable values = self.outv locs = self.outl segsize = self.segsize # pylint:disable=unused-variable self.count = inline(self.code, ['series', 'slen', 'values', 'locs', 'threshold', 'window', 'segsize'], extra_compile_args = [WEAVE_FLAGS] + omp_flags, #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'] + omp_flags, #extra_compile_args = ['-msse3 -O3 -w'] + omp_flags, support_code = self.support, libraries = omp_libs, auto_downcast = 1) if self.count > 0: return values[0:self.count], locs[0:self.count] else: return numpy.array([], dtype = numpy.complex64), numpy.array([], dtype = numpy.uint32)
def threshold_and_cluster_weave(self, threshold, window): # pylint:disable=unused-variable series = self.series # pylint:disable=unused-variable slen = self.slen # pylint:disable=unused-variable values = self.outv locs = self.outl segsize = self.segsize # pylint:disable=unused-variable self.count = inline(self.code, ['series', 'slen', 'values', 'locs', 'threshold', 'window', 'segsize'], extra_compile_args = [WEAVE_FLAGS] + omp_flags, #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'] + omp_flags, #extra_compile_args = ['-msse3 -O3 -w'] + omp_flags, support_code = self.support, libraries = omp_libs, auto_downcast = 1) if self.count > 0: return values[0:self.count], locs[0:self.count] else: return numpy.array([], dtype = numpy.complex64), numpy.array([], dtype = numpy.uint32)
def execute(self, thresh): series = self.series # pylint:disable=unused-variable slen = self.slen # pylint:disable=unused-variable values = self.values # pylint:disable=unused-variable locs = self.locs # pylint:disable=unused-variable window = self.window # pylint:disable=unused-variable segsize = self.segsize # pylint:disable=unused-variable nthr = inline(self.code, ['series', 'slen', 'values', 'locs', 'thresh', 'window', 'segsize'], extra_compile_args = [WEAVE_FLAGS] + omp_flags, #extra_compile_args = ['-mno-avx -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 -mno-sse4a -O2 -w'], #extra_compile_args = ['-msse4.1 -O3 -w'], support_code = self.support, libraries = omp_libs, auto_downcast = 1, verbose = self.verbose) if nthr > 0: return self.values[0:nthr], self.locs[0:nthr] else: return _np.array([], dtype = complex64), _np.array([], dtype = _np.uint32)
def spa_tmplt_engine(htilde, kmin, phase_order, delta_f, piM, pfaN, pfa2, pfa3, pfa4, pfa5, pfl5, pfa6, pfl6, pfa7, amp_factor): """ Calculate the spa tmplt phase """ kfac = numpy.array(spa_tmplt_precondition(len(htilde), delta_f, kmin).data, copy=False) # pylint:disable=unused-variable htilde = numpy.array(htilde.data, copy=False) cbrt_vec = numpy.array(get_cbrt(len(htilde)*delta_f + kmin, delta_f).data, copy=False) # pylint:disable=unused-variable logv_vec = numpy.array(get_log(len(htilde)*delta_f + kmin, delta_f).data, copy=False) # pylint:disable=unused-variable length = len(htilde) # pylint:disable=unused-variable code = """ float piM13 = cbrtf(piM); float logpiM13 = log(piM13); float log4 = log(4.); const float _pfaN=pfaN; const float _pfa2=pfa2; const float _pfa3=pfa3; const float _pfa4=pfa4; const float _pfa5=pfa5; const float _pfl5=pfl5; const float _pfa6=pfa6; const float _pfl6=pfl6; const float _pfa7=pfa7; const float ampc = amp_factor; const float two_pi = 2 * M_PI; const float inv_two_pi = 1 / (2 * M_PI); #pragma omp parallel for schedule(dynamic, 1024) for (unsigned int i=0; i<length; i++){ int index = i + kmin; const float v = piM13 * cbrt_vec[index]; const float logv = logv_vec[index] * 1.0/3.0 + logpiM13; const float v5 = v * v * v * v * v; float phasing = 0; float sinp, cosp; switch (phase_order) { case -1: case 7: phasing = _pfa7 * v; case 6: phasing = (phasing + _pfa6 + _pfl6 * (logv + log4) ) * v; case 5: phasing = (phasing + _pfa5 + _pfl5 * (logv) ) * v; case 4: phasing = (phasing + _pfa4) * v; case 3: phasing = (phasing + _pfa3) * v; case 2: phasing = (phasing + _pfa2) * v * v; case 0: phasing += 1.; break; default: break; } float amp = ampc * kfac[i]; phasing *= _pfaN / v5; phasing -= M_PI_4; phasing -= int(phasing / two_pi) * two_pi; while (phasing < -M_PI){ phasing += two_pi; } while (phasing > M_PI){ phasing -= two_pi; } // compute sine if (phasing < 0) { sinp = 1.27323954 * phasing + .405284735 * phasing * phasing; if (sinp < 0) sinp = .225 * (sinp *-sinp - sinp) + sinp; else sinp = .225 * (sinp * sinp - sinp) + sinp; } else { sinp = 1.27323954 * phasing - 0.405284735 * phasing * phasing; if (sinp < 0) sinp = .225 * (sinp *-sinp - sinp) + sinp; else sinp = .225 * (sinp * sinp - sinp) + sinp; } //compute cosine phasing += M_PI_2; if (phasing > M_PI) phasing -= two_pi; if (phasing < 0) { cosp = 1.27323954 * phasing + .405284735 * phasing * phasing; if (cosp < 0) cosp = .225 * (cosp *-cosp - cosp) + cosp; else cosp = .225 * (cosp * cosp - cosp) + cosp; } else { cosp = 1.27323954 * phasing - 0.405284735 * phasing * phasing; if (cosp < 0) cosp = .225 * (cosp *-cosp - cosp) + cosp; else cosp = .225 * (cosp * cosp - cosp) + cosp; } //printf("%f %f %f \\n", sinp, sin(phasing), phasing); htilde[i] = std::complex<float>(cosp, - sinp) * amp; } """ inline(code, ['htilde', 'cbrt_vec', 'logv_vec', 'kmin', 'phase_order', 'piM', 'pfaN', 'amp_factor', 'kfac', 'pfa2', 'pfa3', 'pfa4', 'pfa5', 'pfl5', 'pfa6', 'pfl6', 'pfa7', 'length'], extra_compile_args=[pycbc.WEAVE_FLAGS] + omp_flags, support_code = support, libraries=omp_libs )
def fd_decompress(amp, phase, sample_frequencies, out=None, df=None, f_lower=None, interpolation='inline_linear'): """Decompresses an FD waveform using the given amplitude, phase, and the frequencies at which they are sampled at. Parameters ---------- amp : array The amplitude of the waveform at the sample frequencies. phase : array The phase of the waveform at the sample frequencies. sample_frequencies : array The frequency (in Hz) of the waveform at the sample frequencies. out : {None, FrequencySeries} The output array to save the decompressed waveform to. If this contains slots for frequencies > the maximum frequency in sample_frequencies, the rest of the values are zeroed. If not provided, must provide a df. df : {None, float} The frequency step to use for the decompressed waveform. Must be provided if out is None. f_lower : {None, float} The frequency to start the decompression at. If None, will use whatever the lowest frequency is in sample_frequencies. All values at frequencies less than this will be 0 in the decompressed waveform. interpolation : {'inline_linear', str} The interpolation to use for the amplitude and phase. Default is 'inline_linear'. If 'inline_linear' a custom interpolater is used. Otherwise, ``scipy.interpolate.interp1d`` is used; for other options, see possible values for that function's ``kind`` argument. Returns ------- out : FrequencySeries If out was provided, writes to that array. Otherwise, a new FrequencySeries with the decompressed waveform. """ precision = _precision_map[sample_frequencies.dtype.name] if _precision_map[amp.dtype.name] != precision or \ _precision_map[phase.dtype.name] != precision: raise ValueError("amp, phase, and sample_points must all have the " "same precision") sample_frequencies = numpy.array(sample_frequencies) amp = numpy.array(amp) phase = numpy.array(phase) if out is None: if df is None: raise ValueError("Either provide output memory or a df") hlen = int(numpy.ceil(sample_frequencies.max()/df+1)) out = FrequencySeries(numpy.zeros(hlen, dtype=_complex_dtypes[precision]), copy=False, delta_f=df) else: # check for precision compatibility if out.precision == 'double' and precision == 'single': raise ValueError("cannot cast single precision to double") df = out.delta_f hlen = len(out) if f_lower is None: imin = 0 # pylint:disable=unused-variable f_lower = sample_frequencies[0] else: if f_lower >= sample_frequencies.max(): raise ValueError("f_lower is > than the maximum sample frequency") if f_lower < sample_frequencies.min(): raise ValueError("f_lower is < than the minimum sample frequency") imin = int(numpy.searchsorted(sample_frequencies, f_lower, side='right')) - 1 # pylint:disable=unused-variable kmin = int(numpy.ceil(f_lower/df)) if kmin >= hlen: raise ValueError('requested f_lower >= largest frequency in out') # interpolate the amplitude and the phase if interpolation == "inline_linear": if out.precision == 'single': code = _linear_decompress_code32 else: code = _linear_decompress_code # use custom interpolation sflen = len(sample_frequencies) # pylint:disable=unused-variable h = numpy.array(out.data, copy=False) # pylint:disable=unused-variable delta_f = float(df) # pylint:disable=unused-variable inline(code, ['h', 'hlen', 'delta_f', 'sample_frequencies', 'sflen', 'amp', 'phase', 'kmin', 'imin'], extra_compile_args=[WEAVE_FLAGS] +\ omp_flags, libraries=omp_libs) else: # use scipy for fancier interpolation outfreq = out.sample_frequencies.numpy() amp_interp = interpolate.interp1d(sample_frequencies, amp, kind=interpolation, bounds_error=False, fill_value=0., assume_sorted=True) phase_interp = interpolate.interp1d(sample_frequencies, phase, kind=interpolation, bounds_error=False, fill_value=0., assume_sorted=True) A = amp_interp(outfreq) phi = phase_interp(outfreq) out.data[:] = A*numpy.cos(phi) + (1j)*A*numpy.sin(phi) return out
def spa_tmplt_engine(htilde, kmin, phase_order, delta_f, piM, pfaN, pfa2, pfa3, pfa4, pfa5, pfl5, pfa6, pfl6, pfa7, amp_factor): """ Calculate the spa tmplt phase """ kfac = numpy.array(spa_tmplt_precondition(len(htilde), delta_f, kmin).data, copy=False) # pylint:disable=unused-variable htilde = numpy.array(htilde.data, copy=False) cbrt_vec = numpy.array(get_cbrt(len(htilde) * delta_f + kmin, delta_f).data, copy=False) # pylint:disable=unused-variable logv_vec = numpy.array(get_log(len(htilde) * delta_f + kmin, delta_f).data, copy=False) # pylint:disable=unused-variable length = len(htilde) # pylint:disable=unused-variable code = """ float piM13 = cbrtf(piM); float logpiM13 = log(piM13); float log4 = log(4.); const float _pfaN=pfaN; const float _pfa2=pfa2; const float _pfa3=pfa3; const float _pfa4=pfa4; const float _pfa5=pfa5; const float _pfl5=pfl5; const float _pfa6=pfa6; const float _pfl6=pfl6; const float _pfa7=pfa7; const float ampc = amp_factor; const float two_pi = 2 * M_PI; const float inv_two_pi = 1 / (2 * M_PI); #pragma omp parallel for schedule(dynamic, 1024) for (unsigned int i=0; i<length; i++){ int index = i + kmin; const float v = piM13 * cbrt_vec[index]; const float logv = logv_vec[index] * 1.0/3.0 + logpiM13; const float v5 = v * v * v * v * v; float phasing = 0; float sinp, cosp; switch (phase_order) { case -1: case 7: phasing = _pfa7 * v; case 6: phasing = (phasing + _pfa6 + _pfl6 * (logv + log4) ) * v; case 5: phasing = (phasing + _pfa5 + _pfl5 * (logv) ) * v; case 4: phasing = (phasing + _pfa4) * v; case 3: phasing = (phasing + _pfa3) * v; case 2: phasing = (phasing + _pfa2) * v * v; case 0: phasing += 1.; break; default: break; } float amp = ampc * kfac[i]; phasing *= _pfaN / v5; phasing -= M_PI_4; phasing -= int(phasing / two_pi) * two_pi; while (phasing < -M_PI){ phasing += two_pi; } while (phasing > M_PI){ phasing -= two_pi; } // compute sine if (phasing < 0) { sinp = 1.27323954 * phasing + .405284735 * phasing * phasing; if (sinp < 0) sinp = .225 * (sinp *-sinp - sinp) + sinp; else sinp = .225 * (sinp * sinp - sinp) + sinp; } else { sinp = 1.27323954 * phasing - 0.405284735 * phasing * phasing; if (sinp < 0) sinp = .225 * (sinp *-sinp - sinp) + sinp; else sinp = .225 * (sinp * sinp - sinp) + sinp; } //compute cosine phasing += M_PI_2; if (phasing > M_PI) phasing -= two_pi; if (phasing < 0) { cosp = 1.27323954 * phasing + .405284735 * phasing * phasing; if (cosp < 0) cosp = .225 * (cosp *-cosp - cosp) + cosp; else cosp = .225 * (cosp * cosp - cosp) + cosp; } else { cosp = 1.27323954 * phasing - 0.405284735 * phasing * phasing; if (cosp < 0) cosp = .225 * (cosp *-cosp - cosp) + cosp; else cosp = .225 * (cosp * cosp - cosp) + cosp; } //printf("%f %f %f \\n", sinp, sin(phasing), phasing); htilde[i] = std::complex<float>(cosp, - sinp) * amp; } """ inline(code, [ 'htilde', 'cbrt_vec', 'logv_vec', 'kmin', 'phase_order', 'piM', 'pfaN', 'amp_factor', 'kfac', 'pfa2', 'pfa3', 'pfa4', 'pfa5', 'pfl5', 'pfa6', 'pfl6', 'pfa7', 'length' ], extra_compile_args=[pycbc.WEAVE_FLAGS] + omp_flags, support_code=support, libraries=omp_libs)
def fd_decompress(amp, phase, sample_frequencies, out=None, df=None, f_lower=None, interpolation='inline_linear'): """Decompresses an FD waveform using the given amplitude, phase, and the frequencies at which they are sampled at. Parameters ---------- amp : array The amplitude of the waveform at the sample frequencies. phase : array The phase of the waveform at the sample frequencies. sample_frequencies : array The frequency (in Hz) of the waveform at the sample frequencies. out : {None, FrequencySeries} The output array to save the decompressed waveform to. If this contains slots for frequencies > the maximum frequency in sample_frequencies, the rest of the values are zeroed. If not provided, must provide a df. df : {None, float} The frequency step to use for the decompressed waveform. Must be provided if out is None. f_lower : {None, float} The frequency to start the decompression at. If None, will use whatever the lowest frequency is in sample_frequencies. All values at frequencies less than this will be 0 in the decompressed waveform. interpolation : {'inline_linear', str} The interpolation to use for the amplitude and phase. Default is 'inline_linear'. If 'inline_linear' a custom interpolater is used. Otherwise, ``scipy.interpolate.interp1d`` is used; for other options, see possible values for that function's ``kind`` argument. Returns ------- out : FrequencySeries If out was provided, writes to that array. Otherwise, a new FrequencySeries with the decompressed waveform. """ precision = _precision_map[sample_frequencies.dtype.name] if _precision_map[amp.dtype.name] != precision or \ _precision_map[phase.dtype.name] != precision: raise ValueError("amp, phase, and sample_points must all have the " "same precision") sample_frequencies = numpy.array(sample_frequencies) amp = numpy.array(amp) phase = numpy.array(phase) if out is None: if df is None: raise ValueError("Either provide output memory or a df") hlen = int(numpy.ceil(sample_frequencies.max() / df + 1)) out = FrequencySeries(numpy.zeros(hlen, dtype=_complex_dtypes[precision]), copy=False, delta_f=df) else: # check for precision compatibility if out.precision == 'double' and precision == 'single': raise ValueError("cannot cast single precision to double") df = out.delta_f hlen = len(out) if f_lower is None: imin = 0 # pylint:disable=unused-variable f_lower = sample_frequencies[0] else: if f_lower >= sample_frequencies.max(): raise ValueError("f_lower is > than the maximum sample frequency") if f_lower < sample_frequencies.min(): raise ValueError("f_lower is < than the minimum sample frequency") imin = int( numpy.searchsorted(sample_frequencies, f_lower, side='right')) - 1 # pylint:disable=unused-variable kmin = int(numpy.ceil(f_lower / df)) if kmin >= hlen: raise ValueError('requested f_lower >= largest frequency in out') # interpolate the amplitude and the phase if interpolation == "inline_linear": if out.precision == 'single': code = _linear_decompress_code32 else: code = _linear_decompress_code # use custom interpolation sflen = len(sample_frequencies) # pylint:disable=unused-variable h = numpy.array(out.data, copy=False) # pylint:disable=unused-variable delta_f = float(df) # pylint:disable=unused-variable inline(code, ['h', 'hlen', 'delta_f', 'sample_frequencies', 'sflen', 'amp', 'phase', 'kmin', 'imin'], extra_compile_args=[WEAVE_FLAGS] +\ omp_flags, libraries=omp_libs) else: # use scipy for fancier interpolation outfreq = out.sample_frequencies.numpy() amp_interp = interpolate.interp1d(sample_frequencies, amp, kind=interpolation, bounds_error=False, fill_value=0., assume_sorted=True) phase_interp = interpolate.interp1d(sample_frequencies, phase, kind=interpolation, bounds_error=False, fill_value=0., assume_sorted=True) A = amp_interp(outfreq) phi = phase_interp(outfreq) out.data[:] = A * numpy.cos(phi) + (1j) * A * numpy.sin(phi) return out