Ejemplo n.º 1
0
    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()))))
Ejemplo n.º 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())))
Ejemplo n.º 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
Ejemplo n.º 4
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())))
Ejemplo n.º 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())))
def diag(v):
    return ctf.diag(v)
Ejemplo n.º 7
0
#!/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)

Ejemplo n.º 8
0
#!/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()

Ejemplo n.º 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)))
Ejemplo n.º 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