def test_steady_state(chi, dtype):
    isometry = misc_mera.w_update_svd_numpy(
        np.random.rand(chi, chi, chi).astype(dtype.as_numpy_dtype))
    unitary = misc_mera.u_update_svd_numpy(
        np.random.rand(chi, chi, chi, chi).astype(dtype.as_numpy_dtype))
    rho = tf.reshape(
        tf.eye(chi * chi * chi, dtype=dtype), (chi, chi, chi, chi, chi, chi))
    rho_ss = bml.steady_state_density_matrix(
        nsteps=60, rho=rho, isometry=isometry, unitary=unitary)
    rho_test = bml.descending_super_operator(rho_ss, isometry, unitary)
    np.testing.assert_array_less(rho_ss - rho_test, 1E-6)
def test_isometry_envs(chi, dtype):
    isometry = misc_mera.w_update_svd_numpy(
        np.random.rand(chi, chi, chi).astype(dtype.as_numpy_dtype))
    unitary = misc_mera.u_update_svd_numpy(
        np.random.rand(chi, chi, chi, chi).astype(dtype.as_numpy_dtype))
    rho = tf.random_uniform(shape=[chi, chi, chi, chi, chi, chi], dtype=dtype)
    ham = tf.random_uniform(shape=[chi, chi, chi, chi, chi, chi], dtype=dtype)
    
    envs = {}
    envs[0] = bml.get_env_isometry_1(ham, rho, isometry, unitary)
    envs[1] = bml.get_env_isometry_3(ham, rho, isometry, unitary)
    envs[2] = bml.get_env_isometry_5(ham, rho, isometry, unitary)
    envs[3] = bml.get_env_isometry_2(ham, rho, isometry, unitary)
    envs[4] = bml.get_env_isometry_4(ham, rho, isometry, unitary)
    envs[5] = bml.get_env_isometry_6(ham, rho, isometry, unitary)
    t_a = [tn.ncon([envs[n], isometry], [[1, 2, 3], [1, 2, 3]]) for n in range(3)]
    t_b = [
        tn.ncon([envs[n], isometry], [[1, 2, 3], [1, 2, 3]]) for n in range(3, 6)
    ]
    np.testing.assert_allclose(t_a, t_a[0])
    np.testing.assert_allclose(t_b, t_b[0])
