示例#1
0
def fftfilt(b, x):
    """Apply the FIR filter with coefficients b to the signal x, as if the filter's
    state is initially all zeros. The output has the same length as x."""

    # Zero-pad by at least (len(b) - 1).
    nfft = int(ceil_pow_2(len(x) + len(b) - 1))

    # Create FFT plans.
    forwardplan = CreateForwardCOMPLEX16FFTPlan(nfft, 0)
    reverseplan = CreateReverseCOMPLEX16FFTPlan(nfft, 0)

    # Create temporary workspaces.
    workspace1 = lal.CreateCOMPLEX16Vector(nfft)
    workspace2 = lal.CreateCOMPLEX16Vector(nfft)
    workspace3 = lal.CreateCOMPLEX16Vector(nfft)

    workspace1.data[:len(x)] = x
    workspace1.data[len(x):] = 0
    lal.COMPLEX16VectorFFT(workspace2, workspace1, forwardplan)
    workspace1.data[:len(b)] = b
    workspace1.data[len(b):] = 0
    lal.COMPLEX16VectorFFT(workspace3, workspace1, forwardplan)
    workspace2.data *= workspace3.data
    lal.COMPLEX16VectorFFT(workspace1, workspace2, reverseplan)

    # Return result with zero-padding stripped.
    return workspace1.data[:len(x)] / nfft
示例#2
0
def _genqnmfreq(mass, spin, l, m, nmodes, qnmfreq=None):
    """Convenience function to generate QNM frequencies from lalsimulation.

    Parameters
    ----------
    mass : float
        The mass of the black hole (in solar masses).
    spin : float
        The dimensionless spin of the black hole.
    l : int
        l-index of the harmonic.
    m : int
        m-index of the harmonic.
    nmodes : int
        The number of overtones to generate.
    qnmfreq : lal.COMPLEX16Vector, optional
        LAL vector to write the results into. Must be the same length as
        ``nmodes``. If None, will create one.

    Returns
    -------
    lal.COMPLEX16Vector
        LAL vector containing the complex QNM frequencies.
    """
    if qnmfreq is None:
        qnmfreq = lal.CreateCOMPLEX16Vector(int(nmodes))
    lalsim.SimIMREOBGenerateQNMFreqV2fromFinal(
        qnmfreq, float(mass), float(spin), int(l), int(m), int(nmodes))
    return qnmfreq
示例#3
0
def get_lm_f0tau(mass, spin, l, m, nmodes):
    """Return the f_0 and the tau of each overtone for a given lm mode
    """
    qnmfreq = lal.CreateCOMPLEX16Vector(nmodes)
    lalsim.SimIMREOBGenerateQNMFreqV2fromFinal(qnmfreq, float(mass),
                                               float(spin), l, m, nmodes)
    f_0 = [qnmfreq.data[n].real / (2 * numpy.pi) for n in range(nmodes)]
    tau = [1. / qnmfreq.data[n].imag for n in range(nmodes)]
    return f_0, tau
示例#4
0
    def lal(self):
        """ Returns a LAL Object that contains this data """

        lal_data = None
        if self._data.dtype == float32:
            lal_data = _lal.CreateREAL4Vector(len(self))
        elif self._data.dtype == float64:
            lal_data = _lal.CreateREAL8Vector(len(self))
        elif self._data.dtype == complex64:
            lal_data = _lal.CreateCOMPLEX8Vector(len(self))
        elif self._data.dtype == complex128:
            lal_data = _lal.CreateCOMPLEX16Vector(len(self))

        lal_data.data[:] = self.numpy()

        return lal_data
示例#5
0
文件: array.py 项目: sugwg/pycbc-dev
    def lal(self):
        """ Returns a LAL Object that contains this data """

        lal_data = None
        if type(self._data) is not _numpy.ndarray:
            raise TypeError("Cannot return lal type from the GPU")
        elif self._data.dtype == float32:
            lal_data = _lal.CreateREAL4Vector(len(self))
        elif self._data.dtype == float64:
            lal_data = _lal.CreateREAL8Vector(len(self))
        elif self._data.dtype == complex64:
            lal_data = _lal.CreateCOMPLEX8Vector(len(self))
        elif self._data.dtype == complex128:
            lal_data = _lal.CreateCOMPLEX16Vector(len(self))

        lal_data.data[:] = self._data

        return lal_data
