예제 #1
0
 def randvec(self, x):
     k = self._k
     n = self._n
     if k == 1:
         u = multiherm(rnd.randn(n, n)+1j*rnd.randn(n, n))
     else:
         u = multiherm(rnd.randn(k, n, n)+1j*rnd.randn(k, n, n))
     return u / self.norm(x, u)
예제 #2
0
 def test_proj(self):
     man = self.man
     x = man.rand()
     a = rnd.randn(self.k, self.n, self.n)
     +1j * rnd.randn(self.k, self.n, self.n)
     np.testing.assert_allclose(man.proj(x, a), multiherm(a))
     np.testing.assert_allclose(man.proj(x, a), man.proj(x, man.proj(x, a)))
예제 #3
0
    def test_rand(self):
        # Just test that rand returns a point on the manifold and two
        # different matrices generated by rand aren't too close together
        k = self.k
        n = self.n
        man = self.man
        x = man.rand()
        y = man.rand()

        assert np.shape(x) == (k, n, n)
        assert x.dtype == np.complex

        # Check symmetry
        np_testing.assert_allclose(x, multiherm(x))

        # Check positivity of eigenvalues
        w = la.eigvalsh(x)
        assert (w > [[0]]).all()

        # Check unit determinant
        d = np.real(la.det(x))
        np_testing.assert_allclose(d, 1)

        # Check randomness
        assert la.norm(x - y) > 1e-3
예제 #4
0
    def log(self, x, y):
        k = self._k

        d, q = la.eigh(x)
        if k == 1:
            x_sqrt = [email protected](np.sqrt(d))@q.conj().T
            x_isqrt = [email protected](1/np.sqrt(d))@q.conj().T
        else:
            temp = np.zeros(q.shape, dtype=np.complex)
            for i in range(q.shape[0]):
                temp[i, :, :] = np.diag(np.sqrt(d[i, :]))[np.newaxis, :, :]
            x_sqrt = multiprod(multiprod(q, temp), multihconj(q))

            temp = np.zeros(q.shape, dtype=np.complex)
            for i in range(q.shape[0]):
                temp[i, :, :] = np.diag(1/np.sqrt(d[i, :]))[np.newaxis, :, :]
            x_isqrt = multiprod(multiprod(q, temp), multihconj(q))

        d, q = la.eigh(multiprod(multiprod(x_isqrt, y), x_isqrt))
        if k == 1:
            log = [email protected](np.log(d))@q.conj().T
        else:
            temp = np.zeros(q.shape, dtype=np.complex)
            for i in range(q.shape[0]):
                temp[i, :, :] = np.diag(np.log(d[i, :]))[np.newaxis, :, :]
            d = temp
            log = multiprod(multiprod(q, d), multihconj(q))

        xi = multiprod(multiprod(x_sqrt, log), x_sqrt)
        xi = multiherm(xi)
        return xi
예제 #5
0
 def test_egrad2rgrad(self):
     man = self.man
     x = man.rand()
     u = rnd.randn(self.k, self.n, self.n)
     +1j * rnd.randn(self.k, self.n, self.n)
     np.testing.assert_allclose(man.egrad2rgrad(x, u),
                                multiprod(multiprod(x, multiherm(u)), x))
예제 #6
0
    def exp(self, x, u):
        k = self._k

        d, q = la.eigh(x)
        if k == 1:
            x_sqrt = [email protected](np.sqrt(d))@q.conj().T
            x_isqrt = [email protected](1/np.sqrt(d))@q.conj().T
        else:
            temp = np.zeros(q.shape, dtype=np.complex)
            for i in range(q.shape[0]):
                temp[i, :, :] = np.diag(np.sqrt(d[i, :]))[np.newaxis, :, :]
            x_sqrt = multiprod(multiprod(q, temp), multihconj(q))

            temp = np.zeros(q.shape, dtype=np.complex)
            for i in range(q.shape[0]):
                temp[i, :, :] = np.diag(1/np.sqrt(d[i, :]))[np.newaxis, :, :]
            x_isqrt = multiprod(multiprod(q, temp), multihconj(q))

        d, q = la.eigh(multiprod(multiprod(x_isqrt, u), x_isqrt))
        if k == 1:
            e = [email protected](np.exp(d))@q.conj().T
        else:
            temp = np.zeros(q.shape, dtype=np.complex)
            for i in range(q.shape[0]):
                temp[i, :, :] = np.diag(np.exp(d[i, :]))[np.newaxis, :, :]
            d = temp
            e = multiprod(multiprod(q, d), multihconj(q))

        e = multiprod(multiprod(x_sqrt, e), x_sqrt)
        e = multiherm(e)
        return e
예제 #7
0
 def test_randvec(self):
     # Just test that randvec returns an element of the tangent space
     # with norm 1 and that two randvecs are different.
     man = self.man
     x = man.rand()
     u = man.randvec(x)
     v = man.randvec(x)
     np_testing.assert_allclose(multiherm(u), u)
     np_testing.assert_almost_equal(1, man.norm(x, u))
     assert la.norm(u - v) > 1e-3
