Example #1
0
    def test_project(self):
        def random_tanget_space_point(X):
            coresX = tt.tensor.to_list(X)
            point = 0 * tt.ones(X.n)
            for dim in range(X.d):
                curr = deepcopy(coresX)
                curr[dim] = np.random.rand(curr[dim].shape[0],
                                           curr[dim].shape[1],
                                           curr[dim].shape[2])
                point += tt.tensor.from_list(curr)
            return point

        for debug_mode in [False, True]:
            for use_jit in [False, True]:
                X = tt.rand([4, 4, 4], 3, [1, 4, 4, 1])
                Z = random_tanget_space_point(X)
                PZ = riemannian.project(X, Z, use_jit=use_jit,
                                        debug=debug_mode)
                np.testing.assert_array_almost_equal(Z.full(), PZ.full())

                X = tt.rand([2, 3, 4], 3, [1, 5, 4, 1])
                Z = random_tanget_space_point(X)
                PZ = riemannian.project(X, Z, use_jit=use_jit,
                                        debug=debug_mode)
                np.testing.assert_array_almost_equal(Z.full(), PZ.full())
Example #2
0
def gen_zero_energy_guess(H, rank):
    """
    Generate psi such that <psi|H|psi> = 0
    Parameters:
    -----------
    H: tt.matrix
       hamiltonian in the TT-matrix format
    rank: int
       Rank of the guess
    """
    v = 1.0
    while v > 1e-12:
        # Create two random TT vectors and normalize them
        psi1 = tt.rand(H.n, r=rank)
        psi2 = tt.rand(H.n, r=1)
        psi1 = psi1 * (1.0 / psi1.norm())
        psi2 = psi2 * (1.0 / psi2.norm())
        # Calculate coefficients of the quadratic equation
        h22 = tt.dot(tt.matvec(H, psi2), psi2)
        h21 = tt.dot(tt.matvec(H, psi2), psi1)
        h11 = tt.dot(tt.matvec(H, psi1), psi1)
        # find vectors such that <psi|H|psi> = 0
        rs = np.roots([h22, 2 * h21, h11])
        v = np.linalg.norm(np.imag(rs))

    psi = psi1 + rs[0] * psi2
    psi = psi * (1.0 / psi.norm())
    return psi
Example #3
0
    def test_project_sum_equal_ranks(self):
        for debug_mode in [False, True]:
            for use_jit in [False, True]:
                X = tt.rand([4, 4, 4], 3, [1, 4, 4, 1])
                Z = [0] * 7
                for idx in range(7):
                    Z[idx] = tt.rand([4, 4, 4], 3, [1, 2, 3, 1])
                project_sum = riemannian.project(X, Z, use_jit=use_jit, debug=debug_mode)

                sum_project = X * 0
                for idx in range(len(Z)):
                    sum_project += riemannian.project(X, Z[idx], use_jit=use_jit, debug=debug_mode)
                np.testing.assert_array_almost_equal(sum_project.full(), project_sum.full())
Example #4
0
    def test_gradient_wrt_core(self):
        w = tt.rand([2, 2, 2], 3, [1, 2, 2, 1])
        x_1 = all_subsets.subset_tensor([3, 4, 5])
        x_2 = all_subsets.subset_tensor([-1, 12, 5])
        X = np.array([[3, 4, 5], [-1, 12, 5]])
        eps = 1e-8

        def loss(core):
            new_w = w.copy()
            new_w.core = copy.copy(core)
            res = (tt.dot(new_w, x_1))**2  # Quadratic.
            res += tt.dot(new_w, x_2)  # Linear.
            return res

        # Derivatives of the quadratic and linear functions in the loss.
        dfdz = [2 * tt.dot(w, x_1), 1]

        core = w.core
        value = loss(core)
        numerical_grad = np.zeros(len(core))
        for i in range(len(core)):
            new_core = copy.copy(core)
            # print(new_core)
            new_core[i] += eps
            numerical_grad[i] = (loss(new_core) - value) / eps

        w_cores = tt.tensor.to_list(w)
        gradient = all_subsets.gradient_wrt_cores(w_cores, X, dfdz)
        np.testing.assert_array_almost_equal(numerical_grad,
                                             gradient,
                                             decimal=3)
Example #5
0
def gen_projected_gaussian_guess(H, r, eps=1e-10):
    """
    Generate full N(0,1) vector and then
    project it to a random unitary TT of given rank

    Parameters:
    -----------
    H: tt.matrix
       Matrix used to infer dimension of a guess vector
    r: int
       TT rank of the guess
    """
    # generate tensor with haar distributed cores
    x = tt.rand(H.n, r=r)
    x = x.round(eps)
    x_cores = gen_haar_cores_like(x, left_to_right=True)
    x = x.from_list(x_cores)

    # project full dimensional gaussian vector to x
    dimensions = x.n
    Z = np.random.randn(*(dimensions))
    Z = tt.tensor(Z)
    PZ = tt_project(x, Z)
    PZ = PZ.round(eps, rmax=r)

    return PZ * (1.0 / PZ.norm())
Example #6
0
    def test_gradient_wrt_core(self):
        w = tt.rand([2, 2, 2], 3, [1, 2, 2, 1])
        x_1 = all_subsets.subset_tensor([3, 4, 5])
        x_2 = all_subsets.subset_tensor([-1, 12, 5])
        X = np.array([[3, 4, 5], [-1, 12, 5]])
        eps = 1e-8

        def loss(core):
            new_w = w.copy()
            new_w.core = copy.copy(core)
            res = (tt.dot(new_w, x_1))**2 # Quadratic.
            res += tt.dot(new_w, x_2)     # Linear.
            return res

        # Derivatives of the quadratic and linear functions in the loss.
        dfdz = [2 * tt.dot(w, x_1), 1]

        core = w.core
        value = loss(core)
        numerical_grad = np.zeros(len(core))
        for i in range(len(core)):
            new_core = copy.copy(core)
            # print(new_core)
            new_core[i] += eps
            numerical_grad[i] = (loss(new_core) - value) / eps

        w_cores = tt.tensor.to_list(w)
        gradient = all_subsets.gradient_wrt_cores(w_cores, X, dfdz)
        np.testing.assert_array_almost_equal(numerical_grad, gradient, decimal=3)
Example #7
0
    def test_project_sum_equal_ranks(self):
        for debug_mode in [False, True]:
            for use_jit in [False, True]:
                X = tt.rand([4, 4, 4], 3, [1, 4, 4, 1])
                Z = [0] * 7
                for idx in range(7):
                    Z[idx] = tt.rand([4, 4, 4], 3, [1, 2, 3, 1])
                project_sum = riemannian.project(X, Z, use_jit=use_jit,
                                                 debug=debug_mode)

                sum_project = X * 0
                for idx in range(len(Z)):
                    sum_project += riemannian.project(X, Z[idx],
                                                      use_jit=use_jit,
                                                      debug=debug_mode)
                np.testing.assert_array_almost_equal(sum_project.full(),
                                                     project_sum.full())
Example #8
0
def tt_from_factors(u0, u1, u2):

    F = tt.rand([np.size(u0), np.size(u1), np.size(u2)], 3, [1, 1, 1, 1])
    F_list = F.to_list(F)
    F_list[0][0, :, 0] = u0
    F_list[1][0, :, 0] = u1
    F_list[2][0, :, 0] = u2
    F = F.from_list(F_list)

    return F
Example #9
0
    def test_base(self):
        def sf(k):
            return np.array([0.1] * k)

        n = np.array([5, 6, 7, 8, 9])
        r = 4
        Z = tt.rand(n, r=r, samplefunc=sf)
        Y = teneva.rand(n, r, sf)

        self.assertTrue(_err(Z, Y) < self.e)
Example #10
0
    def test_project_all_subsets(self):
        reg = 0.7
        for debug_mode in [False, True]:
            w = tt.rand([2, 2, 2, 2], 4, [1, 2, 3, 2, 1])
            X = np.random.randn(10, 4)
            exact_answ = reg * w.full()
            for obj_idx in range(10):
                obj = all_subsets.subset_tensor(X[obj_idx, :])
                exact_answ += riemannian.project(w, obj).full()

            res = all_subsets.project_all_subsets(w, X, reg=reg, debug=debug_mode)
            np.testing.assert_array_almost_equal(res.full(), exact_answ)
Example #11
0
    def test_project(self):
        def random_tanget_space_point(X):
            coresX = tt.tensor.to_list(X)
            point = 0 * tt.ones(X.n)
            for dim in range(X.d):
                curr = deepcopy(coresX)
                curr[dim] = np.random.rand(curr[dim].shape[0], curr[dim].shape[1], curr[dim].shape[2])
                point += tt.tensor.from_list(curr)
            return point

        for debug_mode in [False, True]:
            for use_jit in [False, True]:
                X = tt.rand([4, 4, 4], 3, [1, 4, 4, 1])
                Z = random_tanget_space_point(X)
                PZ = riemannian.project(X, Z, use_jit=use_jit, debug=debug_mode)
                np.testing.assert_array_almost_equal(Z.full(), PZ.full())

                X = tt.rand([2, 3, 4], 3, [1, 5, 4, 1])
                Z = random_tanget_space_point(X)
                PZ = riemannian.project(X, Z, use_jit=use_jit, debug=debug_mode)
                np.testing.assert_array_almost_equal(Z.full(), PZ.full())
Example #12
0
def load_tt(filename, L, N):
    """ Load the solution from a file
    """

    F = np.load(filename)

    f = list()

    for i in range(L):

        f.append(tt.rand([N, N, N], 3, F[:4, i]))
        f[i].core = F[4:f[i].core.size + 4, i]

    return f
Example #13
0
    def test_project_all_subsets(self):
        reg = 0.7
        for debug_mode in [False, True]:
            w = tt.rand([2, 2, 2, 2], 4, [1, 2, 3, 2, 1])
            X = np.random.randn(10, 4)
            exact_answ = reg * w.full()
            for obj_idx in range(10):
                obj = all_subsets.subset_tensor(X[obj_idx, :])
                exact_answ += riemannian.project(w, obj).full()

            res = all_subsets.project_all_subsets(w,
                                                  X,
                                                  reg=reg,
                                                  debug=debug_mode)
            np.testing.assert_array_almost_equal(res.full(), exact_answ)
Example #14
0
    def load_restart(self):
        """ Load the solution from a file
        """

        F = np.load(self.config.init_filename)

        f = list()

        for i in range(self.mesh.nc):

            f.append(tt.rand([self.v.nvx, self.v.nvy, self.v.nvz], 3, F[:4,
                                                                        i]))
            f[i].core = F[4:f[i].core.size + 4, i]

        return f
Example #15
0
def div_tt(a, b):

    a_list = a.to_list(a)
    b_list = a.to_list(b)

    c = tt.rand(a.n, 3, a.r)

    c_list = c.to_list(c)

    c_list[0] = a_list[0] / b_list[0]
    c_list[1] = a_list[1] / b_list[1]
    c_list[2] = a_list[2] / b_list[2]

    c = c.from_list(c_list)

    return c
Example #16
0
def gen_haar_rmps_guess(H, r):
    """
    Generates a random MPS as described in
    "Typicality in random matrix product states" by Garnerone et al. 

    Parameters:
    -----------
    H: tt.matrix
       Matrix used to infer dimension of a guess vector
    r: int
       TT rank of the guess
    """
    # generate tensor with haar distributed cores
    x = tt.rand(H.n, r=r)
    x = x.round(0)
    x_cores = gen_haar_cores_like(x, left_to_right=True)
    x = x.from_list(x_cores)

    return x
Example #17
0
def gen_implicit_gaussian_guess(H, r):
    """
    Generates an implicit projection
    of a normal vector in
    tangent space to a random TT
    (with cores drawn from normal distribution)

    Parameters:
    -----------
    H: tt.matrix
       Matrix used to infer dimension of a guess vector
    r: int
       TT rank of the guess
    """
    dimensions = H.n
    X = tt.rand(dimensions, r=r).round(1e-14)
    psi = project_gaussian_to_x_implicit(X)
    psi = psi.round(0, rmax=r)
    psi = 1. / psi.norm() * psi
    return psi
Example #18
0
def gen_implicit_guess_from_distrib(H,
                                    r,
                                    sample_function=half_normal_distribution,
                                    normalize=True):
    """
    Generates an implicit projection of a vector in
    tangent space of a random TT (with cores drawn
    from normal distribution). The vector is generated by the
    sample_function

    Parameters:
    -----------
    H: tt.matrix
       Matrix used to infer dimension of a guess vector
    r: int
       TT rank of the guess
    """
    dimensions = H.n
    X = tt.rand(dimensions, r=r).round(1e-14)
    psi = project_distribution_to_x_implicit(X, sample_function)
    psi.round(0, rmax=r)
    if normalize:
        psi = 1. / psi.norm() * psi
    return psi
Example #19
0
#Generate the initial condition
psi = None
pp1 = np.exp(-0.5*((x-2)**2))
pp1 = tt.tensor(pp1,1e-12)
for i in xrange(f):
    psi = tt.kron(psi,pp1)

pol = None
for i in xrange(f):
    pol = pol + xx[i]*xx[i]
    pol = pol.round(1e-8)

psi = psi * pol
psi = psi.round(1e-12)


radd = 5
rnd = tt.rand(psi.n,psi.d,radd)

psi = psi + 0*rnd

t = 0
tf = 1
tau = 1e-2
t1 = time.time()
while t <= tf:
    psi = kls(-1.0*A,psi,tau)
    t += tau