def optimize_mod_binary_mera(hamAB_0,
                             hamBA_0,
                             rhoAB_0,
                             rhoBA_0,
                             wC,
                             vC,
                             uC,
                             numiter=1000,
                             refsym=True,
                             nsteps_steady_state=8,
                             verbose=0,
                             opt_u=True,
                             opt_vw=True,
                             numpy_update=True,
                             opt_all_layers=False,
                             opt_u_after=9):
    """
    optimization of a scale invariant modified binary MERA tensor network
    Args:
        hamAB_0 (tf.Tensor): bottom-layer Hamiltonians in AB lattices
        hamBA_0 (tf.Tensor): bottom-layer Hamiltonians in BA lattices
        rhoAB_0 (tf.Tensor):  reduced densit matrix on a-b lattice
        rhoBA_0 (tf.Tensor):  reduced densit matrix on b-a lattice
        wC (list of tf.Tensor): isometries of the MERA, with 
        vC (list of tf.Tensor): isometries of the MERA, with 
        uC (list of tf.Tensor): disentanglers of the MERA
        numiter (int):  number of iteration steps 
        refsym (bool):  if `True`, impose reflection symmetry 
        nsteps_steady_state (int): number of power-method iteration steps for calculating the 
                                   steady state density matrices 
        verbose (int): verbosity flag
        opt_u (bool):  if `False`, skip disentangler optimization 
        opt_vw (bool):  if `False`, skip isometry optimization 
        numpy_update (bool): if `True`, use numpy svd to calculate updates
        opt_all_layers (bool): if `True`, optimize all layers
                               if `False`, optimize only truncating layers
        opt_u_after (int): start optimizing disentangler only after `opt_u_after` initial optimization steps

    Returns: 
        wC (list of tf.Tensor): optimized isometries
        vC (list of tf.Tensor): optimized isometries
        uC (list of tf.Tensor): optimized disentanglers
        rhoAB (tf.Tensor):      steady state density matrices on the A-B lattice at the top layer 
        rhoBA (tf.Tensor):      steady state density matrices on the B-A lattice at the top layer 
        run_times (list of float): run times per iteration step 
        Energies (list of float): energies per iteration step 
    """
    dtype = rhoAB_0.dtype

    hamAB = [0 for x in range(len(vC) + 1)]
    hamBA = [0 for x in range(len(vC) + 1)]
    rhoAB = [0 for x in range(len(vC) + 1)]
    rhoBA = [0 for x in range(len(vC) + 1)]

    hamAB[0] = hamAB_0
    hamBA[0] = hamBA_0

    chi1 = hamAB[0].shape[0]

    bias = tf.math.reduce_max(
        tf.linalg.eigvalsh(tf.reshape(hamAB[0], (chi1 * chi1, chi1 * chi1))))
    hamAB[0] = hamAB[0] - bias * tf.reshape(tf.eye(chi1 * chi1, dtype=dtype),
                                            (chi1, chi1, chi1, chi1))
    hamBA[0] = hamBA[0] - bias * tf.reshape(tf.eye(chi1 * chi1, dtype=dtype),
                                            (chi1, chi1, chi1, chi1))

    skip_layer = [misc_mera.skip_layer(w) for w in wC]
    for p in range(len(wC)):
        if skip_layer[p]:
            hamAB[p + 1], hamBA[p + 1] = ascending_super_operator(
                hamAB[p], hamBA[p], wC[p], vC[p], uC[p], refsym)

    Energies = []
    run_times = []
    for k in range(numiter):
        t1 = time.time()
        rhoAB_0, rhoBA_0 = steady_state_density_matrices(
            nsteps_steady_state, rhoAB_0, rhoBA_0, wC[-1], vC[-1], uC[-1],
            refsym)
        rhoAB[-1] = rhoAB_0
        rhoBA[-1] = rhoBA_0
        for p in range(len(rhoAB) - 2, -1, -1):
            rhoAB[p], rhoBA[p] = descending_super_operator(
                rhoAB[p + 1], rhoBA[p + 1], wC[p], vC[p], uC[p], refsym)

        if verbose > 0:
            if np.mod(k, 10) == 1:
                Energies.append(
                    (tn.ncon([rhoAB[0], hamAB[0]], [[1, 2, 3, 4], [1, 2, 3, 4]]
                             ) + tn.ncon([rhoBA[0], hamBA[0]],
                                         [[1, 2, 3, 4], [1, 2, 3, 4]])) / 4 +
                    bias / 2)
                stdout.write(
                    '\rIteration: %i of %i: E = %.8f, err = %.16f at D = %i with %i layers'
                    % (int(k), int(numiter), float(Energies[-1]),
                       float(Energies[-1] + 4 / np.pi, ), int(
                           wC[-1].shape[2]), len(wC)))
                stdout.flush()

        for p in range(len(wC)):
            if (not opt_all_layers) and skip_layer[p]:
                continue

            if k >= opt_u_after:
                uEnv = get_env_disentangler(hamAB[p], hamBA[p], rhoBA[p + 1],
                                            wC[p], vC[p], uC[p], refsym)
                if opt_u:
                    if refsym:
                        uEnv = uEnv + tf.transpose(uEnv, (1, 0, 3, 2))
                    if numpy_update:
                        uC[p] = misc_mera.u_update_svd_numpy(uEnv)
                    else:
                        uC[p] = misc_mera.u_update_svd(uEnv)

            wEnv = get_env_w_isometry(hamAB[p], hamBA[p], rhoBA[p + 1],
                                      rhoAB[p + 1], wC[p], vC[p], uC[p])
            if opt_vw:
                if numpy_update:
                    wC[p] = misc_mera.w_update_svd_numpy(wEnv)
                else:
                    wC[p] = misc_mera.w_update_svd(wEnv)
                if refsym:
                    vC[p] = wC[p]
                else:
                    vEnv = get_env_v_isometry(hamAB[p], hamBA[p], rhoBA[p + 1],
                                              rhoAB[p + 1], wC[p], vC[p],
                                              uC[p])
                    vC[p] = misc_mera.w_update_svd(vEnv)

            hamAB[p + 1], hamBA[p + 1] = ascending_super_operator(
                hamAB[p], hamBA[p], wC[p], vC[p], uC[p], refsym)

        run_times.append(time.time() - t1)
        if verbose > 2:
            print('time per iteration: ', run_times[-1])

    return wC, vC, uC, rhoAB[-1], rhoBA[-1], run_times, Energies
