Beispiel #1
0
class MachineLearningMPS(MachineLearningFeatureMap):

    def __init__(self, d, chi, dataset='mnist', data_path='..\\..\\..\\MNIST\\',
                 file_sample='train-images.idx3-ubyte', file_label='train-labels.idx1-ubyte',
                 is_normalize=True, par_pool=None, mps=None):
        MachineLearningFeatureMap.__init__(self, d=d, dataset=dataset, data_path=data_path,
                                           file_sample=file_sample, file_label=file_label,
                                           is_normalize=is_normalize, par_pool=par_pool)
        self.chi = chi
        self.vecsLeft = list()
        self.vecsRight = list()
        if mps is None:
            self.mps = MPS(self.length, d, chi, is_eco_dims=True)
        else:
            self.mps = mps

    def initialize_virtual_vecs_train(self):
        self.vecsLeft = bf.empty_list(self.length, list())
        self.vecsRight = bf.empty_list(self.length, list())
        for n in range(0, self.length):
            self.vecsLeft[n] = np.ones((self.mps.virtual_dim[n], self.numVecSample))
            self.vecsRight[n] = np.ones((self.mps.virtual_dim[n+1], self.numVecSample))

    def update_virtual_vecs_train(self, which_t, which_side):
        if (which_side is 'left') or (which_side is 'both'):
            tmp = tm.khatri(self.vecsLeft[which_t], self.vecsImages[:, which_t, :].squeeze())
            self.vecsLeft[which_t + 1] = np.tensordot(
                self.mps.mps[which_t], tmp, ([0, 1], [0, 1]))
        if (which_side is 'right') or (which_side is 'both'):
            tmp = tm.khatri(self.vecsRight[which_t], self.vecsImages[:, which_t, :].squeeze())
            self.vecsRight[which_t - 1] = np.tensordot(
                self.mps.mps[which_t], tmp, ([2, 1], [0, 1]))

    def env_tensor(self, nt, way):
        s = self.mps.mps[nt].shape
        env = tm.khatri(tm.khatri(
            self.vecsLeft[nt], self.vecsImages[:, nt, :].squeeze()).reshape(
            self.mps.virtual_dim[nt] * self.d, self.numVecSample), self.vecsRight[nt])
        if way is 'mera':
            env = env.dot(np.ones((self.numVecSample, )))
        elif way is 'gradient':
            weight = self.mps.mps[nt].reshape(1, -1).dot(env)
            env = env.dot(1 / weight)
        return env.reshape(s)

    def update_tensor_gradient(self, nt, step):
        # for n in self.mps.mps:
        #     print(n)
        # input()
        self.mps.correct_orthogonal_center(nt)
        env = self.env_tensor((nt, 'all', 'gradient'))
        env = tm.normalize_tensor(env)[0]
        # env /= np.linalg.norm(env.reshape(-1, ))
        self.mps.mps[nt] = self.mps.mps[nt] * (1 - step) + step * env.reshape(
            self.mps.mps[nt].shape)
        self.mps.mps[nt] /= np.linalg.norm(self.mps.mps[nt].reshape(-1, ))
 def initial_mps(self, mps=None, center=0, ini_way='1'):
     if mps is None:
         self.mps = MPS(self.length,
                        self.d,
                        self.chi,
                        is_eco_dims=True,
                        ini_way=ini_way)
     else:
         self.mps = mps
     self.mps.correct_orthogonal_center(center, normalize=True)