t2 = time.time()
print('Total time: %f' % (t2-t1))
Example #20
0
def multifuncrs2(X, funs, eps = 1e-6, \
                nswp = 10, \
                rmax = 9999999, \
                verb = 1, \
                kickrank = 5, \
                kickrank2 = 0, \
                d2 = 1, \
                eps_exit = None, \
                y0 = None, \
                do_qr = False, \
                restart_it = 0):
    
    dtype = np.float64
    if len(filter(lambda x: x.is_complex, X)) > 0:
        dtype = np.complex128

    if eps_exit is None:
        eps_exit = eps
    nx = len(X)
    d = X[0].d
    n = X[0].n
    rx = np.transpose(np.array([ttx.r for ttx in X]))
    crx = np.empty((nx, d), dtype = np.object)
    i = 0
    for ttx in X:
        v = tt.tensor.to_list(ttx)
        j = 0
        for w in v:
            crx[i, j] = w
            j = j + 1
        i = i+1
    crx = crx.T
    wasrand = False
    if y0 is None:
        ry = d2 * np.ones((d + 1,), dtype=np.int32)
        ry[0] = 1
        y = tt.rand(n, d, ry)
        wasrand = True
    else: #Initial guess available
        y = y0.copy()
        ry = y.r.copy()
    #Error vector
    z = tt.rand(n, d, kickrank)
    rz = z.r
    z = tt.tensor.to_list(z) 
    ry = y.r
    cry = tt.tensor.to_list(y)
    #Interface matrices - for solution
    one_arr = np.ones((1, 1), dtype=dtype)
    Ry = np.zeros((d + 1, ), dtype=np.object)
    Ry[0] = one_arr
    Ry[d] = one_arr
    Rx = np.zeros((d+1, nx), dtype=np.object)
    Rx[0, :] = np.ones(nx, dtype=dtype)
    Rx[d, :] = np.ones(nx, dtype=dtype)
    Ryz = np.zeros((d + 1, ), dtype = np.object)
    Ryz[0] = one_arr
    Ryz[d] = one_arr
    Rz = np.zeros((d + 1, ), dtype = np.object)
    Rz[0] = one_arr
    Rz[d] = one_arr
    Rxz = np.zeros((d + 1, nx), dtype = np.object)
    Rxz[0, :] = np.ones(nx, dtype=dtype)
    Rxz[d, :] = np.ones(nx, dtype=dtype)
    block_order = [+d, -d]
    # orth
    for i in range(0, d-1):
        cr = cry[i].copy()
        cr = reshape(cr, (ry[i] * n[i], ry[i+1]))
        cr, rv = np.linalg.qr(cr)
        cr2 = cry[i+1].copy()
        cr2 = reshape(cr2, (ry[i+1], n[i+1] * ry[i+2]))
        cr2 = np.dot(rv, cr2) # matrix multiplication
        ry[i+1] = cr.shape[1]
        cr = reshape(cr, (ry[i], n[i], ry[i+1]))
        cry[i+1] = reshape(cr2, (ry[i+1], n[i+1], ry[i+2]))
        cry[i] = cr
        Ry[i+1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i+1])))
        Ry[i+1] = reshape(Ry[i+1], (ry[i] * n[i], ry[i+1]))
        curind = []
        if wasrand:
            # EVERY DAY I'M SHUFFLIN'
            curind = np.random.permutation(n[i] * ry[i])[:ry[i+1]]
        else:
            curind = maxvol(Ry[i+1])
        Ry[i+1] = Ry[i+1][curind, :]
        #Interface matrices for X
        for j in range(0, nx):
            Rx[i+1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j]))
            Rx[i+1, j] = np.dot(Rx[i, j], Rx[i+1, j])
            Rx[i+1, j] = reshape(Rx[i+1, j], (ry[i] * n[i], rx[i+1, j]))
            Rx[i+1, j] = Rx[i+1, j][curind, :]
        #Error for kick
        crz = z[i]
        crz = reshape(crz, (rz[i] * n[i], rz[i+1]))
        crz, rv = np.linalg.qr(crz)
        cr2 = z[i+1]
        cr2 = reshape(cr2, (rz[i+1], n[i+1] * rz[i+2]))
        cr2 = np.dot(rv, cr2)
        rz[i+1] = crz.shape[1]
        crz = reshape(crz, (rz[i], n[i], rz[i+1]))
        z[i+1] = reshape(cr2, (rz[i+1], n[i+1], rz[i+2]))
        z[i] = crz
        #Interfaces for error
        Rz[i+1] = np.dot(Rz[i], reshape(crz, [rz[i], n[i] * rz[i+1]]))
        Rz[i+1] = reshape(Rz[i+1], [rz[i] * n[i], rz[i+1]])
        Ryz[i+1] = np.dot(Ryz[i], reshape(cr, [ry[i], n[i] * ry[i+1]]))
        Ryz[i+1] = reshape(Ryz[i+1], [rz[i] * n[i], ry[i+1]])
        #Pick random initial indices
        curind = np.random.permutation(n[i] * rz[i])[:rz[i+1]]
        Ryz[i+1] = Ryz[i+1][curind, :]
        Rz[i+1] = Rz[i+1][curind, :]
        #Interface matrices for X
        for j in range(0, nx):
            Rxz[i+1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j]))
            Rxz[i+1, j] = np.dot(Rxz[i, j], Rxz[i+1, j])
            Rxz[i+1, j] = reshape(Rxz[i+1, j], (rz[i] * n[i], rx[i+1, j]))
            Rxz[i+1, j] = Rxz[i+1, j][curind, :]
    d2 = ry[d]
    ry[d] = 1
    cry[d-1] = np.transpose(cry[d-1], [2, 0, 1]) # permute
    swp = 1
    max_dy = 0.0
    cur_order = copy.copy(block_order)
    order_index = 1
    i = d-1
    dirn = int(math.copysign(1, cur_order[order_index])) # can't use 'dir' identifier in python
    #DMRG sweeps
    while swp <= nswp or dirn > 0:
        oldy = reshape(cry[i].copy(), (d2 * ry[i] * n[i] * ry[i+1], ))
        #Compute X superblocks
        curbl = np.zeros((ry[i] * n[i] * ry[i+1], nx), dtype)
        for j in range(0, nx):
            cr = reshape(crx[i, j].copy(), (rx[i, j], n[i] * rx[i+1, j]))
            cr = np.dot(Rx[i, j], cr)
            cr = reshape(cr, (ry[i] * n[i], rx[i+1, j]))
            cr = np.dot(cr, Rx[i+1, j])
            curbl[:, j] = cr.flatten('F')
        newy = funs(curbl)
        #multiply with inverted Ry
        newy = reshape(newy, (ry[i], n[i] * ry[i+1] * d2))
        newy = np.linalg.solve(Ry[i], newy) # y = R \ y
        newy = reshape(newy, (ry[i] * n[i] * ry[i+1], d2))
        newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i+1]))
        newy = np.transpose(np.linalg.solve(np.transpose(Ry[i+1]), np.transpose(newy))) # y=y/R
        newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i+1],))
        try: 
            dy = np.linalg.norm(newy - oldy) / np.linalg.norm(newy)
        except ZeroDivisionError:
            print 'Bad initial indices, the solution is exactly zero. Restarting'
            return
        max_dy = max(max_dy, dy)
        # truncation
        if dirn > 0: # left-to-right
            newy = reshape(newy, (d2, ry[i] * n[i] * ry[i+1]))
            newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i+1] * d2))
        else:
            newy = reshape(newy, (d2 * ry[i], n[i] * ry[i+1]))
        if kickrank >= 0:
            try:
                u, s, v = np.linalg.svd(newy, full_matrices = False)
            except:
                tmp = np.array(np.random.randn(newy.shape[1], newy.shape[1]), dtype=dtype)
                tmp, ru_tmp = np.linalg.qr(tmp)
                u, s, v = np.linalg.svd(np.dot(newy, tmp))
                #u * s * v = A * tmp
                v = np.dot(v, np.conj(tmp).T)
            v = np.conj(np.transpose(v))
            r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s))
        else:
            if dirn > 0:
                u, v = np.linalg.qr(newy)
                v = np.conj(np.transpose(v))
                r = u.shape[1]
                s = np.ones((r, ))
            else:
                v, u = np.linalg.qr(np.transpose(newy))
                v = np.conj(v)
                u = np.transpose(u)
                r = u.shape[1]
                s = np.ones((r, ))
        if verb > 1:
            print '=multifuncrs2=   block %d{%d}, dy: %3.3e, r: %d' % (i, dirn, dy, r)
        #Kicks and interfaces
        if dirn > 0 and i < d-1:
            u = u[:, :r]
            v = np.dot(v[:, :r], np.diag(s[:r]))
            # kick
            radd = 0
            rv = 1                
            if kickrank > 0:
                #Compute the function at residual indices
                curbl_y = np.zeros((ry[i] * n[i] * rz[i+1], nx), dtype=dtype)
                curbl_z = np.zeros((rz[i] * n[i] * rz[i+1], nx), dtype=dtype)
                for j in xrange(nx):
                    #For kick
                    cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j]))
                    cr = np.dot(Rx[i, j], cr)
                    cr = reshape(cr, (ry[i] * n[i], rx[i+1, j]))
                    cr = np.dot(cr, Rxz[i+1, j])
                    curbl_y[:, j] = cr.flatten('F')
                    #For z update
                    cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j]))
                    cr = np.dot(Rxz[i, j], cr)
                    cr = reshape(cr, (rz[i] * n[i], rx[i+1, j]))
                    cr = np.dot(cr, Rxz[i+1, j])
                    curbl_z[:, j] = cr.flatten('F')
                #Call the function
                zy = reshape(funs(curbl_y), (-1, d2))
                zz = reshape(funs(curbl_z), (-1, d2))
                #Assemble y at z indices (sic!) and subtract
                dzy = reshape(np.dot(u, v.T), (ry[i] * n[i] * ry[i+1], d2))
                dzy = reshape(dzy.T, (d2 * ry[i] * n[i], ry[i+1]))
                #Cast dzy from core items to samples at right indices
                dzy = np.dot(dzy, Ryz[i+1])
                dzy = reshape(dzy, (d2, ry[i] * n[i] * rz[i+1]))
                dzy = dzy.T
                #zy still requires casting from samples to core entities
                zy = reshape(zy, (ry[i], n[i] * rz[i+1] * d2))
                zy = np.linalg.solve(Ry[i], zy)
                zy = reshape(zy, (ry[i] * n[i] * rz[i+1], d2))
                zy = zy - dzy
                dzy = reshape(dzy, (ry[i], n[i] * rz[i+1] * d2))
                dzy = np.dot(Ryz[i], dzy)
                dzy = reshape(dzy, (rz[i] * n[i] * rz[i+1], d2)) #Sample from both sizes
                zz = zz - dzy
                #Interpolate all remaining samples into core elements
                zy = reshape(zy.T, (d2 * ry[i] * n[i], rz[i+1]))
                zy = np.linalg.solve(Rz[i+1].T, zy.T).T
                zy = reshape(zy, (d2, ry[i] * n[i] * rz[i+1]))
                zy = reshape(zy.T, (ry[i] * n[i], rz[i+1] * d2))
                #SVD to eliminate d2 and possibly overestimated rz
                zy, sz, vz = np.linalg.svd(zy, full_matrices = False)
                zy = zy[:, :min(kickrank, zy.shape[1])]
                # For z update
                zz = reshape(zz, (rz[i], n[i] * rz[i+1] * d2))
                zz = np.linalg.solve(Rz[i], zz)
                zz = reshape(zz, (rz[i] * n[i] * rz[i+1], d2))
                zz = reshape(zz.T, (d2 * rz[i] * n[i], rz[i+1]))
                zz = np.linalg.solve(Rz[i+1].T, zz.T).T 
                zz = reshape(zz, (d2, rz[i] * n[i] * rz[i+1]))
                zz = reshape(zz.T, (rz[i] * n[i], rz[i+1] * d2))
                zz, sz, vz = np.linalg.svd(zz, full_matrices = False)
                zz = zz[:, :min(kickrank, zz.shape[1])]
                #Second random kick rank 
                zz = np.hstack((zz, np.random.randn(rz[i] * n[i], kickrank2)))
                u, rv = np.linalg.qr(np.hstack((u, zy)))
                radd = zy.shape[1]
            v = np.hstack((v, np.zeros((ry[i+1] * d2, radd), dtype=dtype)))
            v = np.dot(rv, v.T)
            r = u.shape[1]
            cr2 = cry[i+1].copy()
            cr2 = reshape(cr2, (ry[i+1], n[i+1] * ry[i+2]))
            v = reshape(v, (r * ry[i+1], d2))
            v = reshape(v.T, (d2 * r, ry[i+1]))
            v = np.dot(v, cr2)
            ry[i+1] = r
            u = reshape(u, (ry[i], n[i], r))
            v = reshape(v, (d2, r, n[i+1], ry[i+2]))
            #Stuff back
            cry[i] = u
            cry[i+1] = v
            # Update kick
            zz, rv = np.linalg.qr(zz)
            rz[i+1] = zz.shape[1]
            z[i] = reshape(zz, (rz[i], n[i], rz[i+1]))
            #z[i+1] is recomputed from scratch we do not need it now
            #Compute left interface matrices
            #Interface matrix for Y
            Ry[i+1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i+1])))
            Ry[i+1] = reshape(Ry[i+1], (ry[i] * n[i], ry[i+1]))
            curind = maxvol(Ry[i+1])
            Ry[i+1] = Ry[i+1][curind, :]
            #Interface matrices for X
            for j in xrange(nx):
                Rx[i+1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j]))
                Rx[i+1, j] = np.dot(Rx[i, j], Rx[i+1, j])
                Rx[i+1, j] = reshape(Rx[i+1, j], (ry[i] * n[i], rx[i+1, j]))
                Rx[i+1, j] = Rx[i+1, j][curind, :]
            #for kick
            Ryz[i+1] = np.dot(Ryz[i], reshape(u, (ry[i], n[i] * ry[i+1])))
            Ryz[i+1] = reshape(Ryz[i+1], (rz[i] * n[i], ry[i+1]))
            Rz[i+1] = np.dot(Rz[i], reshape(zz, (rz[i], n[i] * rz[i+1])))
            Rz[i+1] = reshape(Rz[i+1], (rz[i] * n[i], rz[i+1]))
            curind = maxvol(Rz[i+1])
            Ryz[i+1] = Ryz[i+1][curind, :]
            Rz[i+1] = Rz[i+1][curind, :]
            #Interface matrices for X
            for j in xrange(nx):
                Rxz[i+1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j]))
                Rxz[i+1, j] = np.dot(Rxz[i, j], Rxz[i+1, j])
                Rxz[i+1, j] = reshape(Rxz[i+1, j], (rz[i] * n[i], rx[i+1, j]))
                Rxz[i+1, j] = Rxz[i+1, j][curind, :]
        elif dirn < 0 and i > 0: # Right to left
            u = np.dot(u[:, :r], np.diag(s[:r]))
            v = np.conj(v[:, :r])
            #kick
            radd = 0
            rv = 0
            if kickrank > 0:
                #AMEN kick
                #Compute the function at residual indices
                curbl_y = np.zeros((rz[i] * n[i] * ry[i+1], nx), dtype=dtype)
                curbl_z = np.zeros((rz[i] * n[i] * rz[i+1], nx), dtype=dtype)
                for j in xrange(nx):
                    cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j]))
                    cr = np.dot(Rxz[i, j], cr)
                    cr = reshape(cr, (rz[i] * n[i], rx[i+1, j]))
                    cr = np.dot(cr, Rx[i+1, j])
                    curbl_y[:, j] = cr.flatten('F')
                    #for z update
                    cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i+1, j]))
                    cr = np.dot(Rxz[i, j], cr)
                    cr = reshape(cr, (rz[i] * n[i], rx[i+1, j]))
                    cr = np.dot(cr, Rxz[i+1, j])
                    curbl_z[:, j] = cr.flatten('F')
                #Call the function
                zy = reshape(funs(curbl_y), (-1, d2))
                zz = reshape(funs(curbl_z), (-1, d2))
                #Assemble y at z indices (sic!) and subtract
                dzy = reshape(np.dot(u, v.T), (ry[i], n[i] * ry[i+1] * d2))
                dzy = np.dot(Ryz[i], dzy)
                dzy = reshape(dzy, (rz[i] * n[i] * ry[i+1], d2))
                # zy still requires casting from samples to core entries
                zy = zy.T
                zy = reshape(zy, (d2 * rz[i] * n[i], ry[i+1]))
                zy = np.linalg.solve(Ry[i+1].T, zy.T).T
                zy = reshape(zy, (d2, rz[i] * n[i] * ry[i+1]))
                zy = zy.T
                zy = zy - dzy
                dzy = reshape(dzy.T, (d2 * rz[i] * n[i], ry[i+1]))
                dzy = np.dot(dzy, Ryz[i+1])
                dzy = reshape(dzy, (d2, rz[i] * n[i] * rz[i+1]))
                zz = zz - dzy.T
                # Cast sample indices to core elements
                # ...for kick
                zy = reshape(zy, (rz[i], n[i] * ry[i+1] * d2))
                zy = np.linalg.solve(Rz[i], zy)
                zy = reshape(zy, (rz[i] * n[i] * ry[i+1], d2))
                zy = zy.T
                zy = reshape(zy, (d2 * rz[i], n[i] * ry[i+1]))
                zu, zs, zy = np.linalg.svd(zy, full_matrices = False)
                zy = zy[:min(kickrank, zy.shape[0]), :]
                zy = zy.T
                # ...for z update
                zz = reshape(zz, (rz[i], n[i] * rz[i+1] * d2))
                zz = np.linalg.solve(Rz[i], zz)
                zz = reshape(zz, (rz[i] * n[i] * rz[i+1], d2))
                zz = reshape(zz.T, (d2 * rz[i] * n[i], rz[i+1]))
                zz = np.linalg.solve(Rz[i+1].T, zz.T).T
                zz = reshape(zz, (d2 * rz[i], n[i] * rz[i+1]))
                zu, zs, zz = np.linalg.svd(zz, full_matrices = False)
                zz = zz[:min(kickrank, zz.shape[0]), :]
                zz = zz.T
                zz = np.hstack((zz, np.random.randn(n[i] * rz[i+1], kickrank2)))
                v, rv = np.linalg.qr(np.hstack((v, zy)))
                radd = zy.shape[1]
            u = np.hstack((u, np.zeros((d2 * ry[i], radd), dtype=dtype)))
            u = np.dot(u, rv.T)
            r = v.shape[1]
            cr2 = cry[i-1].copy()
            cr2 = reshape(cr2, (ry[i-1] * n[i-1], ry[i]))
            u = reshape(u, (d2, ry[i] * r))
            u = reshape(u.T, (ry[i], r * d2))
            u = np.dot(cr2, u)
            u = reshape(u, (ry[i-1] * n[i-1] * r, d2))
            u = reshape(u.T, (d2, ry[i-1], n[i-1], r))
            v = reshape(v.T, (r, n[i], ry[i+1]))
            # Stuff back
            ry[i] = r
            cry[i-1] = u
            cry[i] = v
            #kick
            zz, rv = np.linalg.qr(zz)
            rz[i] = zz.shape[1]
            zz = reshape(zz.T, (rz[i], n[i], rz[i+1]))
            z[i] = zz
            #z[i-1] is recomputed from scratch we do not need it
            # Recompute left interface matrices
            # Interface matrix for Y
            Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i+1])), Ry[i+1])
            Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i+1]))
            curind = maxvol(Ry[i].T)
            Ry[i] = Ry[i][:, curind]
            # Interface matrices for X
            for j in xrange(nx):
                Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i+1, j]))
                Rx[i, j] = np.dot(Rx[i, j], Rx[i+1, j])
                Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i+1]))
                Rx[i, j] = Rx[i, j][:, curind]
            # for kick
            Rz[i] = np.dot(reshape(zz, (rz[i] * n[i], rz[i+1])), Rz[i+1])
            Rz[i] = reshape(Rz[i], (rz[i], n[i] * rz[i+1]))
            Ryz[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i+1])), Ryz[i+1])
            Ryz[i] = reshape(Ryz[i], (ry[i], n[i] * rz[i+1]))
            curind = maxvol(Rz[i].T)
            Ryz[i] = Ryz[i][:, curind]
            Rz[i] = Rz[i][:, curind]
            # Interface matrices for X
            for j in xrange(nx):
                Rxz[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i+1, j]))
                Rxz[i, j] = np.dot(Rxz[i, j], Rxz[i+1, j])
                Rxz[i, j] = reshape(Rxz[i, j], (rx[i, j], n[i] * rz[i+1]))
                Rxz[i, j] = Rxz[i, j][:, curind]
        elif dirn > 0 and i == d-1:
            #Just stuff back the last core
            newy = np.dot(u[:, :r], np.dot(np.diag(s[:r]), np.conj(v[:, :r].T)))
            newy = reshape(newy, (ry[i] * n[i] * ry[i+1], d2))
            cry[i] = reshape(newy.T, (d2, ry[i], n[i], ry[i+1]))
        elif dirn < 0 and i == 0:
            newy = np.dot(u[:, :r], np.dot(np.diag(s[:r]), np.conj(v[:, :r].T)))
            newy = reshape(newy, (d2, ry[i], n[i], ry[i+1]))
            cry[i] = newy
        i += dirn
        # Reversing, residue check, etc
        cur_order[order_index] = cur_order[order_index] - dirn
        # New direction
        if cur_order[order_index] == 0:
            order_index = order_index + 1
            if verb > 0:
                print '=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy, \
                    math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n)))        
            if max_dy < eps_exit and dirn > 0: 
                break
            if order_index >= len(cur_order): #New global sweep
                cur_order = copy.copy(block_order)
                order_index = 0
                max_dy = 0
                swp = swp + 1
            dirn = int(math.copysign(1, cur_order[order_index]))
            i = i + dirn
    cry[d-1] = np.transpose(cry[d-1][:, :, :, 0], [1, 2, 0])
    y = tt.tensor.from_list(cry)
    return y
Example #21
0
#%%

from __future__ import print_function, absolute_import, division
import sys
sys.path.append('../')
import numpy as np
import tt
from tt.eigb import *
import time
""" This code computes many eigenvalus of the Laplacian operator """

d = 8
f = 8
A = tt.qlaplace_dd([d] * f)
#A = (-1)*A
#A = tt.eye(2,d)
n = [2] * (d * f)
r = [8] * (d * f + 1)
r[0] = 1
r[d * f] = 8  #Number of eigenvalues sought
x = tt.rand(n, d * f, r)
#x = tt_ones(2,d)
t = time.time()
y, lam = eigb(A, x, 1e-6)

t1 = time.time()
print('Eigenvalues:', lam)
print('Time is:', t1 - t)

