예제 #1
0
def test_eth_derivation(eth, spin_weight_of_eth):
    """Ensure that the various `eth` operators are derivations -- i.e., they obey the Leibniz product law

    Given two spin-weighted functions `f` and `g`, we need to test that

        eth(f * g) = eth(f) * g + f * eth(g)

    This test generates a set of random modes with equal power for `f` and `g`
    (though more realistic functions can be expected to have exponentially decaying
    mode amplitudes).  Because of the large power in high-ell modes, we need to
    double the number of modes in the representation of their product, which is why
    we use

        n_theta = n_phi = 4 * ell_max + 1

    These `f` and `g` functions must be transformed to the physical-space
    representation, multiplied there, the product transformed back to spectral
    space, the eth operator evaluated, and then transformed back again to physical
    space for comparison.

    We test both the Newman-Penrose and Geroch-Held-Penrose versions of eth, as
    well as their conjugates.

    """
    import spinsfast
    ell_max = 16
    n_modes = sf.LM_total_size(0, ell_max)
    n_theta = n_phi = 4 * ell_max + 1
    for s1 in range(-2, 2 + 1):
        for s2 in range(-s1, s1 + 1):
            np.random.seed(1234)
            ell_min1 = abs(s1)
            ell_min2 = abs(s2)
            f = np.random.rand(n_modes) + 1j * np.random.rand(n_modes)
            f[:sf.LM_total_size(0, ell_min1 - 1)] = 0j
            f_j_k = spinsfast.salm2map(f, s1, ell_max, n_theta, n_phi)
            g = np.random.rand(n_modes) + 1j * np.random.rand(n_modes)
            g[:sf.LM_total_size(0, ell_min2 - 1)] = 0j
            g_j_k = spinsfast.salm2map(g, s2, ell_max, n_theta, n_phi)
            fg_j_k = f_j_k * g_j_k
            fg = spinsfast.map2salm(fg_j_k, s1 + s2, 2 * ell_max)
            ethf = eth(f, s1, ell_min=0)
            ethg = eth(g, s2, ell_min=0)
            ethfg = eth(fg, s1 + s2, ell_min=0)
            ethf_j_k = spinsfast.salm2map(ethf, s1 + spin_weight_of_eth,
                                          ell_max, n_theta, n_phi)
            ethg_j_k = spinsfast.salm2map(ethg, s2 + spin_weight_of_eth,
                                          ell_max, n_theta, n_phi)
            ethfg_j_k = spinsfast.salm2map(ethfg, s1 + s2 + spin_weight_of_eth,
                                           2 * ell_max, n_theta, n_phi)
            assert np.allclose(ethfg_j_k,
                               ethf_j_k * g_j_k + f_j_k * ethg_j_k,
                               rtol=1e-10,
                               atol=1e-10)
예제 #2
0
def test_modes_squared_angular_momenta():
    tolerance = 1e-13
    np.random.seed(1234)
    L2 = sf.Modes.Lsquared
    Lz = sf.Modes.Lz
    Lp = sf.Modes.Lplus
    Lm = sf.Modes.Lminus
    R2 = sf.Modes.Rsquared
    Rz = sf.Modes.Rz
    Rp = sf.Modes.Rplus
    Rm = sf.Modes.Rminus
    for s in range(-2, 2 + 1):
        ell_min = abs(s)
        ell_max = 8
        a = np.random.rand(3, 7,
                           sf.LM_total_size(ell_min, ell_max) *
                           2).view(complex)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)

        # Test L^2 = 0.5(L+L- + L-L+) + LzLz
        m1 = L2(m)
        m2 = 0.5 * (Lp(Lm(m)) + Lm(Lp(m))) + Lz(Lz(m))
        assert np.allclose(m1, m2, rtol=tolerance, atol=tolerance)

        # Test R^2 = 0.5(R+R- + R-R+) + RzRz
        m1 = R2(m)
        m2 = 0.5 * (Rp(Rm(m)) + Rm(Rp(m))) + Rz(Rz(m))
        assert np.allclose(m1, m2, rtol=tolerance, atol=tolerance)

        # Test L^2 = R^2
        m1 = L2(m)
        m2 = R2(m)
        assert np.allclose(m1, m2, rtol=tolerance, atol=tolerance)