Beispiel #3
0
 def __init__(self, d, chi, dataset='mnist', data_path='..\\..\\..\\MNIST\\',
              file_sample='train-images.idx3-ubyte', file_label='train-labels.idx1-ubyte',
              is_normalize=True, par_pool=None, mps=None):
     MachineLearningFeatureMap.__init__(self, d=d, dataset=dataset, data_path=data_path,
                                        file_sample=file_sample, file_label=file_label,
                                        is_normalize=is_normalize, par_pool=par_pool)
     self.chi = chi
     self.vecsLeft = list()
     self.vecsRight = list()
     if mps is None:
         self.mps = MPS(self.length, d, chi, is_eco_dims=True)
     else:
         self.mps = mps
 def observe_by_features(self, features, pos):
     if len(pos) == self.length:
         bf.print_error(
             'Input features cannot be as many as the total features')
     features = np.array(features).reshape(-1, 1)
     features = self.map_to_vectors(features).squeeze()
     data_mps = self.mps.wrap_data()
     mps = MPS(self.length, self.d, self.chi)
     mps.refresh_mps_properties(data_mps)
     for n in range(np.array(pos).size):
         mps.mps[pos[n]] = np.tensordot(mps.mps[pos[n]], features[:, n],
                                        [[1], [0]])
     pos = np.sort(pos)
     for n in pos[::-1]:
         if n > 0:
             mps.mps[n - 1] = np.tensordot(mps.mps[n - 1], mps.mps[n],
                                           [[mps.mps[n - 1].ndim - 1], [0]])
         else:
             mps.mps[n + 1] = np.tensordot(mps.mps[n], mps.mps[n + 1],
                                           [[1], [0]])
         mps.mps.__delitem__(n)
     mps.refresh_mps_properties()
     mps.correct_orthogonal_center(0, normalize=True)
     return mps
from library.TensorBasicModule import open_mps_product_state_spin_up
import copy, sys
from library.MPSClass import MpsOpenBoundaryClass

length = 24
d = 2
chi = 3
pre_fix = path.basename(__file__)[:-3] + '_'

para_dmps = parameters_dmps()
para_dmps['num_layers'] = 20
para_dmps['chi_overlap'] = 256
para_dmps['theta'] = 0
para_dmps['num_theta'] = 1

a = MpsOpenBoundaryClass(length, d, chi, spin='half', way='svd', ini_way='r')
a.central_orthogonalization(0, normalize=True)

a.calculate_entanglement_spectrum()
a.calculate_entanglement_entropy()
ent0_mid = a.ent[round(a.length / 2)]
fid0 = a.fidelity_log_to_product_state()
print('Mid entanglement entropy and fid0 = %.12g, %.12g' % (ent0_mid, fid0))

fid, _, _, mpo, _ = deep_mps_qubit(a, para_dmps)

fid = fid[1:]
# plot(fid)
output_txt(fid.reshape(-1, ), pre_fix + 'fid')

