Exemple #1
0
def Cred_100ns(alphaab,times_f,A=5.77e-22,alpha=1.7,fL=1.0/10000):
    corr = N.zeros((len(times_f),len(times_f)),'d')

    ps, ts = len(alphaab), len(times_f) / len(alphaab)

    if not isinstance(A,(list,tuple,N.ndarray)):
        A = [A] * ps
    if not isinstance(alpha,(list,tuple,N.ndarray)):
        alpha = [alpha] * ps

    for i in range(ps):
        t1, t2 = N.meshgrid(times_f[i*ts:(i+1)*ts],times_f[i*ts:(i+1)*ts])

        # t1, t2 are in days
        x = 2 * math.pi * (day/year) * fL * N.abs(t1 - t2)

        if abs(alpha[i] - 2.0) < 1e-7:
            power = (-math.pi/2 + (math.pi/2 - math.pi*EulerGamma/2) * (alpha[i] - 2.0)) * x**(alpha[i] - 1)
        else:
            power = SS.gamma(1-alpha[i]) * math.sin(0.5*math.pi*alpha[i]) * x**(alpha[i] - 1)

        # HypergeometricPFQ[{1/2-alpha/2},{1/2,3/2-alpha/2},-(1/4)fL^2 Tau^2]/(alpha - 1)
        ksum = SS.hyp1f2(0.5 - 0.5*alpha[i],0.5,1.5-0.5*alpha[i],-0.25*x**2)[0] / (alpha[i] - 1)

        # this must be multiplied with an amplitude given in units of s^(3-alpha),
        # so it must have units of s^(alpha - 1) to yield s^2;
        # we further multiply by 1e14 for units of 100 ns
        corr[i*ts:(i+1)*ts,i*ts:(i+1)*ts] = (A[i] * 1.0e14 * year**(alpha[i] - 1) * fL**(1-alpha[i])) * (power + ksum)

    return corr
Exemple #2
0
def PL_covfunc(tau, amp, alpha=-2.0 / 3.0, fL=1.0 / (year * 20)):
    """
    Compute the covariance function for a powerlaw
    Result is in units of (sec)^2.

    :param tau:
        the time lag

    :param amp:
        amplitude

    :param alpha:
        the GWB spectral index

    :param fL:
        the low-frequency cut-off
    """
    fL = fL * year
    x = 2 * np.pi * fL * np.abs(tau) / year
    cf = ss.gamma(-2 + 2 * alpha) * np.cos(np.pi * alpha)
    power = cf * x ** (2 - 2 * alpha)
    ksum = ss.hyp1f2(alpha - 1, 0.5, alpha, -0.25 * x ** 2)[0] / (2 * alpha - 2)
    corr = -(year ** 2 * fL ** (-2 + 2 * alpha)) / (12 * np.pi ** 2) * (power + ksum)

    return amp ** 2 * corr
Exemple #3
0
def PL_covfunc(tau, amp, alpha=-2.0/3.0, fL=1.0/(year*20)):
    """
    Compute the covariance function for a powerlaw
    Result is in units of (sec)^2.

    :param tau:
        the time lag

    :param amp:
        amplitude

    :param alpha:
        the GWB spectral index

    :param fL:
        the low-frequency cut-off
    """
    fL = fL * year
    x = 2 * np.pi * fL * np.abs(tau) / year
    cf = ss.gamma(-2+2*alpha) * np.cos(np.pi*alpha)
    power = cf * x**(2-2*alpha)
    ksum = ss.hyp1f2(alpha-1,0.5,alpha,-0.25*x**2)[0]/(2*alpha-2)
    corr = -(year**2 * fL**(-2+2*alpha)) / (12 * np.pi**2) * (power + ksum)
    
    return amp**2*corr
Exemple #4
0
def S_alpha_wing(z, Tk):
    alf = eta_lya(Tk) * (3. * a_voigt(Tk) / 2. / np.pi / gammaGP(z))**(1. / 3.)
    OneMinusSalpha = 4. * alf / 9. * (
        3.**(2. / 3.) * np.pi * special.airy(-2. * alf / 3.**(1. / 3.))[2] +
        (3. * alf**2.) *
        special.hyp1f2(1., 4. / 3., 5. / 3., -8. * alf**3. / 27.)[0])
    return 1. - OneMinusSalpha
