コード例 #1
0
ファイル: test_gsvd.py プロジェクト: bnaecker/pygsvd
def test_dimensions():
    '''Verify that the input succeeds with 1D arrays (which are promoted
    to 2D), and raises a ValueError for 3+D arrays.
    '''
    x = np.arange(10)
    pygsvd.gsvd(x, x)
    with pytest.raises(ValueError):
        pygsvd.gsvd(x.reshape(5, 2, 1), x.reshape(5, 2, 1))
コード例 #2
0
	def construct_geodesic_flow(self, P_s, P_t):

		dims = P_s.shape[1]
		R_s = null_space(P_s.T)
		N = dims + R_s.shape[1]

		#print(P_s.shape)
		#print(P_t.shape)
		#print(R_s.shape)

		A = np.matmul(P_s.T, P_t)
		B = np.matmul(R_s.T, P_t)

		
		Gam, Sig, V, U1, U2 = pygsvd.gsvd(A, B)
		U2 = -U2
		#print(Gam.shape)
		#print(Sig.shape)
		#print(V.shape)
		#print(U1.shape)
		#print(U2.shape)		

		theta = np.arccos(Gam)
		
		L1 = np.diag(0.5*(1 + (np.sin(2 * theta)/(2 * np.maximum(theta, self.eps)))))
		L2 = np.diag(0.5*((np.cos(2 * theta) - 1)/(2 * np.maximum(theta, self.eps))))
		L3 = L2
		L4 = np.diag(0.5*(1 - (np.sin(2 * theta)/(2 * np.maximum(theta, self.eps)))))

		print(L1.shape)
		print(L2.shape)
		print(L3.shape)
		'''
		omega1_1 = np.hstack([U1, np.zeros(shape=(dims, N-dims))])
		omega1_2 = np.hstack((np.zeros(shape=(N-dims, dims)), U2))
		omega1 = np.vstack([omega1_1, omega1_2])

		
		omega2_1 = np.hstack((L1, L2, np.zeros(shape=(dims, N-2*dims))))
		omega2_2 = np.hstack((L3, L4, np.zeros(shape=(dims, N-2*dims))))
		omega2_3 = np.zeros(shape=(N-2*dims, N))
		omega2 = np.vstack([omega2_1, omega2_2, omega2_3])
		'''
		omega1_1 = np.hstack([U1, np.zeros(shape=(dims, dims))])
		omega1_2 = np.hstack((np.zeros(shape=(N-dims, dims)), U2))
		omega1 = np.vstack([omega1_1, omega1_2])

		
		omega2_1 = np.hstack([L1, L2])
		omega2_2 = np.hstack([L2, L4])
		
		omega2 = np.vstack([omega2_1, omega2_2])

	
		omega3 = omega1.T

		omega = np.dot(np.dot(omega1, omega2), omega3)
		PR_s = np.hstack([P_s, R_s])
		self.G_ = np.dot(np.dot(PR_s, omega), PR_s.T)
		print(self.G_.shape)
コード例 #3
0
def test_nonsquare_matrices_p_lt_n_m():
    '''Test that the correctness of the routine on non-square matrices
       a (mxn) and b (pxn), with p < n < m, where a has full column rank
       b has full row rank and m + p > n.

    This verifies that the returned matrices have the expected
    values, but only up to the number of columns in the inputs.
    The remaining columns are neither constrained nor relevant.
    It also verifies the reconstruction
    '''
    matrices = _load_matrices('nonsquare3')
    outputs = pygsvd.gsvd(matrices[0], matrices[1],
                          full_matrices=True, extras='uv')
    m, n = matrices[0].shape
    p = matrices[1].shape[0]
    c, s, x, u, v = outputs
    for xin, xout in zip(matrices[2:4], (c, s)):
        assert np.allclose(np.abs(xin), np.abs(xout))
    for xin, xout in zip(matrices[4:], (x, u, v)):
        assert np.allclose(np.abs(xin[:, :n]),
                           np.abs(xout[:, :n]))
    # Form matrices for c and s so we can reconstruct a and b
    cc = np.diag(c)
    ss = np.zeros((p, n))
    ss[:, n-p:] = np.diag(s[n-p:])
    assert np.allclose(u.dot(cc).dot(x.T), matrices[0])
    assert np.allclose(v.dot(ss).dot(x.T), matrices[1])
