def test_inner(self):
     man = self.man
     k = self.k
     n = self.n
     x = man.rand()
     a, b = rnd.randn(2, k, n, n)
     np.testing.assert_almost_equal(np.tensordot(a, b, axes=a.ndim),
                                    man.inner(x, multiprod(x, a),
                                              multiprod(x, b)))
Beispiel #2
0
 def dist(self, x, y):
     # Adapted from equation 6.13 of "Positive definite matrices". Chol
     # decomp gives the same result as matrix sqrt. There may be a more
     # efficient way to compute this!
     c = np.linalg.cholesky(x)
     c_inv = np.linalg.inv(c)
     l = multilog(multiprod(multiprod(c_inv, y), multitransp(c_inv)),
                  pos_def=True)
     return la.norm(multiprod(multiprod(c, l), c_inv))
Beispiel #3
0
    def log(self, X, Y):
        ytx = multiprod(multitransp(Y), X)
        At = multitransp(Y) - multiprod(ytx, multitransp(X))
        Bt = np.linalg.solve(ytx, At)
        u, s, vt = svd(multitransp(Bt), full_matrices=False)
        arctan_s = np.expand_dims(np.arctan(s), -2)

        U = multiprod(u * arctan_s, vt)
        return U
    def test_proj(self):
        # Construct a random point X on the manifold.
        X = self.man.rand()

        # Construct a vector H in the ambient space.
        H = rnd.randn(self.k, self.m, self.n)

        # Compare the projections.
        Hproj = H - multiprod(X, multiprod(multitransp(X), H))
        np_testing.assert_allclose(Hproj, self.man.proj(X, H))
 def test_rand(self):
     # Just make sure that things generated are on the manifold and that
     # if you generate two they are not equal.
     X = self.man.rand()
     np_testing.assert_allclose(multiprod(multitransp(X), X), multieye(self.k, self.n), atol=1e-10)
     Y = self.man.rand()
     assert np.linalg.norm(X - Y) > 1e-6
Beispiel #6
0
    def test_multiprod_singlemat(self):
        # Two random matrices A (m x n) and B (n x p)
        A = rnd.randn(self.m, self.n)
        B = rnd.randn(self.n, self.p)

        # Compare the products.
        np_testing.assert_allclose(A.dot(B), multiprod(A, B))
Beispiel #7
0
    def exp(self, X, U):
        u, s, vt = svd(U, full_matrices=False)
        cos_s = np.expand_dims(np.cos(s), -2)
        sin_s = np.expand_dims(np.sin(s), -2)

        Y = (multiprod(multiprod(X, multitransp(vt) * cos_s), vt) +
             multiprod(u * sin_s, vt))

        # From numerical experiments, it seems necessary to
        # re-orthonormalize. This is overall quite expensive.
        if self._k == 1:
            Y, unused = np.linalg.qr(Y)
            return Y
        else:
            for i in range(self._k):
                Y[i], unused = np.linalg.qr(Y[i])
            return Y
    def test_exp(self):
        man = self.man
        x = man.rand()
        u = man.randvec(x)
        e = sp.linalg.expm(la.solve(x, u))

        np_testing.assert_allclose(multiprod(x, e), man.exp(x, u))
        u = u * 1e-6
        np_testing.assert_allclose(man.exp(x, u), x + u)
 def test_randvec(self):
     # Make sure things generated are in tangent space and if you generate
     # two then they are not equal.
     X = self.man.rand()
     U = self.man.randvec(X)
     np_testing.assert_allclose(multisym(multiprod(multitransp(X), U)),
                                np.zeros((self.k, self.n, self.n)),
                                atol=1e-10)
     V = self.man.randvec(X)
     assert la.norm(U - V) > 1e-6
Beispiel #10
0
    def test_multiprod(self):
        # Two random arrays of matrices A (k x m x n) and B (k x n x p)
        A = rnd.randn(self.k, self.m, self.n)
        B = rnd.randn(self.k, self.n, self.p)

        C = np.zeros((self.k, self.m, self.p))
        for i in range(self.k):
            C[i] = A[i].dot(B[i])

        np_testing.assert_allclose(C, multiprod(A, B))