fid_prod0 = np.zeros((para_dmps['num_layers'], ))
Beispiel #6
0
def dmrg_finite_size(para=None):
    from library.MPSClass import MpsOpenBoundaryClass as Mob
    t_start = time.time()
    info = dict()
    print('Preparing the parameters and MPS')
    if para is None:
        para = pm.generate_parameters_dmrg()
    # Initialize MPS
    is_parallel = para['isParallel']
    if is_parallel or para['isParallelEnvLMR']:
        par_pool = dict()
        par_pool['n'] = n_nodes
        par_pool['pool'] = ThreadPool(n_nodes)
    else:
        par_pool = None

    A = Mob(length=para['l'],
            d=para['d'],
            chi=para['chi'],
            way='qr',
            ini_way='r',
            operators=para['op'],
            debug=is_debug,
            is_parallel=para['isParallel'],
            par_pool=par_pool,
            is_save_op=para['is_save_op'],
            eig_way=para['eigWay'],
            is_env_parallel_lmr=para['isParallelEnvLMR'])
    A.correct_orthogonal_center(para['ob_position'])
    print('Starting to sweep ...')
    e0_per_site = 0
    info['convergence'] = 1
    ob = dict()
    for t in range(0, para['sweep_time']):
        if_ob = ((t + 1) % para['dt_ob'] == 0) or t == (para['sweep_time'] - 1)
        if if_ob:
            print('In the %d-th round of sweep ...' % (t + 1))
        for n in range(para['ob_position'] + 1, para['l']):
            if para['if_print_detail']:
                print('update the %d-th tensor from left to right...' % n)
            A.update_tensor_eigs(n,
                                 para['index1'],
                                 para['index2'],
                                 para['coeff1'],
                                 para['coeff2'],
                                 para['tau'],
                                 para['is_real'],
                                 tol=para['eigs_tol'])
        for n in range(para['l'] - 2, -1, -1):
            if para['if_print_detail']:
                print('update the %d-th tensor from right to left...' % n)
            A.update_tensor_eigs(n,
                                 para['index1'],
                                 para['index2'],
                                 para['coeff1'],
                                 para['coeff2'],
                                 para['tau'],
                                 para['is_real'],
                                 tol=para['eigs_tol'])
        for n in range(1, para['ob_position']):
            if para['if_print_detail']:
                print('update the %d-th tensor from left to right...' % n)
            A.update_tensor_eigs(n,
                                 para['index1'],
                                 para['index2'],
                                 para['coeff1'],
                                 para['coeff2'],
                                 para['tau'],
                                 para['is_real'],
                                 tol=para['eigs_tol'])
        if if_ob:
            ob['eb_full'] = A.observe_bond_energy(para['index2'],
                                                  para['coeff2'])
            ob['mx'] = A.observe_magnetization(1)
            ob['mz'] = A.observe_magnetization(3)
            ob['e_per_site'] = (sum(ob['eb_full']) - para['hx'] * sum(ob['mx'])
                                - para['hz'] * sum(ob['mz'])) / A.length
            # if para['lattice'] in ('square', 'chain'):
            #     ob['e_per_site'] = (sum(ob['eb_full']) - para['hx']*sum(ob['mx']) - para['hz'] *
            #                         sum(ob['mz']))/A.length
            # else:
            #     ob['e_per_site'] = sum(ob['eb_full'])
            #     for n in range(0, para['l']):
            #         ob['e_per_site'] += para['hx'][n] * ob['mx'][n]
            #         ob['e_per_site'] += para['hz'][n] * ob['mz'][n]
            #     ob['e_per_site'] /= A.length
            info['convergence'] = abs(ob['e_per_site'] - e0_per_site)
            if info['convergence'] < para['break_tol']:
                print(
                    'Converged at the %d-th sweep with error = %g of energy per site.'
                    % (t + 1, info['convergence']))
                break
            else:
                print('Convergence error of energy per site = %g' %
                      info['convergence'])
                e0_per_site = ob['e_per_site']
        if t == para['sweep_time'] - 1 and info['convergence'] > para[
                'break_tol']:
            print('Not converged with error = %g of eb per bond' %
                  info['convergence'])
            print('Consider to increase para[\'sweep_time\']')
    ob['eb'] = get_bond_energies(ob['eb_full'], para['positions_h2'],
                                 para['index2'])
    A.calculate_entanglement_spectrum()
    A.calculate_entanglement_entropy()
    ob['corr_x'] = A.observe_correlators_from_middle(1, 1)
    ob['corr_z'] = A.observe_correlators_from_middle(3, 3)
    info['t_cost'] = time.time() - t_start
    print('Simulation finished in %g seconds' % info['t_cost'])
    A.clean_to_save()
    if A._is_parallel:
        par_pool['pool'].close()
    return ob, A, info, para
Beispiel #7
0
para_dmps['chi_overlap'] = 256
para_dmps['theta'] = 0
para_dmps['num_theta'] = 1

pre_fix = path.basename(__file__)[:-3] + '_'
num_len = length.size
fid = np.zeros((num_len, ))
fid_prod0 = np.zeros((num_len, ))
ent0_mid = np.zeros((num_len, ))
fid_ini = np.zeros((num_len, ))