# %%
Example #22
0
def multifuncrs(X, funs, eps=1E-6, \
        nswp=10,                   \
        kickrank=5,                \
        y0=None,                   \
        rmax=999999,#TODO:infinity \ 
        kicktype='amr-two',        \
        pcatype='svd',             \
        trunctype='fro',           \
        d2=1,                      \
        do_qr=False,               \
        verb=1):
    """Cross approximation of a (vector-)function of several TT-tensors.
    
    :param X: tuple of TT-tensors
    :param funs: multivariate function
    :param eps: accuracy
    """
    
    dtype = np.float64
    if len(filter(lambda x: x.is_complex, X)) > 0:
        dtype = np.complex128

    y = y0
    wasrand = False
    
    nx = len(X)
    d = X[0].d
    n = X[0].n
    rx = np.transpose(np.array([ttx.r for ttx in X]))
    #crx = [tt.tensor.to_list(ttx) for x in X] 
    #crx = zip(*crx)
    crx = np.transpose(np.array([tt.tensor.to_list(ttx) for ttx in X], dtype=np.object))
    crx = np.empty((nx, d), dtype = np.object)
    i = 0
    for ttx in X:
        v = tt.tensor.to_list(ttx)
        j = 0
        for w in v:
            crx[i, j] = w
            j = j + 1
        i = i + 1
    crx = crx.T
    if y is None:
        ry = d2 * np.ones((d + 1,), dtype=np.int32)
        ry[0] = 1
        y = tt.rand(n, d, ry)
        wasrand = True
    
    ry = y.r
    cry = tt.tensor.to_list(y)
    
    Ry = np.zeros((d + 1, ), dtype=np.object)
    Ry[0] = np.array([[1.0]], dtype=dtype)
    Ry[d] = np.array([[1.0]], dtype=dtype)
    Rx = np.zeros((d+1, nx), dtype=np.object)
    Rx[0, :] = np.ones(nx, dtype=dtype)
    Rx[d, :] = np.ones(nx, dtype=dtype)
    
    block_order = [+d, -d]
    
    # orth
    for i in range(0, d - 1):
        cr = cry[i]
        cr = reshape(cr, (ry[i] * n[i], ry[i + 1]))
        cr, rv = np.linalg.qr(cr)
        cr2 = cry[i + 1]
        cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2]))
        cr2 = np.dot(rv, cr2) # matrix multiplication
        ry[i + 1] = cr.shape[1]
        cr = reshape(cr, (ry[i], n[i], ry[i + 1]))
        cry[i + 1] = reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2]))
        cry[i] = cr
        
        Ry[i + 1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i + 1])))
        Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1]))
        curind = []
        if wasrand:
            # EVERY DAY I'M SHUFFLIN'
            curind = np.random.permutation(n[i] * ry[i])[:ry[i + 1]]
        else:
            curind = maxvol(Ry[i + 1])
        Ry[i + 1] = Ry[i + 1][curind, :]
        for j in range(0, nx):
            try:
                Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
            except:
                pass    
            Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j])
            Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j]))
            Rx[i + 1, j] = Rx[i + 1, j][curind, :]
    
    d2 = ry[d]
    ry[d] = 1
    cry[d - 1] = np.transpose(cry[d - 1], [2, 0, 1]) # permute
    
    last_sweep = False
    swp = 1
    
    dy = np.zeros((d, ))
    max_dy = 0
    
    cur_order = copy.copy(block_order)
    order_index = 1
    i = d - 1
    dirn = int(math.copysign(1, cur_order[order_index])) # can't use 'dir' identifier in python
    
    # DMRG sweeps
    while swp <= nswp or dirn > 0:
        
        oldy = reshape(cry[i], (d2 * ry[i] * n[i] * ry[i + 1],))
        
        if not last_sweep:
            # compute the X superblocks
            curbl = np.zeros((ry[i] * n[i] * ry[i + 1], nx), dtype=dtype)
            for j in range(0, nx):
                cr = reshape(crx[i,j], (rx[i, j], n[i] * rx[i + 1, j]))
                cr = np.dot(Rx[i, j], cr)
                cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j]))
                cr = np.dot(cr, Rx[i + 1, j])
                curbl[:, j] = cr.flatten('F');
            # call the function
            newy = funs(curbl)
            # multiply with inverted Ry
            newy = reshape(newy, (ry[i], n[i] * ry[i + 1] * d2))
            newy = np.linalg.solve(Ry[i], newy) # y = R \ y
            newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2))
            newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i + 1]))
            newy = np.transpose(np.linalg.solve(np.transpose(Ry[i + 1]), np.transpose(newy))) # y=y/R
            newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i + 1],))
        else:
            newy = oldy
        
        dy[i] = np.linalg.norm(newy - oldy) / np.linalg.norm(newy)
        max_dy = max(max_dy, dy[i])
        
        # truncation
        if dirn > 0: # left-to-right
            newy = reshape(newy, (d2, ry[i] * n[i] * ry[i + 1]))
            newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i + 1] * d2))
        else:
            newy = reshape(newy, (d2 * ry[i], n[i] * ry[i + 1]))
        
        r = 0 # defines a variable in global scope
        
        if kickrank >= 0:
            u, s, v = np.linalg.svd(newy, full_matrices=False)
            v = np.conj(np.transpose(v))
            if trunctype == "fro" or last_sweep:
                r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s))
            else:
                # truncate taking into account the (r+1) overhead in the cross (T.S.: what?)
                cums = abs(s * np.arange(2, len(s) + 2)) ** 2
                cums = np.cumsum(cums[::-1])[::-1]
                cums = cums / cums[0]
                ff = [i for i in range(len(cums)) if cums[i] < eps ** 2 / d]
                if len(ff) == 0:
                    r = len(s)
                else:
                    r = np.amin(ff)
            r = min(r, rmax, len(s))
        else:
            if dirn > 0:
                u, v = np.linalg.qr(newy)
                v = np.conj(np.transpose(v))
                r = u.shape[1]
                s = np.ones((r, ))
            else:
                v, u = np.linalg.qr(np.transpose(newy))
                v = np.conj(v)
                u = np.transpose(u)
                r = u.shape[1]
                s = np.ones((r, ))
        
        if verb > 1:
            print '=multifuncrs=   block %d{%d}, dy: %3.3e, r: %d' % (i, dirn, dy[i], r)
        
        # kicks and interfaces
        if dirn > 0 and i < d - 1:
            u = u[:, :r]
            v = np.dot(v[:, :r], np.diag(s[:r]))
            
            # kick
            radd = 0
            rv = 1
            if not last_sweep and kickrank > 0:
                uk = None
                if kicktype == 'amr-two':
                    # AMR(two)-like kick.
                    
                    # compute the X superblocks
                    ind2 = np.unique(np.random.randint(0, ry[i + 2] * n[i + 1], ry[i + 1]))
                    #ind2 = np.unique(np.floor(np.random.rand(ry[i + 1]) * (ry[i + 2] * n[i + 1])))
                    rkick = len(ind2)
                    curbl = np.zeros((ry[i] * n[i] * rkick, nx), dtype=dtype)
                    for j in range(nx):
                        cr1 = reshape(crx[i,j], (rx[i, j], n[i] * rx[i + 1, j]))
                        cr1 = np.dot(Rx[i, j], cr1)
                        cr1 = reshape(cr1, (ry[i] * n[i], rx[i + 1, j]))
                        cr2 = reshape(crx[i + 1,j], (rx[i + 1, j] * n[i + 1], rx[i + 2, j]))
                        cr2 = np.dot(cr2, Rx[i + 2, j])
                        cr2 = reshape(cr2, (rx[i + 1, j], n[i + 1] * ry[i + 2]))
                        cr2 = cr2[:, ind2]
                        curbl[:, j] = reshape(np.dot(cr1, cr2), (ry[i] * n[i] * rkick,))
                    # call the function
                    uk = funs(curbl)
                    uk = reshape(uk, (ry[i], n[i] * rkick * d2))
                    uk = np.linalg.solve(Ry[i], uk)
                    uk = reshape(uk, (ry[i] * n[i], rkick * d2))
                    if pcatype == 'svd':
                        uk, sk, vk = np.linalg.svd(uk, full_matrices=False)
                        vk = np.conj(np.transpose(vk))
                        uk = uk[:, :min(kickrank, uk.shape[1])]
                    else:
                        # uk = uchol(np.transpose(uk), kickrank + 1) # TODO
                        uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1]
                else:
                    uk = np.random.rand(ry[i] * n[i], kickrank)
                u, rv = np.linalg.qr(np.concatenate((u, uk), axis=1))
                radd = uk.shape[1]
            v = np.concatenate((v, np.zeros((ry[i + 1] * d2, radd), dtype=dtype)), axis=1)
            v = np.dot(rv, np.conj(np.transpose(v)))
            r = u.shape[1]
            
            cr2 = cry[i + 1]
            cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2]))
            v = reshape(v, (r * ry[i + 1], d2))
            v = reshape(np.transpose(v), (d2 * r, ry[i + 1]))
            v = np.dot(v, cr2)
            
            ry[i + 1] = r
            
            u = reshape(u, (ry[i], n[i], r))
            v = reshape(v, (d2, r, n[i + 1], ry[i + 2]))
            
            cry[i] = u
            cry[i + 1] = v
            
            Ry[i + 1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i + 1])))
            Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1]))
            curind = maxvol(Ry[i + 1])
            Ry[i + 1] = Ry[i + 1][curind, :]
            for j in range(nx):
                Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j])
                Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j]))
                Rx[i + 1, j] = Rx[i + 1, j][curind, :]
        elif dirn < 0 and i > 0:
            u = np.dot(u[:, :r], np.diag(s[:r]))
            v = np.conj(v[:, :r])
            
            radd = 0
            rv = 1
            if not last_sweep and kickrank > 0:
                if kicktype == 'amr-two':
                    # compute the X superblocks
                    ind2 = np.unique(np.random.randint(0, ry[i - 1] * n[i - 1], ry[i]))
                    rkick = len(ind2)
                    curbl = np.zeros((rkick * n[i] * ry[i + 1], nx), dtype=dtype)
                    for j in range(nx):
                        cr1 = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j]))
                        cr1 = np.dot(cr1, Rx[i + 1, j])
                        cr1 = reshape(cr1, (rx[i, j], n[i] * ry[i + 1]))
                        cr2 = reshape(crx[i - 1, j], (rx[i - 1, j], n[i - 1] * rx[i, j]))
                        cr2 = np.dot(Rx[i - 1, j], cr2)
                        cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], rx[i, j]))
                        cr2 = cr2[ind2, :]
                        curbl[:, j] = reshape(np.dot(cr2, cr1), (rkick * n[i] * ry[i + 1],))
                    # calling the function
                    uk = funs(curbl)
                    uk = reshape(uk, (rkick * n[i] * ry[i + 1], d2))
                    uk = reshape(np.transpose(uk), (d2 * rkick * n[i], ry[i + 1]))
                    uk = np.transpose(np.linalg.solve(np.transpose(Ry[i + 1]), np.transpose(uk)))
                    uk = reshape(uk, (d2 * rkick, n[i] * ry[i + 1]))
                    if pcatype == 'svd':
                        vk, sk, uk = np.linalg.svd(uk, full_matrices=False)
                        uk = np.conj(np.transpose(uk))
                        uk = uk[:, :min(kickrank, uk.shape[1])] # TODO: refactor
                    else:
                        # uk = uchol(uk, kickrank + 1) # TODO
                        uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1]
                else:
                    uk = np.random.rand(n[i] * ry[i + 1], kickrank)
                v, rv = np.linalg.qr(np.concatenate((v, uk), axis=1))
                radd = uk.shape[1]
            u = np.concatenate((u, np.zeros((d2 * ry[i], radd), dtype=dtype)), axis=1)
            u = np.dot(u, np.transpose(rv))
            r = v.shape[1]
            cr2 = cry[i - 1]
            cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], ry[i]))
            u = reshape(u, (d2, ry[i] * r))
            u = reshape(np.transpose(u), (ry[i], r * d2))
            u = np.dot(cr2, u)
            
            u = reshape(u, (ry[i - 1] * n[i - 1] * r, d2))
            u = reshape(np.transpose(u), (d2, ry[i - 1], n[i - 1], r))
            v = reshape(np.transpose(v), (r, n[i], ry[i + 1]))
            
            ry[i] = r
            cry[i - 1] = u
            cry[i] = v
            
            Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ry[i + 1])
            Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i + 1]))
            curind = maxvol(np.transpose(Ry[i]))
            Ry[i] = Ry[i][:, curind]
            for j in range(nx):
                Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j]))
                Rx[i, j] = np.dot(Rx[i, j], Rx[i + 1, j])
                Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i + 1]))
                Rx[i, j] = Rx[i, j][:, curind]
        elif dirn > 0 and i == d - 1:
            newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])), np.conj(np.transpose(v[:, :r])))
            newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2))
            cry[i] = reshape(np.transpose(newy), (d2, ry[i], n[i], ry[i + 1]))
        elif dirn < 0 and i == 0:
            newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])), np.conj(np.transpose(v[:, :r])))
            newy = reshape(newy, (d2, ry[i], n[i], ry[i + 1]))
            cry[i] = newy
        
        i = i + dirn
        cur_order[order_index] = cur_order[order_index] - dirn
        if cur_order[order_index] == 0:
            order_index = order_index + 1
            if verb > 0:
                print '=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy, \
                    math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n)))
            
            if last_sweep:
                 break
            if max_dy < eps and dirn < 0:
                last_sweep = True
                kickrank = 0
            
            if order_index >= len(cur_order):
                cur_order = copy.copy(block_order)
                order_index = 0
                if last_sweep:
                    cur_order = [d - 1]
                
                max_dy = 0
                swp = swp + 1
            
            dirn = int(math.copysign(1, cur_order[order_index]))
            i = i + dirn
            
    cry[d - 1] = np.transpose(cry[d - 1][:, :, :, 0], [1, 2, 0])
    y = tt.tensor.from_list(cry)
    return y