예제 #8
0
    def test_proj(self):
        man = self.man
        x = man.rand()
        a = rnd.randn(self.n, self.n)
        +1j * rnd.randn(self.n, self.n)
        p = man.proj(x, a)

        assert np.shape(p) == (self.n, self.n)

        np.testing.assert_allclose(p, multiherm(p))

        t = np.real(np.trace(la.solve(x, p)))
        np_testing.assert_almost_equal(t, 0)

        np.testing.assert_allclose(p, man.proj(x, p))
예제 #9
0
    def proj(self, x, u):
        n = self._n
        k = self._k

        # Project matrix on tangent space of HPD.
        u = multiherm(u)

        # Project on tangent space of SHPD at x.
        t = np.trace(la.solve(x, u), axis1=-2, axis2=-1)
        if k == 1:
            u = u - (1/n) * np.real(t) * x
        else:
            u = u - (1/n) * np.real(t.reshape(-1, 1, 1)) * x

        return u
예제 #10
0
    def test_proj(self):
        man = self.man
        x = man.rand()
        a = rnd.randn(self.k, self.n, self.n)
        +1j * rnd.randn(self.k, self.n, self.n)
        p = man.proj(x, a)

        np.testing.assert_allclose(p, multiherm(p))

        t = np.ones(man._k, dtype=np.complex)
        temp = la.solve(x, p)
        for i in range(man._k):
            t[i] = np.real(np.trace(temp[i, :, :]))
        np_testing.assert_allclose(t, 0, atol=1e-7)

        np.testing.assert_allclose(p, man.proj(x, p))
예제 #11
0
    def test_exp(self):
        # exp(x, u) = x + u.
        man = self.man
        x = man.rand()
        u = man.randvec(x)
        e = man.exp(x, u)

        # Check symmetry
        np_testing.assert_allclose(e, multiherm(e))

        # Check positivity of eigenvalues
        w = la.eigvalsh(e)
        assert (w > [0]).all()

        u = u * 1e-6
        np_testing.assert_allclose(man.exp(x, u), x + u)
예제 #12
0
    def test_rand(self):
        # Just test that rand returns a point on the manifold and two
        # different matrices generated by rand aren't too close together
        n = self.n
        man = self.man
        x = man.rand()

        assert np.shape(x) == (n, n)
        assert x.dtype == np.complex

        # Check symmetry
        np_testing.assert_allclose(x, multiherm(x))

        # Check positivity of eigenvalues
        w = la.eigvalsh(x)
        assert (w > [0]).all()
예제 #13
0
    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 = man.exp(x, u)

        # Check symmetry
        np_testing.assert_allclose(e, multiherm(e))

        # Check positivity of eigenvalues
        w = la.eigvalsh(e)
        assert (w > [[0]]).all()

        u = u * 1e-6
        np_testing.assert_allclose(man.exp(x, u), x + u)
예제 #14
0
    def test_retr(self):
        # Check that result is on manifold and for small vectors
        # retr(x, u) = x + u.
        man = self.man
        x = man.rand()
        u = man.randvec(x)
        y = man.retr(x, u)

        assert np.shape(y) == (self.k, self.n, self.n)
        # Check symmetry
        np_testing.assert_allclose(y, multiherm(y))

        # Check positivity of eigenvalues
        w = la.eigvalsh(y)
        assert (w > [[0]]).all()

        u = u * 1e-6
        np_testing.assert_allclose(man.retr(x, u), x + u)
예제 #15
0
    def test_randvec(self):
        # Just test that randvec returns an element of the tangent space
        # with norm 1 and that two randvecs are different.
        man = self.man
        x = man.rand()
        u = man.randvec(x)
        v = man.randvec(x)

        np_testing.assert_allclose(multiherm(u), u)

        t = np.empty(man._k, dtype=np.complex)
        temp = la.solve(x, u)
        for i in range(man._k):
            t[i] = np.real(np.trace(temp[i, :, :]))
        np_testing.assert_allclose(t, 0, atol=1e-7)

        np_testing.assert_almost_equal(1, man.norm(x, u))

        assert la.norm(u - v) > 1e-3
예제 #16
0
    def test_randvec(self):
        # Just test that randvec returns an element of the tangent space
        # with norm 1 and that two randvecs are different.
        man = self.man
        n = self.n
        man = self.man
        x = man.rand()
        u = man.randvec(x)
        v = man.randvec(x)

        assert np.shape(x) == (n, n)
        assert x.dtype == np.complex

        np_testing.assert_allclose(multiherm(u), u)

        t = np.real(np.trace(la.solve(x, u)))
        np_testing.assert_almost_equal(t, 0)

        np_testing.assert_almost_equal(1, man.norm(x, u))

        assert la.norm(u - v) > 1e-3
예제 #17
0
 def ehess2rhess(self, x, egrad, ehess, u):
     egrad = multiherm(egrad)
     hess = multiprod(multiprod(x, multiherm(ehess)), x)
     hess += multiherm(multiprod(multiprod(u, egrad), x))
     return hess
예제 #18
0
 def egrad2rgrad(self, x, u):
     return multiprod(multiprod(x, multiherm(u)), x)
예제 #19
0
 def proj(self, X, G):
     return multiherm(G)