コード例 #4
0
 def check_case(full_matrices=False):
     """
     Checks a single case
     """
     C, S, X, U, V = gsvd(A, B, X1=True, full_matrices=True)
     assert matrix_rank(B) == s.l, msg
     assert matrix_rank(vstack((A, B))) == s.r, msg
     assert s.q == s.m + s.p, msg
     if full_matrices == True:
         assert matrix_rank(X) == s.n, msg
     CC = U.T.dot(A).dot(X)
     if s.m < s.r:
         CCd = zeros(s.r)
         CCd[:s.m] = diag(CC)
     else:
         CCd = diag(CC)
         CCd = CCd[:s.r]
     assert CCd.shape == C.shape, msg
     assert allclose(CCd, C), msg
     SS = V.T.dot(B).dot(X)
     k = s.r - s.l
     if k > 0 and s.p < s.r:
         SSd1 = diag(SS, k)
         SSd = zeros(s.r)
         SSd[k:] = SSd1[:s.r - k]
     else:
         SSd = diag(SS)
         SSd = SSd[:s.r]
     assert SSd.shape == S.shape, msg
     assert allclose(SSd, S), msg
コード例 #5
0
def test_large_matrices():
    '''Test the correctness of the routine on larger matrices.'''
    matrices = _load_matrices('large')
    c, s, x, u, v = pygsvd.gsvd(matrices[0], matrices[1],
                                full_matrices=True, extras='uv')
    assert np.allclose(u.dot(np.diag(c)).dot(x.T), matrices[0])
    assert np.allclose(v.dot(np.diag(s)).dot(x.T), matrices[1])
コード例 #6
0
def test_nonsquare_matrices_p_lt_n_eq_m():
    '''Test that the correctness of the routine on non-square matrices
       a (mxn) and b (pxn), with p < n = m, where a has full column rank
       b has full row rank.

    This verifies that the returned matrices have the expected
    values, but only up to the number of columns in the inputs.
    The remaining columns are neither constrained nor relevant.
    It also verifies the reconstruction
    '''
    n = 22
    L = .45
    power = 10
    c = np.zeros(n)
    c[:2] = [1-2*L, L]
    d = np.ones(n)
    a = np.diag(d*(1-2*L)) + np.diag(d[:-1]*L, 1) + np.diag(d[:-1]*L, -1)
    a = la.matrix_power(a, power)  # n x n blur array
    o = np.ones(n)
    b = (np.zeros((n, n)) - np.diag(o) + np.diag(o[:n-1], 1))[:n-1, :]
    outputs = pygsvd.gsvd(a, b,
                          full_matrices=True, extras='uv')
    m, n = a.shape
    p = b.shape[0]
    c, s, x, u, v = outputs
    # Form matrices for c and s so we can reconstruct a and b
    cc = np.ones(n)
    cc[n-p:] = c[1:]
    cc = np.diag(cc)
    ss = np.zeros((p, n))
    ss[:, n-p:] = np.diag(s[1:])
    assert np.allclose(u.dot(cc).dot(x.T), a)
    assert np.allclose(v.dot(ss).dot(x.T), b)