示例#6
0
c8.data = c8dat
assert (lal.swig_lal_test_copyinout_COMPLEX8Vector(c8))
assert ((c8.data == 3 * c8dat).all())
c8.data = c8dat
retn, c8 = lal.swig_lal_test_copyinout_COMPLEX8Vector(c8)
assert (retn)
assert ((c8.data == 3 * c8dat).all())
c8 = c8dat
retn, c8 = lal.swig_lal_test_copyinout_COMPLEX8Vector(c8)
assert (retn)
assert ((c8 == 3 * c8dat).all())
del c8
del c8out
del c8dat
lal.CheckMemoryLeaks()
c16 = lal.CreateCOMPLEX16Vector(len(c16dat))
c16.data = c16dat
c16out = lal.CreateCOMPLEX16Vector(len(c16dat))
c16out.data = numpy.zeros(numpy.shape(c16dat), dtype=c16dat.dtype)
assert (lal.swig_lal_test_viewin_COMPLEX16Vector(c16out, c16))
assert ((c16out.data == c16.data).all())
c16out.data = numpy.zeros(numpy.shape(c16dat), dtype=c16dat.dtype)
assert (lal.swig_lal_test_viewin_COMPLEX16Vector(c16out, c16dat))
assert ((c16out.data == c16dat).all())
c16out.data = numpy.zeros(numpy.shape(c16dat), dtype=c16dat.dtype)
assert (lal.swig_lal_test_viewinout_COMPLEX16Vector(c16out, c16))
assert ((2 * c16out.data == c16.data).all())
c16out.data = numpy.zeros(numpy.shape(c16dat), dtype=c16dat.dtype)
assert (lal.swig_lal_test_viewinout_COMPLEX16Vector(c16out, c16dat))
assert ((2 * c16out.data == c16dat).all())
c16.data = c16dat
示例#7
0
def truncated_ifft(y, nsamples_out=None):
    """Truncated inverse FFT.

    See http://www.fftw.org/pruned.html for a discussion of related algorithms.

    Perform inverse FFT to obtain truncated autocorrelation time series.
    This makes use of a folded DFT for a speedup of

        log(nsamples)/log(nsamples_out)

    over directly computing the inverse FFT and truncating. Here is how it
    works. Say we have a frequency-domain signal X[k], for 0 ≤ k ≤ N - 1. We
    want to compute its DFT x[n], for 0 ≤ n ≤ M, where N is divisible by M:
    N = cM, for some integer c. The DFT is:

               N - 1
               ______
               \           2 π i k n
        x[n] =  \     exp[-----------] Y[k]
               /               N
              /------
               k = 0

               c - 1   M - 1
               ______  ______
               \       \           2 π i n (m c + j)
             =  \       \     exp[------------------] Y[m c + j]
               /       /                 c M
              /------ /------
               j = 0   m = 0

               c - 1                     M - 1
               ______                    ______
               \           2 π i n j     \           2 π i n m
             =  \     exp[-----------]    \     exp[-----------] Y[m c + j]
               /               N         /               M
              /------                   /------
               j = 0                     m = 0

    So: we split the frequency series into c deinterlaced sub-signals, each of
    length M, compute the DFT of each sub-signal, and add them back together
    with complex weights.

    Parameters
    ----------
    y : `numpy.ndarray`
        Complex input vector.
    nsamples_out : int, optional
        Length of output vector. By default, same as length of input vector.

    Returns
    -------
    x : `numpy.ndarray`
        The first nsamples_out samples of the IFFT of x, zero-padded if


    First generate the IFFT of a random signal:
    >>> nsamples_out = 1024
    >>> y = np.random.randn(nsamples_out) + np.random.randn(nsamples_out) * 1j
    >>> plan = CreateReverseCOMPLEX16FFTPlan(nsamples_out, 0)
    >>> freq = lal.CreateCOMPLEX16Vector(nsamples_out)
    >>> freq.data = y
    >>> time = lal.CreateCOMPLEX16Vector(nsamples_out)
    >>> _ = lal.COMPLEX16VectorFFT(time, freq, plan)
    >>> x = time.data

    Now check that the truncated IFFT agrees:
    >>> np.allclose(x, truncated_ifft(y), rtol=1e-15)
    True
    >>> np.allclose(x, truncated_ifft(y, 1024), rtol=1e-15)
    True
    >>> np.allclose(x[:128], truncated_ifft(y, 128), rtol=1e-15)
    True
    >>> np.allclose(x[:1], truncated_ifft(y, 1), rtol=1e-15)
    True
    >>> np.allclose(x[:32], truncated_ifft(y, 32), rtol=1e-15)
    True
    >>> np.allclose(x[:63], truncated_ifft(y, 63), rtol=1e-15)
    True
    >>> np.allclose(x[:25], truncated_ifft(y, 25), rtol=1e-15)
    True
    >>> truncated_ifft(y, 1025)
    Traceback (most recent call last):
      ...
    ValueError: Input is too short: you gave me an input of length 1024, but you asked for an IFFT of length 1025.
    """
    nsamples = len(y)
    if nsamples_out is None:
        nsamples_out = nsamples
    elif nsamples_out > nsamples:
        raise ValueError(
            'Input is too short: you gave me an input of length {0}, '
            'but you asked for an IFFT of length {1}.'.format(
                nsamples, nsamples_out))
    elif nsamples & (nsamples - 1):
        raise NotImplementedError(
            'I am too lazy to implement for nsamples that is '
            'not a power of 2.')

    # Find number of FFTs.
    # FIXME: only works if nsamples is a power of 2.
    # Would be better to find the smallest divisor of nsamples that is
    # greater than or equal to nsamples_out.
    nsamples_batch = int(ceil_pow_2(nsamples_out))
    c = nsamples // nsamples_batch

    # FIXME: Implement for real-to-complex FFTs as well.
    plan = CreateReverseCOMPLEX16FFTPlan(nsamples_batch, 0)
    input_workspace = lal.CreateCOMPLEX16Vector(nsamples_batch)
    output_workspace = lal.CreateCOMPLEX16Vector(nsamples_batch)
    twiddle = exp_i(2 * np.pi * np.arange(nsamples_batch) / nsamples)

    j = c - 1
    input_workspace.data = y[j::c]
    lal.COMPLEX16VectorFFT(output_workspace, input_workspace, plan)
    x = output_workspace.data.copy()  # Make sure this is a deep copy

    for j in range(c-2, -1, -1):
        input_workspace.data = y[j::c]
        lal.COMPLEX16VectorFFT(output_workspace, input_workspace, plan)
        x *= twiddle  # FIXME: check stability of this recurrence relation.
        x += output_workspace.data

    # Now need to truncate remaining samples.
    if nsamples_out < nsamples_batch:
        x = x[:nsamples_out]

    return x
    ax.set_ylim(1e-24, 1e-21)
    if i == len(data) - 1:
        ax.set_xlabel('frequency (Hz)')
    else:
        plt.setp(ax.get_xticklabels(), visible=False)
    if i == 0:
        ax.set_title('Noise amp. spectral density')

    duration = lalsimulation.SimInspiralTaylorF2ReducedSpinChirpTime(
        10, mass1*lal.MSUN_SI, mass2*lal.MSUN_SI, 0,
        lalsimulation.PNORDER_THREE_POINT_FIVE)
    duration = int(np.ceil(filter.ceil_pow_2(duration)))
    sample_rate = 16384
    nsamples = duration * sample_rate
    nsamples_fft = nsamples//2 + 1
    af = lal.CreateCOMPLEX16Vector(nsamples)
    f = np.arange(nsamples) / duration

    hplus, hcross = lalsimulation.SimInspiralChooseFDWaveform(
        0, 1/duration,
        mass1*lal.MSUN_SI, mass2*lal.MSUN_SI,
        0, 0, 0, 0, 0, 0,
        9, 0, 40,
        500 * lal.PC_SI, 0, 0, 0,
        None, None,
        lalsimulation.PNORDER_THREE_POINT_FIVE,
        lalsimulation.PNORDER_NEWTONIAN, lalsimulation.TaylorF2)

    af.data[:len(hplus.data.data)] = abs2(hplus.data.data + 1j * hcross.data.data)
    af.data[len(hplus.data.data):] = 0
    af.data[0] = 0