probabilistic-numerics / probnum

Probabilistic Numerics in Python.
http://probnum.org
MIT License
438 stars 57 forks source link

Test vectorization operators #98

Closed JonathanWenger closed 3 years ago

JonathanWenger commented 4 years ago

Vectorization operators Vec and Svec are currently not very well tested.

Some suggestions for the form of tests to add to test_linearoperators.py:

        # Linear map Q such that svec(x) = Qvec(x).
        @pytest.mark.parametrize("n", [1, 3, 5, 100])
        def test_svec(n):
            """Test symmetric vectorization operator shape and entries."""
            A = np.random.normal(size=(n, n))
            A = 0.5 * (A + A.T)
            svec = linops.Vec2Svec(dim=n, check_symmetric=True)
            y = svec @ A

            # Check shape
            assert np.shape(y)[0] == int(0.5 * n * (n + 1)), "Svec(X) does not have the correct dimension."

            # Check diagonal entries
            diagind = np.hstack([0, np.cumsum(np.arange(2, n + 1)[::-1])])
            self.assertArrayEqual(y[diagind, :].ravel(), np.diag(A), "Entries of diagonal are not correct.")

            # Check off-diagonal entries
            supdiagtri = np.sqrt(2) * A[np.triu_indices(n, k=1)]
            self.assertArrayEqual(np.delete(y, diagind), supdiagtri,
                                          "Off-diagonal entries are incorrect.")

        @pytest.mark.parametrize("n", [1, 5, 100])
        def test_vec2svec_orthonormality(n):
            """Check orthonormality of Q: Q^TQ = I"""
            Q = linops.Vec2Svec(dim=n)
            self.assertAllClose((Q @ Q.T).todense(),
                                       np.eye(N=int(0.5 * n * (n + 1))),
                                       msg="Vec2Svec does not have orthonormal rows.")

        def test_vec2svec_explicit_form():
            """Check vec2svec against some explicit matrix forms."""
            s2 = np.sqrt(2) / 2
            Q_explicit_n2 = np.array([[1, 0, 0, 0],
                                      [0, s2, s2, 0],
                                      [0, 0, 0, 1]])

            Q_explicit_n3 = np.array([[1, 0, 0, 0, 0, 0, 0, 0, 0],
                                      [0, s2, 0, s2, 0, 0, 0, 0, 0],
                                      [0, 0, s2, 0, 0, 0, s2, 0, 0],
                                      [0, 0, 0, 0, 1, 0, 0, 0, 0],
                                      [0, 0, 0, 0, 0, s2, 0, s2, 0],
                                      [0, 0, 0, 0, 0, 0, 0, 0, 1]])

            self.assertAllClose(linops.Vec2Svec(dim=2).todense(), Q_explicit_n2)
            self.assertAllClose(linops.Vec2Svec(dim=3).todense(), Q_explicit_n3)
JonathanWenger commented 3 years ago

Vectorization operators were removed from the package.