Exemple #5
0
def Cgw_days(alphaab,times_f,alpha=-2/3,fL=1.0/10000,approx_ksum=False):
    """Compute the residual covariance matrix for an hc = 1 x (f year)^alpha GW background.
    Result is in units of (days)^2."""

    t1, t2 = N.meshgrid(times_f,times_f)

    # t1, t2 are in units of days
    x = 2 * math.pi * N.abs(t1 - t2)
    power = (day/year)**(-2*alpha) * (SS.gamma(-2+2*alpha) * math.cos(math.pi*alpha)) * x**(2-2*alpha)

    # Mathematica solves Sum[(-1)^n x^(2 n)/((2 n)! (2 n + 2 alpha - 2)), {n, 0, Infinity}]
    # as HypergeometricPFQ[{-1+alpha}, {1/2,alpha}, -(x^2/4)]/(2 alpha - 2)
    # the corresponding scipy.special function is hyp1f2 (which returns value and error)
    # TO DO, for speed: could replace with the first few terms of the sum!
    # ksum = SS.hyp1f2(alpha-1,0.5,alpha,-0.25*x**2)[0]/(2*alpha-2)

    if not fL:                  # do not include any low-fcut correction
        ksum = 0
    else:
        fLd = (day/year) * fL

        if approx_ksum:
            ksum = (year/day)**2 * fL**(-2+2*alpha) * (1.0 / (2*alpha - 2) - (fLd * x)**2 / (4*alpha) + (fLd * x)**4 / (24 * (2 + 2*alpha)))
        else:
            ksum = (year/day)**2 * fL**(-2+2*alpha) * SS.hyp1f2(alpha-1,0.5,alpha,-0.25*(fLd * x)**2)[0]/(2*alpha-2)

    corr = -(power + ksum) / (12 * math.pi**2)

    # multiply by alphaab; there must be a more numpythonic way to do it
    ps, ts = len(alphaab), len(times_f) / len(alphaab)
    for i in range(ps):
        for j in range(ps):
            corr[i*ts:(i+1)*ts,j*ts:(j+1)*ts] *= alphaab[i,j]

    return corr
Exemple #6
0
 def _mom(self, k):
     output = numpy.array([
         special.hyp1f2(k_ + .5, .5, k_ + 1.5, -numpy.pi**2 / 4)[0]
         for k_ in k.flatten()
     ]).reshape(k.shape)
     output = 1 / (1. + k) + 1 / (1. + 2 * k) * output
     output = numpy.where(k % 2, output, 0)
     return output
Exemple #7
0
 def hyp1f2(a, b, c, x):
     v, err = sc.hyp1f2(a, b, c, x)
     if abs(err) > max(1, abs(v)) * 1e-7:
         return np.nan
     return v
Exemple #8
0
 def _mom(self, k):
     return np.where(k%2, 0, 2/(k+2) + 1/(k+1)*\
             special.hyp1f2((k+1)/2.), .5, (k+3)/2., -np.pi**2/4)
Exemple #9
0
 def hyp1f2(a, b, c, x):
     v, err = sc.hyp1f2(a, b, c, x)
     if abs(err) > max(1, abs(v)) * 1e-7:
         return np.nan
     return v
Exemple #10
0
 def _mom(self, k):
     return np.where(k%2, 0, 2/(k+2) + 1/(k+1)*\
             special.hyp1f2((k+1)/2.), .5, (k+3)/2., -np.pi**2/4)