Beispiel #11
0
 def exp(self, x, u):
     # TODO: Check which method is faster depending on n, k.
     x_inv_u = np.linalg.solve(x, u)
     if self._k > 1:
         e = np.zeros(np.shape(x))
         for i in range(self._k):
             e[i] = sp.linalg.expm(x_inv_u[i])
     else:
         e = sp.linalg.expm(x_inv_u)
     return multiprod(x, e)
Beispiel #12
0
    def rand(self):
        # The way this is done is arbitrary. I think the space of p.d.
        # matrices would have infinite measure w.r.t. the Riemannian metric
        # (c.f. integral 0-inf [ln(x)] dx = inf) so impossible to have a
        # 'uniform' distribution.

        # Generate eigenvalues between 1 and 2
        d = np.ones((self._k, self._n, 1)) + rnd.rand(self._k, self._n, 1)

        # Generate an orthogonal matrix. Annoyingly qr decomp isn't
        # vectorized so need to use a for loop. Could be done using
        # svd but this is slower for bigger matrices.
        u = np.zeros((self._k, self._n, self._n))
        for i in range(self._k):
            u[i], r = la.qr(rnd.randn(self._n, self._n))

        if self._k == 1:
            return multiprod(u, d * multitransp(u))[0]
        else:
            return multiprod(u, d * multitransp(u))
Beispiel #13
0
    def retr(self, X, G):
        # Calculate 'thin' qr decomposition of X + G
        # XNew, r = np.linalg.qr(X + G)

        # We do not need to worry about flipping signs of columns here,
        # since only the column space is important, not the actual
        # columns. Compare this with the Stiefel manifold.

        # Compute the polar factorization of Y = X+G
        u, s, vt = svd(X + G, full_matrices=False)
        return multiprod(u, vt)
 def test_exp(self):
     # Test against manopt implementation, test that for small vectors
     # exp(x, u) = x + u.
     man = self.man
     x = man.rand()
     u = man.randvec(x)
     e = np.zeros((self.k, self.n, self.n))
     for i in range(self.k):
         e[i] = sp.linalg.expm(la.solve(x[i], u[i]))
     np_testing.assert_allclose(multiprod(x, e), man.exp(x, u))
     u = u * 1e-6
     np_testing.assert_allclose(man.exp(x, u), x + u)
    def test_retr(self):
        # Test that the result is on the manifold and that for small
        # tangent vectors it has little effect.
        x = self.man.rand()
        u = self.man.randvec(x)

        xretru = self.man.retr(x, u)

        np_testing.assert_allclose(multiprod(multitransp(xretru), xretru), multieye(self.k, self.n), atol=1e-10)

        u = u * 1e-6
        xretru = self.man.retr(x, u)
        np_testing.assert_allclose(xretru, x + u)
    def test_exp(self):
        # Check that exp lies on the manifold and that exp of a small vector u
        # is close to x + u.
        s = self.man
        x = s.rand()
        u = s.randvec(x)

        xexpu = s.exp(x, u)
        np_testing.assert_allclose(multiprod(multitransp(xexpu), xexpu), multieye(self.k, self.n), atol=1e-10)

        u = u * 1e-6
        xexpu = s.exp(x, u)
        np_testing.assert_allclose(xexpu, x + u)