Example #23
0
def amen_mv(A, x, tol, y=None, z=None, nswp=20, kickrank=4,
            kickrank2=0, verb=True, init_qr=True, renorm='direct', fkick=False):
    '''
       Approximate the matrix-by-vector via the AMEn iteration
       [y,z]=amen_mv(A, x, tol, varargin)
       Attempts to approximate the y = A*x
       with accuracy TOL using the AMEn+ALS iteration.
       Matrix A has to be given in the TT-format, right-hand side x should be
       given in the TT-format also.

       Options are provided in form
       'PropertyName1',PropertyValue1,'PropertyName2',PropertyValue2 and so
       on. The parameters are set to default (in brackets in the following)
       The list of option names and default values are:
           o y0 - initial approximation to Ax [rand rank-2]
           o nswp - maximal number of sweeps [20]
           o verb - verbosity level, 0-silent, 1-sweep info, 2-block info [1]
           o kickrank - compression rank of the error,
             i.e. enrichment size [3]
           o init_qr - perform QR of the input (save some time in ts, etc) [true]
           o renorm - Orthog. and truncation methods: direct (svd,qr) or gram
             (apply svd to the gram matrix, faster for m>>n) [direct]
           o fkick - Perform solution enrichment during forward sweeps [false]
             (rather questionable yet; false makes error higher, but "better
             structured": it does not explode in e.g. subsequent matvecs)
           o z0 - initial approximation to the error Ax-y [rand rank-kickrank]


    ********
       For description of adaptive ALS please see
       Sergey V. Dolgov, Dmitry V. Savostyanov,
       Alternating minimal energy methods for linear systems in higher dimensions.
       Part I: SPD systems, http://arxiv.org/abs/1301.6068,
       Part II: Faster algorithm and application to nonsymmetric systems, http://arxiv.org/abs/1304.1222

       Use {sergey.v.dolgov, dmitry.savostyanov}@gmail.com for feedback
    ********
    '''

    if renorm is 'gram':
        print("Not implemented yet. Renorm is switched to 'direct'")
        renorm = 'direct'

    if isinstance(x, _tt.vector):
        d = x.d
        m = x.n
        rx = x.r
        x = _tt.vector.to_list(x)
        vectype = 1  # tt_tensor
    elif isinstance(x, list):
        d = len(x)
        m = _np.zeros(d)
        rx = _np.ones(d + 1, dtype=_np.int32)
        for i in xrange(d):
            [_, m[i], rx[i + 1]] = x[i].shape
        vectype = 0  # cell
    else:
        raise Exception('x: use tt.tensor or list of cores as numpy.arrays')

    if isinstance(A, _tt.matrix):
        n = A.n
        ra = A.tt.r
        A = _tt.matrix.to_list(A)
        # prepare A for fast ALS-mv
        for i in xrange(d):
            A[i] = _reshape(A[i], (ra[i] * n[i], m[i] * ra[i + 1]))
        atype = 1  # tt_matrix
    # Alternative: A is a cell of cell: sparse canonical format
    elif isinstance(A, list):
        n = _np.zeros(d)
        for i in xrange(d):
            n[i] = A[i][0].shape[0]
        ra = len(A[0])
        atype = 0  # cell
    else:
        raise Exception('A: use tt.matrix or list of cores as numpy.arrays')

    if y is None:
        y = _tt.rand(n, d, 2)
        y = _tt.vector.to_list(y)
    else:
        if isinstance(y, _tt.vector):
            y = _tt.vector.to_list(y)

    ry = _np.ones(d + 1, dtype=_np.int32)
    for i in range(d):
        ry[i + 1] = y[i].shape[2]

    if (kickrank + kickrank2 > 0):
        if z is None:
            z = _tt.rand(n, d, kickrank + kickrank2)
            rz = z.r
            z = _tt.vector.to_list(z)
        else:
            if isinstance(z, _tt.vector):
                z = _tt.vector.to_list(z)
            rz = _np.ones(d + 1, dtype=_np.int32)
            for i in range(d):
                rz[i + 1] = z[i].shape[2]

        phizax = [None] * (d + 1)  # cell(d+1,1);
        if (atype == 1):
            phizax[0] = _np.ones((1, 1, 1))  # 1
            phizax[d] = _np.ones((1, 1, 1))  # 1
        else:
            phizax[0] = _np.ones((1, ra))  # 33
            phizax[d] = _np.ones((1, ra))
        phizy = [None] * (d + 1)
        phizy[0] = _np.ones((1))  # , 1))
        phizy[d] = _np.ones((1))  # , 1))

    phiyax = [None] * (d + 1)
    if (atype == 1):
        phiyax[0] = _np.ones((1, 1, 1))  # 1
        phiyax[d] = _np.ones((1, 1, 1))  # 1
    else:
        phiyax[0] = _np.ones((1, ra))  # 3
        phiyax[d] = _np.ones((1, ra))

    nrms = _np.ones(d)

    # Initial ort
    for i in range(d - 1):
        if init_qr:
            cr = _reshape(y[i], (ry[i] * n[i], ry[i + 1]))
            if (renorm is 'gram') and (ry[i] * n[i] > 5 * ry[i + 1]):
                [cr, s, R] = _svdgram(cr)
            else:
                [cr, R] = _np.linalg.qr(cr)
            nrmr = _np.linalg.norm(R)  # , 'fro')
            if (nrmr > 0):
                R = R / nrmr
            cr2 = _reshape(y[i + 1], (ry[i + 1], n[i + 1] * ry[i + 2]))
            cr2 = _np.dot(R, cr2)
            ry[i + 1] = cr.shape[1]
            y[i] = _reshape(cr, (ry[i], n[i], ry[i + 1]))
            y[i + 1] = _reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2]))

        [phiyax[i + 1], nrms[i]
         ] = _compute_next_Phi(phiyax[i], y[i], x[i], 'lr', A[i])

        if (kickrank + kickrank2 > 0):
            cr = _reshape(z[i], (rz[i] * n[i], rz[i + 1]))
            if (renorm == 'gram') and (rz[i] * n[i] > 5 * rz[i + 1]):
                [cr, s, R] = _svdgram(cr)
            else:
                [cr, R] = _np.linalg.qr(cr)
            nrmr = _np.linalg.norm(R)  # , 'fro')
            if (nrmr > 0):
                R = R / nrmr
            cr2 = _reshape(z[i + 1], (rz[i + 1], n[i + 1] * rz[i + 2]))
            cr2 = _np.dot(R, cr2)
            rz[i + 1] = cr.shape[1]
            z[i] = _reshape(cr, (rz[i], n[i], rz[i + 1]))
            z[i + 1] = _reshape(cr2, (rz[i + 1], n[i + 1], rz[i + 2]))
            phizax[
                i +
                1] = _compute_next_Phi(
                phizax[i],
                z[i],
                x[i],
                'lr',
                A[i],
                nrms[i],
                return_norm=False)
            phizy[
                i +
                1] = _compute_next_Phi(
                phizy[i],
                z[i],
                y[i],
                'lr',
                return_norm=False)

    i = d - 1
    direct = -1
    swp = 1
    max_dx = 0

    while swp <= nswp:
        # Project the MatVec generating vector
        crx = _reshape(x[i], (rx[i] * m[i] * rx[i + 1], 1))
        cry = _bfun3(phiyax[i], A[i], phiyax[i + 1], crx)
        nrms[i] = _np.linalg.norm(cry)  # , 'fro')
        # The main goal is to keep y[i] of norm 1
        if (nrms[i] > 0):
            cry = cry / nrms[i]
        else:
            nrms[i] = 1
        y[i] = _reshape(y[i], (ry[i] * n[i] * ry[i + 1], 1))
        dx = _np.linalg.norm(cry - y[i])
        max_dx = max(max_dx, dx)

        # Truncation and enrichment
        if ((direct > 0) and (i < d - 1)):  # ?? i<d
            cry = _reshape(cry, (ry[i] * n[i], ry[i + 1]))
            if (renorm == 'gram'):
                [u, s, v] = _svdgram(cry, tol / d**0.5)
                v = v.T
                r = u.shape[1]
            else:
                [u, s, vt] = _np.linalg.svd(cry, full_matrices=False)
                #s = diag(s)
                r = _my_chop2(s, tol * _np.linalg.norm(s) / d**0.5)
                u = u[:, :r]
                # ????? s - matrix or vector
                v = _np.dot(_tconj(vt[:r, :]), _np.diag(s[:r]))

            # Prepare enrichment, if needed
            if (kickrank + kickrank2 > 0):
                cry = _np.dot(u, v.T)
                cry = _reshape(cry, (ry[i] * n[i], ry[i + 1]))
                # For updating z
                crz = _bfun3(phizax[i], A[i], phizax[i + 1], crx)
                crz = _reshape(crz, (rz[i] * n[i], rz[i + 1]))
                ys = _np.dot(cry, phizy[i + 1])
                yz = _reshape(ys, (ry[i], n[i] * rz[i + 1]))
                yz = _np.dot(phizy[i], yz)
                yz = _reshape(yz, (rz[i] * n[i], rz[i + 1]))
                crz = crz / nrms[i] - yz
                nrmz = _np.linalg.norm(crz)  # , 'fro')
                if (kickrank2 > 0):
                    [crz, _, _] = _np.linalg.svd(crz, full_matrices=False)
                    crz = crz[:, : min(crz.shape[1], kickrank)]
                    crz = _np.hstack(
                        (crz, _np.random.randn(
                            rz[i] * n[i], kickrank2)))
                # For adding into solution
                if fkick:
                    crs = _bfun3(phiyax[i], A[i], phizax[i + 1], crx)
                    crs = _reshape(crs, (ry[i] * n[i], rz[i + 1]))
                    crs = crs / nrms[i] - ys
                    u = _np.hstack((u, crs))
                    if (renorm == 'gram') and (
                            ry[i] * n[i] > 5 * (ry[i + 1] + rz[i + 1])):
                        [u, s, R] = _svdgram(u)
                    else:
                        [u, R] = _np.linalg.qr(u)
                    v = _np.hstack((v, _np.zeros((ry[i + 1], rz[i + 1]))))
                    v = _np.dot(v, R.T)
                    r = u.shape[1]
            y[i] = _reshape(u, (ry[i], n[i], r))

            cr2 = _reshape(y[i + 1], (ry[i + 1], n[i + 1] * ry[i + 2]))
            v = _reshape(v, (ry[i + 1], r))
            cr2 = _np.dot(v.T, cr2)
            y[i + 1] = _reshape(cr2, (r, n[i + 1], ry[i + 2]))

            ry[i + 1] = r

            [phiyax[i + 1], nrms[i]
             ] = _compute_next_Phi(phiyax[i], y[i], x[i], 'lr', A[i])

            if (kickrank + kickrank2 > 0):
                if (renorm == 'gram') and (rz[i] * n[i] > 5 * rz[i + 1]):
                    [crz, s, R] = _svdgram(crz)
                else:
                    [crz, R] = _np.linalg.qr(crz)
                rz[i + 1] = crz.shape[1]
                z[i] = _reshape(crz, (rz[i], n[i], rz[i + 1]))
                # z[i+1] will be recomputed from scratch in the next step

                phizax[
                    i +
                    1] = _compute_next_Phi(
                    phizax[i],
                    z[i],
                    x[i],
                    'lr',
                    A[i],
                    nrms[i],
                    return_norm=False)
                phizy[
                    i +
                    1] = _compute_next_Phi(
                    phizy[i],
                    z[i],
                    y[i],
                    'lr',
                    return_norm=False)

        elif ((direct < 0) and (i > 0)):
            cry = _reshape(cry, (ry[i], n[i] * ry[i + 1]))
            if (renorm == 'gram'):
                [v, s, u] = _svdgram(cry.T, tol / d**0.5)
                u = u.T
                r = v.shape[1]
            else:
                #[v, s, u] = _np.linalg.svd(cry.T, full_matrices=False)
                [u, s, vt] = _np.linalg.svd(cry, full_matrices=False)
                #s = diag(s);
                r = _my_chop2(s, tol * _np.linalg.norm(s) / d**0.5)
                v = _tconj(vt[:r, :])

                #v = vt[:r, :]
                #v = _np.dot(v[:, :r], _np.diag(s[:r]))
                u = _np.dot(u[:, :r], _np.diag(s[:r]))  # ??????????????????

            # Prepare enrichment, if needed
            if (kickrank + kickrank2 > 0):
                cry = _np.dot(u, v.T)  # .T)
                cry = _reshape(cry, (ry[i], n[i] * ry[i + 1]))
                # For updating z
                crz = _bfun3(phizax[i], A[i], phizax[i + 1], crx)
                crz = _reshape(crz, (rz[i], n[i] * rz[i + 1]))
                ys = _np.dot(phizy[i], cry)
                yz = _reshape(ys, (rz[i] * n[i], ry[i + 1]))
                yz = _np.dot(yz, phizy[i + 1])
                yz = _reshape(yz, (rz[i], n[i] * rz[i + 1]))
                crz = crz / nrms[i] - yz
                nrmz = _np.linalg.norm(crz)  # , 'fro')
                if (kickrank2 > 0):
                    [_, _, crz] = _np.linalg.svd(crz, full_matrices=False)
                    crz = crz[:, : min(crz.shape[1], kickrank)]
                    crz = _tconj(crz)
                    crz = _np.vstack(
                        (crz, _np.random.randn(kickrank2, n[i] * rz[i + 1])))
                # For adding into solution
                crs = _bfun3(phizax[i], A[i], phiyax[i + 1], crx)
                crs = _reshape(crs, (rz[i], n[i] * ry[i + 1]))
                crs = crs / nrms[i] - ys
                v = _np.hstack((v, crs.T))  # .T
                #v = v.T
                if (renorm == 'gram') and (
                        n[i] * ry[i + 1] > 5 * (ry[i] + rz[i])):
                    [v, s, R] = _svdgram(v)
                else:
                    [v, R] = _np.linalg.qr(v)
                u = _np.hstack((u, _np.zeros((ry[i], rz[i]))))
                u = _np.dot(u, R.T)
                r = v.shape[1]

            cr2 = _reshape(y[i - 1], (ry[i - 1] * n[i - 1], ry[i]))
            cr2 = _np.dot(cr2, u)
            y[i - 1] = _reshape(cr2, (ry[i - 1], n[i - 1], r))
            y[i] = _reshape(v.T, (r, n[i], ry[i + 1]))

            ry[i] = r

            [phiyax[i], nrms[i]] = _compute_next_Phi(
                phiyax[i + 1], y[i], x[i], 'rl', A[i])

            if (kickrank + kickrank2 > 0):
                if (renorm == 'gram') and (n[i] * rz[i + 1] > 5 * rz[i]):
                    [crz, s, R] = _svdgram(crz.T)
                else:
                    [crz, R] = _np.linalg.qr(crz.T)
                rz[i] = crz.shape[1]
                z[i] = _reshape(crz.T, (rz[i], n[i], rz[i + 1]))
                # don't update z[i-1], it will be recomputed from scratch

                phizax[i] = _compute_next_Phi(
                    phizax[
                        i + 1],
                    z[i],
                    x[i],
                    'rl',
                    A[i],
                    nrms[i],
                    return_norm=False)
                phizy[i] = _compute_next_Phi(
                    phizy[i + 1], z[i], y[i], 'rl', return_norm=False)

        if (verb > 1):
            print('amen-mv: swp=[%d,%d], dx=%.3e, r=%d, |y|=%.3e, |z|=%.3e' % (swp, i, dx, r, _np.linalg.norm(cry), nrmz))

        # Stopping or reversing
        if ((direct > 0) and (i == d - 1)) or ((direct < 0) and (i == 0)):
            if (verb > 0):
                print('amen-mv: swp=%d{%d}, max_dx=%.3e, max_r=%d' % (swp, (1 - direct) // 2, max_dx, max(ry)))
            if ((max_dx < tol) or (swp == nswp)) and (direct > 0):
                break
            else:
                # We are at the terminal block
                y[i] = _reshape(cry, (ry[i], n[i], ry[i + 1]))
                if (direct > 0):
                    swp = swp + 1
            max_dx = 0
            direct = -direct
        else:
            i = i + direct
    # if (direct>0)
    y[d - 1] = _reshape(cry, (ry[d - 1], n[d - 1], ry[d]))
    # else
    #     y{1} = reshape(cry, ry(1), n(1), ry(2));
    # end;

    # Distribute norms equally...
    nrms = _np.exp(sum(_np.log(nrms)) / d)
    # ... and plug them into y
    for i in xrange(d):
        y[i] = _np.dot(y[i], nrms)

    if (vectype == 1):
        y = _tt.vector.from_list(y)
        if kickrank == 0:
            z = None
        else:
            z = _tt.vector.from_list(z)

    return y, z
Example #24
0
"""Example of using tt.optimize module."""

import tt
from tt.optimize import tt_min
from scipy.optimize import rosen


def my_rosen(x):
    return rosen(x.T)

print("Minimize 4-d Rosenbrock function on a 4-dimensional grid (512 points " +
      "along each dimension). The global minimum is 0 in the (1, 1, 1, 1) point.")
val, x_full = tt_min.min_func(my_rosen, -2, 2, d=4, n0=512, rmax=10, nswp=30)

tens = tt.rand([3, 4, 5, 4, 3], 5, 3)
min_element = min(tens.full().flatten())
print("Minimize random 5-dimensional TT tensor with ranks equal to 3. " +
      "The minimal element is %f" % min_element)
val, point = tt_min.min_tens(tens, rmax=10, nswp=30)
Example #25
0
def multifuncrs2(X, funs, eps = 1e-6, \
                nswp = 10, \
                rmax = 9999999, \
                verb = 1, \
                kickrank = 5, \
                kickrank2 = 0, \
                d2 = 1, \
                eps_exit = None, \
                y0 = None, \
                do_qr = False, \
                restart_it = 0):

    dtype = np.float64
    if len(filter(lambda x: x.is_complex, X)) > 0:
        dtype = np.complex128

    if eps_exit is None:
        eps_exit = eps
    y = y0
    nx = len(X)
    d = X[0].d
    n = X[0].n
    rx = np.transpose(np.array([ttx.r for ttx in X]))
    crx = np.empty((nx, d), dtype=np.object)
    i = 0
    for ttx in X:
        v = tt.tensor.to_list(ttx)
        j = 0
        for w in v:
            crx[i, j] = w
            j = j + 1
        i = i + 1
    crx = crx.T
    wasrand = False
    if y is None:
        ry = d2 * np.ones((d + 1, ), dtype=np.int32)
        ry[0] = 1
        y = tt.rand(n, d, ry)
        wasrand = True

    #Error vector
    z = tt.rand(n, d, kickrank)
    rz = z.r
    z = tt.tensor.to_list(z)

    ry = y.r
    cry = tt.tensor.to_list(y)

    #Interface matrices - for solution
    one_arr = np.ones((1, 1), dtype=dtype)
    Ry = np.zeros((d + 1, ), dtype=np.object)
    Ry[0] = one_arr
    Ry[d] = one_arr
    Rx = np.zeros((d + 1, nx), dtype=np.object)
    Rx[0, :] = np.ones(nx, dtype=dtype)
    Rx[d, :] = np.ones(nx, dtype=dtype)
    Ryz = np.zeros((d + 1, ), dtype=np.object)
    Ryz[0] = one_arr
    Ryz[d] = one_arr
    Rz = np.zeros((d + 1, ), dtype=np.object)
    Rz[0] = one_arr
    Rz[d] = one_arr
    Rxz = np.zeros((d + 1, nx), dtype=np.object)
    Rxz[0, :] = np.ones(nx, dtype=dtype)
    Rxz[d, :] = np.ones(nx, dtype=dtype)
    block_order = [+d, -d]
    # orth
    for i in range(0, d - 1):
        cr = cry[i]
        cr = reshape(cr, (ry[i] * n[i], ry[i + 1]))
        cr, rv = np.linalg.qr(cr)
        cr2 = cry[i + 1]
        cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2]))
        cr2 = np.dot(rv, cr2)  # matrix multiplication
        ry[i + 1] = cr.shape[1]
        cr = reshape(cr, (ry[i], n[i], ry[i + 1]))
        cry[i + 1] = reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2]))
        cry[i] = cr

        Ry[i + 1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i + 1])))
        Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1]))
        curind = []
        if wasrand:
            # EVERY DAY I'M SHUFFLIN'
            curind = np.random.permutation(n[i] * ry[i])[:ry[i + 1]]
        else:
            curind = maxvol(Ry[i + 1])
        Ry[i + 1] = Ry[i + 1][curind, :]
        #Interface matrices for X
        for j in range(0, nx):
            Rx[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
            Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j])
            Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j]))
            Rx[i + 1, j] = Rx[i + 1, j][curind, :]

        #Error for kick
        crz = z[i]
        crz = reshape(crz, (rz[i] * n[i], rz[i + 1]))
        crz, rv = np.linalg.qr(crz)
        cr2 = z[i + 1]
        cr2 = reshape(cr2, (rz[i + 1], n[i + 1] * rz[i + 2]))
        cr2 = np.dot(rv, cr2)
        rz[i + 1] = crz.shape[1]
        crz = reshape(crz, (rz[i], n[i], rz[i + 1]))
        z[i + 1] = reshape(cr2, (rz[i + 1], n[i + 1], rz[i + 2]))
        z[i] = crz

        #Interfaces for error
        Rz[i + 1] = np.dot(Rz[i], reshape(crz, [rz[i], n[i] * rz[i + 1]]))
        Rz[i + 1] = reshape(Rz[i + 1], [rz[i] * n[i], rz[i + 1]])
        Ryz[i + 1] = np.dot(Ryz[i], reshape(cr, [ry[i], n[i] * ry[i + 1]]))
        Ryz[i + 1] = reshape(Ryz[i + 1], [rz[i] * n[i], ry[i + 1]])
        #Pick random initial indices
        curind = np.random.permutation(n[i] * rz[i])[:rz[i + 1]]
        Ryz[i + 1] = Ryz[i + 1][curind, :]
        Rz[i + 1] = Rz[i + 1][curind, :]
        #Interface matrices for X
        for j in range(0, nx):
            Rxz[i + 1, j] = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
            Rxz[i + 1, j] = np.dot(Rxz[i, j], Rxz[i + 1, j])
            Rxz[i + 1, j] = reshape(Rxz[i + 1, j],
                                    (rz[i] * n[i], rx[i + 1, j]))
            Rxz[i + 1, j] = Rxz[i + 1, j][curind, :]

    d2 = ry[d]
    ry[d] = 1
    cry[d - 1] = np.transpose(cry[d - 1], [2, 0, 1])  # permute

    swp = 1
    max_dy = 0.0
    cur_order = copy.copy(block_order)
    order_index = 1
    i = d - 1
    dirn = int(math.copysign(
        1, cur_order[order_index]))  # can't use 'dir' identifier in python

    #DMRG sweeps
    while swp <= nswp or dirn > 0:
        oldy = reshape(cry[i], (d2 * ry[i] * n[i] * ry[i + 1], ))
        #Compute X superblocks
        curbl = np.zeros((ry[i] * n[i] * ry[i + 1], nx), dtype)
        for j in range(0, nx):
            cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
            cr = np.dot(Rx[i, j], cr)
            cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j]))
            cr = np.dot(cr, Rx[i + 1, j])
            curbl[:, j] = cr.flatten('F')
        newy = funs(curbl)
        # multiply with inverted Ry
        newy = reshape(newy, (ry[i], n[i] * ry[i + 1] * d2))
        newy = np.linalg.solve(Ry[i], newy)  # y = R \ y
        newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2))
        newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i + 1]))
        newy = np.transpose(
            np.linalg.solve(np.transpose(Ry[i + 1]),
                            np.transpose(newy)))  # y=y/R
        newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i + 1], ))
        try:
            dy = np.linalg.norm(newy - oldy) / np.linalg.norm(newy)
        except ZeroDivisionError:
            print 'Bad initial indices, the solution is exactly zero. Restarting'
            return
        max_dy = max(max_dy, dy)

        # truncation
        if dirn > 0:  # left-to-right
            newy = reshape(newy, (d2, ry[i] * n[i] * ry[i + 1]))
            newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i + 1] * d2))
        else:
            newy = reshape(newy, (d2 * ry[i], n[i] * ry[i + 1]))

        if kickrank >= 0:
            try:
                u, s, v = np.linalg.svd(newy, full_matrices=False)
            except:
                tmp = np.array(np.random.randn(newy.shape[1], newy.shape[1]),
                               dtype=dtype)
                tmp, ru_tmp = np.linalg.qr(tmp)
                u, s, v = np.linalg.svd(np.dot(newy, tmp))
                #u * s * v = A * tmp
                v = np.dot(v, np.conj(tmp).T)
            v = np.conj(np.transpose(v))
            r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s))
        else:
            if dirn > 0:
                u, v = np.linalg.qr(newy)
                v = np.conj(np.transpose(v))
                r = u.shape[1]
                s = np.ones((r, ))
            else:
                v, u = np.linalg.qr(np.transpose(newy))
                v = np.conj(v)
                u = np.transpose(u)
                r = u.shape[1]
                s = np.ones((r, ))
        if verb > 1:
            print '=multifuncrs=   block %d{%d}, dy: %3.3e, r: %d' % (i, dirn,
                                                                      dy, r)
        #Kicks and interfaces
        if dirn > 0 and i < d - 1:
            u = u[:, :r]
            v = np.dot(v[:, :r], np.diag(s[:r]))
            # kick
            radd = 0
            rv = 1
            if kickrank > 0:
                #Compute the function at residual indices
                curbl_y = np.zeros((ry[i] * n[i] * rz[i + 1], nx), dtype=dtype)
                curbl_z = np.zeros((rz[i] * n[i] * rz[i + 1], nx), dtype=dtype)
                for j in xrange(nx):
                    #For kick
                    cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                    cr = np.dot(Rx[i, j], cr)
                    cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j]))
                    cr = np.dot(cr, Rxz[i + 1, j])
                    curbl_y[:, j] = cr.flatten('F')
                    #For z update
                    cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                    cr = np.dot(Rxz[i, j], cr)
                    cr = reshape(cr, (rz[i] * n[i], rx[i + 1, j]))
                    cr = np.dot(cr, Rxz[i + 1, j])
                    curbl_z[:, j] = cr.flatten('F')
                #Call the function
                zy = reshape(funs(curbl_y), (-1, d2))
                zz = reshape(funs(curbl_z), (-1, d2))
                #Assemble y at z indices (sic!) and subtract
                dzy = reshape(np.dot(u, v.T), (ry[i] * n[i] * ry[i + 1], d2))
                dzy = reshape(dzy.T, (d2 * ry[i] * n[i], ry[i + 1]))
                #Cast dzy from core items to samples at right indices
                dzy = np.dot(dzy, Ryz[i + 1])
                dzy = reshape(dzy, (d2, ry[i] * n[i] * rz[i + 1]))
                dzy = dzy.T
                #zy still requires casting from samples to core entities
                zy = reshape(zy, (ry[i], n[i] * rz[i + 1] * d2))
                zy = np.linalg.solve(Ry[i], zy)
                zy = reshape(zy, (ry[i] * n[i] * rz[i + 1], d2))
                zy = zy - dzy
                dzy = reshape(dzy, (ry[i], n[i] * rz[i + 1] * d2))
                dzy = np.dot(Ryz[i], dzy)
                dzy = reshape(
                    dzy,
                    (rz[i] * n[i] * rz[i + 1], d2))  #Sample from both sizes
                zz = zz - dzy
                #Interpolate all remaining samples into core elements
                zy = reshape(zy.T, (d2 * ry[i] * n[i], rz[i + 1]))
                zy = np.linalg.solve(Rz[i + 1].T, zy.T).T
                zy = reshape(zy, (d2, ry[i] * n[i] * rz[i + 1]))
                zy = reshape(zy.T, (ry[i] * n[i], rz[i + 1] * d2))
                #SVD to eliminate d2 and possibly overestimated rz
                zy, sz, vz = np.linalg.svd(zy, full_matrices=False)
                zy = zy[:, :min(kickrank, zy.shape[1])]
                # For z update
                zz = reshape(zz, (rz[i], n[i] * rz[i + 1] * d2))
                zz = np.linalg.solve(Rz[i], zz)
                zz = reshape(zz, (rz[i] * n[i] * rz[i + 1], d2))
                zz = reshape(zz.T, (d2 * rz[i] * n[i], rz[i + 1]))
                zz = np.linalg.solve(Rz[i + 1].T, zz.T).T
                zz = reshape(zz, (d2, rz[i] * n[i] * rz[i + 1]))
                zz = reshape(zz.T, (rz[i] * n[i], rz[i + 1] * d2))
                zz, sz, vz = np.linalg.svd(zz, full_matrices=False)
                zz = zz[:, :min(kickrank, zz.shape[1])]
                #Second random kick rank
                zz = np.hstack((zz, np.random.randn(rz[i] * n[i], kickrank2)))
                u, rv = np.linalg.qr(np.hstack((u, zy)))
                radd = zy.shape[1]
            v = np.hstack((v, np.zeros((ry[i + 1] * d2, radd), dtype=dtype)))
            v = np.dot(rv, v.T)
            r = u.shape[1]
            cr2 = cry[i + 1]
            cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2]))
            v = reshape(v, (r * ry[i + 1], d2))
            v = reshape(v.T, (d2 * r, ry[i + 1]))
            v = np.dot(v, cr2)
            ry[i + 1] = r
            u = reshape(u, (ry[i], n[i], r))
            v = reshape(v, (d2, r, n[i + 1], ry[i + 2]))
            #Stuff back
            cry[i] = u
            cry[i + 1] = v
            # Update kick
            zz, rv = np.linalg.qr(zz)
            rz[i + 1] = zz.shape[1]
            z[i] = reshape(zz, (rz[i], n[i], rz[i + 1]))
            #z[i + 1] is recomputed from scratch we do not need it now

            #Compute left interface matrices
            #Interface matrix for Y
            Ry[i + 1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i + 1])))
            Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1]))
            curind = maxvol(Ry[i + 1])
            Ry[i + 1] = Ry[i + 1][curind, :]
            #Interface matrices for X
            for j in xrange(nx):
                Rx[i + 1, j] = reshape(crx[i, j],
                                       (rx[i, j], n[i] * rx[i + 1, j]))
                Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j])
                Rx[i + 1, j] = reshape(Rx[i + 1, j],
                                       (ry[i] * n[i], rx[i + 1, j]))
                Rx[i + 1, j] = Rx[i + 1, j][curind, :]
            #for kick
            Ryz[i + 1] = np.dot(Ryz[i], reshape(u, (ry[i], n[i] * ry[i + 1])))
            Ryz[i + 1] = reshape(Ryz[i + 1], (rz[i] * n[i], ry[i + 1]))
            Rz[i + 1] = np.dot(Rz[i], reshape(zz, (rz[i], n[i] * rz[i + 1])))
            Rz[i + 1] = reshape(Rz[i + 1], (rz[i] * n[i], rz[i + 1]))
            curind = maxvol(Rz[i + 1])
            Ryz[i + 1] = Ryz[i + 1][curind, :]
            Rz[i + 1] = Rz[i + 1][curind, :]
            #Interface matrices for X
            for j in xrange(nx):
                Rxz[i + 1, j] = reshape(crx[i, j],
                                        (rx[i, j], n[i] * rx[i + 1, j]))
                Rxz[i + 1, j] = np.dot(Rxz[i, j], Rxz[i + 1, j])
                Rxz[i + 1, j] = reshape(Rxz[i + 1, j],
                                        (rz[i] * n[i], rx[i + 1, j]))
                Rxz[i + 1, j] = Rxz[i + 1, j][curind, :]
        elif dirn < 0 and i > 0:  # Right to left
            u = np.dot(u[:, :r], np.diag(s[:r]))
            v = np.conj(v[:, :r])
            #kick
            radd = 0
            rv = 0
            if kickrank > 0:
                #AMEN kick
                #Compute the function at residual indices
                curbl_y = np.zeros((rz[i] * n[i] * ry[i + 1], nx), dtype=dtype)
                curbl_z = np.zeros((rz[i] * n[i] * rz[i + 1], nx), dtype=dtype)
                for j in xrange(nx):
                    cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                    cr = np.dot(Rxz[i, j], cr)
                    cr = reshape(cr, (rz[i] * n[i], rx[i + 1, j]))
                    cr = np.dot(cr, Rx[i + 1, j])
                    curbl_y[:, j] = cr.flatten('F')
                    #for z update
                    cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                    cr = np.dot(Rxz[i, j], cr)
                    cr = reshape(cr, (rz[i] * n[i], rx[i + 1, j]))
                    cr = np.dot(cr, Rxz[i + 1, j])
                    curbl_z[:, j] = cr.flatten('F')
                #Call the function
                zy = reshape(funs(curbl_y), (-1, d2))
                zz = reshape(funs(curbl_z), (-1, d2))
                #Assemble y at z indices (sic!) and subtract
                dzy = reshape(np.dot(u, v.T), (ry[i], n[i] * ry[i + 1] * d2))
                dzy = np.dot(Ryz[i], dzy)
                dzy = reshape(dzy, (rz[i] * n[i] * ry[i + 1], d2))
                # zy still requires casting from samples to core entries
                zy = zy.T
                zy = reshape(zy, (d2 * rz[i] * n[i], ry[i + 1]))
                zy = np.linalg.solve(Ry[i + 1].T, zy.T).T
                zy = reshape(zy, (d2, rz[i] * n[i] * ry[i + 1]))
                zy = zy.T
                zy = zy - dzy
                dzy = reshape(dzy.T, (d2 * rz[i] * n[i], ry[i + 1]))
                dzy = np.dot(dzy, Ryz[i + 1])
                dzy = reshape(dzy, (d2, rz[i] * n[i] * rz[i + 1]))
                zz = zz - dzy.T
                # Cast sample indices to core elements
                # ...for kick
                zy = reshape(zy, (rz[i], n[i] * ry[i + 1] * d2))
                zy = np.linalg.solve(Rz[i], zy)
                zy = reshape(zy, (rz[i] * n[i] * ry[i + 1], d2))
                zy = zy.T
                zy = reshape(zy, (d2 * rz[i], n[i] * ry[i + 1]))
                zu, zs, zy = np.linalg.svd(zy, full_matrices=False)
                zy = zy[:min(kickrank, zy.shape[0]), :]
                zy = zy.T

                # ...for z update
                zz = reshape(zz, (rz[i], n[i] * rz[i + 1] * d2))
                zz = np.linalg.solve(Rz[i], zz)
                zz = reshape(zz, (rz[i] * n[i] * rz[i + 1], d2))
                zz = reshape(zz.T, (d2 * rz[i] * n[i], rz[i + 1]))
                zz = np.linalg.solve(Rz[i + 1].T, zz.T).T
                zz = reshape(zz, (d2 * rz[i], n[i] * rz[i + 1]))
                zu, zs, zz = np.linalg.svd(zz, full_matrices=False)
                zz = zz[:min(kickrank, zz.shape[0]), :]
                zz = zz.T
                zz = np.hstack((zz, np.random.randn(n[i] * rz[i + 1],
                                                    kickrank2)))
                v, rv = np.linalg.qr(np.hstack((v, zy)))
                radd = zy.shape[1]
            u = np.hstack((u, np.zeros((d2 * ry[i], radd), dtype=dtype)))
            u = np.dot(u, rv.T)
            r = v.shape[1]
            cr2 = cry[i - 1]
            cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], ry[i]))
            u = reshape(u, (d2, ry[i] * r))
            u = reshape(u.T, (ry[i], r * d2))
            u = np.dot(cr2, u)
            u = reshape(u, (ry[i - 1] * n[i - 1] * r, d2))
            u = reshape(u.T, (d2, ry[i - 1], n[i - 1], r))
            v = reshape(v.T, (r, n[i], ry[i + 1]))
            # Stuff back
            ry[i] = r
            cry[i - 1] = u
            cry[i] = v
            #kick
            zz, rv = np.linalg.qr(zz)
            rz[i] = zz.shape[1]
            zz = reshape(zz.T, (rz[i], n[i], rz[i + 1]))
            z[i] = zz
            #z[i - 1] is recomputed from scratch we do not need it

            # Recompute left interface matrices
            # Interface matrix for Y
            Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ry[i + 1])
            Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i + 1]))
            curind = maxvol(Ry[i].T)
            Ry[i] = Ry[i][:, curind]
            # Interface matrices for X
            for j in xrange(nx):
                Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j]))
                Rx[i, j] = np.dot(Rx[i, j], Rx[i + 1, j])
                Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i + 1]))
                Rx[i, j] = Rx[i, j][:, curind]
            # for kick
            Rz[i] = np.dot(reshape(zz, (rz[i] * n[i], rz[i + 1])), Rz[i + 1])
            Rz[i] = reshape(Rz[i], (rz[i], n[i] * rz[i + 1]))
            Ryz[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ryz[i + 1])
            Ryz[i] = reshape(Ryz[i], (ry[i], n[i] * rz[i + 1]))
            curind = maxvol(Rz[i].T)
            Ryz[i] = Ryz[i][:, curind]
            Rz[i] = Rz[i][:, curind]
            # Interface matrices for X
            for j in xrange(nx):
                Rxz[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j]))
                Rxz[i, j] = np.dot(Rxz[i, j], Rxz[i + 1, j])
                Rxz[i, j] = reshape(Rxz[i, j], (rx[i, j], n[i] * rz[i + 1]))
                Rxz[i, j] = Rxz[i, j][:, curind]
        elif dirn > 0 and i == d - 1:
            #Just stuff back the last core
            newy = np.dot(u[:, :r], np.dot(np.diag(s[:r]),
                                           np.conj(v[:, :r].T)))
            newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2))
            cry[i] = reshape(newy.T, (d2, ry[i], n[i], ry[i + 1]))
        elif dirn < 0 and i is 0:
            newy = np.dot(u[:, :r], np.dot(np.diag(s[:r]),
                                           np.conj(v[:, :r].T)))
            newy = reshape(newy, (d2, ry[i], n[i], ry[i + 1]))
            cry[i] = newy
        i += dirn
        # Reversing, residue check, etc
        cur_order[order_index] = cur_order[order_index] - dirn
        # New direction
        if cur_order[order_index] == 0:
            order_index = order_index + 1
            if verb > 0:
                print '=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy, \
                    math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n)))
            if max_dy < eps_exit:
                break

            if order_index >= len(cur_order):  #New global sweep
                cur_order = copy.copy(block_order)
                order_index = 0
                max_dy = 0
                swp = swp + 1
            dirn = int(math.copysign(1, cur_order[order_index]))
            i = i + dirn
    cry[d - 1] = np.transpose(cry[d - 1][:, :, :, 0], [1, 2, 0])
    y = tt.tensor.from_list(cry)
    return y
