def test_bug_9793(self, dtype, rand, eps):
     if _IS_32BIT and dtype == np.complex_ and rand:
         pytest.xfail("bug in external fortran code")
     A = np.array(
         [[-1, -1, -1, 0, 0, 0], [0, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0],
          [0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 0, 1]],
         dtype=dtype,
         order="C")
     B = A.copy()
     interp_decomp(A.T, eps, rand=rand)
     assert_array_equal(A, B)
Пример #2
0
    def test_bug_9793(self):
        dtypes = [np.float_, np.complex_]
        rands = [True, False]
        epss = [1, 0.1]

        for dtype, eps, rand in itertools.product(dtypes, epss, rands):
            A = np.array(
                [[-1, -1, -1, 0, 0, 0], [0, 0, 0, 1, 1, 1], [1, 0, 0, 1, 0, 0],
                 [0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 0, 1]],
                dtype=dtype,
                order="C")
            B = A.copy()
            interp_decomp(A.T, eps, rand=rand)
            assert_array_equal(A, B)
    def test_id_to_svd(self, A, eps, rank):
        k = rank

        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        U, S, V = pymatrixid.id_to_svd(A[:, idx[:k]], idx, proj)
        B = U * S @ V.T.conj()
        assert_allclose(A, B, rtol=eps, atol=1e-08)
    def test_real_id_fixed_rank(self, A, L, eps, rank, rand, lin_op):
        if _IS_32BIT and A.dtype == np.complex_ and rand:
            pytest.xfail("bug in external fortran code")
        k = rank
        A_or_L = A if not lin_op else L

        idx, proj = pymatrixid.interp_decomp(A_or_L, k, rand=rand)
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        assert_allclose(A, B, rtol=eps, atol=1e-08)
Пример #5
0
def extract_independent_columns_ID(A, rank):
    if rank == 'randomized_rank':
        rank = compute_rank(A)
    elif rank == 'exact_rank':
        rank = exact_rank(A, eps=10**-5)

    col_idxs, _ = ID.interp_decomp(A, eps_or_k=rank, rand=True)

    return col_idxs[:rank]
Пример #6
0
    def test_full_rank(self):
        eps = 1.0e-12

        # fixed precision
        A = np.random.rand(16, 8)
        k, idx, proj = pymatrixid.interp_decomp(A, eps)
        assert_equal(k, A.shape[1])

        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_allclose(A, B @ P)

        # fixed rank
        idx, proj = pymatrixid.interp_decomp(A, k)

        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_allclose(A, B @ P)
Пример #7
0
    def test_full_rank(self):
        eps = 1.0e-12

        # fixed precision
        A = np.random.rand(16, 8)
        k, idx, proj = pymatrixid.interp_decomp(A, eps)
        assert_(k == A.shape[1])

        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_allclose(A, B.dot(P))

        # fixed rank
        idx, proj = pymatrixid.interp_decomp(A, k)

        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_allclose(A, B.dot(P))
    def test_real_id_skel_and_interp_matrices(self, A, L, eps, rank, rand,
                                              lin_op):
        k = rank
        A_or_L = A if not lin_op else L

        idx, proj = pymatrixid.interp_decomp(A_or_L, k, rand=rand)
        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_allclose(B, A[:, idx[:k]], rtol=eps, atol=1e-08)
        assert_allclose(B @ P, A, rtol=eps, atol=1e-08)
Пример #9
0
def randsvd(A, eps_or_k):
	"""
	Interpolative decomposition computed using randomized SVD approach. It is a 
	wrapper for scipy.linalg.interpolative
	Parameters:
	----------
	eps_or_k : float or int
        	Relative error (if `eps_or_k < 1`) or rank (if `eps_or_k >= 1`) of
        	approximation.

	Returns:
	--------
       	u : {(m, k) } array
        	Unitary matrices. The actual shape depends on the value of
        	``full_matrices``. Only returned when ``compute_uv`` is True.
    	s : (k,) array
        	The singular values for every matrix, sorted in descending order.
    	v : {(n, k) } array
        	Unitary matrices. The actual shape depends on the value of
        	``full_matrices``. Only returned when ``compute_uv`` is True.

	Notes:
	------
		See scipy.linalg.interpolative function interp_decomp, id_to_svd

	"""	

	from scipy.linalg.interpolative import interp_decomp, id_to_svd
	if eps_or_k < 1:
		k, idx, proj = interp_decomp(A, eps_or_k)
		B = A[:,idx[:k]]
	else:
		idx, proj= interp_decomp(A, eps_or_k)
		k = eps_or_k

	B = A[:,idx[:k]]
	u, s, vh = id_to_svd(B, idx, proj)

	return u, s, vh
