コード例 #1
0
ファイル: test_la.py プロジェクト: solomonik/ctf
    def test_svd(self):
        m = 9
        n = 5
        k = 5
        for dt in [numpy.float32, numpy.float64]:
            A = ctf.random.random((m,n))
            A = ctf.astensor(A,dtype=dt)
            [U,S,VT]=ctf.svd(A,k)
            [U1,S1,VT1]=la.svd(ctf.to_nparray(A),full_matrices=False)
            self.assertTrue(allclose(A, ctf.dot(U,ctf.dot(ctf.diag(S),VT))))
            self.assertTrue(allclose(ctf.eye(k), ctf.dot(U.T(), U)))
            self.assertTrue(allclose(ctf.eye(k), ctf.dot(VT, VT.T())))

        A = ctf.tensor((m,n),dtype=numpy.complex64)
        rA = ctf.tensor((m,n),dtype=numpy.float32)
        rA.fill_random()
        A.real(rA)
        iA = ctf.tensor((m,n),dtype=numpy.float32)
        iA.fill_random()
        A.imag(iA)

        [U,S,VT]=ctf.svd(A,k)
        self.assertTrue(allclose(A, ctf.dot(U,ctf.dot(ctf.diag(S),VT))))

        self.assertTrue(allclose(ctf.eye(k,dtype=numpy.complex64), ctf.dot(ctf.conj(U.T()), U)))
        self.assertTrue(allclose(ctf.eye(k,dtype=numpy.complex64), ctf.dot(VT, ctf.conj(VT.T()))))

        A = ctf.tensor((m,n),dtype=numpy.complex128)
        rA = ctf.tensor((m,n),dtype=numpy.float64)
        rA.fill_random()
        A.real(rA)
        iA = ctf.tensor((m,n),dtype=numpy.float64)
        iA.fill_random()
        A.imag(iA)

        [U,S,VT]=ctf.svd(A,k)
        self.assertTrue(allclose(A, ctf.dot(U,ctf.dot(ctf.diag(S),VT))))
        self.assertTrue(allclose(ctf.eye(k,dtype=numpy.complex128), ctf.dot(ctf.conj(U.T()), U)))
        self.assertTrue(allclose(ctf.eye(k,dtype=numpy.complex128), ctf.dot(VT, ctf.conj(VT.T()))))
コード例 #2
0
 def test_svd(self):
     m = 9
     n = 5
     k = 5
     for dt in [
             numpy.float32, numpy.float64, numpy.complex64, numpy.complex128
     ]:
         A = ctf.random.random((m, n))
         A = ctf.astensor(A, dtype=dt)
         [U, S, VT] = ctf.svd(A, k)
         [U1, S1, VT1] = la.svd(ctf.to_nparray(A), full_matrices=False)
         self.assertTrue(allclose(A, ctf.dot(U, ctf.dot(ctf.diag(S), VT))))
         self.assertTrue(allclose(ctf.eye(k), ctf.dot(U.T(), U)))
         self.assertTrue(allclose(ctf.eye(k), ctf.dot(VT, VT.T())))
コード例 #3
0
def einsvd(einstr,
           A,
           r=None,
           transpose=True,
           compute_uv=True,
           full_matrices=True,
           mult_sv=False):
    str_a, str_uv = einstr.split("->")
    str_u, str_v = str_uv.split(",")
    U, S, Vh = A.i(str_a).svd(str_u, str_v, rank=r)
    if not compute_uv:
        return S
    if mult_sv:
        char_i = list(set(str_v) - set(str_a))[0]
        char_s = list(set(str_a) - set(str_v))[0]
        Vh = ctf.einsum(
            char_s + char_i + "," + str_v + "->" +
            str_v.replace(char_i, char_s), ctf.diag(S), Vh)
    if not transpose:
        Vh = Vh.T
    return U, S, Vh
コード例 #4
0
ファイル: test_base.py プロジェクト: solomonik/ctf
 def test_diag(self):
     a0 = ctf.astensor(numpy.arange(9).reshape(3,3))
     a1 = a0.diagonal()
     self.assertTrue(ctf.all(a1 == ctf.diag(a0)))
     self.assertTrue(ctf.all(ctf.diag(a1) == numpy.diag(numpy.arange(9).reshape(3,3).diagonal())))
コード例 #5
0
 def test_diag(self):
     a0 = ctf.astensor(numpy.arange(9).reshape(3,3))
     a1 = a0.diagonal()
     self.assertTrue(ctf.all(a1 == ctf.diag(a0)))
     self.assertTrue(ctf.all(ctf.diag(a1) == numpy.diag(numpy.arange(9).reshape(3,3).diagonal())))
コード例 #6
0
def diag(v):
    return ctf.diag(v)
コード例 #7
0
ファイル: test_svd.py プロジェクト: yuzhiliu/ctf
#!/usr/bin/env python

import ctf
import sys

from ctf import random

A = ctf.random.random((32,32))