Exemple #11
0
def pl_cov(t, Si=4.33, fL=1.0/20, approx_ksum=False):
    """
    Analytically calculate the covariance matrix for a stochastic signal with a
    power spectral density given by pl_psd.

    @param t:   Time-series timestamps
    @param Si:  Spectral index of power-law spectrum
    @param fL:  Low-frequency cut-off
    @param approx_ksum:     Whether we approximate the infinite sum

    @return:    Covariance matrix
    """

    EulerGamma = 0.5772156649015329
    alpha = 0.5*(3.0-Si)

    # Make a mesh-grid for the covariance matrix elements
    t1, t2 = np.meshgrid(t,t)
    x = 2 * np.pi * fL * np.abs(t1 - t2)
    del t1
    del t2

    # The tolerance for which to use the Gamma function expansion
    tol = 1e-5

    # the exact solutions for alpha = 0, -1 should be acceptable in a small
    # interval around them...
    if abs(alpha) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = cosx - x * sinx
        sinint, cosint = sl.sici(x)

        corr = (fL**-2) / (24 * math.pi**2) * (power + x**2 * cosint)
    elif abs(alpha + 1) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = 6 * cosx - 2 * x * sinx - x**2 * cosx + x**3 * sinx
        sinint, cosint = ss.sici(x)

        corr = (fL**-4) / (288 * np.pi**2) * (power - x**4 * cosint)
    else:
        # leading-order expansion of Gamma[-2+2*alpha]*Cos[Pi*alpha] around -0.5
        # and 0.5
        if   abs(alpha - 0.5) < tol:
            cf =  np.pi/2   + (np.pi - np.pi*EulerGamma) * (alpha - 0.5)
        elif abs(alpha + 0.5) < tol:
            cf = -np.pi/12  + (-11*np.pi/36 + EulerGamma*math.pi/6) * (alpha + 0.5)
        elif abs(alpha + 1.5) < tol:
            cf =  np.pi/240 + (137*np.pi/7200 - EulerGamma*np.pi/120) * (alpha + 1.5)
        else:
            cf = ss.gamma(-2+2*alpha) * np.cos(np.pi*alpha)

        power = cf * x**(2-2*alpha)

        # Mathematica solves Sum[(-1)^n x^(2 n)/((2 n)! (2 n + 2 alpha - 2)),
        # {n, 0, Infinity}] as HypergeometricPFQ[{-1+alpha}, {1/2,alpha},
        # -(x^2/4)]/(2 alpha - 2) the corresponding scipy.special function is
        # hyp1f2 (which returns value and error)
        if approx_ksum:
            ksum = 1.0 / (2*alpha - 2) - x**2 / (4*alpha) + x**4 / (24 * (2 + 2*alpha))
        else:
            ksum = ss.hyp1f2(alpha-1,0.5,alpha,-0.25*x**2)[0]/(2*alpha-2)

        del x

        corr = -(fL**(-2+2*alpha)) * (power + ksum)
        
    return corr
Exemple #12
0
def Cgw_sec(model, alpha=-2.0/3.0, fL=1.0/500, approx_ksum=False, inc_cor=True):
    """ Compute the residual covariance matrix for an hc = 1 x (f year)^alpha GW background.
        Result is in units of (100 ns)^2.
        Modified from Michele Vallisneri's mc3pta (https://github.com/vallis/mc3pta)

        @param: list of libstempo pulsar objects
                (as returned by readRealisations)
        @param: the H&D correlation matrix
        @param: the TOAs
        @param: the GWB spectral index
        @param: the low-frequency cut-off
        @param: approx_ksum
    """
    psrobs = model[6]
    alphaab = model[5]
    times_f = model[0]
    
    day    = 86400.0              # seconds, sidereal (?)
    year   = 3.15581498e7         # seconds, sidereal (?)

    EulerGamma = 0.5772156649015329

    npsrs = alphaab.shape[0]

    t1, t2 = np.meshgrid(times_f,times_f)

    # t1, t2 are in units of days; fL in units of 1/year (sidereal for both?)
    # so typical values here are 10^-6 to 10^-3
    x = 2 * np.pi * (day/year) * fL * np.abs(t1 - t2)

    del t1
    del t2

    # note that the gamma is singular for all half-integer alpha < 1.5
    #
    # for -1 < alpha < 0, the x exponent ranges from 4 to 2 (it's 3.33 for alpha = -2/3)
    # so for the lower alpha values it will be comparable in value to the x**2 term of ksum
    #
    # possible alpha limits for a search could be [-0.95,-0.55] in which case the sign of `power`
    # is always positive, and the x exponent ranges from ~ 3 to 4... no problem with cancellation

    # The tolerance for which to use the Gamma function expansion
    tol = 1e-5

    # the exact solutions for alpha = 0, -1 should be acceptable in a small interval around them...
    if abs(alpha) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = cosx - x * sinx
        sinint, cosint = sl.sici(x)

        corr = (year**2 * fL**-2) / (24 * math.pi**2) * (power + x**2 * cosint)
    elif abs(alpha + 1) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = 6 * cosx - 2 * x * sinx - x**2 * cosx + x**3 * sinx
        sinint, cosint = ss.sici(x)

        corr = (year**2 * fL**-4) / (288 * np.pi**2) * (power - x**4 * cosint)
    else:
        # leading-order expansion of Gamma[-2+2*alpha]*Cos[Pi*alpha] around -0.5 and 0.5
        if   abs(alpha - 0.5) < tol:
            cf =  np.pi/2   + (np.pi - np.pi*EulerGamma)              * (alpha - 0.5)
        elif abs(alpha + 0.5) < tol:
            cf = -np.pi/12  + (-11*np.pi/36 + EulerGamma*math.pi/6)     * (alpha + 0.5)
        elif abs(alpha + 1.5) < tol:
            cf =  np.pi/240 + (137*np.pi/7200 - EulerGamma*np.pi/120) * (alpha + 1.5)
        else:
            cf = ss.gamma(-2+2*alpha) * np.cos(np.pi*alpha)

        power = cf * x**(2-2*alpha)

        # Mathematica solves Sum[(-1)^n x^(2 n)/((2 n)! (2 n + 2 alpha - 2)), {n, 0, Infinity}]
        # as HypergeometricPFQ[{-1+alpha}, {1/2,alpha}, -(x^2/4)]/(2 alpha - 2)
        # the corresponding scipy.special function is hyp1f2 (which returns value and error)
        # TO DO, for speed: could replace with the first few terms of the sum!
        if approx_ksum:
            ksum = 1.0 / (2*alpha - 2) - x**2 / (4*alpha) + x**4 / (24 * (2 + 2*alpha))
        else:
            ksum = ss.hyp1f2(alpha-1,0.5,alpha,-0.25*x**2)[0]/(2*alpha-2)

        del x

        # this form follows from Eq. (A31) of Lee, Jenet, and Price ApJ 684:1304 (2008)
        corr = -(year**2 * fL**(-2+2*alpha)) / (12 * np.pi**2) * (power + ksum)

    if inc_cor:
        # multiply by alphaab; there must be a more numpythonic way to do it
        # npsrs psrobs
        inda, indb = 0, 0
        for a in range(npsrs):
            for b in range(npsrs):
                corr[inda:inda+psrobs[a], indb:indb+psrobs[b]] *= alphaab[a, b]
                indb += psrobs[b]
            indb = 0
            inda += psrobs[a]
        
    return corr
