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
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