Пример #10
0
def ID(A, k):
    """
    A_{m,n}=A[:,J] P

    :return P: k by n
    """
    idx, proj = sli.interp_decomp(A, k)
    J = idx[:k]

    kp = np.eye(k)
    if len(proj):
        kp = np.hstack((kp, proj))

    P = kp[:, np.argsort(idx)]
    return J, P
Пример #11
0
    def __row_extraction(self):
        A = self.A
        Q = self.Q

        m, n = A.shape
        m, k = Q.shape
        idx, proj = sli.interp_decomp(Q, k, rand=False)
        Qj = sli.reconstruct_skel_matrix(Q, k, idx)
        X = sli.reconstruct_interp_matrix(idx, proj)
        Qj = Qj.T
        X = X.T
        V, R = linalg.qr(X)
        Ajj = A[np.ix_(idx, idx)]
        Z = np.dot(R, np.dot(Ajj, R))
        w, W = linalg.eig(Z)
        U = np.dot(V, W)
        return w, U
Пример #12
0
    def __row_extraction(self):
        A = self.A
        Q = self.Q

        m, n = A.shape
        m, k = Q.shape
        idx, proj = sli.interp_decomp(Q, k, rand=False)
        Qj = sli.reconstruct_skel_matrix(Q, k, idx)
        X = sli.reconstruct_interp_matrix(idx, proj)
        Qj = Qj.T
        X = X.T
        Aj = A[idx, :]
        W, R = linalg.qr(Aj.T)
        Z = np.dot(X, R.T)
        U, sigma, Vt = linalg.svd(Z)
        V = np.dot(W, Vt.T)
        Vt = V.T
        return U, sigma, Vt