Exemple #13
0
def Cred_sec(toas, alpha=-2.0/3.0, fL=1.0/20, approx_ksum=False):
    day    = 86400.0
    year   = 3.15581498e7
    EulerGamma = 0.5772156649015329

    psrobs = [len(toas)]
    alphaab = np.array([[1.0]])
    times_f = toas / day
    
    npsrs = alphaab.shape[0]

    t1, t2 = np.meshgrid(times_f,times_f)

    # t1, t2 are in units of days; fL in units of 1/year (sidereal for both?)
    # so typical values here are 10^-6 to 10^-3
    x = 2 * np.pi * (day/year) * fL * np.abs(t1 - t2)

    del t1
    del t2

    # note that the gamma is singular for all half-integer alpha < 1.5
    #
    # for -1 < alpha < 0, the x exponent ranges from 4 to 2 (it's 3.33 for alpha = -2/3)
    # so for the lower alpha values it will be comparable in value to the x**2 term of ksum
    #
    # possible alpha limits for a search could be [-0.95,-0.55] in which case the sign of `power`
    # is always positive, and the x exponent ranges from ~ 3 to 4... no problem with cancellation

    # The tolerance for which to use the Gamma function expansion
    tol = 1e-5

    # the exact solutions for alpha = 0, -1 should be acceptable in a small interval around them...
    if abs(alpha) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = cosx - x * sinx
        sinint, cosint = sl.sici(x)

        corr = (year**2 * fL**-2) / (24 * math.pi**2) * (power + x**2 * cosint)
    elif abs(alpha + 1) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = 6 * cosx - 2 * x * sinx - x**2 * cosx + x**3 * sinx
        sinint, cosint = ss.sici(x)

        corr = (year**2 * fL**-4) / (288 * np.pi**2) * (power - x**4 * cosint)
    else:
        # leading-order expansion of Gamma[-2+2*alpha]*Cos[Pi*alpha] around -0.5 and 0.5
        if   abs(alpha - 0.5) < tol:
            cf =  np.pi/2   + (np.pi - np.pi*EulerGamma)              * (alpha - 0.5)
        elif abs(alpha + 0.5) < tol:
            cf = -np.pi/12  + (-11*np.pi/36 + EulerGamma*math.pi/6)     * (alpha + 0.5)
        elif abs(alpha + 1.5) < tol:
            cf =  np.pi/240 + (137*np.pi/7200 - EulerGamma*np.pi/120) * (alpha + 1.5)
        else:
            cf = ss.gamma(-2+2*alpha) * np.cos(np.pi*alpha)

        power = cf * x**(2-2*alpha)

        # Mathematica solves Sum[(-1)^n x^(2 n)/((2 n)! (2 n + 2 alpha - 2)), {n, 0, Infinity}]
        # as HypergeometricPFQ[{-1+alpha}, {1/2,alpha}, -(x^2/4)]/(2 alpha - 2)
        # the corresponding scipy.special function is hyp1f2 (which returns value and error)
        # TO DO, for speed: could replace with the first few terms of the sum!
        if approx_ksum:
            ksum = 1.0 / (2*alpha - 2) - x**2 / (4*alpha) + x**4 / (24 * (2 + 2*alpha))
        else:
            ksum = ss.hyp1f2(alpha-1,0.5,alpha,-0.25*x**2)[0]/(2*alpha-2)

        del x

        # this form follows from Eq. (A31) of Lee, Jenet, and Price ApJ 684:1304 (2008)
        corr = -(year**2 * fL**(-2+2*alpha)) / (12 * np.pi**2) * (power + ksum)
        
    return corr
