Esempio n. 1
0
    def test_multiqr(self):
        shape = (self.k, self.m, self.m)
        A_real = np.random.normal(size=shape)
        q, r = multiqr(A_real)
        np_testing.assert_allclose(q @ r, A_real)

        A_complex = np.random.normal(
            size=shape) + 1j * np.random.normal(size=shape)
        q, r = multiqr(A_complex)
        np_testing.assert_allclose(q @ r, A_complex)
Esempio n. 2
0
 def random_point(self):
     q, _ = multiqr(
         np.random.normal(size=(self._k, self._n, self._p)) +
         1j * np.random.normal(size=(self._k, self._n, self._p)))
     if self._k == 1:
         return q[0]
     return q
Esempio n. 3
0
    def exp(self, point, tangent_vector):
        U, S, VH = np.linalg.svd(tangent_vector, full_matrices=False)
        cos_S = np.expand_dims(np.cos(S), -2)
        sin_S = np.expand_dims(np.sin(S), -2)
        Y = point @ (multihconj(VH) * cos_S) @ VH + (U * sin_S) @ VH

        # From numerical experiments, it seems necessary to
        # re-orthonormalize. This is overall quite expensive.
        q, _ = multiqr(Y)
        return q
Esempio n. 4
0
    def random_point(self):
        # Generate eigenvalues between 1 and 2.
        d = 1.0 + np.random.uniform(size=(self._k, self._n, 1))

        # Generate an orthogonal matrix.
        q, _ = multiqr(np.random.normal(size=(self._n, self._n)))
        point = q @ (d * multitransp(q))
        if self._k == 1:
            return point[0]
        return point
Esempio n. 5
0
    def exp(self, point, tangent_vector):
        u, s, vt = np.linalg.svd(tangent_vector, full_matrices=False)
        cos_s = np.expand_dims(np.cos(s), -2)
        sin_s = np.expand_dims(np.sin(s), -2)

        Y = point @ (multitransp(vt) * cos_s) @ vt + (u * sin_s) @ vt

        # From numerical experiments, it seems necessary to re-orthonormalize.
        # This is quite expensive.
        q, _ = multiqr(Y)
        return q
Esempio n. 6
0
 def random_point(self):
     n, k = self._n, self._k
     if n == 1:
         point = np.ones((k, 1, 1))
     else:
         point, _ = multiqr(np.random.normal(size=(k, n, n)))
         # Swap the first two columns of matrices where det(point) < 0 to
         # flip the sign of their determinants.
         negative_det, *_ = np.where(np.linalg.det(point) < 0)
         slice_ = np.arange(point.shape[1])
         point[np.ix_(negative_det, slice_,
                      [0, 1])] = point[np.ix_(negative_det, slice_, [1, 0])]
     if k == 1:
         return point[0]
     return point
Esempio n. 7
0
 def _retraction_qr(self, point, tangent_vector):
     a = point + tangent_vector
     point, _ = multiqr(a)
     return point
Esempio n. 8
0
 def random_point(self):
     point, _ = multiqr(np.random.normal(size=(self._k, self._n, self._p)))
     if self._k == 1:
         return point[0]
     return point
Esempio n. 9
0
 def _retraction_qr(self, point, tangent_vector):
     Y = point + point @ tangent_vector
     q, _ = multiqr(Y)
     return q