Beispiel #17
0
 def dist(self, X, Y):
     if self._k == 1:
         u, s, v = np.linalg.svd(np.dot(X.T, Y))
         s[s > 1] = 1
         s = np.arccos(s)
         return np.linalg.norm(s)
     else:
         XtY = multiprod(multitransp(X), Y)
         square_d = 0
         for i in xrange(self._k):
             s = np.linalg.svd(XtY[i], compute_uv=False)
             # Ensure that -1 <= s <= 1
             s = np.fmin(s, [1])
             s = np.fmax(s, [-1])
             square_d = square_d + np.linalg.norm(np.arccos(s))**2
         return np.sqrt(square_d)
    def test_ehess2rhess(self):
        # Use manopt's slow method
        man = self.man
        n = self.n
        k = self.k
        x = man.rand()
        egrad, ehess = rnd.randn(2, k, n, n)
        u = man.randvec(x)

        Hess = (multiprod(multiprod(x, multisym(ehess)), x) +
                2*multisym(multiprod(multiprod(u, multisym(egrad)), x)))

        # Correction factor for the non-constant metric
        Hess = Hess - multisym(multiprod(multiprod(u, multisym(egrad)), x))
        np_testing.assert_almost_equal(Hess, man.ehess2rhess(x, egrad, ehess,
                                                             u))
Beispiel #19
0
 def proj(self, X, U):
     return U - multiprod(X, multiprod(multitransp(X), U))
Beispiel #20
0
 def ehess2rhess(self, X, egrad, ehess, H):
     # Convert Euclidean into Riemannian Hessian.
     PXehess = self.proj(X, ehess)
     XtG = multiprod(multitransp(X), egrad)
     HXtG = multiprod(H, XtG)
     return PXehess - HXtG
Beispiel #21
0
 def proj(self, X, U):
     return U - multiprod(X, multiprod(multitransp(X), U))
Beispiel #22
0
 def dist(self, X, Y):
     u, s, v = svd(multiprod(multitransp(X), Y))
     s[s > 1] = 1
     s = np.arccos(s)
     return np.linalg.norm(s)
Beispiel #23
0
 def test_egrad2rgrad(self):
     man = self.man
     x = man.rand()
     u = rnd.randn(self.n, self.n) + 1j * rnd.randn(self.n, self.n)
     np.testing.assert_allclose(man.egrad2rgrad(x, u),
                                multiprod(multiprod(x, multiherm(u)), x))
Beispiel #24
0
 def proj(self, X, U):
     UNew = U - multiprod(
         X, multiprod(multitransp(X), U) + multiprod(multitransp(U), X)) / 2
     return UNew
Beispiel #25
0
 def ehess2rhess(self, X, egrad, ehess, H):
     # Convert Euclidean into Riemannian Hessian.
     XtG = multiprod(multitransp(X), egrad)
     symXtG = multisym(XtG)
     HsymXtG = multiprod(H, symXtG)
     return self.proj(X, ehess - HsymXtG)
 def test_egrad2rgrad(self):
     man = self.man
     x = man.rand()
     u = rnd.randn(self.k, self.n, self.n)
     np.testing.assert_allclose(man.egrad2rgrad(x, u),
                                multiprod(multiprod(x, multisym(u)), x))
Beispiel #27
0
 def ehess2rhess(self, x, egrad, ehess, u):
     # TODO: Check that this is correct
     return (multiprod(multiprod(x, multisym(ehess)), x) +
             multisym(multiprod(multiprod(u, multisym(egrad)), x)))
Beispiel #28
0
 def egrad2rgrad(self, x, u):
     # TODO: Check that this is correct
     return multiprod(multiprod(x, multisym(u)), x)
Beispiel #29
0
 def log(self, x, y):
     c = la.cholesky(x)
     c_inv = la.inv(c)
     l = multilog(multiprod(multiprod(c_inv, y), multitransp(c_inv)),
                  pos_def=True)
     return multiprod(multiprod(c, l), multitransp(c))
 def test_norm(self):
     man = self.man
     x = man.rand()
     a = np.random.randn(self.k, self.n, self.n)
     np_testing.assert_almost_equal(la.norm(a), man.norm(x,
                                                         multiprod(x, a)))
Beispiel #31
0
 def ehess2rhess(self, X, egrad, ehess, H):
     # Convert Euclidean hessian into Riemannian hessian.
     PXehess = self.proj(X, ehess)
     XtG = multiprod(multitransp(X), egrad)
     HXtG = multiprod(H, XtG)
     return PXehess - HXtG