Exemple #14
0
def Cgw_sec(model,
            alpha=-2.0 / 3.0,
            fL=1.0 / 500,
            approx_ksum=False,
            inc_cor=True):
    """ Compute the residual covariance matrix for an hc = 1 x (f year)^alpha GW background.
        Result is in units of (100 ns)^2.
        Modified from Michele Vallisneri's mc3pta (https://github.com/vallis/mc3pta)

        @param: list of libstempo pulsar objects
                (as returned by readRealisations)
        @param: the H&D correlation matrix
        @param: the TOAs
        @param: the GWB spectral index
        @param: the low-frequency cut-off
        @param: approx_ksum
    """
    psrobs = model[6]
    alphaab = model[5]
    times_f = model[0]

    day = 86400.0  # seconds, sidereal (?)
    year = 3.15581498e7  # seconds, sidereal (?)

    EulerGamma = 0.5772156649015329

    npsrs = alphaab.shape[0]

    t1, t2 = np.meshgrid(times_f, times_f)

    # t1, t2 are in units of days; fL in units of 1/year (sidereal for both?)
    # so typical values here are 10^-6 to 10^-3
    x = 2 * np.pi * (day / year) * fL * np.abs(t1 - t2)

    del t1
    del t2

    # note that the gamma is singular for all half-integer alpha < 1.5
    #
    # for -1 < alpha < 0, the x exponent ranges from 4 to 2 (it's 3.33 for alpha = -2/3)
    # so for the lower alpha values it will be comparable in value to the x**2 term of ksum
    #
    # possible alpha limits for a search could be [-0.95,-0.55] in which case the sign of `power`
    # is always positive, and the x exponent ranges from ~ 3 to 4... no problem with cancellation

    # The tolerance for which to use the Gamma function expansion
    tol = 1e-5

    # the exact solutions for alpha = 0, -1 should be acceptable in a small interval around them...
    if abs(alpha) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = cosx - x * sinx
        sinint, cosint = sl.sici(x)

        corr = (year**2 * fL**-2) / (24 * math.pi**2) * (power + x**2 * cosint)
    elif abs(alpha + 1) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = 6 * cosx - 2 * x * sinx - x**2 * cosx + x**3 * sinx
        sinint, cosint = ss.sici(x)

        corr = (year**2 * fL**-4) / (288 * np.pi**2) * (power - x**4 * cosint)
    else:
        # leading-order expansion of Gamma[-2+2*alpha]*Cos[Pi*alpha] around -0.5 and 0.5
        if abs(alpha - 0.5) < tol:
            cf = np.pi / 2 + (np.pi - np.pi * EulerGamma) * (alpha - 0.5)
        elif abs(alpha + 0.5) < tol:
            cf = -np.pi / 12 + (-11 * np.pi / 36 +
                                EulerGamma * math.pi / 6) * (alpha + 0.5)
        elif abs(alpha + 1.5) < tol:
            cf = np.pi / 240 + (137 * np.pi / 7200 -
                                EulerGamma * np.pi / 120) * (alpha + 1.5)
        else:
            cf = ss.gamma(-2 + 2 * alpha) * np.cos(np.pi * alpha)

        power = cf * x**(2 - 2 * alpha)

        # Mathematica solves Sum[(-1)^n x^(2 n)/((2 n)! (2 n + 2 alpha - 2)), {n, 0, Infinity}]
        # as HypergeometricPFQ[{-1+alpha}, {1/2,alpha}, -(x^2/4)]/(2 alpha - 2)
        # the corresponding scipy.special function is hyp1f2 (which returns value and error)
        # TO DO, for speed: could replace with the first few terms of the sum!
        if approx_ksum:
            ksum = 1.0 / (2 * alpha -
                          2) - x**2 / (4 * alpha) + x**4 / (24 *
                                                            (2 + 2 * alpha))
        else:
            ksum = ss.hyp1f2(alpha - 1, 0.5, alpha,
                             -0.25 * x**2)[0] / (2 * alpha - 2)

        del x

        # this form follows from Eq. (A31) of Lee, Jenet, and Price ApJ 684:1304 (2008)
        corr = -(year**2 * fL**(-2 + 2 * alpha)) / (12 * np.pi**2) * (power +
                                                                      ksum)

    if inc_cor:
        # multiply by alphaab; there must be a more numpythonic way to do it
        # npsrs psrobs
        inda, indb = 0, 0
        for a in range(npsrs):
            for b in range(npsrs):
                corr[inda:inda + psrobs[a],
                     indb:indb + psrobs[b]] *= alphaab[a, b]
                indb += psrobs[b]
            indb = 0
            inda += psrobs[a]

    return corr