for n in range(num_len):
    length_now = int(length[n])
    a = MpsOpenBoundaryClass(length_now,
                             d,
                             chi,
                             spin='half',
                             way='svd',
                             ini_way='r')
    a.central_orthogonalization(0, normalize=True)

    a.calculate_entanglement_spectrum()
    a.calculate_entanglement_entropy()
    ent0_mid[n] = a.ent[round(a.length / 2)]
    fid_ini[n] = a.fidelity_log_by_spins_up()
    # print('Mid entanglement entropy and fid0 = %.12g, %.12g' % (ent0_mid, fid_ini))

    fid_tmp, _, _, mpo, _ = deep_mps_qubit(a, para_dmps)
    fid[n] = fid_tmp[-1]

    mps_ini = open_mps_product_state_spin_up(a.length, a.mps[0].shape[1])[0]
    fid_prod0[n] = fidelities_to_original_state(a, mps_ini, mpo,
class MachineLearningMPS(MachineLearningFeatureMap):
    def __init__(self, d, chi, dataset):
        MachineLearningFeatureMap.__init__(self, d=d, dataset=dataset)
        self.chi = chi
        self.vecsLeft = list() * self.length
        self.vecsRight = list() * self.length
        self.norms = None

    def initial_mps(self, mps=None, center=0, ini_way='1'):
        if mps is None:
            self.mps = MPS(self.length,
                           self.d,
                           self.chi,
                           is_eco_dims=True,
                           ini_way=ini_way)
        else:
            self.mps = mps
        self.mps.correct_orthogonal_center(center, normalize=True)

    def initialize_virtual_vecs_train(self, way='contract'):
        self.norms = np.ones((self.length, self.numVecSample))
        self.vecsLeft = bf.empty_list(self.length)
        self.vecsRight = bf.empty_list(self.length)
        if way is 'random':
            for n in range(0, self.length):
                self.vecsLeft[n] = np.random.randn(self.mps.virtual_dim[n],
                                                   self.numVecSample)
                self.vecsRight[n] = np.random.randn(
                    self.mps.virtual_dim[n + 1], self.numVecSample)
        elif way is 'ones':
            for n in range(0, self.length):
                self.vecsLeft[n] = np.ones(
                    (self.mps.virtual_dim[n], self.numVecSample))
                self.vecsRight[n] = np.ones(
                    (self.mps.virtual_dim[n + 1], self.numVecSample))
        else:
            self.vecsRight[self.length - 1] = np.ones(
                (self.mps.virtual_dim[self.length], self.numVecSample))
            self.update_virtual_vecs_train_all_tensors('right')
            self.vecsLeft[0] = np.ones(
                (self.mps.virtual_dim[0], self.numVecSample))

    def update_virtual_vecs_train(self, which_t, which_side):
        if (which_side is 'left') or (which_side is 'both'):
            tmp = tm.khatri(self.vecsLeft[which_t],
                            self.vecsImages[:, which_t, :])
            self.vecsLeft[which_t + 1] = np.tensordot(self.mps.mps[which_t],
                                                      tmp, ([0, 1], [0, 1]))
            norm = np.linalg.norm(self.vecsLeft[which_t + 1], axis=0)
            self.norms[which_t, :] = norm
            self.vecsLeft[which_t + 1] /= norm.repeat(
                self.mps.virtual_dim[which_t + 1]).reshape(
                    self.numVecSample, self.mps.virtual_dim[which_t + 1]).T
        if (which_side is 'right') or (which_side is 'both'):
            tmp = tm.khatri(self.vecsRight[which_t],
                            self.vecsImages[:, which_t, :])
            self.vecsRight[which_t - 1] = np.tensordot(self.mps.mps[which_t],
                                                       tmp, ([2, 1], [0, 1]))
            norm = np.linalg.norm(self.vecsRight[which_t - 1], axis=0)
            self.norms[which_t, :] = norm
            self.vecsRight[which_t - 1] /= norm.repeat(
                self.mps.virtual_dim[which_t]).reshape(
                    self.numVecSample, self.mps.virtual_dim[which_t]).T

    def update_virtual_vecs_train_all_tensors(self, which_side):
        if (which_side is 'left') or (which_side is 'both'):
            for n in range(self.length - 1):
                self.update_virtual_vecs_train(n, 'left')
        if (which_side is 'right') or (which_side is 'both'):
            for n in range(self.length - 1, 0, -1):
                self.update_virtual_vecs_train(n, 'right')

    def env_tensor(self, nt, way):
        s = self.mps.mps[nt].shape
        env = tm.khatri(
            tm.khatri(self.vecsLeft[nt], self.vecsImages[:, nt, :]).reshape(
                self.mps.virtual_dim[nt] * self.d, self.numVecSample),
            self.vecsRight[nt])
        if way is 'mera':
            env = env.dot(np.ones((self.numVecSample, )))
        elif way is 'gradient':
            weight = self.mps.mps[nt].reshape(1, -1).dot(
                env.reshape(-1, self.numVecSample))
            self.norms[nt, :] = weight
            env = env.dot(1 / weight.T)
        return env.reshape(s)

    def update_tensor_gradient(self, nt, step):
        env = self.env_tensor(nt, way='gradient')
        env = self.mps.mps[nt] - env / self.numVecSample
        # env /= np.linalg.norm(env.reshape(-1, ))
        env /= (np.linalg.norm(env) + 1e-8)
        self.mps.mps[nt] -= (step * env)
        self.mps.mps[nt] /= np.linalg.norm(self.mps.mps[nt])

    def generate_features(self,
                          features,
                          pos=None,
                          gene_order=None,
                          theta_max=np.pi / 2,
                          f_min=-1e20,
                          f_max=1e20,
                          is_display=False,
                          way='eigs'):
        # pos: the positions that the features correspond to
        # gene_order: the order how the unknown features will be generated
        if pos is None:
            pos = list(range(len(features)))
        mps = self.observe_by_features(features, pos)
        if gene_order is None:
            gene_order = list(range(mps.mps.__len__()))
        features_new = self.generate_vecs_features_by_mps(mps,
                                                          gene_order,
                                                          way=way,
                                                          theta_max=theta_max)
        if self.is_dct:
            features_new *= self.dct_info['factor']
            features_new += self.dct_info['shift']
            features_new = cv2.idct(features_new.reshape(self.img_size))
            features_new = features_new.reshape(-1, 1)
            features_new = np.max(np.hstack(
                (np.zeros(features_new.shape), features_new)),
                                  axis=1)
            features_new = np.min(np.hstack(
                (np.ones(features_new.shape), features_new)),
                                  axis=1)
        features_new = self.vecs2images(
            data=features_new.reshape(features_new.shape + (1, )),
            theta_max=theta_max)
        features_new = features_new.reshape(-1, 1)
        features_new = np.max(np.hstack(
            (features_new, f_min * np.ones(features_new.shape))),
                              axis=1)
        features_new = features_new.reshape(-1, 1)
        features_new = np.min(np.hstack(
            (features_new, f_max * np.ones(features_new.shape))),
                              axis=1)
        pos_new = list(range(self.length))
        pos = list(pos)
        feature_all = np.zeros((self.length, ))
        for n in range(len(pos)):
            feature_all[pos[n]] = features[n]
            pos_new.remove(pos[n])
        for n in range(len(pos_new)):
            feature_all[pos_new[gene_order[n]]] = features_new[n]
        if is_display is 'colored':
            img_rgb = np.zeros((feature_all.size, 3))
            for n in range(len(pos)):
                img_rgb[pos[n], 0] = features[n]
            for n in range(len(pos_new)):
                img_rgb[pos_new[gene_order[n]], 1] = features_new[n]
            self.show_image(img_rgb.reshape(self.img_size + [3]))
        elif is_display is 'original':
            self.show_image(feature_all.reshape(self.img_size))
        return feature_all

    def observe_by_features(self, features, pos):
        if len(pos) == self.length:
            bf.print_error(
                'Input features cannot be as many as the total features')
        features = np.array(features).reshape(-1, 1)
        features = self.map_to_vectors(features).squeeze()
        data_mps = self.mps.wrap_data()
        mps = MPS(self.length, self.d, self.chi)
        mps.refresh_mps_properties(data_mps)
        for n in range(np.array(pos).size):
            mps.mps[pos[n]] = np.tensordot(mps.mps[pos[n]], features[:, n],
                                           [[1], [0]])
        pos = np.sort(pos)
        for n in pos[::-1]:
            if n > 0:
                mps.mps[n - 1] = np.tensordot(mps.mps[n - 1], mps.mps[n],
                                              [[mps.mps[n - 1].ndim - 1], [0]])
            else:
                mps.mps[n + 1] = np.tensordot(mps.mps[n], mps.mps[n + 1],
                                              [[1], [0]])
            mps.mps.__delitem__(n)
        mps.refresh_mps_properties()
        mps.correct_orthogonal_center(0, normalize=True)
        return mps

    @staticmethod
    def generate_vecs_features_by_mps(mps,
                                      order=None,
                                      way='eigs',
                                      theta_max=np.pi / 2):
        # way='eigs': use the dominant eigen-vector to observe; generate grey images
        # way='rand': use rho[0,0] and rho[1,1] as the probabilities to choose [1,0] or [0,1] to observe;
        #             generate black-and-white images
        d = mps.mps[0].shape[1]
        v = np.zeros((d, mps.mps.__len__()))
        if order is None:
            order = range(mps.length)
        order = np.array(order)
        order0 = order.copy()
        now = 0
        while order.size > 0:
            n = order[0]
            mps.correct_orthogonal_center(n, normalize=True)
            rho = np.tensordot(mps.mps[n], mps.mps[n].conj(), [[0, 2], [0, 2]])
            # rho = rho + rho.T.conj()
            if way is 'eigs':
                u = np.abs(eigsh(rho, k=1, which='LM')[1].reshape(-1, 1))
                v[:, order0[now]] = np.min(np.hstack((u, np.ones(u.shape))),
                                           axis=1)
            else:
                rho /= np.trace(rho)
                r = np.random.rand()
                if r < rho[0, 0]:
                    v[:, order0[now]] = np.array([1, 0])
                else:
                    v[:, order0[now]] = np.array(
                        [np.cos(theta_max),
                         np.sin(theta_max)])
            mat = np.tensordot(mps.mps[n], v[:, order0[now]], [[1], [0]])
            mps.mps.__delitem__(n)
            mps.orthogonality = np.delete(mps.orthogonality, n)
            mps.length -= 1
            order = order[1:]
            order = order - (order > n)
            if mps.length > 0:
                if n != mps.length:
                    mps.mps[n] = np.tensordot(mat, mps.mps[n], [[1], [0]])
                    mps.orthogonality[n] = 0
                    mps.center = n
                else:
                    mps.mps[n - 1] = np.tensordot(mps.mps[n - 1], mat,
                                                  [[2], [0]])
                    mps.orthogonality[n - 1] = 0
                    mps.center = n - 1
            now += 1
        return v

    def compute_nll(self):
        self.env_tensor(self.mps.center,
                        way='gradient')  # to update the norms at the center
        return -np.sum(np.log(self.norms**2)) / self.numVecSample - np.log(
            self.numVecSample)

    def check_normalization_env(self, tol=1e-14):
        num = 0
        for n in self.vecsLeft:
            tmp = np.linalg.norm(n, axis=0)
            tmp = np.abs(tmp - 1)
            tmp = tmp[tmp > tol]
            num += tmp.size
        for n in self.vecsRight:
            tmp = np.linalg.norm(n, axis=0)
            tmp = np.abs(tmp - 1)
            tmp = tmp[tmp > tol]
            num += tmp.size
        if num > 0.5:
            print(
                'Several vecsR not well normalized. There are %i vecs nor normalized'
                % num)
        else:
            print('All vecs well normalized')

    def clear_before_save(self):
        self.images = np.zeros(0)
        self.labels = np.zeros(0)
        self.vecsLeft = list()
        self.vecsRight = list()
        self.vecsImages = np.zeros(0)
        self.vecsLabels = np.zeros(0)
        self.clear_tmp_data()
Beispiel #9
0
import os
import sys
import numpy as np
import library.Parameters as pm
import library.HamiltonianModule as hm
import library.TensorBasicModule as tm
import library.BasicFunctions as bf
import scipy.linalg as la
import pickle
import math
import os.path as opath
import time
import torch
import library.TNmachineLearning as TNML
from library.MPSClass import MpsOpenBoundaryClass
from algorithms.DeepMPSfinite import act_umpo_on_mps

num = 4
mps = tm.mps_ghz_state(num)
a = MpsOpenBoundaryClass(num, 2, 2)
mpd = tm.mpd_of_ghz(num)
mps = act_umpo_on_mps(mps, mpd)
a.input_mps(mps, if_deepcopy=False)
a.correct_orthogonal_center(a.length - 1)
a.check_mps_norm1()

f0 = a.fidelity_log_by_spins_up()
print(f0)