コード例 #7
0
ファイル: test_gsvd.py プロジェクト: bnaecker/pygsvd
def test_non_full_matrices():
    '''Verify that the kwarg to return the "economy" decomposition works.

    This option allows returning the matrices of singular vectors only
    up to the actual numerical rank of the inputs, rather than the
    full square matrices.
    '''
    a, b = _load_matrices('nonsquare')[:2]
    c, s, x, u, v = pygsvd.gsvd(a, b, full_matrices=True, extras='uv')
    assert x.shape == (a.shape[1], a.shape[1])
    assert u.shape == (a.shape[0], a.shape[0])
    assert v.shape == (b.shape[0], b.shape[0])

    c, s, x, u, v = pygsvd.gsvd(a, b, extras='uv')
    assert x.shape == (a.shape[1], a.shape[1])
    assert u.shape == (a.shape[0], a.shape[1])
    assert v.shape == (b.shape[0], b.shape[1])
コード例 #8
0
ファイル: test_gsvd.py プロジェクト: bnaecker/pygsvd
def test_dtype_promotion():
    '''Verify that the routine handles inputs of non-double type correctly.

    Any real-valued non-double inputs (integer, float32) should be promoted
    to doubles.
    '''
    a, b = _load_matrices('square')[:2]
    dtypes = (np.int16, np.int32, np.int64, np.float32)
    for dtype in dtypes:
        outputs = pygsvd.gsvd(a.astype(dtype), b.astype(dtype))
        for out in outputs:
            assert out.dtype == np.double
コード例 #9
0
def test_A_short_B_square():
    '''Test the case: bnaeker/pygsvd - issue #5
       opened on Nov 13, 2018
       where ``a`` is a short matrix and ``b`` is square
    '''
    m, n, p = 4, 15, 15
    a = np.random.poisson(1, (m, n))
    b = np.random.poisson(1, (p, n))
    C, S, X, U, V = pygsvd.gsvd(a, b, extras='uv')
    CC = np.zeros((m, n))
    CC[:, :m] = np.diag(C[:m])

    assert np.allclose(U.dot(CC).dot(X.T), a)
    assert np.allclose(V.dot(np.diag(S)).dot(X.T), b)
コード例 #10
0
def test_rank_deficient_matrices():
    '''Test the correctness of the routine when using rank-deficient matrices.

    In this case, the return matrix ``V`` is treated differently. As some
    of the first columns are irrelevant, the sorting of ``V`` applies only
    to the trailing columns.
    '''
    matrices = _load_matrices('rank-deficient')
    outputs = pygsvd.gsvd(matrices[0], matrices[1],
                          full_matrices=True, extras='uv')
    for xin, xout in zip(matrices[2:], outputs):
        assert np.allclose(np.abs(xin), np.abs(xout))
    c, s, x, u, v = outputs
    assert np.allclose(u.dot(np.diag(c)).dot(x.T), matrices[0])
    assert np.allclose(v.dot(np.diag(s)).dot(x.T), matrices[1])
コード例 #11
0
def test_square_matrices():
    '''Test that the correctness of the routine on square matrices.

    This verifies that the returned matrices have the expected
    values, and that the original matrices can be reconstructed
    from them.
    '''
    matrices = _load_matrices('square')
    outputs = pygsvd.gsvd(matrices[0], matrices[1],
                          full_matrices=True, extras='uv')
    for xin, xout in zip(matrices[2:], outputs):
        assert np.allclose(np.abs(xin), np.abs(xout))
    c, s, x, u, v = outputs
    assert np.allclose(u.dot(np.diag(c)).dot(x.T), matrices[0])
    assert np.allclose(v.dot(np.diag(s)).dot(x.T), matrices[1])
コード例 #12
0
ファイル: test_gsvd.py プロジェクト: bnaecker/pygsvd
def test_complex():
    '''Verify that the routine handles complex inputs correctly.

    If either one of the arrays is complex, the complex version of the
    LAPACK routine should be called (zggsvd3). The returns singular
    values are always real, but the returned matrices should be complex
    as well.
    '''
    a = np.loadtxt('square/a.txt')
    b = np.loadtxt('square/b.txt').astype(np.complex)
    c, s, x, u, v = pygsvd.gsvd(a, b, full_matrices=True, extras='uv')
    assert c.dtype == np.double  # Singular values are always real
    assert s.dtype == np.double  # Singular values are always real
    for matrix in (x, u, v):
        assert np.iscomplexobj(matrix)
    assert np.allclose(u.dot(np.diag(c)).dot(x.T.conj()), a)
    assert np.allclose(v.dot(np.diag(s)).dot(x.T.conj()), b)
