def test_ascending_descending(chi, dtype):
    """
    test if ascending and descending operations are doing the right thing
    """
    wC, uC, rho_0 = bml.initialize_binary_MERA_random(phys_dim=2,
                                                      chi=chi,
                                                      dtype=dtype)
    wC, uC = bml.unlock_layer(wC, uC)  #add a transitional layer
    wC, uC = bml.unlock_layer(wC, uC)  #add a transitional layer
    ham_0 = bml.initialize_TFI_hams(dtype)
    rho = [0 for n in range(len(wC) + 1)]
    ham = [0 for n in range(len(wC) + 1)]
    rho[-1] = bml.steady_state_density_matrix(10, rho_0, wC[-1], uC[-1])
    ham[0] = ham_0
    for p in range(len(rho) - 2, -1, -1):
        rho[p] = bml.descending_super_operator(rho[p + 1], wC[p], uC[p])
    for p in range(len(wC)):
        ham[p + 1] = bml.ascending_super_operator(ham[p], wC[p], uC[p])
    energies = [
        tn.ncon([rho[p], ham[p]], [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]])
        for p in range(len(rho))
    ]
    np.testing.assert_allclose(
        np.array(
            [energies[p] / energies[p + 1] for p in range(len(energies) - 1)]),
        0.5)
def test_padding(chi, dtype):
    wC, uC, rho_0 = bml.initialize_binary_MERA_random(phys_dim=2,
                                                      chi=chi,
                                                      dtype=dtype)
    wC, uC = bml.unlock_layer(wC, uC)  #add a transitional layer
    wC, uC = bml.unlock_layer(wC, uC)  #add a transitional layer
    ham_0 = bml.initialize_TFI_hams(dtype)

    def get_energies(wC, uC, rho_0, ham_0):
        rho = [0 for n in range(len(wC) + 1)]
        ham = [0 for n in range(len(wC) + 1)]

        rho[-1] = bml.steady_state_density_matrix(10, rho_0, wC[-1], uC[-1])
        ham[0] = ham_0
        for p in range(len(rho) - 2, -1, -1):
            rho[p] = bml.descending_super_operator(rho[p + 1], wC[p], uC[p])
        for p in range(len(wC)):
            ham[p + 1] = bml.ascending_super_operator(ham[p], wC[p], uC[p])
        energies = [
            tn.ncon([rho[p], ham[p]], [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]])
            for p in range(len(rho))
        ]
        return energies

    energies_1 = get_energies(wC, uC, rho_0, ham_0)

    chi_new = chi + 1
    wC, uC = bml.pad_mera_tensors(chi_new, wC, uC)
    rho_0 = misc_mera.pad_tensor(rho_0, [chi_new] * 6)
    energies_2 = get_energies(wC, uC, rho_0, ham_0)
    np.testing.assert_allclose(energies_1, energies_2)