Example #26
0
# Simulate artificial covariates
x = np.random.randn(d * np.size(y)) / d
x = np.reshape(x, [d, np.size(y)], order='F')

# short index function for cross
myfun = lambda ind: crossfun(ind, theta, x, y, censind, beta_mean, beta_var)

print('Running ' + repr(runs) + ' tests for ' + repr(d) +
      ' covariates, producing ' + repr(2**log2N) + ' samples')
print('')

Q_py = runs * [None]
tau = runs * [None]
for irun in range(0, runs):
    # Run cross
    f0 = tt.rand(n, d + 2, 8)
    f = rect_cross.cross(myfun, f0, nswp=50, kickrank=2, rf=2, eps=tol)
    print(f)

    # Seed points
    M = 2**log2N
    q = np.random.random([M, d + 2])
    q = np.reshape(q, [M, d + 2], order='F')

    ttt = time.time()
    # Sample
    Z, lPz = tt_irt1(q, f, theta_f)
    ttimes_invcdf = time.time() - ttt
    print('Sampling time = ' + repr(ttimes_invcdf))

    Z = np.reshape(Z, [M, d + 2], order='F')  # Proposed samples
Example #27
0
"""Example of using tt.optimize module."""

import tt
from tt.optimize import tt_min
from scipy.optimize import rosen


def my_rosen(x):
    return rosen(x.T)


print(
    "Minimize 4-d Rosenbrock function on a 4-dimensional grid (512 points " +
    "along each dimension). The global minimum is 0 in the (1, 1, 1, 1) point."
)
val, x_full = tt_min.min_func(my_rosen, -2, 2, d=4, n0=512, rmax=10, nswp=30)

tens = tt.rand([3, 4, 5, 4, 3], 5, 3)
min_element = min(tens.full().flatten())
print("Minimize random 5-dimensional TT tensor with ranks equal to 3. " +
      "The minimal element is %f" % min_element)
val, point = tt_min.min_tens(tens, rmax=10, nswp=30)
Example #28
0
def multifuncrs(X, funs, eps=1E-6,
                nswp=10,
                kickrank=5,
                y0=None,
                rmax=999999,  # TODO:infinity \
                kicktype='amr-two',        \
                pcatype='svd',             \
                trunctype='fro',           \
                d2=1,                      \
                do_qr=False,               \
                verb=1):
    """Cross approximation of a (vector-)function of several TT-tensors.

    :param X: tuple of TT-tensors
    :param funs: multivariate function
    :param eps: accuracy
    """

    dtype = np.float64
    if len(filter(lambda x: x.is_complex, X)) > 0:
        dtype = np.complex128

    y = y0
    wasrand = False

    nx = len(X)
    d = X[0].d
    n = X[0].n
    rx = np.transpose(np.array([ttx.r for ttx in X]))
    #crx = [tt.tensor.to_list(ttx) for x in X]
    #crx = zip(*crx)
    crx = np.transpose(np.array([tt.tensor.to_list(ttx)
                                 for ttx in X], dtype=np.object))
    crx = np.empty((nx, d), dtype=np.object)
    i = 0
    for ttx in X:
        v = tt.tensor.to_list(ttx)
        j = 0
        for w in v:
            crx[i, j] = w
            j = j + 1
        i = i + 1
    crx = crx.T
    if y is None:
        ry = d2 * np.ones((d + 1,), dtype=np.int32)
        ry[0] = 1
        y = tt.rand(n, d, ry)
        wasrand = True

    ry = y.r
    cry = tt.tensor.to_list(y)

    Ry = np.zeros((d + 1, ), dtype=np.object)
    Ry[0] = np.array([[1.0]], dtype=dtype)
    Ry[d] = np.array([[1.0]], dtype=dtype)
    Rx = np.zeros((d + 1, nx), dtype=np.object)
    Rx[0, :] = np.ones(nx, dtype=dtype)
    Rx[d, :] = np.ones(nx, dtype=dtype)

    block_order = [+d, -d]

    # orth
    for i in range(0, d - 1):
        cr = cry[i]
        cr = reshape(cr, (ry[i] * n[i], ry[i + 1]))
        cr, rv = np.linalg.qr(cr)
        cr2 = cry[i + 1]
        cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2]))
        cr2 = np.dot(rv, cr2)  # matrix multiplication
        ry[i + 1] = cr.shape[1]
        cr = reshape(cr, (ry[i], n[i], ry[i + 1]))
        cry[i + 1] = reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2]))
        cry[i] = cr

        Ry[i + 1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i + 1])))
        Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1]))
        curind = []
        if wasrand:
            # EVERY DAY I'M SHUFFLIN'
            curind = np.random.permutation(n[i] * ry[i])[:ry[i + 1]]
        else:
            curind = maxvol(Ry[i + 1])
        Ry[i + 1] = Ry[i + 1][curind, :]
        for j in range(0, nx):
            try:
                Rx[i + 1, j] = reshape(crx[i, j],
                                       (rx[i, j], n[i] * rx[i + 1, j]))
            except:
                pass
            Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j])
            Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j]))
            Rx[i + 1, j] = Rx[i + 1, j][curind, :]

    d2 = ry[d]
    ry[d] = 1
    cry[d - 1] = np.transpose(cry[d - 1], [2, 0, 1])  # permute

    last_sweep = False
    swp = 1

    dy = np.zeros((d, ))
    max_dy = 0

    cur_order = copy.copy(block_order)
    order_index = 1
    i = d - 1
    # can't use 'dir' identifier in python
    dirn = int(math.copysign(1, cur_order[order_index]))

    # DMRG sweeps
    while swp <= nswp or dirn > 0:

        oldy = reshape(cry[i], (d2 * ry[i] * n[i] * ry[i + 1],))

        if not last_sweep:
            # compute the X superblocks
            curbl = np.zeros((ry[i] * n[i] * ry[i + 1], nx), dtype=dtype)
            for j in range(0, nx):
                cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                cr = np.dot(Rx[i, j], cr)
                cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j]))
                cr = np.dot(cr, Rx[i + 1, j])
                curbl[:, j] = cr.flatten('F')
            # call the function
            newy = funs(curbl)
            # multiply with inverted Ry
            newy = reshape(newy, (ry[i], n[i] * ry[i + 1] * d2))
            newy = np.linalg.solve(Ry[i], newy)  # y = R \ y
            newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2))
            newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i + 1]))
            newy = np.transpose(np.linalg.solve(
                np.transpose(Ry[i + 1]), np.transpose(newy)))  # y=y/R
            newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i + 1],))
        else:
            newy = oldy

        dy[i] = np.linalg.norm(newy - oldy) / np.linalg.norm(newy)
        max_dy = max(max_dy, dy[i])

        # truncation
        if dirn > 0:  # left-to-right
            newy = reshape(newy, (d2, ry[i] * n[i] * ry[i + 1]))
            newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i + 1] * d2))
        else:
            newy = reshape(newy, (d2 * ry[i], n[i] * ry[i + 1]))

        r = 0  # defines a variable in global scope

        if kickrank >= 0:
            u, s, v = np.linalg.svd(newy, full_matrices=False)
            v = np.conj(np.transpose(v))
            if trunctype == "fro" or last_sweep:
                r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s))
            else:
                # truncate taking into account the (r+1) overhead in the cross
                # (T.S.: what?)
                cums = abs(s * np.arange(2, len(s) + 2)) ** 2
                cums = np.cumsum(cums[::-1])[::-1]
                cums = cums / cums[0]
                ff = [i for i in range(len(cums)) if cums[i] < eps ** 2 / d]
                if len(ff) == 0:
                    r = len(s)
                else:
                    r = np.amin(ff)
            r = min(r, rmax, len(s))
        else:
            if dirn > 0:
                u, v = np.linalg.qr(newy)
                v = np.conj(np.transpose(v))
                r = u.shape[1]
                s = np.ones((r, ))
            else:
                v, u = np.linalg.qr(np.transpose(newy))
                v = np.conj(v)
                u = np.transpose(u)
                r = u.shape[1]
                s = np.ones((r, ))

        if verb > 1:
            print '=multifuncrs=   block %d{%d}, dy: %3.3e, r: %d' % (i, dirn, dy[i], r)

        # kicks and interfaces
        if dirn > 0 and i < d - 1:
            u = u[:, :r]
            v = np.dot(v[:, :r], np.diag(s[:r]))

            # kick
            radd = 0
            rv = 1
            if not last_sweep and kickrank > 0:
                uk = None
                if kicktype == 'amr-two':
                    # AMR(two)-like kick.

                    # compute the X superblocks
                    ind2 = np.unique(np.random.randint(
                        0, ry[i + 2] * n[i + 1], ry[i + 1]))
                    #ind2 = np.unique(np.floor(np.random.rand(ry[i + 1]) * (ry[i + 2] * n[i + 1])))
                    rkick = len(ind2)
                    curbl = np.zeros((ry[i] * n[i] * rkick, nx), dtype=dtype)
                    for j in range(nx):
                        cr1 = reshape(
                            crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                        cr1 = np.dot(Rx[i, j], cr1)
                        cr1 = reshape(cr1, (ry[i] * n[i], rx[i + 1, j]))
                        cr2 = reshape(
                            crx[i + 1, j], (rx[i + 1, j] * n[i + 1], rx[i + 2, j]))
                        cr2 = np.dot(cr2, Rx[i + 2, j])
                        cr2 = reshape(
                            cr2, (rx[i + 1, j], n[i + 1] * ry[i + 2]))
                        cr2 = cr2[:, ind2]
                        curbl[:, j] = reshape(
                            np.dot(cr1, cr2), (ry[i] * n[i] * rkick,))
                    # call the function
                    uk = funs(curbl)
                    uk = reshape(uk, (ry[i], n[i] * rkick * d2))
                    uk = np.linalg.solve(Ry[i], uk)
                    uk = reshape(uk, (ry[i] * n[i], rkick * d2))
                    if pcatype == 'svd':
                        uk, sk, vk = np.linalg.svd(uk, full_matrices=False)
                        vk = np.conj(np.transpose(vk))
                        uk = uk[:, :min(kickrank, uk.shape[1])]
                    else:
                        # uk = uchol(np.transpose(uk), kickrank + 1) # TODO
                        uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1]
                else:
                    uk = np.random.rand(ry[i] * n[i], kickrank)
                u, rv = np.linalg.qr(np.concatenate((u, uk), axis=1))
                radd = uk.shape[1]
            v = np.concatenate(
                (v, np.zeros((ry[i + 1] * d2, radd), dtype=dtype)), axis=1)
            v = np.dot(rv, np.conj(np.transpose(v)))
            r = u.shape[1]

            cr2 = cry[i + 1]
            cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2]))
            v = reshape(v, (r * ry[i + 1], d2))
            v = reshape(np.transpose(v), (d2 * r, ry[i + 1]))
            v = np.dot(v, cr2)

            ry[i + 1] = r

            u = reshape(u, (ry[i], n[i], r))
            v = reshape(v, (d2, r, n[i + 1], ry[i + 2]))

            cry[i] = u
            cry[i + 1] = v

            Ry[i + 1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i + 1])))
            Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1]))
            curind = maxvol(Ry[i + 1])
            Ry[i + 1] = Ry[i + 1][curind, :]
            for j in range(nx):
                Rx[i + 1, j] = reshape(crx[i, j],
                                       (rx[i, j], n[i] * rx[i + 1, j]))
                Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j])
                Rx[i + 1, j] = reshape(Rx[i + 1, j],
                                       (ry[i] * n[i], rx[i + 1, j]))
                Rx[i + 1, j] = Rx[i + 1, j][curind, :]
        elif dirn < 0 and i > 0:
            u = np.dot(u[:, :r], np.diag(s[:r]))
            v = np.conj(v[:, :r])

            radd = 0
            rv = 1
            if not last_sweep and kickrank > 0:
                if kicktype == 'amr-two':
                    # compute the X superblocks
                    ind2 = np.unique(np.random.randint(
                        0, ry[i - 1] * n[i - 1], ry[i]))
                    rkick = len(ind2)
                    curbl = np.zeros(
                        (rkick * n[i] * ry[i + 1], nx), dtype=dtype)
                    for j in range(nx):
                        cr1 = reshape(
                            crx[i, j], (rx[i, j] * n[i], rx[i + 1, j]))
                        cr1 = np.dot(cr1, Rx[i + 1, j])
                        cr1 = reshape(cr1, (rx[i, j], n[i] * ry[i + 1]))
                        cr2 = reshape(
                            crx[i - 1, j], (rx[i - 1, j], n[i - 1] * rx[i, j]))
                        cr2 = np.dot(Rx[i - 1, j], cr2)
                        cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], rx[i, j]))
                        cr2 = cr2[ind2, :]
                        curbl[:, j] = reshape(
                            np.dot(cr2, cr1), (rkick * n[i] * ry[i + 1],))
                    # calling the function
                    uk = funs(curbl)
                    uk = reshape(uk, (rkick * n[i] * ry[i + 1], d2))
                    uk = reshape(np.transpose(
                        uk), (d2 * rkick * n[i], ry[i + 1]))
                    uk = np.transpose(np.linalg.solve(
                        np.transpose(Ry[i + 1]), np.transpose(uk)))
                    uk = reshape(uk, (d2 * rkick, n[i] * ry[i + 1]))
                    if pcatype == 'svd':
                        vk, sk, uk = np.linalg.svd(uk, full_matrices=False)
                        uk = np.conj(np.transpose(uk))
                        # TODO: refactor
                        uk = uk[:, :min(kickrank, uk.shape[1])]
                    else:
                        # uk = uchol(uk, kickrank + 1) # TODO
                        uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1]
                else:
                    uk = np.random.rand(n[i] * ry[i + 1], kickrank)
                v, rv = np.linalg.qr(np.concatenate((v, uk), axis=1))
                radd = uk.shape[1]
            u = np.concatenate(
                (u, np.zeros((d2 * ry[i], radd), dtype=dtype)), axis=1)
            u = np.dot(u, np.transpose(rv))
            r = v.shape[1]
            cr2 = cry[i - 1]
            cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], ry[i]))
            u = reshape(u, (d2, ry[i] * r))
            u = reshape(np.transpose(u), (ry[i], r * d2))
            u = np.dot(cr2, u)

            u = reshape(u, (ry[i - 1] * n[i - 1] * r, d2))
            u = reshape(np.transpose(u), (d2, ry[i - 1], n[i - 1], r))
            v = reshape(np.transpose(v), (r, n[i], ry[i + 1]))

            ry[i] = r
            cry[i - 1] = u
            cry[i] = v

            Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ry[i + 1])
            Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i + 1]))
            curind = maxvol(np.transpose(Ry[i]))
            Ry[i] = Ry[i][:, curind]
            for j in range(nx):
                Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j]))
                Rx[i, j] = np.dot(Rx[i, j], Rx[i + 1, j])
                Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i + 1]))
                Rx[i, j] = Rx[i, j][:, curind]
        elif dirn > 0 and i == d - 1:
            newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])),
                          np.conj(np.transpose(v[:, :r])))
            newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2))
            cry[i] = reshape(np.transpose(newy), (d2, ry[i], n[i], ry[i + 1]))
        elif dirn < 0 and i == 0:
            newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])),
                          np.conj(np.transpose(v[:, :r])))
            newy = reshape(newy, (d2, ry[i], n[i], ry[i + 1]))
            cry[i] = newy

        i = i + dirn
        cur_order[order_index] = cur_order[order_index] - dirn
        if cur_order[order_index] == 0:
            order_index = order_index + 1
            if verb > 0:
                print '=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy,
                                                                                math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n)))

            if last_sweep:
                break
            if max_dy < eps and dirn < 0:
                last_sweep = True
                kickrank = 0

            if order_index >= len(cur_order):
                cur_order = copy.copy(block_order)
                order_index = 0
                if last_sweep:
                    cur_order = [d - 1]

                max_dy = 0
                swp = swp + 1

            dirn = int(math.copysign(1, cur_order[order_index]))
            i = i + dirn

    cry[d - 1] = np.transpose(cry[d - 1][:, :, :, 0], [1, 2, 0])
    y = tt.tensor.from_list(cry)
    return y