コード例 #13
0
def test_complex_X1():
    '''Verify that the routine handles complex inputs correctly.

    If either one of the arrays is complex, the complex version of the
    LAPACK routine should be called (zggsvd3). The returns singular
    values are always real, but the returned matrices should be complex
    as well.
    '''
    path = os.path.join(os.path.dirname(__file__), 'square/{}.txt')
    a = np.loadtxt(path.format('a'))
    b = np.loadtxt(path.format('b')).astype(np.complex)
    c, s, x, u, v = pygsvd.gsvd(a, b, full_matrices=True, extras='uv', X1=True)
    assert c.dtype == np.double  # Singular values are always real
    assert s.dtype == np.double  # Singular values are always real
    for matrix in (x, u, v):
        assert np.iscomplexobj(matrix)

    assert np.allclose(u.T.dot(a).dot(x), np.diag(c).astype(np.complex))
    assert np.allclose(v.T.dot(b).dot(x), np.diag(s).astype(np.complex))
コード例 #14
0
def test_nonsquare_matrices():
    '''Test that the correctness of the routine on non-square matrices.

    This verifies that the returned matrices have the expected
    values, but only up to the number of columns in the inputs.
    The remaining columns are neither constrained nor relevant.
    It also verifies the reconstruction
    '''
    matrices = _load_matrices('nonsquare')
    outputs = pygsvd.gsvd(matrices[0], matrices[1],
                          full_matrices=True, extras='uv')
    max_size = matrices[0].shape[1]
    c, s, x, u, v = outputs
    for xin, xout in zip(matrices[2:4], (c, s)):
        assert np.allclose(np.abs(xin), np.abs(xout))
    for xin, xout in zip(matrices[4:], (x, u, v)):
        assert np.allclose(np.abs(xin[:, :max_size]),
                           np.abs(xout[:, :max_size]))
    assert np.allclose(u[:, :max_size].dot(np.diag(c)).dot(x.T), matrices[0])
    assert np.allclose(v[:, :max_size].dot(np.diag(s)).dot(x.T), matrices[1])
コード例 #15
0
ファイル: test_gsvd.py プロジェクト: bnaecker/pygsvd
def test_return_extras():
    '''Verify that the extra arrays are returned as expected.'''
    names = ('a', 'b', 'c', 's', 'x', 'u', 'v')
    matrices = dict(
        zip(names,
            map(np.loadtxt, ('square/{}.txt'.format(name) for name in names))))
    extras = 'uv'

    # Make all combinations of 'uv' of length 0 through 3, inclusive
    for combo_length in range(len(extras) + 1):
        combinations = list(itertools.combinations(extras, combo_length))

        for combo in combinations:
            # Join the combination letters to make the `extra` kwarg
            ex = ''.join(combo)

            # Compute GSVD including the extras, assigned to a dict
            out = dict(
                zip(('c', 's', 'r') + combo,
                    pygsvd.gsvd(matrices['a'], matrices['b'], extras=ex)))

            # Compare each extra output to the expected
            for each in combo:
                assert np.allclose(np.abs(out[each]), np.abs(matrices[each]))
コード例 #16
0
ファイル: test_gsvd.py プロジェクト: bnaecker/pygsvd
def test_same_columns():
    '''Verify that the method raises a ValueError when the inputs
    have a different number of columns.
    '''
    with pytest.raises(ValueError):
        pygsvd.gsvd(np.arange(10).reshape(5, 2), np.arange(10).reshape(2, 5))