예제 #3
0
def test_modes_conjugate():
    tolerance = 1e-15
    np.random.seed(1234)
    for inplace in [False, True]:
        for s in range(-2, 2 + 1):
            ell_min = abs(s)
            ell_max = 8
            a = np.random.rand(3, 7,
                               sf.LM_total_size(ell_min, ell_max) *
                               2).view(complex)
            m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
            g = m.grid()
            s = m.s
            ell_min = m.ell_min
            ell_max = m.ell_max
            shape = m.shape
            mbar = m.conjugate(inplace)
            gbar = mbar.grid()
            assert s == -mbar.s
            assert ell_min == mbar.ell_min
            assert ell_max == mbar.ell_max
            assert shape == mbar.shape
            assert np.allclose(g,
                               np.conjugate(gbar),
                               rtol=tolerance,
                               atol=tolerance)
예제 #4
0
def test_modes_ufuncs():
    for s1 in range(-2, 2 + 1):
        ell_min1 = abs(s1)
        ell_max1 = 8
        a1 = np.random.rand(11,
                            sf.LM_total_size(ell_min1, ell_max1) *
                            2).view(complex)
        m1 = sf.Modes(a1, spin_weight=s1, ell_min=ell_min1, ell_max=ell_max1)
        positivem1 = +m1
        assert np.array_equal(m1.view(np.ndarray), positivem1.view(np.ndarray))
        negativem1 = -m1
        assert np.array_equal(-(m1.view(np.ndarray)),
                              negativem1.view(np.ndarray))
예제 #5
0
def test_modes_norm():
    tolerance = 1e-15
    np.random.seed(1234)
    for s in range(-2, 2 + 1):
        ell_min = abs(s)
        ell_max = 8
        a = np.random.rand(3, 7,
                           sf.LM_total_size(ell_min, ell_max) *
                           2).view(complex)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
        mmbar = m.multiply(m.conjugate())
        norm = np.sqrt(2 * math.sqrt(np.pi) *
                       mmbar[..., 0].view(np.ndarray).real)
        assert np.allclose(norm, m.norm(), rtol=tolerance, atol=tolerance)
예제 #6
0
def test_modes_copying_and_pickling(copier):
    for s in range(-2, 2 + 1):
        ell_min = abs(s)
        ell_max = 8
        a = np.random.rand(3, 7,
                           sf.LM_total_size(ell_min, ell_max) *
                           2).view(complex)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
        c = copier(m)
        assert m is not c
        assert np.array_equal(c, m)
        assert isinstance(c, type(m))
        assert c.s == m.s
        assert c.ell_min == m.ell_min
        assert c.ell_max == m.ell_max
예제 #7
0
def test_modes_grid():
    for s in range(-2, 2 + 1):
        ell_min = abs(s)
        ell_max = 8
        a = np.random.rand(3, 7,
                           sf.LM_total_size(ell_min, ell_max) *
                           2).view(complex)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
        n = 2 * ell_max + 1
        for n_theta, n_phi in [[None, None], [n, None], [None, n], [n, n],
                               [n + 1, n], [n, n + 1], [n + 1, n + 1]]:
            g = m.grid(n_theta=n_theta, n_phi=n_phi)
            assert g.dtype == complex
            assert g.shape[:-2] == a.shape[:-1]
            if n_theta is None:
                n_theta = n
            if n_phi is None:
                n_phi = n
            assert g.shape[-2:] == (n_theta, n_phi)