Exemple #15
0
def approxBesselInt(b, q, r):
    return 0.5 * q**(-2.0 - b) * spec.gamma(-b / 2.0 - 1.0) * spec.hyp1f2(
        -b / 2.0 - 1.0, 1, -b / 2.0,
        q**2 * r**2 / 4.0)[0] / (spec.gamma(1) * spec.gamma(-b / 2.0))
Exemple #16
0
def _cosine_volume(dim):
    hyp, _ = hyp1f2(0.5 * dim, 0.5, 0.5 * dim + 1, -_PI_SQ / 16.0)
    return _vn(dim) * (_PI_2 ** dim) * hyp
Exemple #17
0
 def _mom(self, k):
     output = numpy.array([special.hyp1f2(k_+.5, .5, k_+1.5, -numpy.pi**2/4)[0]
                           for k_ in k.flatten()]).reshape(k.shape)
     output = 1/(1.+k) + 1/(1.+2*k)*output
     output = numpy.where(k % 2, output, 0)
     return output
Exemple #18
0
def Cgw_sec(toas, alpha=-2.0 / 3.0, fL=1.0 / 20, approx_ksum=False):
    day = 86400.0
    year = 3.15581498e7
    EulerGamma = 0.5772156649015329

    psrobs = [len(toas)]
    alphaab = np.array([[1.0]])
    times_f = toas / day

    npsrs = alphaab.shape[0]

    t1, t2 = np.meshgrid(times_f, times_f)

    # t1, t2 are in units of days; fL in units of 1/year (sidereal for both?)
    # so typical values here are 10^-6 to 10^-3
    x = 2 * np.pi * (day / year) * fL * np.abs(t1 - t2)

    del t1
    del t2

    # note that the gamma is singular for all half-integer alpha < 1.5
    #
    # for -1 < alpha < 0, the x exponent ranges from 4 to 2 (it's 3.33 for alpha = -2/3)
    # so for the lower alpha values it will be comparable in value to the x**2 term of ksum
    #
    # possible alpha limits for a search could be [-0.95,-0.55] in which case the sign of `power`
    # is always positive, and the x exponent ranges from ~ 3 to 4... no problem with cancellation

    # The tolerance for which to use the Gamma function expansion
    tol = 1e-5

    # the exact solutions for alpha = 0, -1 should be acceptable in a small interval around them...
    if abs(alpha) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = cosx - x * sinx
        sinint, cosint = sl.sici(x)

        corr = (year**2 * fL**-2) / (24 * math.pi**2) * (power + x**2 * cosint)
    elif abs(alpha + 1) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = 6 * cosx - 2 * x * sinx - x**2 * cosx + x**3 * sinx
        sinint, cosint = ss.sici(x)

        corr = (year**2 * fL**-4) / (288 * np.pi**2) * (power - x**4 * cosint)
    else:
        # leading-order expansion of Gamma[-2+2*alpha]*Cos[Pi*alpha] around -0.5 and 0.5
        if abs(alpha - 0.5) < tol:
            cf = np.pi / 2 + (np.pi - np.pi * EulerGamma) * (alpha - 0.5)
        elif abs(alpha + 0.5) < tol:
            cf = -np.pi / 12 + (-11 * np.pi / 36 +
                                EulerGamma * math.pi / 6) * (alpha + 0.5)
        elif abs(alpha + 1.5) < tol:
            cf = np.pi / 240 + (137 * np.pi / 7200 -
                                EulerGamma * np.pi / 120) * (alpha + 1.5)
        else:
            cf = ss.gamma(-2 + 2 * alpha) * np.cos(np.pi * alpha)

        power = cf * x**(2 - 2 * alpha)

        # Mathematica solves Sum[(-1)^n x^(2 n)/((2 n)! (2 n + 2 alpha - 2)), {n, 0, Infinity}]
        # as HypergeometricPFQ[{-1+alpha}, {1/2,alpha}, -(x^2/4)]/(2 alpha - 2)
        # the corresponding scipy.special function is hyp1f2 (which returns value and error)
        # TO DO, for speed: could replace with the first few terms of the sum!
        if approx_ksum:
            ksum = 1.0 / (2 * alpha -
                          2) - x**2 / (4 * alpha) + x**4 / (24 *
                                                            (2 + 2 * alpha))
        else:
            ksum = ss.hyp1f2(alpha - 1, 0.5, alpha,
                             -0.25 * x**2)[0] / (2 * alpha - 2)

        del x

        # this form follows from Eq. (A31) of Lee, Jenet, and Price ApJ 684:1304 (2008)
        corr = -(year**2 * fL**(-2 + 2 * alpha)) / (12 * np.pi**2) * (power +
                                                                      ksum)

    return corr