Example #29
0
 def setUp(self):
     self.Z = tt.rand(np.array([5, 6, 7, 8, 9]), r=10)
     self.Y = tt.tensor.to_list(self.Z)
     self.e = 1.E-14
Example #30
0
 def test_projector_splitting_add(self):
     for debug_mode in [False, True]:
         Y = tt.rand([5, 2, 3], 3, [1, 2, 3, 1])
         my_res = riemannian.projector_splitting_add(Y.copy(), Y.copy(),
                                                     debug=debug_mode)
         np.testing.assert_array_almost_equal(2 * Y.full(), my_res.full())
Example #31
0
def ttSparseALS(cooP, shape, x0=None, ttRank=1, tol=1e-5, maxnsweeps=20, verbose=True, alpha=1e-2):
    '''
    TT completion via Alternating Least Squares algorithm.
    
    Parameters:
        :dict: cooP
            dictionary with two records
                - 'indices': numpy.array of P x d shape,
                contains index subspace of P known elements;
                each string is an index of one element.
                - 'values': numpy array of size P,
                contains P known values.   
        :list, numpy.array: shape
            full-format shape of tensor to be completed [dimensions]
        :tt.vector: x0 = None
            initial approximation of completed tensor
            If it is specified, parameters 'shape' and 'ttRank' will be ignored
        :int, numpy.array: ttRank = 1
            assumed rank of completed tensor
        :float: tol = 1e-5
            tolerance for functional value
        :int: maxnsweeps = 20
            maximal number of sweeps [sequential optimization of all d cores
            in right or left direction]
        :boolean: verbose = True
            switcher of messages from function
        :float: alpha: = 1e-2
            regularizer of least squares problem for each slice of current TT core.
            [rcond parameter for np.linalg.lstsq]
            
    Returns:
        :tt.vector: xNew
            completed TT vector
        :list: fit
            list of functional values at each sweep
    '''
    indices = cooP['indices']
    values = cooP['values']
    
    [P, d] = indices.shape
    assert P == len(values)
    
    timeVal = time.clock()
    if x0 is None:
        x = tt.rand(shape, r = ttRank)
        x = x.round(0.)
        x = (1./x.norm())*x
    else:
        x = copy.deepcopy(x0)
    assert d == x.d
    # TODO: also check if cooP indices are aligned with shape
    normP = np.linalg.norm(values)
    values /= normP
    fitList = []
    sweepTimeList = []
    initTime = time.clock() - timeVal
    
    timeVal = time.clock()
    coreList = tt.vector.to_list(x)
    #coreList = orthLRFull(coreList, mu = d, splitResult = False)
    # orthTime = time.clock() - timeVal
    
    if verbose:
        print("Initialization time: %.3f seconds (proc.time)" % (initTime))
        # print "Orthogonalizing time: %.3f seconds (proc.time)" % (orthTime)
    
    for sweep in xrange(maxnsweeps):
        sweepStart = time.clock()
        # list left + right
        [kStart, kEnd, kStep] = [0, d, 1]
        # select direction of sweep
        '''
        if sweep % 2 == 0: # left to rigth
            [kStart, kEnd, kStep] = [0, d, 1]
        else: # right to left
            [kStart, kEnd, kStep] = [d-1, -1, -1]
        '''
        # fix k-th core to update
        for k in xrange(kStart, kEnd, kStep):
            [r1, n, r2] = coreList[k].shape
            core = np.zeros([r1, n, r2])
            leftU = []
            rightV = []
            if k > 0:
                leftU = coreList[:k]
            if k < d-1:
                rightV = coreList[k+1:] 
            for i in xrange(n):
                thetaI = np.where(indices[:, k] == i)[0]
                if len(thetaI) > 0:
                    A = np.zeros([len(thetaI), r1*r2])
                    for j in xrange(len(thetaI)):
                        tmp = getRow(leftU, rightV, indices[thetaI[j], :])
                        A[j:j+1, :] += tmp   # .flatten(order = 'F')
                    vecCoreSlice, _, _, _ = np.linalg.lstsq(A, values[thetaI])#, rcond = alpha)
                    # 0.5*np.linalg.norm(np.dot(A, vecCoreSlice) - values[thetaI])**2.
                    core[:, i, :] += reshape(vecCoreSlice, [r1, r2]) ####
            '''
            if k < (d-1):
                core = reshape(core, [r1*n, r2])
                Q, R = np.linalg.qr(core)
                rnew = Q.shape[1]
                core = reshape(Q, [r1, n, rnew])
                coreList[k+1] = np.einsum('ijk,li->ljk', coreList[k+1], R)
            '''
            coreList[k] = core.copy()
            '''
            else:
                if (k > 0):
                    core = reshape(core, [r1, n*r2])
                    Q, R = np.linalg.qr(core.T)
                    rnew = Q.shape[1]
                    core = reshape(Q.T, [rnew, n, r2])
                    coreList[k-1] = np.einsum('ijk,lk->ijl', coreList[k-1], R)
            '''
            
        xNew = tt.vector.from_list(coreList)
        fit = computeFunctional(xNew, cooP)
        fitList.append(fit)
        if fit < tol:
            break
        if sweep > 0:
            if abs(fit - fitList[-2]) < tol:
                break
        sweepTimeList.append(time.clock() - sweepStart)
        if verbose:
            print("sweep %d/%d\t fit value: %.5e\t time: %.3f seconds (proc.time)" % (sweep+1, maxnsweeps, fit, sweepTimeList[-1]))
    if verbose:
        print("Total sweep time: %.3f seconds (proc.time)\t Total time: %.3f seconds (proc.time)" % (sum(sweepTimeList), sum(sweepTimeList) + initTime))# + orthTime)
    info = {'fit': fitList, 'initTime': initTime,  'sweepTime': sweepTimeList} # 'orthTime': orthTime,
    xNew *= normP
    values *= normP
    
    return xNew, info
Example #32
0
import timeit
import numpy as np
import pickle
import argparse
import tt
from tt.riemannian import riemannian

parser = argparse.ArgumentParser(description='Measure execution time of various t3f operations.')
parser.add_argument('--file_path', help='Path to the file to save logs.')
args = parser.parse_args()

matrix = tt.matrix(tt.rand(100, 10, 10))
vec = tt.matrix(tt.rand(10, 10, 10), n=[10] * 10, m=[1] * 10)
vec_100 = tt.matrix(tt.rand(10, 10, 100), n=[10] * 10, m=[1] * 10)
tens = np.random.randn(10, 10, 10, 10)
globals = {'matrix': matrix, 'vec': vec, 'vec_100': vec_100, 'tens': tens,
           'tt': tt, 'riemannian': riemannian}

logs = {'lib': 'ttpy'}

# Warmup
timeit.timeit("matrix * vec", globals=globals, number=10)

matvec_time = timeit.timeit("matrix * vec", globals=globals, number=1000) / 1000
print('Multiplying a matrix by a vector takes %f seconds.' % matvec_time)
logs['matvec_time'] = matvec_time

matmul_time = timeit.timeit("matrix * matrix", globals=globals, number=100) / 100
print('Multiplying a matrix by a matrix takes %f seconds.' % matmul_time)
logs['matmul_time'] = matmul_time
Example #33
0
    e = tt.matrix(e,1e-12)
    #Generate ssx, ssz
    ssp = [gen_1d(sp,e,i,d) for i in xrange(d)]
    ssz = [gen_1d(sz,e,i,d) for i in xrange(d)]
    ssm = [gen_1d(sm,e,i,d) for i in xrange(d)]
    A = None
    for i in xrange(d-1):
        A = A + 0.5 * (ssp[i] * ssm[i+1] + ssm[i] * ssp[i+1]) +  (ssz[i] * ssz[i+1])
        A = A.round(1e-8)
    return A

if __name__ == '__main__':
    
    d = 60 #The dimension of the problem (number of spins)
    B = 5 # Number of eigenvalues sought
    eps = 1e-5 #Accuracy of the computations 
    
    A = gen_heisen(d)
    n = A.n
    d = A.tt.d
    r = [B]*(d+1)
    r[0] = 1
    r[d] = B
    x0 = tt.rand(n,d,r)
    t1 = time.time()
    print('Matrices are done')
    y, lam = eigb(A, x0, eps, max_full_size = 1000)
    t2 = time.time()
    print('Elapsed time: %3.1f' % (t2 - t1))
    print('Eigenvalues: ', lam)
Example #34
0
    V = V.round(eps)


A = 0.5*lp2 + tt.diag(0.5*harm + lm*V)
A = A.round(eps) 

H = 1j*A
#Generate the initial Gaussian, which is just shifted

gs = np.exp(-0.5*(x-2)**2)
gs = tt.tensor(gs,1e-8)
start = None
for i in xrange(f):
    start = tt.kron(start,gs)
radd = 20
start = start+0*tt.rand(start.n,start.d,radd)
y = start.copy()
print 'initial value norm:', start.norm()
cf = []
tf = 150.0
nit = 5000
tau = (tf/nit)
i = 0
t = 0
import time
t1 = time.time()
while t <= tf:
    print '%f/%f' % (t,tf)
    y = ksl(H,y,tau)
    cf.append(tt.dot(y,start))
    t += tau
Example #35
0
import sys
sys.path.append('../')
import numpy as np
import tt
from tt.eigb import *
import time

""" This code computes many eigenvalus of the Laplacian operator """

d = 8
f = 8
A = tt.qlaplace_dd([d]*f)
#A = (-1)*A
#A = tt.eye(2,d)
n = [2] *(d * f)
r = [8] *(d * f + 1)
r[0] = 1
r[d * f] = 8 #Number of eigenvalues sought
x = tt.rand(n, d * f, r)
#x = tt_ones(2,d)
t = time.time()
y, lam = eigb(A, x, 1e-6)

t1 = time.time()
print 'Eigenvalues:', lam
print 'Time is:', t1-t
Example #36
0
    tt2.ps = np.cumsum(np.concatenate((np.ones(1), r2[:-1] * n2 * r2[1:])))


    tt2.n[0] = tt2.n[0] / rl
    tt2.n[d2-1] = tt2.n[d2-1] / rr
    tt2.r[0] = rl
    tt2.r[d2] = rr

    if ismatrix:
        ttt = tt.eye(1,1) # dummy tt matrix
        ttt.n = sz_n
        ttt.m = sz_m
        ttt.tt = tt2
        return ttt
    else:
        return tt2
        
        
if __name__ == '__main__':
    a = tt.rand(8, 6)
    sz = np.array([2, 4]*5)
    b = tt_reshape(a, sz, eps=1e-14, rl=2, rr=4)
    print np.linalg.norm(a.full().flatten(order = 'F') - b.full().flatten(order = 'F'))
    
    k = 4
    c = tt.eye(8, k)
    sz = np.array([[2, 4]*(k), [2, 4]*(k)]).T
    d = tt_reshape(c, sz, eps=1e-14, rl=1, rr=1)
    print np.linalg.norm(c.full().flatten(order = 'F') - d.full().flatten(order = 'F'))
        
from __future__ import print_function, absolute_import, division
import numpy as np
import tt
from . import rect_cross

#Tested function
def myfun(x):
    return np.sin((x.sum(axis=1))) #** 2
    #return 1.0 / ((x.sum(axis=1)) + 1e-3)

    #return (x + 1).prod(axis=1)
    #return np.ones(x.shape[0])
d = 80
n = 5
r = 2

#sz = [n] * d
#ind_all = np.unravel_index(np.arange(n ** d), sz)
#ind_all = np.array(ind_all).T
#ft = reshape(myfun(ind_all), sz)
#xall = tt.tensor(ft, 1e-8)
#x0 = tt.tensor(ft, 1e-8)


x0 = tt.rand(n, d, r)

x1 = rect_cross.cross(myfun, x0, nswp=5, kickrank=1, rf=2)
Example #38
0
        y = _np.dot(Phi1, y)
        y = _reshape(y, (ry1 * n * ry2, b))

    return y


if __name__ == '__main__':

    d = 12
    n = 15
    m = 15
    ra = 30
    rb = 10
    eps = 1e-6

    a = 0 * _tt.rand(n * m, d, r=ra)
    a = a + _tt.ones(n * m, d)
    #a = a.round(1e-12)
    a = _tt.vector.to_list(a)
    for i in xrange(d):
        sa = a[i].shape
        a[i] = _reshape(a[i], (sa[0], m, n, sa[-1]))
    A = _tt.matrix.from_list(a)

    b = _tt.rand(n, d, r=rb)

    c = amen_mv(A, b, eps, y=None, z=None, nswp=20, kickrank=4,
                kickrank2=0, verb=True, init_qr=True, renorm='gram', fkick=False)
    d = _tt.matvec(A, b).round(eps)

    print((c[0] - d).norm() / d.norm())