예제 #8
0
def test_modes_imag():
    tolerance = 1e-14
    np.random.seed(1234)
    for inplace in [False, True]:
        s = 0
        ell_min = abs(s)
        ell_max = 8
        a = np.random.rand(3, 7,
                           sf.LM_total_size(ell_min, ell_max) *
                           2).view(complex)
        # Test success with spin_weight==0
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
        g = m.grid()
        s = m.s
        ell_min = m.ell_min
        ell_max = m.ell_max
        shape = m.shape
        mimag = m._imag_func(inplace)
        gimag = mimag.grid()
        assert s == mimag.s
        assert ell_min == mimag.ell_min
        assert ell_max == mimag.ell_max
        assert shape == mimag.shape
        assert np.allclose(gimag,
                           np.real(gimag),
                           rtol=tolerance,
                           atol=tolerance)  # gimag is purely real
        assert np.allclose(np.array(np.imag(g.ndarray), dtype=complex),
                           gimag.ndarray,
                           rtol=tolerance,
                           atol=tolerance)  # imag(g) == gimag
        assert np.allclose(np.imag(gimag.ndarray),
                           np.zeros_like(g.ndarray, dtype=float),
                           rtol=tolerance,
                           atol=tolerance)  # imag(gimag) == 0
        # Test failure with s!=0
        for s in [-3, -2, -1, 1, 2, 3]:
            m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
            with pytest.raises(ValueError):
                mimag = m._imag_func(inplace)
예제 #9
0
def test_modes_real():
    tolerance = 1e-14
    np.random.seed(1234)
    for inplace in [False, True]:
        s = 0
        ell_min = abs(s)
        ell_max = 8
        a = np.random.rand(3, 7,
                           sf.LM_total_size(ell_min, ell_max) *
                           2).view(complex)
        # Test success with spin_weight==0
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
        g = m.grid()
        s = m.s
        ell_min = m.ell_min
        ell_max = m.ell_max
        shape = m.shape
        mreal = m._real_func(inplace)
        greal = mreal.grid()
        assert s == mreal.s
        assert ell_min == mreal.ell_min
        assert ell_max == mreal.ell_max
        assert shape == mreal.shape
        assert np.allclose(greal,
                           np.real(greal) + 0.0j,
                           rtol=tolerance,
                           atol=tolerance)
        assert np.allclose(np.real(g),
                           np.real(greal),
                           rtol=tolerance,
                           atol=tolerance)
        assert np.allclose(np.zeros_like(g, dtype=float),
                           np.imag(greal),
                           rtol=tolerance,
                           atol=tolerance)
        # Test failure with s!=0
        for s in [-3, -2, -1, 1, 2, 3]:
            m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
            with pytest.raises(ValueError):
                mreal = m._real_func(inplace)