Exemple #19
0
def Cgw_100ns(alphaab,times_f,alpha=-2/3,fL=1.0/10000,approx_ksum=False):
    """Compute the residual covariance matrix for an hc = 1 x (f year)^alpha GW background.
    Result is in units of (100 ns)^2."""

    t1, t2 = N.meshgrid(times_f,times_f)

    # t1, t2 are in units of days; fL in units of 1/year (sidereal for both?)
    # so typical values here are 10^-6 to 10^-3
    x = 2 * math.pi * (day/year) * fL * N.abs(t1 - t2)

    # note that the gamma is singular for all half-integer alpha < 1.5
    #
    # for -1 < alpha < 0, the x exponent ranges from 4 to 2 (it's 3.33 for alpha = -2/3)
    # so for the lower alpha values it will be comparable in value to the x**2 term of ksum
    #
    # possible alpha limits for a search could be [-0.95,-0.55] in which case the sign of `power`
    # is always positive, and the x exponent ranges from ~ 3 to 4... no problem with cancellation

    # the variance, as computed below, is in units of year^2; we convert it
    # to units of (100 ns)^2, so the multiplier is ~ 10^28
    year100ns = year/1e-7
    tol = 1e-5

    # the exact solutions for alpha = 0, -1 should be acceptable in a small interval around them...
    if abs(alpha) < 1e-7:
        cosx, sinx = N.cos(x), N.sin(x)

        power = cosx - x * sinx
        sinint, cosint = SL.sici(x)

        corr = (year100ns**2 * fL**-2) / (24 * math.pi**2) * (power + x**2 * cosint)
    elif abs(alpha + 1) < 1e-7:
        cosx, sinx = N.cos(x), N.sin(x)

        power = 6 * cosx - 2 * x * sinx - x**2 * cosx + x**3 * sinx
        sinint, cosint = SL.sici(x)

        corr = (year100ns**2 * fL**-4) / (288 * math.pi**2) * (power - x**4 * cosint)
    else:
        # leading-order expansion of Gamma[-2+2*alpha]*Cos[Pi*alpha] around -0.5 and 0.5
        if   abs(alpha - 0.5) < tol:
            cf =  math.pi/2   + (math.pi - math.pi*EulerGamma)              * (alpha - 0.5)
        elif abs(alpha + 0.5) < tol:
            cf = -math.pi/12  + (-11*math.pi/36 + EulerGamma*math.pi/6)     * (alpha + 0.5)
        elif abs(alpha + 1.5) < tol:
            cf =  math.pi/240 + (137*math.pi/7200 - EulerGamma*math.pi/120) * (alpha + 1.5)
        else:
            cf = SS.gamma(-2+2*alpha) * math.cos(math.pi*alpha)

        power = cf * x**(2-2*alpha)

        # Mathematica solves Sum[(-1)^n x^(2 n)/((2 n)! (2 n + 2 alpha - 2)), {n, 0, Infinity}]
        # as HypergeometricPFQ[{-1+alpha}, {1/2,alpha}, -(x^2/4)]/(2 alpha - 2)
        # the corresponding scipy.special function is hyp1f2 (which returns value and error)
        # TO DO, for speed: could replace with the first few terms of the sum!
        if approx_ksum:
            ksum = 1.0 / (2*alpha - 2) - x**2 / (4*alpha) + x**4 / (24 * (2 + 2*alpha))
        else:
            ksum = SS.hyp1f2(alpha-1,0.5,alpha,-0.25*x**2)[0]/(2*alpha-2)

        # this form follows from Eq. (A31) of Lee, Jenet, and Price ApJ 684:1304 (2008)

        corr = -(year100ns**2 * fL**(-2+2*alpha)) / (12 * math.pi**2) * (power + ksum)

    # multiply by alphaab; there must be a more numpythonic way to do it
    ps, ts = len(alphaab), len(times_f) / len(alphaab)
    for i in range(ps):
        for j in range(ps):
            corr[i*ts:(i+1)*ts,j*ts:(j+1)*ts] *= alphaab[i,j]

    return corr