Example #39
0
def ttSparseALS(cooP,
                shape,
                x0=None,
                ttRank=1,
                tol=1e-5,
                maxnsweeps=20,
                verbose=True,
                alpha=1e-2):
    '''
    TT completion via Alternating Least Squares algorithm.
    
    Parameters:
        :dict: cooP
            dictionary with two records
                - 'indices': numpy.array of P x d shape,
                contains index subspace of P known elements;
                each string is an index of one element.
                - 'values': numpy array of size P,
                contains P known values.   
        :list, numpy.array: shape
            full-format shape of tensor to be completed [dimensions]
        :tt.vector: x0 = None
            initial approximation of completed tensor
            If it is specified, parameters 'shape' and 'ttRank' will be ignored
        :int, numpy.array: ttRank = 1
            assumed rank of completed tensor
        :float: tol = 1e-5
            tolerance for functional value
        :int: maxnsweeps = 20
            maximal number of sweeps [sequential optimization of all d cores
            in right or left direction]
        :boolean: verbose = True
            switcher of messages from function
        :float: alpha: = 1e-2
            regularizer of least squares problem for each slice of current TT core.
            [rcond parameter for np.linalg.lstsq]
            
    Returns:
        :tt.vector: xNew
            completed TT vector
        :list: fit
            list of functional values at each sweep
    '''
    indices = cooP['indices']
    values = cooP['values']

    [P, d] = indices.shape
    assert P == len(values)

    timeVal = time.clock()
    if x0 is None:
        x = tt.rand(shape, r=ttRank)
        x = x.round(0.)
        x = (1. / x.norm()) * x
    else:
        x = copy.deepcopy(x0)
    assert d == x.d
    # TODO: also check if cooP indices are aligned with shape
    normP = np.linalg.norm(values)
    values /= normP
    fitList = []
    sweepTimeList = []
    initTime = time.clock() - timeVal

    timeVal = time.clock()
    coreList = tt.vector.to_list(x)
    #coreList = orthLRFull(coreList, mu = d, splitResult = False)
    # orthTime = time.clock() - timeVal

    if verbose:
        print("Initialization time: %.3f seconds (proc.time)" % (initTime))
        # print "Orthogonalizing time: %.3f seconds (proc.time)" % (orthTime)

    for sweep in xrange(maxnsweeps):
        sweepStart = time.clock()
        # list left + right
        [kStart, kEnd, kStep] = [0, d, 1]
        # select direction of sweep
        '''
        if sweep % 2 == 0: # left to rigth
            [kStart, kEnd, kStep] = [0, d, 1]
        else: # right to left
            [kStart, kEnd, kStep] = [d-1, -1, -1]
        '''
        # fix k-th core to update
        for k in xrange(kStart, kEnd, kStep):
            [r1, n, r2] = coreList[k].shape
            core = np.zeros([r1, n, r2])
            leftU = []
            rightV = []
            if k > 0:
                leftU = coreList[:k]
            if k < d - 1:
                rightV = coreList[k + 1:]
            for i in xrange(n):
                thetaI = np.where(indices[:, k] == i)[0]
                if len(thetaI) > 0:
                    A = np.zeros([len(thetaI), r1 * r2])
                    for j in xrange(len(thetaI)):
                        tmp = getRow(leftU, rightV, indices[thetaI[j], :])
                        A[j:j + 1, :] += tmp  # .flatten(order = 'F')
                    vecCoreSlice, _, _, _ = np.linalg.lstsq(
                        A, values[thetaI])  #, rcond = alpha)
                    # 0.5*np.linalg.norm(np.dot(A, vecCoreSlice) - values[thetaI])**2.
                    core[:, i, :] += reshape(vecCoreSlice, [r1, r2])  ####
            '''
            if k < (d-1):
                core = reshape(core, [r1*n, r2])
                Q, R = np.linalg.qr(core)
                rnew = Q.shape[1]
                core = reshape(Q, [r1, n, rnew])
                coreList[k+1] = np.einsum('ijk,li->ljk', coreList[k+1], R)
            '''
            coreList[k] = core.copy()
            '''
            else:
                if (k > 0):
                    core = reshape(core, [r1, n*r2])
                    Q, R = np.linalg.qr(core.T)
                    rnew = Q.shape[1]
                    core = reshape(Q.T, [rnew, n, r2])
                    coreList[k-1] = np.einsum('ijk,lk->ijl', coreList[k-1], R)
            '''

        xNew = tt.vector.from_list(coreList)
        fit = computeFunctional(xNew, cooP)
        fitList.append(fit)
        if fit < tol:
            break
        if sweep > 0:
            if abs(fit - fitList[-2]) < tol:
                break
        sweepTimeList.append(time.clock() - sweepStart)
        if verbose:
            print(
                "sweep %d/%d\t fit value: %.5e\t time: %.3f seconds (proc.time)"
                % (sweep + 1, maxnsweeps, fit, sweepTimeList[-1]))
    if verbose:
        print(
            "Total sweep time: %.3f seconds (proc.time)\t Total time: %.3f seconds (proc.time)"
            %
            (sum(sweepTimeList), sum(sweepTimeList) + initTime))  # + orthTime)
    info = {
        'fit': fitList,
        'initTime': initTime,
        'sweepTime': sweepTimeList
    }  # 'orthTime': orthTime,
    xNew *= normP
    values *= normP

    return xNew, info
Example #40
0
        y = _np.dot(Phi1, y)
        y = _reshape(y, (ry1 * n * ry2, b))

    return y


if __name__ == '__main__':

    d = 12
    n = 15
    m = 15
    ra = 30
    rb = 10
    eps = 1e-6

    a = 0 * _tt.rand(n * m, d, r=ra)
    a = a + _tt.ones(n * m, d)
    #a = a.round(1e-12)
    a = _tt.vector.to_list(a)
    for i in xrange(d):
        sa = a[i].shape
        a[i] = _reshape(a[i], (sa[0], m, n, sa[-1]))
    A = _tt.matrix.from_list(a)

    b = _tt.rand(n, d, r=rb)

    c = amen_mv(A,
                b,
                eps,
                y=None,
                z=None,
Example #41
0
def solver_tt(gas_params, problem, mesh, nt, nv, vx_, vx, vy, vz, \
              CFL, tol, filename, init = '0'):
    """Solve Boltzmann equation with model collision integral 
    
    gas_params -- object of class GasParams, contains gas parameters and viscosity law
    
    problem -- object of class Problem, contains list of boundary conditions,
    data for b.c., and function for initial condition
    
    mesh - object of class Mesh
    
    nt -- number of time steps
    
    vmax -- maximum velocity in each direction in velocity mesh
    
    nv -- number of nodes in velocity mesh
    
    CFL -- courant number
    
    filename -- name of output file for f
    
    init - name of restart file
    """
    # Function for LU-SGS
    mydivide = lambda x: x[:, 0] / x[:, 1]
    zero_tt = 0. * tt.ones((nv, nv, nv))
    ones_tt = tt.ones((nv, nv, nv))
    #
    # Initialize main arrays and lists
    #
    vn = [None
          ] * mesh.nf  # list of tensors of normal velocities at each mesh face
    vn_tmp = np.zeros((nv, nv, nv))
    vnm = [None] * mesh.nf  # negative part of vn: 0.5 * (vn - |vn|)
    vnp = [None] * mesh.nf  # positive part of vn: 0.5 * (vn + |vn|)
    vn_abs = [None] * mesh.nf  # approximations of |vn|

    vx_tt = tt.tensor(vx).round(tol)
    vy_tt = tt.tensor(vy).round(tol)
    vz_tt = tt.tensor(vz).round(tol)

    vn_error = 0.
    for jf in range(mesh.nf):
        vn_tmp = mesh.face_normals[jf, 0] * vx + mesh.face_normals[
            jf, 1] * vy + mesh.face_normals[jf, 2] * vz
        vn[jf] = mesh.face_normals[jf, 0] * vx_tt + mesh.face_normals[
            jf, 1] * vy_tt + mesh.face_normals[jf, 2] * vz_tt
        vnp[jf] = tt.tensor(np.where(vn_tmp > 0, vn_tmp, 0.), eps=tol)
        vnm[jf] = tt.tensor(np.where(vn_tmp < 0, vn_tmp, 0.), eps=tol)
        vn_abs[jf] = tt.tensor(np.abs(vn_tmp), rmax=4)
        vn_error = max(
            vn_error,
            np.linalg.norm(vn_abs[jf].full() - np.abs(vn_tmp)) /
            np.linalg.norm(np.abs(vn_tmp)))
    print('max||vn_abs_tt - vn_abs||_F/max||vn_abs||_F = ', vn_error)

    h = np.min(mesh.cell_diam)
    tau = h * CFL / (np.max(vx_) * (3.**0.5))
    v2 = (vx_tt * vx_tt + vy_tt * vy_tt + vz_tt * vz_tt).round(tol)

    diag = [None] * mesh.nc  # part of diagonal coefficient in implicit scheme
    # precompute diag
    diag_full = np.zeros(
        (mesh.nc, nv, nv,
         nv))  # part of diagonal coefficient in implicit scheme
    # precompute diag
    for ic in range(mesh.nc):
        for j in range(6):
            jf = mesh.cell_face_list[ic, j]
            vn_tmp = mesh.face_normals[jf, 0] * vx + mesh.face_normals[
                jf, 1] * vy + mesh.face_normals[jf, 2] * vz
            vnp_full = np.where(
                mesh.cell_face_normal_direction[ic, j] * vn_tmp[:, :, :] > 0,
                mesh.cell_face_normal_direction[ic, j] * vn_tmp[:, :, :], 0.)
            diag_full[ic, :, :, :] += (mesh.face_areas[jf] /
                                       mesh.cell_volumes[ic]) * vnp_full

    for ic in range(mesh.nc):
        diag_temp = np.zeros((nv, nv, nv))
        for j in range(6):
            jf = mesh.cell_face_list[ic, j]
            vn_full = (mesh.face_normals[jf, 0] * vx + mesh.face_normals[jf, 1] * vy \
                       + mesh.face_normals[jf, 2] * vz) * mesh.cell_face_normal_direction[ic, j]
            vnp_full = np.where(vn_full > 0, vn_full, 0.)
            vn_abs_full = np.abs(vn_full)
            diag_temp += (mesh.face_areas[jf] /
                          mesh.cell_volumes[ic]) * vnp_full
#            diag_temp += 0.5 * (mesh.face_areas[jf] / mesh.cell_volumes[ic]) * vn_abs_full
        diag[ic] = tt.tensor(diag_temp)
    # Compute mean rank of diag
    diag_rank = 0.
    for ic in range(mesh.nc):
        diag_rank += 0.5 * (diag[ic].r[1] + diag[ic].r[2])
    diag_rank = diag_rank / ic
    print('diag_rank = ', diag_rank)
    #
    diag_scal = np.zeros(mesh.nc)
    for ic in range(mesh.nc):
        for j in range(6):
            jf = mesh.cell_face_list[ic, j]
            diag_scal[ic] += 0.5 * (mesh.face_areas[jf] /
                                    mesh.cell_volumes[ic])
    diag_scal *= np.max(np.abs(vx_)) * 3**0.5
    # set initial condition
    f = [None] * mesh.nc
    if (init == '0'):
        for i in range(mesh.nc):
            x = mesh.cell_center_coo[i, 0]
            y = mesh.cell_center_coo[i, 1]
            z = mesh.cell_center_coo[i, 2]
            f[i] = problem.f_init(x, y, z, vx, vy, vz)
    else:
        #        restart from distribution function
        #        f = load_tt(init, mesh.nc, nv)
        #        restart form macroparameters array
        init_data = np.loadtxt(init)
        for ic in range(mesh.nc):
            f[ic] = tt.tensor(f_maxwell(vx, vy, vz, init_data[ic, 5], \
             init_data[ic, 0], init_data[ic, 1], init_data[ic, 2], init_data[ic, 3], gas_params.Rg), tol)

    # TODO: may be join f_plus and f_minus in one array
    f_plus = [None] * mesh.nf  # Reconstructed values on the right
    f_minus = [None] * mesh.nf  # reconstructed values on the left
    flux = [None] * mesh.nf  # Flux values
    rhs = [None] * mesh.nc
    df = [None] * mesh.nc

    # Arrays for macroparameters
    n = np.zeros(mesh.nc)
    rho = np.zeros(mesh.nc)
    ux = np.zeros(mesh.nc)
    uy = np.zeros(mesh.nc)
    uz = np.zeros(mesh.nc)
    p = np.zeros(mesh.nc)
    T = np.zeros(mesh.nc)
    nu = np.zeros(mesh.nc)
    rank = np.zeros(mesh.nc)
    data = np.zeros((mesh.nc, 7))

    # Dummy tensor with [1, 1, 1, 1] ranks
    F = tt.rand([nv, nv, nv], 3, [1, 1, 1, 1])
    frob_norm_iter = np.array([])

    it = 0
    while (it < nt):
        it += 1
        # reconstruction for inner faces
        # 1st order
        for ic in range(mesh.nc):
            for j in range(6):
                jf = mesh.cell_face_list[ic, j]
                if (mesh.cell_face_normal_direction[ic, j] == 1):
                    f_minus[jf] = f[ic].copy()
                else:
                    f_plus[jf] = f[ic].copy()

        # boundary condition
        # loop over all boundary faces
        for j in range(mesh.nbf):
            jf = mesh.bound_face_info[j, 0]  # global face index
            bc_num = mesh.bound_face_info[j, 1]
            bc_type = problem.bc_type_list[bc_num]
            bc_data = problem.bc_data[bc_num]
            if (mesh.bound_face_info[j, 2] == 1):
                f_plus[jf] = set_bc_tt(gas_params, bc_type, bc_data,
                                       f_minus[jf], vx, vy, vz, vn[jf],
                                       vnp[jf], vnm[jf], tol)
            else:
                f_minus[jf] = set_bc_tt(gas_params, bc_type, bc_data,
                                        f_plus[jf], vx, vy, vz, -vn[jf],
                                        -vnm[jf], -vnp[jf], tol)

        # riemann solver - compute fluxes
        for jf in range(mesh.nf):
            flux[jf] = 0.5 * mesh.face_areas[jf] *\
            ((f_plus[jf] + f_minus[jf]) * vn[jf]  - (f_plus[jf] - f_minus[jf]) * vn_abs[jf])
            flux[jf] = flux[jf].round(tol)

        # computation of the right-hand side
        for ic in range(mesh.nc):
            rhs[ic] = zero_tt.copy()
            # sum up fluxes from all faces of this cell
            for j in range(6):

                jf = mesh.cell_face_list[ic, j]
                rhs[ic] += -(mesh.cell_face_normal_direction[ic, j]) * (
                    1. / mesh.cell_volumes[ic]) * flux[jf]
                rhs[ic] = rhs[ic].round(tol)
            # Compute macroparameters and collision integral
            J, n[ic], ux[ic], uy[ic], uz[ic], T[ic], nu[ic], rho[ic], p[
                ic] = comp_macro_param_and_j_tt(f[ic], vx_, vx, vy, vz, vx_tt,
                                                vy_tt, vz_tt, v2, gas_params,
                                                tol, F, ones_tt)
            rhs[ic] += J
            rhs[ic] = rhs[ic].round(tol)

        frob_norm_iter = np.append(
            frob_norm_iter,
            np.sqrt(sum([(rhs[ic].norm())**2 for ic in range(mesh.nc)])))
        #
        # update values, expclicit scheme
        #
        for ic in range(mesh.nc):
            f[ic] = (f[ic] + tau * rhs[ic]).round(tol)

        # save rhs norm and tec tile
        if ((it % 100) == 0):
            fig, ax = plt.subplots(figsize=(20, 10))
            line, = ax.semilogy(frob_norm_iter / frob_norm_iter[0])
            ax.set(title='$Steps =$' + str(it))
            plt.savefig('norm_iter.png')
            plt.close()

            data[:, 0] = n[:]
            data[:, 1] = ux[:]
            data[:, 2] = uy[:]
            data[:, 3] = uz[:]
            data[:, 4] = p[:]
            data[:, 5] = T[:]
            data[:, 6] = rank[:]

            write_tecplot(mesh, data, 'tec_tt.dat',
                          ('n', 'ux', 'uy', 'uz', 'p', 'T', 'rank'))

    save_tt(filename, f, mesh.nc, nv)

    Return = namedtuple(
        'Return',
        ['f', 'n', 'ux', 'uy', 'uz', 'T', 'p', 'rank', 'frob_norm_iter'])

    S = Return(f, n, ux, uy, uz, T, p, rank, frob_norm_iter)

    return S
Example #42
0
def amen_mv(A,
            x,
            tol,
            y=None,
            z=None,
            nswp=20,
            kickrank=4,
            kickrank2=0,
            verb=True,
            init_qr=True,
            renorm='direct',
            fkick=False):
    '''
       Approximate the matrix-by-vector via the AMEn iteration
       [y,z]=amen_mv(A, x, tol, varargin)
       Attempts to approximate the y = A*x
       with accuracy TOL using the AMEn+ALS iteration.
       Matrix A has to be given in the TT-format, right-hand side x should be
       given in the TT-format also.

       Options are provided in form
       'PropertyName1',PropertyValue1,'PropertyName2',PropertyValue2 and so
       on. The parameters are set to default (in brackets in the following)
       The list of option names and default values are:
           o y0 - initial approximation to Ax [rand rank-2]
           o nswp - maximal number of sweeps [20]
           o verb - verbosity level, 0-silent, 1-sweep info, 2-block info [1]
           o kickrank - compression rank of the error,
             i.e. enrichment size [3]
           o init_qr - perform QR of the input (save some time in ts, etc) [true]
           o renorm - Orthog. and truncation methods: direct (svd,qr) or gram
             (apply svd to the gram matrix, faster for m>>n) [direct]
           o fkick - Perform solution enrichment during forward sweeps [false]
             (rather questionable yet; false makes error higher, but "better
             structured": it does not explode in e.g. subsequent matvecs)
           o z0 - initial approximation to the error Ax-y [rand rank-kickrank]


    ********
       For description of adaptive ALS please see
       Sergey V. Dolgov, Dmitry V. Savostyanov,
       Alternating minimal energy methods for linear systems in higher dimensions.
       Part I: SPD systems, http://arxiv.org/abs/1301.6068,
       Part II: Faster algorithm and application to nonsymmetric systems, http://arxiv.org/abs/1304.1222

       Use {sergey.v.dolgov, dmitry.savostyanov}@gmail.com for feedback
    ********
    '''

    if renorm is 'gram':
        print "Not implemented yet. Renorm is switched to 'direct'"
        renorm = 'direct'

    if isinstance(x, _tt.vector):
        d = x.d
        m = x.n
        rx = x.r
        x = _tt.vector.to_list(x)
        vectype = 1  # tt_tensor
    elif isinstance(x, list):
        d = len(x)
        m = _np.zeros(d)
        rx = _np.ones(d + 1)
        for i in xrange(d):
            [_, m[i], rx[i + 1]] = x[i].shape
        vectype = 0  # cell
    else:
        raise Exception('x: use tt.tensor or list of cores as numpy.arrays')

    if isinstance(A, _tt.matrix):
        n = A.n
        ra = A.tt.r
        A = _tt.matrix.to_list(A)
        # prepare A for fast ALS-mv
        for i in xrange(d):
            A[i] = _reshape(A[i], (ra[i] * n[i], m[i] * ra[i + 1]))
        atype = 1  # tt_matrix
    # Alternative: A is a cell of cell: sparse canonical format
    elif isinstance(A, list):
        n = _np.zeros(d)
        for i in xrange(d):
            n[i] = A[i][0].shape[0]
        ra = len(A[0])
        atype = 0  # cell
    else:
        raise Exception('A: use tt.matrix or list of cores as numpy.arrays')

    if y is None:
        y = _tt.rand(n, d, 2)
        y = _tt.vector.to_list(y)
    else:
        if isinstance(y, _tt.vector):
            y = _tt.vector.to_list(y)

    ry = _np.ones(d + 1)
    for i in range(d):
        ry[i + 1] = y[i].shape[2]

    if (kickrank + kickrank2 > 0):
        if z is None:
            z = _tt.rand(n, d, kickrank + kickrank2)
            rz = z.r
            z = _tt.vector.to_list(z)
        else:
            if isinstance(z, _tt.vector):
                z = _tt.vector.to_list(z)
            rz = _np.ones(d + 1)
            for i in range(d):
                rz[i + 1] = z[i].shape[2]

        phizax = [None] * (d + 1)  # cell(d+1,1);
        if (atype == 1):
            phizax[0] = _np.ones((1, 1, 1))  # 1
            phizax[d] = _np.ones((1, 1, 1))  # 1
        else:
            phizax[0] = _np.ones((1, ra))  # 33
            phizax[d] = _np.ones((1, ra))
        phizy = [None] * (d + 1)
        phizy[0] = _np.ones((1))  # , 1))
        phizy[d] = _np.ones((1))  # , 1))

    phiyax = [None] * (d + 1)
    if (atype == 1):
        phiyax[0] = _np.ones((1, 1, 1))  # 1
        phiyax[d] = _np.ones((1, 1, 1))  # 1
    else:
        phiyax[0] = _np.ones((1, ra))  # 3
        phiyax[d] = _np.ones((1, ra))

    nrms = _np.ones(d)

    # Initial ort
    for i in range(d - 1):
        if init_qr:
            cr = _reshape(y[i], (ry[i] * n[i], ry[i + 1]))
            if (renorm is 'gram') and (ry[i] * n[i] > 5 * ry[i + 1]):
                [cr, s, R] = _svdgram(cr)
            else:
                [cr, R] = _np.linalg.qr(cr)
            nrmr = _np.linalg.norm(R)  # , 'fro')
            if (nrmr > 0):
                R = R / nrmr
            cr2 = _reshape(y[i + 1], (ry[i + 1], n[i + 1] * ry[i + 2]))
            cr2 = _np.dot(R, cr2)
            ry[i + 1] = cr.shape[1]
            y[i] = _reshape(cr, (ry[i], n[i], ry[i + 1]))
            y[i + 1] = _reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2]))

        [phiyax[i + 1], nrms[i]] = _compute_next_Phi(phiyax[i], y[i], x[i],
                                                     'lr', A[i])

        if (kickrank + kickrank2 > 0):
            cr = _reshape(z[i], (rz[i] * n[i], rz[i + 1]))
            if (renorm == 'gram') and (rz[i] * n[i] > 5 * rz[i + 1]):
                [cr, s, R] = _svdgram(cr)
            else:
                [cr, R] = _np.linalg.qr(cr)
            nrmr = _np.linalg.norm(R)  # , 'fro')
            if (nrmr > 0):
                R = R / nrmr
            cr2 = _reshape(z[i + 1], (rz[i + 1], n[i + 1] * rz[i + 2]))
            cr2 = _np.dot(R, cr2)
            rz[i + 1] = cr.shape[1]
            z[i] = _reshape(cr, (rz[i], n[i], rz[i + 1]))
            z[i + 1] = _reshape(cr2, (rz[i + 1], n[i + 1], rz[i + 2]))
            phizax[i + 1] = _compute_next_Phi(phizax[i],
                                              z[i],
                                              x[i],
                                              'lr',
                                              A[i],
                                              nrms[i],
                                              return_norm=False)
            phizy[i + 1] = _compute_next_Phi(phizy[i],
                                             z[i],
                                             y[i],
                                             'lr',
                                             return_norm=False)

    i = d - 1
    direct = -1
    swp = 1
    max_dx = 0

    while swp <= nswp:
        # Project the MatVec generating vector
        crx = _reshape(x[i], (rx[i] * m[i] * rx[i + 1], 1))
        cry = _bfun3(phiyax[i], A[i], phiyax[i + 1], crx)
        nrms[i] = _np.linalg.norm(cry)  # , 'fro')
        # The main goal is to keep y[i] of norm 1
        if (nrms[i] > 0):
            cry = cry / nrms[i]
        else:
            nrms[i] = 1
        y[i] = _reshape(y[i], (ry[i] * n[i] * ry[i + 1], 1))
        dx = _np.linalg.norm(cry - y[i])
        max_dx = max(max_dx, dx)

        # Truncation and enrichment
        if ((direct > 0) and (i < d - 1)):  # ?? i<d
            cry = _reshape(cry, (ry[i] * n[i], ry[i + 1]))
            if (renorm == 'gram'):
                [u, s, v] = _svdgram(cry, tol / d**0.5)
                v = v.T
                r = u.shape[1]
            else:
                [u, s, vt] = _np.linalg.svd(cry, full_matrices=False)
                #s = diag(s)
                r = _my_chop2(s, tol * _np.linalg.norm(s) / d**0.5)
                u = u[:, :r]
                # ????? s - matrix or vector
                v = _np.dot(_tconj(vt[:r, :]), _np.diag(s[:r]))

            # Prepare enrichment, if needed
            if (kickrank + kickrank2 > 0):
                cry = _np.dot(u, v.T)
                cry = _reshape(cry, (ry[i] * n[i], ry[i + 1]))
                # For updating z
                crz = _bfun3(phizax[i], A[i], phizax[i + 1], crx)
                crz = _reshape(crz, (rz[i] * n[i], rz[i + 1]))
                ys = _np.dot(cry, phizy[i + 1])
                yz = _reshape(ys, (ry[i], n[i] * rz[i + 1]))
                yz = _np.dot(phizy[i], yz)
                yz = _reshape(yz, (rz[i] * n[i], rz[i + 1]))
                crz = crz / nrms[i] - yz
                nrmz = _np.linalg.norm(crz)  # , 'fro')
                if (kickrank2 > 0):
                    [crz, _, _] = _np.linalg.svd(crz, full_matrices=False)
                    crz = crz[:, :min(crz.shape[1], kickrank)]
                    crz = _np.hstack(
                        (crz, _np.random.randn(rz[i] * n[i], kickrank2)))
                # For adding into solution
                if fkick:
                    crs = _bfun3(phiyax[i], A[i], phizax[i + 1], crx)
                    crs = _reshape(crs, (ry[i] * n[i], rz[i + 1]))
                    crs = crs / nrms[i] - ys
                    u = _np.hstack((u, crs))
                    if (renorm == 'gram') and (ry[i] * n[i] > 5 *
                                               (ry[i + 1] + rz[i + 1])):
                        [u, s, R] = _svdgram(u)
                    else:
                        [u, R] = _np.linalg.qr(u)
                    v = _np.hstack((v, _np.zeros((ry[i + 1], rz[i + 1]))))
                    v = _np.dot(v, R.T)
                    r = u.shape[1]
            y[i] = _reshape(u, (ry[i], n[i], r))

            cr2 = _reshape(y[i + 1], (ry[i + 1], n[i + 1] * ry[i + 2]))
            v = _reshape(v, (ry[i + 1], r))
            cr2 = _np.dot(v.T, cr2)
            y[i + 1] = _reshape(cr2, (r, n[i + 1], ry[i + 2]))

            ry[i + 1] = r

            [phiyax[i + 1],
             nrms[i]] = _compute_next_Phi(phiyax[i], y[i], x[i], 'lr', A[i])

            if (kickrank + kickrank2 > 0):
                if (renorm == 'gram') and (rz[i] * n[i] > 5 * rz[i + 1]):
                    [crz, s, R] = _svdgram(crz)
                else:
                    [crz, R] = _np.linalg.qr(crz)
                rz[i + 1] = crz.shape[1]
                z[i] = _reshape(crz, (rz[i], n[i], rz[i + 1]))
                # z[i+1] will be recomputed from scratch in the next step

                phizax[i + 1] = _compute_next_Phi(phizax[i],
                                                  z[i],
                                                  x[i],
                                                  'lr',
                                                  A[i],
                                                  nrms[i],
                                                  return_norm=False)
                phizy[i + 1] = _compute_next_Phi(phizy[i],
                                                 z[i],
                                                 y[i],
                                                 'lr',
                                                 return_norm=False)

        elif ((direct < 0) and (i > 0)):
            cry = _reshape(cry, (ry[i], n[i] * ry[i + 1]))
            if (renorm == 'gram'):
                [v, s, u] = _svdgram(cry.T, tol / d**0.5)
                u = u.T
                r = v.shape[1]
            else:
                #[v, s, u] = _np.linalg.svd(cry.T, full_matrices=False)
                [u, s, vt] = _np.linalg.svd(cry, full_matrices=False)
                #s = diag(s);
                r = _my_chop2(s, tol * _np.linalg.norm(s) / d**0.5)
                v = _tconj(vt[:r, :])

                #v = vt[:r, :]
                #v = _np.dot(v[:, :r], _np.diag(s[:r]))
                u = _np.dot(u[:, :r], _np.diag(s[:r]))  # ??????????????????

            # Prepare enrichment, if needed
            if (kickrank + kickrank2 > 0):
                cry = _np.dot(u, v.T)  # .T)
                cry = _reshape(cry, (ry[i], n[i] * ry[i + 1]))
                # For updating z
                crz = _bfun3(phizax[i], A[i], phizax[i + 1], crx)
                crz = _reshape(crz, (rz[i], n[i] * rz[i + 1]))
                ys = _np.dot(phizy[i], cry)
                yz = _reshape(ys, (rz[i] * n[i], ry[i + 1]))
                yz = _np.dot(yz, phizy[i + 1])
                yz = _reshape(yz, (rz[i], n[i] * rz[i + 1]))
                crz = crz / nrms[i] - yz
                nrmz = _np.linalg.norm(crz)  # , 'fro')
                if (kickrank2 > 0):
                    [_, _, crz] = _np.linalg.svd(crz, full_matrices=False)
                    crz = crz[:, :min(crz.shape[1], kickrank)]
                    crz = _tconj(crz)
                    crz = _np.vstack(
                        (crz, _np.random.randn(kickrank2, n[i] * rz[i + 1])))
                # For adding into solution
                crs = _bfun3(phizax[i], A[i], phiyax[i + 1], crx)
                crs = _reshape(crs, (rz[i], n[i] * ry[i + 1]))
                crs = crs / nrms[i] - ys
                v = _np.hstack((v, crs.T))  # .T
                #v = v.T
                if (renorm == 'gram') and (n[i] * ry[i + 1] > 5 *
                                           (ry[i] + rz[i])):
                    [v, s, R] = _svdgram(v)
                else:
                    [v, R] = _np.linalg.qr(v)
                u = _np.hstack((u, _np.zeros((ry[i], rz[i]))))
                u = _np.dot(u, R.T)
                r = v.shape[1]

            cr2 = _reshape(y[i - 1], (ry[i - 1] * n[i - 1], ry[i]))
            cr2 = _np.dot(cr2, u)
            y[i - 1] = _reshape(cr2, (ry[i - 1], n[i - 1], r))
            y[i] = _reshape(v.T, (r, n[i], ry[i + 1]))

            ry[i] = r

            [phiyax[i], nrms[i]] = _compute_next_Phi(phiyax[i + 1], y[i], x[i],
                                                     'rl', A[i])

            if (kickrank + kickrank2 > 0):
                if (renorm == 'gram') and (n[i] * rz[i + 1] > 5 * rz[i]):
                    [crz, s, R] = _svdgram(crz.T)
                else:
                    [crz, R] = _np.linalg.qr(crz.T)
                rz[i] = crz.shape[1]
                z[i] = _reshape(crz.T, (rz[i], n[i], rz[i + 1]))
                # don't update z[i-1], it will be recomputed from scratch

                phizax[i] = _compute_next_Phi(phizax[i + 1],
                                              z[i],
                                              x[i],
                                              'rl',
                                              A[i],
                                              nrms[i],
                                              return_norm=False)
                phizy[i] = _compute_next_Phi(phizy[i + 1],
                                             z[i],
                                             y[i],
                                             'rl',
                                             return_norm=False)

        if (verb > 1):
            print 'amen-mv: swp=[%d,%d], dx=%.3e, r=%d, |y|=%.3e, |z|=%.3e' % (
                swp, i, dx, r, _np.linalg.norm(cry), nrmz)

        # Stopping or reversing
        if ((direct > 0) and (i == d - 1)) or ((direct < 0) and (i == 0)):
            if (verb > 0):
                print 'amen-mv: swp=%d{%d}, max_dx=%.3e, max_r=%d' % (
                    swp, (1 - direct) / 2, max_dx, max(ry))
            if ((max_dx < tol) or (swp == nswp)) and (direct > 0):
                break
            else:
                # We are at the terminal block
                y[i] = _reshape(cry, (ry[i], n[i], ry[i + 1]))
                if (direct > 0):
                    swp = swp + 1
            max_dx = 0
            direct = -direct
        else:
            i = i + direct
    # if (direct>0)
    y[d - 1] = _reshape(cry, (ry[d - 1], n[d - 1], ry[d]))
    # else
    #     y{1} = reshape(cry, ry(1), n(1), ry(2));
    # end;

    # Distribute norms equally...
    nrms = _np.exp(sum(_np.log(nrms)) / d)
    # ... and plug them into y
    for i in xrange(d):
        y[i] = _np.dot(y[i], nrms)

    if (vectype == 1):
        y = _tt.vector.from_list(y)
        if kickrank == 0:
            z = None
        else:
            z = _tt.vector.from_list(z)

    return y, z