예제 #10
0
def test_modes_derivatives_on_grids():
    # Test various SWSH-derivative expressions on grids
    tolerance = 2e-14
    np.random.seed(1234)
    for s in range(-2, 2 + 1):
        ell_min = 0
        ell_max = abs(s) + 5
        zeros = lambda: np.zeros(sf.LM_total_size(ell_min, ell_max),
                                 dtype=complex)
        for ell in range(abs(s), ell_max + 1):
            for m in range(-ell, ell + 1):
                sYlm = sf.Modes(zeros(),
                                spin_weight=s,
                                ell_min=ell_min,
                                ell_max=ell_max)
                sYlm[sYlm.index(ell, m)] = 1.0
                g_sYlm = sYlm.grid()
                n_theta, n_phi = g_sYlm.shape[-2:]

                # Test Lsquared {s}Y{l,m} = l * (l+1) * {s}Y{l,m}
                L2_sYlm = sYlm.Lsquared()
                g_L2_sYlm = L2_sYlm.grid(n_theta, n_phi)
                factor = ell * (ell + 1)
                assert np.allclose(g_L2_sYlm,
                                   factor * g_sYlm,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test Lz {s}Y{l,m} = m * {s}Y{l,m}
                Lz_sYlm = sYlm.Lz()
                g_Lz_sYlm = Lz_sYlm.grid(n_theta, n_phi)
                factor = m
                assert np.allclose(g_Lz_sYlm,
                                   factor * g_sYlm,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test Lplus {s}Y{l,m} = sqrt((l-m)*(l+m+1)) {s}Y{l,m+1}
                invalid = abs(m + 1) > ell
                sYlmp1 = sf.Modes(zeros(),
                                  spin_weight=s,
                                  ell_min=ell_min,
                                  ell_max=ell_max)
                if invalid:
                    with pytest.raises(ValueError):
                        sYlmp1.index(ell, m + 1)
                else:
                    sYlmp1[sYlmp1.index(ell, m + 1)] = 1.0
                g_sYlmp1 = sYlmp1.grid(n_theta, n_phi)
                Lp_sYlm = sYlm.Lplus()
                g_Lp_sYlm = Lp_sYlm.grid(n_theta, n_phi)
                factor = 0.0 if invalid else math.sqrt(
                    (ell - m) * (ell + m + 1))
                assert np.allclose(g_Lp_sYlm,
                                   factor * g_sYlmp1,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test Lminus {s}Y{l,m} = sqrt((l+m)*(l-m+1)) * {s}Y{l,m-1}
                invalid = abs(m - 1) > ell
                sYlmm1 = sf.Modes(zeros(),
                                  spin_weight=s,
                                  ell_min=ell_min,
                                  ell_max=ell_max)
                if invalid:
                    with pytest.raises(ValueError):
                        sYlmm1.index(ell, m - 1)
                else:
                    sYlmm1[sYlmm1.index(ell, m - 1)] = 1.0
                g_sYlmm1 = sYlmm1.grid(n_theta, n_phi)
                Lm_sYlm = sYlm.Lminus()
                g_Lm_sYlm = Lm_sYlm.grid(n_theta, n_phi)
                factor = 0.0 if invalid else math.sqrt(
                    (ell + m) * (ell - m + 1))
                assert np.allclose(g_Lm_sYlm,
                                   factor * g_sYlmm1,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test Rsquared {s}Y{l,m} = l * (l+1) * {s}Y{l,m}
                R2_sYlm = sYlm.Rsquared()
                g_R2_sYlm = R2_sYlm.grid(n_theta, n_phi)
                factor = ell * (ell + 1)
                assert np.allclose(g_R2_sYlm,
                                   factor * g_sYlm,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test Rz {s}Y{l,m} = -s * {s}Y{l,m}
                Rz_sYlm = sYlm.Rz()
                g_Rz_sYlm = Rz_sYlm.grid(n_theta, n_phi)
                factor = -s
                assert np.allclose(g_Rz_sYlm,
                                   factor * g_sYlm,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test Rplus {s}Y{l,m} = sqrt((l+s)(l-s+1)) {s-1}Y{l,m}
                invalid = abs(s - 1) > ell
                sm1Ylm = sf.Modes(zeros(),
                                  spin_weight=s - 1,
                                  ell_min=ell_min,
                                  ell_max=ell_max)
                if invalid:
                    with pytest.raises(ValueError):
                        sm1Ylm.index(ell, m)
                else:
                    sm1Ylm[sm1Ylm.index(ell, m)] = 1.0
                g_sm1Ylm = sm1Ylm.grid(n_theta, n_phi)
                Rp_sYlm = sYlm.Rplus()
                g_Rp_sYlm = Rp_sYlm.grid(n_theta, n_phi)
                factor = 0.0 if invalid else math.sqrt(
                    (ell + s) * (ell - s + 1))
                assert np.allclose(g_Rp_sYlm,
                                   factor * g_sm1Ylm,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test Rminus {s}Y{l,m} = sqrt((l-s)(l+s+1)) {s+1}Y{l,m}
                invalid = abs(s + 1) > ell
                sp1Ylm = sf.Modes(zeros(),
                                  spin_weight=s + 1,
                                  ell_min=ell_min,
                                  ell_max=ell_max)
                if invalid:
                    with pytest.raises(ValueError):
                        sp1Ylm.index(ell, m)
                else:
                    sp1Ylm[sp1Ylm.index(ell, m)] = 1.0
                Rm_sYlm = sYlm.Rminus()
                g_sp1Ylm = sp1Ylm.grid(n_theta, n_phi)
                g_Rm_sYlm = Rm_sYlm.grid(n_theta, n_phi)
                factor = 0.0 if invalid else math.sqrt(
                    (ell - s) * (ell + s + 1))
                assert np.allclose(g_Rm_sYlm,
                                   factor * g_sp1Ylm,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test eth {s}Y{l,m} = sqrt((l-s)(l+s+1)) {s+1}Y{l,m}
                invalid = abs(s + 1) > ell
                sp1Ylm = sf.Modes(zeros(),
                                  spin_weight=s + 1,
                                  ell_min=ell_min,
                                  ell_max=ell_max)
                if invalid:
                    with pytest.raises(ValueError):
                        sp1Ylm.index(ell, m)
                else:
                    sp1Ylm[sp1Ylm.index(ell, m)] = 1.0
                eth_sYlm = sYlm.eth
                g_sp1Ylm = sp1Ylm.grid(n_theta, n_phi)
                g_eth_sYlm = eth_sYlm.grid(n_theta, n_phi)
                factor = 0.0 if invalid else math.sqrt(
                    (ell - s) * (ell + s + 1))
                assert np.allclose(g_eth_sYlm,
                                   factor * g_sp1Ylm,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test ethbar {s}Y{l,m} = -sqrt((l+s)(l-s+1)) {s-1}Y{l,m}
                invalid = abs(s - 1) > ell
                sm1Ylm = sf.Modes(zeros(),
                                  spin_weight=s - 1,
                                  ell_min=ell_min,
                                  ell_max=ell_max)
                if invalid:
                    with pytest.raises(ValueError):
                        sm1Ylm.index(ell, m)
                else:
                    sm1Ylm[sm1Ylm.index(ell, m)] = 1.0
                g_sm1Ylm = sm1Ylm.grid(n_theta, n_phi)
                ethbar_sYlm = sYlm.ethbar
                g_ethbar_sYlm = ethbar_sYlm.grid(n_theta, n_phi)
                factor = 0.0 if invalid else -math.sqrt(
                    (ell + s) * (ell - s + 1))
                assert np.allclose(g_ethbar_sYlm,
                                   factor * g_sm1Ylm,
                                   rtol=tolerance,
                                   atol=tolerance)

                # Test ethbar eth sYlm = -(l-s)(l+s+1) sYlm
                ethbar_eth_sYlm = sYlm.eth.ethbar
                g_ethbar_eth_sYlm = ethbar_eth_sYlm.grid(n_theta, n_phi)
                factor = 0.0 if (abs(s + 1) > ell or
                                 abs(s) > ell) else -(ell - s) * (ell + s + 1)
                assert np.allclose(g_ethbar_eth_sYlm,
                                   factor * g_sYlm,
                                   rtol=tolerance,
                                   atol=tolerance)
예제 #11
0
def test_modes_derivative_commutators():
    tolerance = 1e-13
    np.random.seed(1234)
    # Note that post-fix operators are in the opposite order compared
    # to prefixed commutators, so we pull the post-fix operators out
    # as functions to make things look right.
    np.random.seed(1234)
    L2 = sf.Modes.Lsquared
    Lz = sf.Modes.Lz
    Lp = sf.Modes.Lplus
    Lm = sf.Modes.Lminus
    R2 = sf.Modes.Rsquared
    Rz = sf.Modes.Rz
    Rp = sf.Modes.Rplus
    Rm = sf.Modes.Rminus
    eth = lambda modes: modes.eth
    ethbar = lambda modes: modes.ethbar
    for s in range(-2, 2 + 1):
        ell_min = abs(s)
        ell_max = 8
        a = np.random.rand(3, 7,
                           sf.LM_total_size(ell_min, ell_max) *
                           2).view(complex)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
        # Test [Ri, Lj] = 0
        for R in [Rz, Rp, Rm]:
            for L in [Lz, Lp, Lm]:
                assert np.max(np.abs(L(R(m)) - R(L(m)))) < tolerance
        # Test [L2, Lj] = 0
        for L in [Lz, Lp, Lm]:
            assert np.max(np.abs(L2(L(m)) - L(L2(m)))) < 5 * tolerance
        # Test [R2, Rj] = 0
        for R in [Rz, Rp, Rm]:
            assert np.max(np.abs(R2(R(m)) - R(R2(m)))) < 5 * tolerance
        # Test [Lz, Lp] = Lp
        assert np.allclose(Lz(Lp(m)) - Lp(Lz(m)),
                           Lp(m),
                           rtol=tolerance,
                           atol=tolerance)
        # Test [Lz, Lm] = -Lm
        assert np.allclose(Lz(Lm(m)) - Lm(Lz(m)),
                           -Lm(m),
                           rtol=tolerance,
                           atol=tolerance)
        # Test [Lp, Lm] = 2Lz
        assert np.allclose(Lp(Lm(m)) - Lm(Lp(m)),
                           2 * Lz(m),
                           rtol=tolerance,
                           atol=tolerance)
        # Test [Rz, Rp] = Rp
        assert np.allclose(Rz(Rp(m)) - Rp(Rz(m)),
                           Rp(m),
                           rtol=tolerance,
                           atol=tolerance)
        # Test [Rz, Rm] = -Rm
        assert np.allclose(Rz(Rm(m)) - Rm(Rz(m)),
                           -Rm(m),
                           rtol=tolerance,
                           atol=tolerance)
        # Test [Rp, Rm] = 2Rz
        assert np.allclose(Rp(Rm(m)) - Rm(Rp(m)),
                           2 * Rz(m),
                           rtol=tolerance,
                           atol=tolerance)
        # Test [ethbar, eth] = 2s
        assert np.allclose(ethbar(eth(m)) - eth(ethbar(m)),
                           2 * m.s * m,
                           rtol=tolerance,
                           atol=tolerance)
예제 #12
0
def test_modes_multiplication():
    tolerance = 1e-13
    np.random.seed(1234)
    # Test without truncation
    for i_mul, mul in enumerate([
            np.multiply, lambda a, b: a.multiply(b),
            lambda a, b: a.multiply(b, truncator=max)
    ]):
        for s1 in range(-2, 2 + 1):
            ell_min1 = abs(s1)
            ell_max1 = 8
            a1 = np.random.rand(3, 7,
                                sf.LM_total_size(ell_min1, ell_max1) *
                                2).view(complex)
            m1 = sf.Modes(a1,
                          spin_weight=s1,
                          ell_min=ell_min1,
                          ell_max=ell_max1)
            # Check scalar multiplications
            s = np.random.rand()
            m1s = mul(m1, s)
            assert m1.s == s1
            assert m1s.ell_max == m1.ell_max
            g1s = m1s.grid()
            n_theta, n_phi = g1s.shape[-2:]
            g1 = m1.grid(n_theta, n_phi)
            assert np.allclose(g1 * s, g1s, rtol=tolerance, atol=tolerance)
            if mul is np.multiply:
                sm1 = mul(s, m1)
                assert sm1.s == s1
                assert sm1.ell_max == m1.ell_max
                sg1 = sm1.grid()
                n_theta, n_phi = sg1.shape[-2:]
                g1 = m1.grid(n_theta, n_phi)
                assert np.allclose(s * g1, sg1, rtol=tolerance, atol=tolerance)
            # Check scalar-array multiplications
            s = np.random.rand(3, 7)
            m1s = mul(m1, s)
            assert m1.s == s1
            assert m1s.ell_max == m1.ell_max
            g1s = m1s.grid()
            n_theta, n_phi = g1s.shape[-2:]
            g1 = m1.grid(n_theta, n_phi)
            assert np.allclose(g1 * s, g1s, rtol=tolerance, atol=tolerance)
            if mul is np.multiply:
                sm1 = mul(s, m1)
                assert sm1.s == s1
                assert sm1.ell_max == m1.ell_max
                sg1 = sm1.grid()
                n_theta, n_phi = sg1.shape[-2:]
                g1 = m1.grid(n_theta, n_phi)
                assert np.allclose(s * g1, sg1, rtol=tolerance, atol=tolerance)
            # Check spin-weighted multiplications
            for s2 in range(-s1, s1 + 1):
                ell_min2 = ell_min1 + 1
                ell_max2 = ell_max1 - 1
                a2 = np.random.rand(3, 7,
                                    sf.LM_total_size(ell_min2, ell_max2) *
                                    2).view(complex)
                m2 = sf.Modes(a2,
                              spin_weight=s2,
                              ell_min=ell_min2,
                              ell_max=ell_max2)
                m1m2 = mul(m1, m2)
                assert m1m2.s == s1 + s2
                if i_mul == 2:
                    assert m1m2.ell_max == max(m1.ell_max, m2.ell_max)
                else:
                    assert m1m2.ell_max == m1.ell_max + m2.ell_max
                    g12 = m1m2.grid()
                    n_theta, n_phi = g12.shape[-2:]
                    g1 = m1.grid(n_theta, n_phi)
                    g2 = m2.grid(n_theta, n_phi)
                    assert np.allclose(g1 * g2,
                                       g12,
                                       rtol=tolerance,
                                       atol=tolerance)
예제 #13
0
def test_modes_subtraction():
    tolerance = 1e-14
    np.random.seed(1234)
    for s1 in range(-2, 2 + 1):
        ell_min1 = abs(s1)
        ell_max1 = 8
        a1 = np.random.rand(3, 7, sf.LM_total_size(ell_min1, ell_max1) * 2)
        a2 = np.random.rand(*a1.shape)
        a1 = a1.view(complex)
        a2 = a2.view(complex)
        m1 = sf.Modes(a1, spin_weight=s1, ell_min=ell_min1, ell_max=ell_max1)
        m2 = sf.Modes(a2, spin_weight=s1, ell_min=ell_min1, ell_max=ell_max1)
        m1m2 = m1 - m2
        assert m1m2.s == s1
        assert m1m2.ell_max == m1.ell_max
        assert np.array_equal(m1m2, m1.subtract(m2))
        assert np.array_equal(m1m2, m1.view(np.ndarray) - m2.view(np.ndarray))
        for s2 in range(-s1, s1 + 1):
            ell_min2 = ell_min1 + 1
            ell_max2 = ell_max1 - 1
            a2 = np.random.rand(3, 7,
                                sf.LM_total_size(ell_min2, ell_max2) *
                                2).view(complex)
            m2 = sf.Modes(a2,
                          spin_weight=s2,
                          ell_min=ell_min2,
                          ell_max=ell_max2)
            if s1 != s2:
                # Don't allow addition of non-zero data
                with pytest.raises(ValueError):
                    m1m2 = m1.subtract(m2)
                # Do allow subtraction with various forms of 0, for convenience
                for m3 in [
                        m1.subtract(0),
                        m1.subtract(np.zeros(1)),
                        m1.subtract(np.zeros((1, ))),
                        m1.subtract(np.zeros((7, ))),
                        m1.subtract(np.zeros((3, 7))),
                        m1 - 0,
                        m1 - np.zeros(1),
                        m1 - np.zeros((1, )),
                        m1 - np.zeros((7, )),
                        m1 - np.zeros((3, 7)),
                ]:
                    assert m3.s == s1
                    assert m3.ell_min == m1.ell_min
                    assert m3.ell_max == m1.ell_max
                    assert np.array_equal(m1, m3)
                for m3 in [
                        0 - m1,
                        np.zeros(1) - m1,
                        np.zeros((1, )) - m1,
                        np.zeros((7, )) - m1,
                        np.zeros((3, 7)) - m1,
                ]:
                    assert m3.s == s1
                    assert m3.ell_min == m1.ell_min
                    assert m3.ell_max == m1.ell_max
                    assert np.array_equal(-m1, m3)
            else:
                m1m2 = m1.subtract(m2)
                assert m1m2.s == s1
                assert m1m2.ell_max == m1.ell_max
                i1 = sf.LM_total_size(0, min(ell_min1, ell_min2) - 1)
                i2 = sf.LM_total_size(0, max(ell_min1, ell_min2) - 1)
                i3 = sf.LM_total_size(0, min(ell_max1, ell_max2))
                i4 = sf.LM_total_size(0, max(ell_max1, ell_max2))
                assert np.array_equiv(m1m2[..., :i1], 0.0)
                assert np.array_equal(m1m2[..., i1:i2], a1[..., :i2 - i1])
                assert np.array_equal(m1m2[..., i1:i2],
                                      m1.view(np.ndarray)[..., i1:i2])
                assert np.array_equal(
                    m1m2[..., i2:i3],
                    m1.view(np.ndarray)[..., i2:i3] -
                    m2.view(np.ndarray)[..., i2:i3])
                assert np.array_equal(m1m2[..., i3:i4],
                                      m1.view(np.ndarray)[..., i3:i4])
                g12 = m1m2.grid()
                n_theta, n_phi = g12.shape[-2:]
                g1 = m1.grid(n_theta, n_phi)
                g2 = m2.grid(n_theta, n_phi)
                assert np.allclose(g1 - g2,
                                   g12,
                                   rtol=tolerance,
                                   atol=tolerance)
예제 #14
0
def test_modes_creation():
    for s in range(-2, 2 + 1):
        ell_min = abs(s)
        ell_max = 8

        # Test successful creation with real data of the right shape
        a = np.random.rand(3, 7, sf.LM_total_size(ell_min, ell_max) * 2)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
        assert m.s == s
        assert m.ell_min == 0  # NOTE: This is hard coded!!!
        assert m.ell_max == ell_max
        assert np.array_equal(a.view(complex),
                              m[..., sf.LM_total_size(0, ell_min - 1):])
        assert np.all(m[..., :sf.LM_total_size(0, abs(s) - 1)] == 0.0)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min)  # ell_max is deduced!
        assert m.s == s
        assert m.ell_min == 0  # NOTE: This is hard coded!!!
        assert m.ell_max == ell_max
        assert np.array_equal(a.view(complex),
                              m[..., sf.LM_total_size(0, ell_min - 1):])
        assert np.all(m[..., :sf.LM_total_size(0, abs(s) - 1)] == 0.0)

        # Test successful creation with complex data of the right shape
        a = a.view(complex)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min, ell_max=ell_max)
        assert m.s == s
        assert m.ell_min == 0  # NOTE: This is hard coded!!!
        assert m.ell_max == ell_max
        assert np.array_equal(a, m[..., sf.LM_total_size(0, ell_min - 1):])
        assert np.all(m[..., :sf.LM_total_size(0, abs(s) - 1)] == 0.0)
        m = sf.Modes(a, spin_weight=s, ell_min=ell_min)  # ell_max is deduced!
        assert m.s == s
        assert m.ell_min == 0  # NOTE: This is hard coded!!!
        assert m.ell_max == ell_max
        assert np.array_equal(a, m[..., sf.LM_total_size(0, ell_min - 1):])
        assert np.all(m[..., :sf.LM_total_size(0, abs(s) - 1)] == 0.0)

        # Test failed creation with complex data of inconsistent shape
        if ell_min != 0:
            with pytest.raises(ValueError):
                m = sf.Modes(a, spin_weight=s)
        with pytest.raises(ValueError):
            m = sf.Modes(a,
                         spin_weight=s,
                         ell_min=ell_min - 1,
                         ell_max=ell_max)
        with pytest.raises(ValueError):
            m = sf.Modes(a,
                         spin_weight=s,
                         ell_min=ell_min + 1,
                         ell_max=ell_max)
        with pytest.raises(ValueError):
            m = sf.Modes(a,
                         spin_weight=s,
                         ell_min=ell_min,
                         ell_max=ell_max - 1)
        with pytest.raises(ValueError):
            m = sf.Modes(a,
                         spin_weight=s,
                         ell_min=ell_min,
                         ell_max=ell_max + 1)

        # Test failed creation with complex data of impossible shape
        with pytest.raises(ValueError):
            m = sf.Modes(a[..., 1:], spin_weight=s, ell_min=ell_min)

        # Test successful creation with complex data containing extraneous data at ell<abs(s)
        a = np.random.rand(3, 7, sf.LM_total_size(0, ell_max) * 2)
        a = a.view(complex)
        m = sf.Modes(a, spin_weight=s)
        assert m.s == s
        assert m.ell_min == 0  # NOTE: This is hard coded!!!
        assert m.ell_max == ell_max
        assert np.all(m[..., :sf.LM_total_size(0, abs(s) - 1)] == 0.0)
예제 #15
0
def test_LM_total_size(ell_max):
    for l_min in range(ell_max + 1):
        for l_max in range(l_min, ell_max + 1):
            assert sf.LM_index(l_max + 1, -(l_max + 1),
                               l_min) == sf.LM_total_size(l_min, l_max)