Пример #13
0
    def check_id(self, dtype):
        # Test ID routines on a Hilbert matrix.

        # set parameters
        n = 300
        eps = 1e-12

        # construct Hilbert matrix
        A = hilbert(n).astype(dtype)
        if np.issubdtype(dtype, np.complexfloating):
            A = A * (1 + 1j)
        L = aslinearoperator(A)

        # find rank
        S = np.linalg.svd(A, compute_uv=False)
        try:
            rank = np.nonzero(S < eps)[0][0]
        except:
            rank = n

        # print input summary
        _debug_print("Hilbert matrix dimension:        %8i" % n)
        _debug_print("Working precision:               %8.2e" % eps)
        _debug_print("Rank to working precision:       %8i" % rank)

        # set print format
        fmt = "%8.2e (s) / %5s"

        # test real ID routines
        _debug_print("-----------------------------------------")
        _debug_print("Real ID routines")
        _debug_print("-----------------------------------------")

        # fixed precision
        _debug_print("Calling iddp_id / idzp_id  ...", )
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(A, eps, rand=False)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_aid / idzp_aid ...", )
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(A, eps)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_rid / idzp_rid ...", )
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(L, eps)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # fixed rank
        k = rank

        _debug_print("Calling iddr_id / idzr_id  ...", )
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_aid / idzr_aid ...", )
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(A, k)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_rid / idzr_rid ...", )
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(L, k)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # check skeleton and interpolation matrices
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_(np.allclose(B, A[:, idx[:k]], eps))
        assert_(np.allclose(B.dot(P), A, eps))

        # test SVD routines
        _debug_print("-----------------------------------------")
        _debug_print("SVD routines")
        _debug_print("-----------------------------------------")

        # fixed precision
        _debug_print("Calling iddp_svd / idzp_svd ...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, eps, rand=False)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_asvd / idzp_asvd...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, eps)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_rsvd / idzp_rsvd...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(L, eps)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # fixed rank
        k = rank

        _debug_print("Calling iddr_svd / idzr_svd ...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, k, rand=False)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_asvd / idzr_asvd ...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, k)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_rsvd / idzr_rsvd ...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(L, k)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # ID to SVD
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        Up, Sp, Vp = pymatrixid.id_to_svd(A[:, idx[:k]], idx, proj)
        B = U.dot(np.diag(S).dot(V.T.conj()))
        assert_(np.allclose(A, B, eps))

        # Norm estimates
        s = svdvals(A)
        norm_2_est = pymatrixid.estimate_spectral_norm(A)
        assert_(np.allclose(norm_2_est, s[0], 1e-6))

        B = A.copy()
        B[:, 0] *= 1.2
        s = svdvals(A - B)
        norm_2_est = pymatrixid.estimate_spectral_norm_diff(A, B)
        assert_(np.allclose(norm_2_est, s[0], 1e-6))

        # Rank estimates
        B = np.array([[1, 1, 0], [0, 0, 1], [0, 0, 1]], dtype=dtype)
        for M in [A, B]:
            ML = aslinearoperator(M)

            rank_tol = 1e-9
            rank_np = np.linalg.matrix_rank(M, norm(M, 2) * rank_tol)
            rank_est = pymatrixid.estimate_rank(M, rank_tol)
            rank_est_2 = pymatrixid.estimate_rank(ML, rank_tol)

            assert_(rank_est >= rank_np)
            assert_(rank_est <= rank_np + 10)

            assert_(rank_est_2 >= rank_np - 4)
            assert_(rank_est_2 <= rank_np + 4)
Пример #14
0
def hoid(T, rank=None, eps=None, method='qr', compute_core=True):
    """
	Parameters:
	-----------
	T:	(I_1,...,I_d) dtensor
		object of dtensor class. See scikit.dtensor
	
	rank:	(r_1,...,r_d) int array, optional
		Ranks of the individual modes	

	eps:	float, optional	
		Relative error of the representation

	method:	{'qr','randsvd'} string, optional
		qr uses pivoted QR, 'interpolative' uses scipy.linalg.interpolative
		Uses 'qr' by default
	
	compute_core: bool, optional
		Compute core tensor by projection. True by default

	Returns:
	--------
	T:	object of Tucker class
		G - core, U - list of mode vectors, I - index list. 
		Returned if compute_core = True

	ulst:	list
		List of column vectors. Returned if compute_core = False

	"""

    modes = matricize(T)
    dim = T.ndim

    assert (rank is not None) or (eps is not None)
    if eps is not None: eps_or_k = eps / np.sqrt(dim)

    clst, indlst = [], []
    for d, mode in zip(range(dim), modes):
        if rank is not None: eps_or_k = rank[d]

        if method == 'qr':
            p, _ = id_(mode, eps_or_k)
        elif method == 'rrqr':
            assert eps_or_k >= 1.
            _, _, p = srrqr(mode, eps_or_k)
        elif method == 'rid':
            assert eps_or_k >= 1.
            rpp = mode.shape[0] + 10  #Oversampling factor
            Omega = np.random.randn(rpp, mode.shape[0])
            ind, _ = interp_decomp(np.dot(Omega, mode), eps_or_k, rand=False)
            p = ind[:eps_or_k]
        elif method == 'randsvd':
            assert eps_or_k >= 1.
            k = eps_or_k
            ind, _ = interp_decomp(mode, eps_or_k)
            p = ind[:k]
        else:
            raise NotImplementedError

        c = mode[:, p]
        clst.append(c)
        indlst.append(p)

    #Compute core tensor
    if compute_core:
        cinv = [pinv(c, 1.e-8) for c in clst]
        G = T.ttm(cinv)
        return Tucker(G=G, U=clst, I=indlst)
    else:
        return clst
Пример #15
0
def _remove_redundancy_id(A, rhs, rank=None, randomized=True):
    """Eliminates redundant equations from a system of equations.

    Eliminates redundant equations from system of equations defined by Ax = b
    and identifies infeasibilities.

    Parameters
    ----------
    A : 2-D array
        An array representing the left-hand side of a system of equations
    rhs : 1-D array
        An array representing the right-hand side of a system of equations
    rank : int, optional
        The rank of A
    randomized: bool, optional
        True for randomized interpolative decomposition

    Returns
    -------
    A : 2-D array
        An array representing the left-hand side of a system of equations
    rhs : 1-D array
        An array representing the right-hand side of a system of equations
    status: int
        An integer indicating the status of the system
        0: No infeasibility identified
        2: Trivially infeasible
    message : str
        A string descriptor of the exit status of the optimization.

    """

    status = 0
    message = ""
    inconsistent = ("There is a linear combination of rows of A_eq that "
                    "results in zero, suggesting a redundant constraint. "
                    "However the same linear combination of b_eq is "
                    "nonzero, suggesting that the constraints conflict "
                    "and the problem is infeasible.")

    A, rhs, status, message = _remove_zero_rows(A, rhs)

    if status != 0:
        return A, rhs, status, message

    m, n = A.shape

    k = rank
    if rank is None:
        k = np.linalg.matrix_rank(A)

    idx, proj = interp_decomp(A.T, k, rand=randomized)

    # first k entries in idx are indices of the independent rows
    # remaining entries are the indices of the m-k dependent rows
    # proj provides a linear combinations of rows of A2 that form the
    # remaining m-k (dependent) rows. The same linear combination of entries
    # in rhs2 must give the remaining m-k entries. If not, the system is
    # inconsistent, and the problem is infeasible.
    if not np.allclose(rhs[idx[:k]] @ proj, rhs[idx[k:]]):
        status = 2
        message = inconsistent

    # sort indices because the other redundancy removal routines leave rows
    # in original order and tests were written with that in mind
    idx = sorted(idx[:k])
    A2 = A[idx, :]
    rhs2 = rhs[idx]
    return A2, rhs2, status, message
Пример #16
0
def IDLeft(matrix, rank, random=True):
    idx, proj = sli.interp_decomp(matrix, rank, rand=random)
    Askel = sli.reconstruct_skel_matrix(matrix, rank, idx)
    return Askel
Пример #17
0
 def test_badcall(self):
     A = hilbert(5).astype(np.float32)
     with assert_raises(ValueError):
         pymatrixid.interp_decomp(A, 1e-6, rand=False)
Пример #18
0
    def check_id(self, dtype):
        # Test ID routines on a Hilbert matrix.

        # set parameters
        n = 300
        eps = 1e-12

        # construct Hilbert matrix
        A = hilbert(n).astype(dtype)
        if np.issubdtype(dtype, np.complexfloating):
            A = A * (1 + 1j)
        L = aslinearoperator(A)

        # find rank
        S = np.linalg.svd(A, compute_uv=False)
        try:
            rank = np.nonzero(S < eps)[0][0]
        except:
            rank = n

        # print input summary
        _debug_print("Hilbert matrix dimension:        %8i" % n)
        _debug_print("Working precision:               %8.2e" % eps)
        _debug_print("Rank to working precision:       %8i" % rank)

        # set print format
        fmt = "%8.2e (s) / %5s"

        # test real ID routines
        _debug_print("-----------------------------------------")
        _debug_print("Real ID routines")
        _debug_print("-----------------------------------------")

        # fixed precision
        _debug_print("Calling iddp_id / idzp_id  ...",)
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(A, eps, rand=False)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_aid / idzp_aid ...",)
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(A, eps)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_rid / idzp_rid ...",)
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(L, eps)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # fixed rank
        k = rank

        _debug_print("Calling iddr_id / idzr_id  ...",)
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_aid / idzr_aid ...",)
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(A, k)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_rid / idzr_rid ...",)
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(L, k)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # check skeleton and interpolation matrices
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_(np.allclose(B, A[:,idx[:k]], eps))
        assert_(np.allclose(B.dot(P), A, eps))

        # test SVD routines
        _debug_print("-----------------------------------------")
        _debug_print("SVD routines")
        _debug_print("-----------------------------------------")

        # fixed precision
        _debug_print("Calling iddp_svd / idzp_svd ...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, eps, rand=False)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_asvd / idzp_asvd...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, eps)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_rsvd / idzp_rsvd...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(L, eps)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # fixed rank
        k = rank

        _debug_print("Calling iddr_svd / idzr_svd ...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, k, rand=False)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_asvd / idzr_asvd ...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, k)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_rsvd / idzr_rsvd ...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(L, k)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # ID to SVD
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        Up, Sp, Vp = pymatrixid.id_to_svd(A[:, idx[:k]], idx, proj)
        B = U.dot(np.diag(S).dot(V.T.conj()))
        assert_(np.allclose(A, B, eps))

        # Norm estimates
        s = svdvals(A)
        norm_2_est = pymatrixid.estimate_spectral_norm(A)
        assert_(np.allclose(norm_2_est, s[0], 1e-6))

        B = A.copy()
        B[:,0] *= 1.2
        s = svdvals(A - B)
        norm_2_est = pymatrixid.estimate_spectral_norm_diff(A, B)
        assert_(np.allclose(norm_2_est, s[0], 1e-6))

        # Rank estimates
        B = np.array([[1, 1, 0], [0, 0, 1], [0, 0, 1]], dtype=dtype)
        for M in [A, B]:
            ML = aslinearoperator(M)

            rank_np = np.linalg.matrix_rank(M, 1e-9)
            rank_est = pymatrixid.estimate_rank(M, 1e-9)
            rank_est_2 = pymatrixid.estimate_rank(ML, 1e-9)

            assert_(rank_est >= rank_np)
            assert_(rank_est <= rank_np + 10)

            assert_(rank_est_2 >= rank_np)
            assert_(rank_est_2 <= rank_np + 10)
Пример #19
0
def imd(collection: Collection, taglist: List[str]=['all'],
                region: str='xanes', range: list=[-inf,inf], 
                eps: float=1e-4, kweight: int=2) -> Dataset:
    """Computes the interpolative matrix decomposition for a collection.

    Parameters
    ----------
    collection
        Collection with the groups to compute the rank.
    taglist
        List with keys to filter groups based on their ``tags``
        attributes in the Collection.
        The default is ['all'].
    region
        XAFS region to compute the rank. Accepted values are 'dxanes',
        'xanes', or 'exafs'. The default is 'xanes'.
    range
        Domain range in absolute values. Energy units are expected
        for 'dxanes' or 'xanes', while wavenumber (k) units are expected 
        for 'exafs'.
        The default is [-:data:`~numpy.inf`, :data:`~numpy.inf`].
    eps
        Relative error of approximation.
        The default is 1e-4.
    kweight
        Exponent for weighting chi(k) by k^kweight.
        Only valid for ``region='exafs'``.
        The default is 2.

    Returns
    -------
    :
        Dataset with the following arguments:

        - ``rank``         : matrix rank.
        - ``idx``          : column index array.
        - ``proj``         : interpolation coefficients.
        - ``groupnames``   : list with names of groups.
        - ``energy``       : array with energy values. Returned only if
          ``region='xanes`` or ``region=dxanes``.
        - ``k``            : array with wavenumber values. Returned only if
          ``region='exafs'``.
        - ``matrix``       : array with observed values for groups in ``range``.
        - ``id_pars``      : dictionary with parameters of calculation.

    Notes
    -----
    The interpolative decomposition (ID) of a :math:`m` by :math:`n` 
    matrix :math:`A` of rank :math:`k < min\{m,n\}` is a factorization 
    of the following form,

    .. math::

       A\Pi = [A\Pi_1 \quad A\Pi_2 ] = A \Pi_1 [I \quad T]
    
    where :math:`\Pi = [\Pi_1 \quad \Pi_2]` is a permutation matrix, 
    with :math:`\Pi_1` being a :math:`k` by :math:`n` matrix.
    
    The latter can be equivalently written as :math:`A = BP`, where :math:`B`
    is known as the *skeleton matrix*, while :math:`P` is known as the 
    *interpolation matrix*.

    Therefore, the original matrix can be factorized into an skeleton matrix that
    preserves the original matrix rank, while the rest of the original matrix can 
    be reconstructed through the interpolation matrix.

    Computation of the interpolative decompsition method is performed with the
    :func:`~scipy.linalg.interpolative.interp_decomp` function of ``scipy``, which is
    based on the ID software package [2]_. Therefore, the *skeleton matrix* can be 
    computed as follows::
    
        B = A[:,idx[:rank]]

    while the *interpolation matrix* can be computed as follows::
    
        P = numpy.hstack([numpy.eye(rank), proj])[:, np.argsort(idx)]

    References
    ----------
     .. [2] P.G. Martinsson, V. Rokhlin, Y. Shkolnisky, M. Tygert. 
        “ID: a software package for low-rank approximation of matrices via interpolative 
        decompositions, version 0.2.” http://tygert.com/id_doc.4.pdf.

    Example
    -------
    >>> from araucaria.testdata import get_testpath
    >>> from araucaria import Dataset
    >>> from araucaria.xas import pre_edge, autobk
    >>> from araucaria.linalg import imd
    >>> from araucaria.io import read_collection_hdf5
    >>> from araucaria.utils import check_objattrs
    >>> fpath      = get_testpath('Fe_database.h5')
    >>> collection = read_collection_hdf5(fpath)
    >>> collection.apply(pre_edge)
    >>> out        = imd(collection, region='xanes')
    >>> attrs      = ['groupnames', 'energy', 'matrix', 'rank', 'idx', 'proj', 'id_pars']
    >>> check_objattrs(out, Dataset, attrs)
    [True, True, True, True, True, True, True]
    >>> print(out.idx)
    [0 1 3 2]
    """
    xvals, matrix = get_mapped_data(collection, taglist=taglist, region=region, 
                                    range=range, kweight=kweight)

    # condtion number
    rnk, idx, proj = interp_decomp(matrix, eps_or_k=eps)

    # storing parameters
    id_pars = {'region' : region, 
               'range'  : range,
               'eps'    : eps,}

    # additional parameters
    if region == 'exafs':
        xvar  = 'k'    # x-variable
        rank_pars['kweight'] = kweight
    else:
        # xanes/dxanes clustering
        xvar  = 'energy'    # x-variable

    # storing cluster results
    content = {'groupnames' : collection.get_names(taglist=taglist),
               xvar         : xvals,
               'matrix'     : matrix,
               'rank'       : rnk,
               'idx'        : idx,
               'proj'       : proj,
               'id_pars'    : id_pars,}

    out = Dataset(**content)
    return out
Пример #20
0
import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt

n = 100
A0 = np.random.randn(n, n)
U0, sigma0, VT0 = la.svd(A0)
print(la.norm((U0 * sigma0).dot(VT0) - A0))

sigma = np.exp(-np.arange(n))

A = (U0 * sigma).dot(VT0)
print("A:{}".format(A.shape))
plt.semilogy(sigma)

import scipy.linalg.interpolative as sli

k = 20
idx, proj = sli.interp_decomp(A, k)
print("idx:{}".format(idx.shape))
print("proj:{}".format(proj.shape))
sort_idx = np.argsort(idx)

B = A[:, idx[:k]]
P = np.hstack([np.eye(k), proj])[:, np.argsort(idx)]
print("B:{}".format(B.shape))
print("P:{}".format(P.shape))
Aapprox = np.dot(B, P)
print("norm:{}".format(la.norm(A - Aapprox, 2)))
Пример #21
0
def hoid(T, rank = None, eps = None, method = 'qr', compute_core = True):
	"""
	Parameters:
	-----------
	T:	(I_1,...,I_d) dtensor
		object of dtensor class. See scikit.dtensor
	
	rank:	(r_1,...,r_d) int array, optional
		Ranks of the individual modes	

	eps:	float, optional	
		Relative error of the representation

	method:	{'qr','randsvd'} string, optional
		qr uses pivoted QR, 'interpolative' uses scipy.linalg.interpolative
		Uses 'qr' by default
	
	compute_core: bool, optional
		Compute core tensor by projection. True by default

	Returns:
	--------
	T:	object of Tucker class
		G - core, U - list of mode vectors, I - index list. 
		Returned if compute_core = True

	ulst:	list
		List of column vectors. Returned if compute_core = False

	"""

	modes = matricize(T)
	dim   = T.ndim

	assert (rank is not None) or (eps is not None)
	if eps is not None: eps_or_k = eps/np.sqrt(dim)
	
	clst, indlst = [], []
	for d, mode in zip(range(dim), modes):
		if rank is not None:	eps_or_k = rank[d]
		
		if method == 'qr':
			p, _ = id_(mode, eps_or_k)
		elif method == 'rrqr':
			assert eps_or_k >= 1.
			_,_,p = srrqr(mode, eps_or_k)
		elif method == 'rid':
			assert eps_or_k >= 1.
			rpp = mode.shape[0] + 10	#Oversampling factor
			Omega = np.random.randn(rpp,mode.shape[0])
			ind, _ = interp_decomp(np.dot(Omega,mode), eps_or_k, rand = False)
			p = ind[:eps_or_k]
		elif method == 'randsvd':
			assert eps_or_k >= 1.
			k = eps_or_k
			ind, _ = interp_decomp(mode, eps_or_k)
			p = ind[:k]
		else:
			raise NotImplementedError
			
		c = mode[:, p]
		clst.append(c)
		indlst.append(p)

	#Compute core tensor
	if compute_core:
		cinv = [pinv(c, 1.e-8) for c in clst]
		G = T.ttm(cinv)
		return Tucker(G = G, U = clst, I = indlst)
	else:
		return clst