Пример #4
0
def optimize_mod_binary_mera(hamAB_0,
                             hamBA_0,
                             rhoAB_0,
                             rhoBA_0,
                             wC,
                             vC,
                             uC,
                             numiter=1000,
                             refsym=True,
                             nsteps_steady_state=8,
                             verbose=0,
                             opt_u=True,
                             opt_vw=True,
                             numpy_update=True,
                             opt_all_layers=False,
                             opt_u_after=9):
    """
    ------------------------
    adapted from Glen Evenbly (c) for www.tensors.net, (v1.1) - last modified 24/1/2019
    ------------------------
    optimization of a scale invariant modified binary MERA tensor network
    Parameters:
    ----------------------------
    hamAB_0, hamBA_0:      tf.Tensor
                           bottom-layer Hamiltonians in AB and BA sublattices
    rhoAB_0, rhoBA_0:      tf.Tensor 
                           initial values for steady-state density matrices
    wC, vC, uC:            list of tf.Tensor 
                           isometries (wC, vC) and disentanglers (uC) of the MERA, with 
                           bottom layers first 
    numiter:               int 
                           number of iteration steps 
    refsym:                bool 
                           impose reflection symmetry 
    nsteps_steady_state:   int 
                           number of power-methodf iteration steps for calculating the 
                           steady state density matrices 
    verbose:               int 
                           verbosity flag 
    opt_u, opt_uv:         bool 
                           if False, skip unitary or isometry optimization 
    numpy_update:          bool
                           if True, use numpy svd to calculate update of disentanglers
    opt_all_layers:        bool
                           if True, optimize all layers
                           if False, optimize only truncating layers
    opt_u_after:           int 
                           start optimizing disentangler only after `opt_u_after` initial optimization steps
    Returns: 
    -------------------------------
    (wC, vC, uC, rhoAB, rhoBA, run_times, Energies)
    wC, vC, uC:             list of tf.Tensor 
                            obtimized MERA tensors
    rhoAB, rhoBA:           tf.Tensor 
                            steady state density matrices at the top layer 
    run_times:              list 
                            run times per iteration step 
    Energies:               list 
                            energies at each iteration step
    """
    dtype = rhoAB_0.dtype

    hamAB = [0 for x in range(len(vC) + 1)]
    hamBA = [0 for x in range(len(vC) + 1)]
    rhoAB = [0 for x in range(len(vC) + 1)]
    rhoBA = [0 for x in range(len(vC) + 1)]

    hamAB[0] = hamAB_0
    hamBA[0] = hamBA_0

    chi1 = hamAB[0].shape[0]

    bias = tf.math.reduce_max(
        tf.linalg.eigvalsh(tf.reshape(hamAB[0], (chi1 * chi1, chi1 * chi1))))
    hamAB[0] = hamAB[0] - bias * tf.reshape(
        tf.eye(chi1 * chi1, dtype=dtype), (chi1, chi1, chi1, chi1))
    hamBA[0] = hamBA[0] - bias * tf.reshape(
        tf.eye(chi1 * chi1, dtype=dtype), (chi1, chi1, chi1, chi1))

    skip_layer = [misc_mera.skip_layer(w) for w in wC]
    for p in range(len(wC)):
        if skip_layer[p]:
            hamAB[p + 1], hamBA[p + 1] = ascending_super_operator(
                hamAB[p], hamBA[p], wC[p], vC[p], uC[p], refsym)

    Energies = []
    run_times = []
    for k in range(numiter):
        t1 = time.time()
        rhoAB_0, rhoBA_0 = steady_state_density_matrices(
            nsteps_steady_state, rhoAB_0, rhoBA_0, wC[-1], vC[-1], uC[-1],
            refsym)
        rhoAB[-1] = rhoAB_0
        rhoBA[-1] = rhoBA_0
        for p in range(len(rhoAB) - 2, -1, -1):
            rhoAB[p], rhoBA[p] = descending_super_operator(
                rhoAB[p + 1], rhoBA[p + 1], wC[p], vC[p], uC[p], refsym)

        if verbose > 0:
            if np.mod(k, 10) == 1:
                Energies.append(
                    (tn.ncon([rhoAB[0], hamAB[0]],
                               [[1, 2, 3, 4], [1, 2, 3, 4]]) + tn.
                     ncon([rhoBA[0], hamBA[0]], [[1, 2, 3, 4], [1, 2, 3, 4]])) /
                    4 + bias / 2)
                stdout.write(
                    '\rIteration: %i of %i: E = %.8f, err = %.16f at D = %i with %i layers'
                    % (int(k), int(numiter), float(Energies[-1]),
                       float(Energies[-1] + 4 / np.pi,), int(wC[-1].shape[2]),
                       len(wC)))
                stdout.flush()

        for p in range(len(wC)):
            if (not opt_all_layers) and skip_layer[p]:
                continue

            if k >= opt_u_after:
                uEnv = get_env_disentangler(hamAB[p], hamBA[p], rhoBA[p + 1],
                                            wC[p], vC[p], uC[p], refsym)
                if opt_u:
                    if refsym:
                        uEnv = uEnv + tf.transpose(uEnv, (1, 0, 3, 2))
                    if numpy_update:
                        uC[p] = misc_mera.u_update_svd_numpy(uEnv)
                    else:
                        uC[p] = misc_mera.u_update_svd(uEnv)

            wEnv = get_env_w_isometry(hamAB[p], hamBA[p], rhoBA[p + 1],
                                      rhoAB[p + 1], wC[p], vC[p], uC[p])
            if opt_vw:
                if numpy_update:
                    wC[p] = misc_mera.w_update_svd_numpy(wEnv)
                else:
                    wC[p] = misc_mera.w_update_svd(wEnv)
                if refsym:
                    vC[p] = wC[p]
                else:
                    vEnv = get_env_v_isometry(hamAB[p], hamBA[p], rhoBA[p + 1],
                                              rhoAB[p + 1], wC[p], vC[p], uC[p])
                    vC[p] = misc_mera.w_update_svd(vEnv)

            hamAB[p + 1], hamBA[p + 1] = ascending_super_operator(
                hamAB[p], hamBA[p], wC[p], vC[p], uC[p], refsym)

        run_times.append(time.time() - t1)
        if verbose > 2:
            print('time per iteration: ', run_times[-1])

    return wC, vC, uC, rhoAB[-1], rhoBA[-1], run_times, Energies