Exemple #20
0
def pl_cov(t, Si=4.33, fL=1.0 / 20, approx_ksum=False):
    """
    Analytically calculate the covariance matrix for a stochastic signal with a
    power spectral density given by pl_psd.

    @param t:   Time-series timestamps
    @param Si:  Spectral index of power-law spectrum
    @param fL:  Low-frequency cut-off
    @param approx_ksum:     Whether we approximate the infinite sum

    @return:    Covariance matrix
    """

    EulerGamma = 0.5772156649015329
    alpha = 0.5 * (3.0 - Si)

    # Make a mesh-grid for the covariance matrix elements
    t1, t2 = np.meshgrid(t, t)
    x = 2 * np.pi * fL * np.abs(t1 - t2)
    del t1
    del t2

    # The tolerance for which to use the Gamma function expansion
    tol = 1e-5

    # the exact solutions for alpha = 0, -1 should be acceptable in a small
    # interval around them...
    if abs(alpha) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = cosx - x * sinx
        sinint, cosint = sl.sici(x)

        corr = (fL**-2) / (24 * math.pi**2) * (power + x**2 * cosint)
    elif abs(alpha + 1) < 1e-7:
        cosx, sinx = np.cos(x), np.sin(x)

        power = 6 * cosx - 2 * x * sinx - x**2 * cosx + x**3 * sinx
        sinint, cosint = ss.sici(x)

        corr = (fL**-4) / (288 * np.pi**2) * (power - x**4 * cosint)
    else:
        # leading-order expansion of Gamma[-2+2*alpha]*Cos[Pi*alpha] around -0.5
        # and 0.5
        if abs(alpha - 0.5) < tol:
            cf = np.pi / 2 + (np.pi - np.pi * EulerGamma) * (alpha - 0.5)
        elif abs(alpha + 0.5) < tol:
            cf = -np.pi / 12 + (-11 * np.pi / 36 +
                                EulerGamma * math.pi / 6) * (alpha + 0.5)
        elif abs(alpha + 1.5) < tol:
            cf = np.pi / 240 + (137 * np.pi / 7200 -
                                EulerGamma * np.pi / 120) * (alpha + 1.5)
        else:
            cf = ss.gamma(-2 + 2 * alpha) * np.cos(np.pi * alpha)

        power = cf * x**(2 - 2 * alpha)

        # Mathematica solves Sum[(-1)^n x^(2 n)/((2 n)! (2 n + 2 alpha - 2)),
        # {n, 0, Infinity}] as HypergeometricPFQ[{-1+alpha}, {1/2,alpha},
        # -(x^2/4)]/(2 alpha - 2) the corresponding scipy.special function is
        # hyp1f2 (which returns value and error)
        if approx_ksum:
            ksum = 1.0 / (2 * alpha -
                          2) - x**2 / (4 * alpha) + x**4 / (24 *
                                                            (2 + 2 * alpha))
        else:
            ksum = ss.hyp1f2(alpha - 1, 0.5, alpha,
                             -0.25 * x**2)[0] / (2 * alpha - 2)

        del x

        corr = -(fL**(-2 + 2 * alpha)) * (power + ksum)

    return corr
Exemple #21
0
def _cosine_volume(dim):
    hyp, _ = hyp1f2(0.5 * dim, 0.5, 0.5 * dim + 1, -_PI_SQ / 16.0)
    return _vn(dim) * (_PI_2**dim) * hyp