Example #43
0
import sys
sys.path.append("../")
import tt
#import ctypes as ct
#ct.CDLL("libblas.so.3", ct.RTLD_GLOBAL)
#ct.CDLL("libcblas.so.1", ct.RTLD_GLOBAL)
#ct.CDLL("liblapacke.so", ct.RTLD_GLOBAL)
import numpy as np

a = tt.rand([3, 5, 7, 11], 4, [1, 4, 6, 5, 1])
b = tt.rand([3, 5, 7, 11], 4, [1, 2, 4, 3, 1])

c = tt.multifuncrs2([a, b], lambda x: np.sum(x, axis=1), eps=1E-6)

print "Relative error norm:", (c - (a + b)).norm() / (a + b).norm()









Example #44
0
    def prep(self):
        '''
        Construct function values on the spatial grid.

        OUTPUT:

        FN - self
        type: fpcross.Func

        TODO If Y0 is not set, how select best random value (rank, etc.)?

        TODO Set more accurate algorithm for tt-round of initial guess.

        TODO Add catch (we should always remove log file).
        '''

        if self.Y is not None:
            raise ValueError('Function values are already prepared.')

        if self.f is None:
            raise ValueError('Function is not set. Can not prepare.')

        if self.with_tt:

            def func(ind):
                t = tpc()
                X = self.SG.comp(ind)
                Y = self.f(X, ind) if self.opts['is_f_with_i'] else self.f(X)
                self.tms['func'] += tpc() - t
                self.res['evals'] += X.shape[1]
                return Y

            def func_v(ind):
                ind = ind.T.astype(int)
                return func(ind)

            def func_s(ind):
                ind = ind.T.astype(int)
                Y = np.zeros(ind.shape[1])
                for j in range(ind.shape[1]):
                    nm = '-'.join([str(i) for i in ind[:, j]])
                    if nm in self.Y_hst:
                        y = self.Y_hst[nm]
                    else:
                        y = func(ind[:, j].reshape(-1, 1))[0]
                        self.Y_hst[nm] = y
                    Y[j] = y
                return Y

            f = func_s if self.opts['with_Y_hst'] else func_v
            log_file = './__tt-cross_tmp.txt'

            if self.opts['Y0'] is None:
                Z = tt.rand(self.SG.n, self.SG.d, 1)
            else:
                Z = self.opts['Y0'].copy()

                rmax = None
                for n, r in zip(self.SG.n, Z.r[1:]):
                    if r > n and (rmax is None or rmax > n):
                        rmax = n
                if rmax is not None:
                    Z = Z.round(rmax=rmax)

            try:
                log = open(log_file, 'w')
                stdout0 = sys.stdout
                sys.stdout = log

                self.Y = cross(f,
                               Z,
                               eps=self.eps,
                               nswp=self.opts['nswp'],
                               kickrank=self.opts['kickrank'],
                               rf=self.opts['rf'],
                               verbose=True)
            finally:
                log.close()
                sys.stdout = stdout0

            self.tms['func'] /= (self.res['evals'] or 1)

            log = open(log_file, 'r')
            res = log.readlines()[-1].split('swp: ')[1]
            self.res['iters'] = int(res.split('/')[0]) + 1
            res = res.split('er_rel = ')[1]
            self.res['err_rel'] = float(res.split('er_abs = ')[0])
            res = res.split('er_abs = ')[1]
            self.res['err_abs'] = float(res.split('erank = ')[0])
            res = res.split('erank = ')[1]
            self.res['erank'] = float(res.split('fun_eval')[0])
            log.close()
            os.remove(log_file)

            if self.opts['Y0'] is None:
                self.err0 = None
            else:
                Y1 = self.opts['Y0']
                Y2 = self.Y
                self.err0 = (Y1 - Y2).norm() / Y2.norm()

        else:
            self.tms['func'] = tpc()

            if self.opts['is_f_with_i']:
                I = self.SG.comp(is_ind=True)
                X = self.SG.comp(I)
                Y = self.f(X, I)
            else:
                X = self.SG.comp()
                Y = self.f(X)

            self.Y = Y.reshape(self.SG.n, order='F')

            if self.opts['Y0'] is None:
                self.err0 = None
            else:
                Y1 = self.opts['Y0']
                Y2 = self.Y
                self.err0 = np.linalg.norm(Y1 - Y2) / np.linalg.norm(Y2)

            self.res['evals'] = X.shape[1]
            self.tms['func'] = (tpc() - self.tms['func']) / self.res['evals']
Example #45
0
def demo_completion():
    d = 3
    n=20
    crossR=18
    shape = np.array([n]*d)
    def func(X):
        return 1./(1+(X - n/2)**2).sum(axis = 1)**0.5

    # tt-approximation built via cross approximation
    x0 = tt.rand(np.array([n]*d), r = crossR)
    tta = cross(func, x0)
    print("TT-cross ranks: ", tta.r)

    R = 10
    gamma = 0.25
    P = int(np.floor(gamma*d*n*(R**2)))
    Pb = 100

    # random choice 
    indices = np.random.choice(n, [P, d])
    indicesB = np.random.choice(n, [Pb, d])
    # making list of tupled stings [indices]
    indices = [tuple(indices[k, :]) for k in xrange(indices.shape[0])]
    indicesB = [tuple(indicesB[k, :]) for k in xrange(indicesB.shape[0])]

    # set naturally filters input to be unique
    indices = set(indices)
    indicesB = set(indicesB)
    # convert it into list
    indices = list(indices)
    indicesB = list(indicesB)
    # return into numpy.array form
    indices = np.array(indices)
    indicesB = np.array(indicesB)

    print("Unique sample points: %d/%d (%d)" % (indices.shape[0], P, n**d))

    vals = func(indices)
    cooP = {'values': vals, 'indices': indices}
    cooPb = {'values': func(indicesB), 'indices': indicesB}

    maxR = 5
    x0 = tt.rand(shape, r=1)
    x0 = x0 * (1./ x0.norm())
    x0 = x0.round(0.)


    # verbose
    vb = True

    X1, f = ttSparseALS(
                        cooP,
                        shape,
                        x0=None,
                        ttRank=maxR,
                        maxnsweeps=50,
                        verbose=vb,
                        tol=1e-8,
                        alpha = 1e-3
    )
                       

    # Restore original, initial and approximation into full-format (do not try it in higher dimensions!)
    xf1 = X1.full() # approximation ALS
    a = tta.full() # original
    b = np.zeros([n]*d) # initial
    for p in xrange(indices.shape[0]):
        b[tuple(indices[p,:])] += vals[p]

    # Visualize slices of original, completed and initial tensors. Colormap is standartized.
    plt.clf()
    M = [a, xf1, b]
    titles = ['Original', 'Completed (ALS)', 'Initial']
    nRow = n
    nCol = 3
    fig = plt.figure(figsize=(5*nCol, nRow*5))
    gs = gridspec.GridSpec(nRow, nCol, wspace=0., hspace=1e-2, right=1-0.5/nCol)#top=1 - 0.5/nRow, 
        #bottom=0.5/nRow, left=0.5/nCol, right=1 - 0.5/nCol)

    for k in xrange(nRow):
        vmin = [x[k, :, :].min() for x in M]
        vmax = [x[k, :, :].max() for x in M]
        vmin = min( vmin)
        vmax = max( vmax)
        for l in xrange(nCol):
            ax = plt.subplot(gs[k, l])
            im = ax.imshow(M[l][k, :, :].T, vmin=vmin, vmax=vmax, interpolation='none')
            ax.set_axis_off()
            ax.set_xticklabels([])
            ax.set_yticklabels([])
            if k == 0:
                ax.set_title(titles[l], fontsize=20)
            if l == (nCol-1):
                box = ax.get_position()
                ax.set_position([box.x0*1.05, box.y0, box.width, box.height])
                axColor = plt.axes([box.x0*1.05 + box.width * 1.05, box.y0, 0.01, box.height])
                fig.colorbar(im, cax = axColor)
                
        
    #fig.subplots_adjust(right = 0.5)
    #cbar_ax = fig.add_axes([0.55, 0.45, 0.005, 0.11])
    #fig.colorbar(im, cax=cbar_ax)
    #fig.subplots_adjust(wspace=0., hspace=0.)
    plt.savefig('demo_completion_gridplot.pdf', dpi=300)
    #fig.show()
    # plot functional curves

    plt.clf()
    fig = plt.figure()
    plt.semilogy(f['fit'], label='ALS')
    plt.xlabel('It.num.')
    plt.ylabel('ln( Fit )')
    plt.grid(True)
    plt.legend()
    plt.title('Funval ALS')
    plt.savefig('demo_completion_fitplot.pdf', dpi=300)
Example #46
0
 def test_projector_splitting_add(self):
     for debug_mode in [False, True]:
         Y = tt.rand([5, 2, 3], 3, [1, 2, 3, 1])
         my_res = riemannian.projector_splitting_add(Y.copy(), Y.copy(), debug=debug_mode)
         np.testing.assert_array_almost_equal(2 * Y.full(), my_res.full())