[U,S,VT]=ctf.svd(A)

err = A-ctf.dot(U,ctf.dot(ctf.diag(S),VT))

success=True

err_nrm = err.norm2()
if err_nrm > 1.E-6:
  success=False

if ctf.comm().rank() == 0:
    if success:
      print("success, norm is ", err_nrm)
    else:
      print("failure, norm is ", err_nrm)

ctf.MPI_Stop()
sys.exit(not success)

コード例 #8
0
ファイル: test_svd.py プロジェクト: alejandrogallo/ctf
#!/usr/bin/env python

import ctf

from ctf import random

A = ctf.random.random((32,32))

[U,S,VT]=ctf.svd(A)

err = A-ctf.dot(U,ctf.dot(ctf.diag(S),VT))

success=True

err_nrm = err.norm2()
if err_nrm > 1.E-6:
  success=False

if ctf.comm().rank() == 0:
    if success:
      print("success, norm is ", err_nrm)
    else:
      print("failure, norm is ", err_nrm)

ctf.MPI_Stop()

コード例 #9
0
 def inv(matrix):
     U, s, V = ctf.svd(matrix)
     return ctf.dot(ctf.transpose(V),
                    ctf.dot(ctf.diag(s**-1), ctf.transpose(U)))
コード例 #10
0
def einsvd(einstr,
           A,
           rank=None,
           threshold=None,
           size_limit=None,
           criterion=None,
           mult_s=True):
    """
    Perform Singular Value Decomposition according to the specified Einstein notation string. 
    Will always preserve at least one singular value during the truncation.

    Parameters
    ----------
    einstr: str
        A string of Einstein notations in the form of 'idxofA->idxofU,idxofV'. There must be one and only one contraction index.

    A: tensor_like
        The tensor to be decomposed. Should be of order 2 or more.

    rank: int or None, optional
        The minimum number of singular values/vectors to preserve. Will influence the actual truncation rank.

    threshold: float or None, optional
        The value used with criterion to decide the cutoff. Will influence the actual truncation rank.

    size_limit: int or tuple or None, optional
        The size limit(s) for both U and V (when specified as a int) or U and V respectively (when specified as a tuple).
        Will influence the actual truncation rank.

    criterion: int or None, optional
        The norm to be used together with threshold to decide the cutoff. Will influence the actual truncation rank.
        When being left as None, the threshold is treated as the plain cutoff value.
        Otherwise, cutoff rank is the largest int satisfies: threshold * norm(s) > norm(s[rank:]).

    mult_s: bool, optional
        Whether or not to multiply U and V by S**0.5 to decompose A into two tensors instead of three. True by default.
        
    Returns
    -------
    u: tensor_like
        A unitary tensor with indices ordered by the Einstein notation string.

    s: 1d tensor_like
        A 1d tensor containing singular values sorted in descending order.

    v: tensor_like
        A unitary tensor with indices ordered by the Einstein notation string.
    """
    str_a, str_uv = einstr.replace(' ', '').split('->')
    str_u, str_v = str_uv.split(',')
    char_i = list(set(str_v) - set(str_a))[0]
    shape_u = np.prod([A.shape[str_a.find(c)] for c in str_u if c != char_i])
    shape_v = np.prod([A.shape[str_a.find(c)] for c in str_v if c != char_i])

    rank = rank or min(shape_u, shape_v)

    if size_limit is not None:
        if np.isscalar(size_limit):
            size_limit = (size_limit, size_limit)
        if size_limit[0] is not None:
            rank = min(rank, int(size_limit[0] / shape_u) or 1)
        if size_limit[1] is not None:
            rank = min(rank, int(size_limit[1] / shape_v) or 1)

    if threshold is None or criterion is None:
        u, s, vh = A.i(str_a).svd(str_u, str_v, rank, threshold)
    else:
        u, s, vh = A.i(str_a).svd(str_u, str_v)
        threshold = threshold * ctf.norm(s, criterion)
        # will always preserve at least one singular value
        for i in range(rank, 0, -1):
            if ctf.norm(s[i - 1:], criterion) >= threshold:
                rank = i
                break
        if rank < s.size:
            u = u[tuple(slice(None) for i in range(str_u.find(char_i))) +
                  (slice(0, rank), )]
            s = s[:rank]
            vh = vh[tuple(slice(None) for i in range(str_v.find(char_i))) +
                    (slice(0, rank), )]

    if mult_s:
        char_s = list(set(string.ascii_letters) - set(str_v))[0]
        sqrtS = ctf.diag(s**0.5)
        vh = ctf.einsum(
            char_s + char_i + ',' + str_v + '->' +
            str_v.replace(char_i, char_s), sqrtS, vh)
        char_s = list(set(string.ascii_letters) - set(str_u))[0]
        u = ctf.einsum(
            str_u + ',' + char_s + char_i + '->' +
            str_u.replace(char_i, char_s), u, sqrtS)

    return u, s, vh