Exemple #3
0
def run_binary_mera_optimization_TFI(chis=[4, 6, 8],
                                     niters=[200, 300, 1000],
                                     embeddings=None,
                                     dtype=tf.float64,
                                     verbose=1,
                                     nsteps_steady_state=4,
                                     numpy_update=True,
                                     opt_u_after=40,
                                     opt_all_layers=None,
                                     wC=0,
                                     uC=0,
                                     rho_0=0,
                                     noises=None,
                                     filename=None):
    """
    optimize a binary mera to approximate the ground-state of the infinite transverse field Ising model
    Args:
        chis (list of int):   bond dimension of successive MERA simulations 
        niters (list of int): number of optimization steps of successive MERA optimizations 
        embeddings (list of str or None): type of embedding scheme used to embed mera into the next larger bond dimension 
                                          entries can be: 'p' or 'pad' for padding with zeros without, if possible, adding new layers 
                                                          'a' or 'add' for adding new layer with increased  bond dimension
                                                          'n'          for keeping the MERA as it is (e.g. for resuming optimization)
                                          the first entry will be ignored for the case where no `wC` and `uC` tensors are passed
        dtype (tensorflow dtype):      dtype
        verbose (int):                 verbosity flag, if `verbose>0`, print out info  during optimization
        nsteps_steady_state (int):     number of power-method iteration steps for calculating the 
                                       steady state density matrices 
        numpy_update (bool):           if True, use numpy svd to calculate update of disentanglers and isometries
        opt_u_after (int):             start optimizing disentangler only after `opt_u_after` initial optimization steps
        opt_all_layers (bool):         if `True`, optimize all layers
                                       if `False`, only optimize truncating layers
        wC (list of tf.Tensor or 0.0): initial values for isometries; if `0.0`, initialize with  identities
        uC (list of tf.Tensor or 0.0): initial values for disentanglers; if `0.0`, initialize with  identities
        rho_0 (tf.Tensor or 0.0):      initial value for reduced density matrix; if `0.0`, initialize with  identities
        noises (list of float):        noise values for initializing new layers

    Returns: 
        wC (list of tf.Tensor): optimized isometries of the MERA
        uC (list of tf.Tensor): optimized disentanglers of the MERA
        energies (list of tf.Tensor): energies per iteration steps
        walltimes (list of float):    walltimes per iteration step 
    """

    if not embeddings:
        embeddings = ['p'] * len(chis)
    if not noises:
        noises = [0.0] * len(chis)
    if not opt_all_layers:
        opt_all_layers = [True] * len(chis)

    init = False
    if wC == 0:
        init = True
        wC, _, _ = bml.initialize_binary_MERA_identities(phys_dim=2,
                                                         chi=chis[0],
                                                         dtype=dtype)
    if uC == 0:
        init = True
        _, uC, _ = bml.initialize_binary_MERA_identities(phys_dim=2,
                                                         chi=chis[0],
                                                         dtype=dtype)
    if rho_0 == 0:
        _, _, rho_0 = bml.initialize_binary_MERA_identities(phys_dim=2,
                                                            chi=chis[0],
                                                            dtype=dtype)

    ham_0 = bml.initialize_TFI_hams(dtype=dtype)

    data = {'profile': {}, 'energies': {}}

    for chi, niter, which, noise, opt_all in zip(chis, niters, embeddings,
                                                 noises, opt_all_layers):
        energies = []
        walltimes = []
        if not init:
            if which in ('a', 'add'):
                wC, uC = bml.unlock_layer(wC, uC, noise=noise)
                wC, uC = bml.pad_mera_tensors(chi, wC, uC, noise=noise)
            elif which in ('p', 'pad'):
                wC, uC = bml.pad_mera_tensors(chi, wC, uC, noise=noise)

        rho_0 = misc_mera.pad_tensor(rho_0, [chi, chi, chi, chi, chi, chi])

        wC, uC, rho_0, times, es = bml.optimize_binary_mera(
            ham_0=ham_0,
            #rho_0=rho_0,
            wC=wC,
            uC=uC,
            numiter=niter,
            nsteps_steady_state=nsteps_steady_state,
            verbose=verbose,
            opt_u=True,
            opt_w=True,
            numpy_update=numpy_update,
            opt_u_after=opt_u_after,
            opt_all_layers=opt_all)
        energies.extend(es)
        walltimes.extend(times)
        data['profile'][chi] = walltimes
        data['energies'][chi] = energies
        init = False
        if filename:
            with open(filename + '_tensors.pickle', 'wb') as f:
                pickle.dump([wC, uC], f)
            with open('energies_walltimes_' + filename + '.pickle', 'wb') as f:
                pickle.dump(data, f)

    return wC, uC, walltimes, energies
Exemple #4
0
def run_naive_optimization_benchmark(filename,
                                     chis=[4, 6, 8, 10, 12],
                                     dtype=tf.float64,
                                     numiter=10,
                                     nsteps_steady_state=4,
                                     opt_u=True,
                                     opt_w=True,
                                     numpy_update=True,
                                     device=None,
                                     opt_u_after=40):
    """
    run a naive optimization benchmark, i.e. one without growing bond dimensions by embedding 
    Args:
        filename (str):           filename under which results are stored as a pickle file
        chis (list):              list of bond dimensions for which to run the benchmark
        dtype (tensorflow dtype): dtype to be used for the benchmark
        numiter (int):            number of iteration steps 
        nsteps_steady_state (int):number of iterations steps used to obtain the steady-state 
                                  reduced density matrix
        opt_u (bool):             if True, optimize disentangler `u`
        opt_w (bool):             if True, optimize isometries `w`
        numpy_update (bool):      if True, use numpy-svd to update tensors
        device (str or None):     device on  which the benchmark should be run
        opt_u_after (int):        do not optimize `u` for the first `opt_u_after' steps

    Returns: 
       dict:  dictionary containing the walltimes and energies
              key 'profile': list of runtimes
              key 'energies' list of energies per iteration step
    """

    walltimes = {'profile': {}, 'energies': {}}
    with tf.device(device):
        for chi in chis:
            print('running naive optimization benchmark for chi = {0}'.format(
                chi))

            wC, uC, rho_0 = bml.initialize_binary_MERA_identities(phys_dim=2,
                                                                  chi=chi,
                                                                  dtype=dtype)
            ham_0 = bml.initialize_TFI_hams(dtype=dtype)
            wC, uC, rho_0, runtimes, energies = bml.optimize_binary_mera(
                ham_0=ham_0,
                rho_0=rho_0,
                wC=wC,
                uC=uC,
                numiter=numiter,
                nsteps_steady_state=nsteps_steady_state,
                verbose=1,
                opt_u=opt_u,
                opt_w=opt_w,
                numpy_update=numpy_update,
                opt_u_after=opt_u_after)

            walltimes['profile'][chi] = runtimes
            walltimes['energies'][chi] = energies
            print('     steps took {0} s'.format(walltimes['profile'][chi]))
            with open(filename + '.pickle', 'wb') as f:
                pickle.dump(walltimes, f)

    return walltimes