コード例 #1
0
ファイル: NX01_master_epta.py プロジェクト: stasbabak/NX01
def modelIndependentFullPTANoisePL(x):
    """
    Model Independent stochastic background likelihood function

    """

    Agwb = 10.0**x[0]
    if args.fix_slope:
        gam_gwb = 13. / 3.
        ct = 1
    else:
        gam_gwb = x[1]
        ct = 2
    #####
    Ared = 10.0**x[ct:ct + len(psr)]
    gam_red = x[ct + len(psr):ct + 2 * len(psr)]
    Adm = 10.0**x[ct + 2 * len(psr):ct + 3 * len(psr)]
    gam_dm = x[ct + 3 * len(psr):ct + 4 * len(psr)]
    EFAC = x[ct + 4 * len(psr):ct + 5 * len(psr)]
    Acm = 10.0**x[ct + 5 * len(psr)]
    gam_cm = x[ct + 5 * len(psr) + 1]
    Aun = 10.0**x[ct + 5 * len(psr) + 2]
    gam_un = x[ct + 5 * len(psr) + 3]
    ###################
    orf_coeffs = x[ct + 5 * len(psr) + 4:]
    orf_coeffs = orf_coeffs.reshape(
        (tmp_num_gwfreq_wins, ((args.LMAX + 1)**2) - 1))
    clm = np.array([[0.0] * ((args.LMAX + 1)**2)
                    for ii in range(tmp_num_gwfreq_wins)])
    clm[:, 0] = 2.0 * np.sqrt(np.pi)
    physicality = 0.
    if args.LMAX != 0:
        for kk in range(tmp_num_gwfreq_wins):
            for ii in range(1, ((args.LMAX + 1)**2)):
                clm[kk, ii] = orf_coeffs[kk, ii - 1]

            if (utils.PhysPrior(clm[kk], harm_sky_vals) == 'Unphysical'):
                physicality += -10.0**7.0
            else:
                physicality += 0.

    npsr = len(psr)

    ORF = []
    for ii in range(tmp_num_gwfreq_wins):  # number of frequency windows
        for jj in range(len(
                anis_modefreqs[ii])):  # number of frequencies in this window
            ORF.append(
                sum(clm[ii, kk] * CorrCoeff[kk]
                    for kk in range(len(CorrCoeff))))
    for ii in range(tmp_num_gwfreq_wins):  # number of frequency windows
        for jj in range(len(
                anis_modefreqs[ii])):  # number of frequencies in this window
            ORF.append(np.zeros((npsr, npsr)))

    ORF = np.array(ORF)
    ORFtot = np.zeros(
        (4 * args.nmodes, npsr, npsr)
    )  # shouldn't be applying ORF to dmfreqs, but the projection of GW spec onto dmfreqs is defined as zero below
    ORFtot[0::2] = ORF
    ORFtot[1::2] = ORF

    loglike1 = 0
    FtNF = []
    for p in range(len(psr)):

        # compute d
        if p == 0:
            d = np.dot(F_prime[p].T, res_prime[p] / ((EFAC[p]**2.0) * Diag[p]))
        else:
            d = np.append(
                d,
                np.dot(F_prime[p].T,
                       res_prime[p] / ((EFAC[p]**2.0) * Diag[p])))

        # compute FT N F
        N = 1. / ((EFAC[p]**2.0) * Diag[p])
        right = (N * F_prime[p].T).T
        FtNF.append(np.dot(F_prime[p].T, right))

        # log determinant of N
        logdet_N = np.sum(np.log((EFAC[p]**2.0) * Diag[p]))

        # triple product in likelihood function
        dtNdt = np.sum(res_prime[p]**2.0 / ((EFAC[p]**2.0) * Diag[p]))

        loglike1 += -0.5 * (logdet_N + dtNdt)

    # parameterize intrinsic red noise as power law
    Tspan = (1 / fqs[0]) * 86400.0
    f1yr = 1 / 3.16e7
    rho = np.log10(Agwb**2 / 12 / np.pi**2 * f1yr**(gam_gwb - 3) *
                   (fqs / 86400.0)**(-gam_gwb) / Tspan)

    # spectrum of common-mode
    cm = np.log10(Acm**2 / 12 / np.pi**2 * f1yr**(gam_cm - 3) *
                  (fqs / 86400.0)**(-gam_cm) / Tspan)

    # spectrum of common uncorrelated red-noise
    un = np.log10(Aun**2 / 12 / np.pi**2 * f1yr**(gam_un - 3) *
                  (fqs / 86400.0)**(-gam_un) / Tspan)

    # parameterize intrinsic red-noise and DM-variations as power law
    kappa = []
    for ii in range(npsr):
        kappa.append(np.log10( np.append( Ared[ii]**2/12/np.pi**2 * f1yr**(gam_red[ii]-3) * (fqs/86400.0)**(-gam_red[ii])/Tspan,\
                                          Adm[ii]**2/12/np.pi**2 * f1yr**(gam_dm[ii]-3) * (fqs/86400.0)**(-gam_dm[ii])/Tspan ) ))

    # construct elements of sigma array
    sigdiag = []
    sigoffdiag = []
    sigcm = []
    for ii in range(npsr):
        tot = np.zeros(4 * args.nmodes)
        offdiag = np.zeros(4 * args.nmodes)
        commonmode = np.zeros(4 * args.nmodes)

        # off diagonal terms
        offdiag[0::2] = np.append(10**rho, np.zeros(len(rho)))
        offdiag[1::2] = np.append(10**rho, np.zeros(len(rho)))

        # diagonal terms
        tot[0::2] = ORF[:, ii, ii] * np.append(10**rho, np.zeros(
            len(rho))) + np.append(10**cm + 10**un, np.zeros(
                len(rho))) + 10**kappa[ii]
        tot[1::2] = ORF[:, ii, ii] * np.append(10**rho, np.zeros(
            len(rho))) + np.append(10**cm + 10**un, np.zeros(
                len(rho))) + 10**kappa[ii]

        # common-mode terms
        commonmode[0::2] = np.append(10**cm, np.zeros(len(rho)))
        commonmode[1::2] = np.append(10**cm, np.zeros(len(rho)))

        # fill in lists of arrays
        sigdiag.append(tot)
        sigoffdiag.append(offdiag)
        sigcm.append(commonmode)

    # compute Phi inverse from Lindley's code
    smallMatrix = np.zeros((4 * args.nmodes, npsr, npsr))
    for ii in range(npsr):
        for jj in range(ii, npsr):

            if ii == jj:
                smallMatrix[:, ii, jj] = sigdiag[jj]
            else:
                smallMatrix[:, ii,
                            jj] = ORFtot[:, ii,
                                         jj] * sigoffdiag[jj] + sigcm[jj]
                smallMatrix[:, jj, ii] = smallMatrix[:, ii, jj]

    # invert them
    logdet_Phi = 0
    non_pos_def = 0
    for ii in range(4 * args.nmodes):
        try:
            L = sl.cho_factor(smallMatrix[ii, :, :])
            smallMatrix[ii, :, :] = sl.cho_solve(L, np.eye(npsr))
            logdet_Phi += np.sum(2 * np.log(np.diag(L[0])))
        except np.linalg.LinAlgError:
            print 'Cholesky Decomposition Failed!! Rejecting...'
            non_pos_def += 1

    if non_pos_def > 0:
        return -np.inf
    else:
        nftot = 4 * args.nmodes
        Phi = np.zeros((npsr * nftot, npsr * nftot))
        # now fill in real covariance matrix
        ind = [np.arange(kk * nftot, kk * nftot + nftot) for kk in range(npsr)]
        for ii in range(npsr):
            for jj in range(npsr):
                Phi[ind[ii], ind[jj]] = smallMatrix[:, ii, jj]

        # compute sigma
        Sigma = sl.block_diag(*FtNF) + Phi

        # cholesky decomp for second term in exponential
        if args.use_gpu:
            try:
                Sigma_gpu = gpuarray.to_gpu(Sigma.astype(np.float64).copy())
                expval2_gpu = gpuarray.to_gpu(d.astype(np.float64).copy())
                culinalg.cho_solve(
                    Sigma_gpu, expval2_gpu
                )  # in-place linear-algebra: Sigma and expval2 overwritten
                logdet_Sigma = np.sum(2.0 * np.log(np.diag(Sigma_gpu.get())))

            except cula.culaDataError:
                print 'Cholesky Decomposition Failed (GPU error!!!!!!!!!!)'
                return -np.inf

            logLike = -0.5 * (logdet_Phi + logdet_Sigma) + 0.5 * (np.dot(
                d, expval2_gpu.get())) + loglike1

        else:
            try:
                cf = sl.cho_factor(Sigma)
                expval2 = sl.cho_solve(cf, d)
                logdet_Sigma = np.sum(2 * np.log(np.diag(cf[0])))

            except np.linalg.LinAlgError:
                print 'Cholesky Decomposition Failed second time!! Using SVD instead'
                u, s, v = sl.svd(Sigma)
                expval2 = np.dot(v.T, 1 / s * np.dot(u.T, d))
                logdet_Sigma = np.sum(np.log(s))

            logLike = -0.5 * (logdet_Phi + logdet_Sigma) + 0.5 * (np.dot(
                d, expval2)) + loglike1

        if args.limit_or_detect == 'limit':
            prior_factor = np.log(Agwb * np.log(10.0))
        else:
            prior_factor = 0.0
        return logLike + prior_factor + physicality