Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _apply_op_network(site_edges, op, n1, pbc=False):
N = len(site_edges)
op_sites = len(op.shape) // 2
n_op = tensornetwork.Node(op, backend="tensorflow")
for m in range(op_sites):
target_site = (n1 + m) % N if pbc else n1 + m
tensornetwork.connect(n_op[op_sites + m], site_edges[target_site])
site_edges[target_site] = n_op[m]
return site_edges, n_op
Raises:
ValueError: If any of the clauses have a 0 in them.
"""
for clause in clauses:
if 0 in clause:
raise ValueError("0's are not allowed in the clauses.")
var_set = set()
for clause in clauses:
var_set |= {abs(x) for x in clause}
num_vars = max(var_set)
var_nodes = []
var_edges = []
# Prepare the variable nodes.
for _ in range(num_vars):
new_node = tn.Node(np.ones(2, dtype=np.int32))
var_nodes.append(new_node)
var_edges.append(new_node[0])
# Create the nodes for each clause
for clause in clauses:
a, b, c, = clause
clause_tensor = np.ones((2, 2, 2), dtype=np.int32)
clause_tensor[(-np.sign(a) + 1) // 2, (-np.sign(b) + 1) // 2,
(-np.sign(c) + 1) // 2] = 0
clause_node = tn.Node(clause_tensor)
# Connect the variable to the clause through a copy tensor.
for i, var in enumerate(clause):
copy_tensor_node = tn.CopyNode(3, 2)
clause_node[i] ^ copy_tensor_node[0]
var_edges[abs(var) - 1] ^ copy_tensor_node[1]
if skip > 0:
if gate is not None:
raise ValueError(
"Overlapping gates in same layer at site {}!".format(n))
skip -= 1
elif gate is not None:
site_edges, n_gate = _apply_op_network(site_edges, gate, n)
nodes.append(n_gate)
# keep track of how many sites this gate included
op_sites = len(gate.shape) // 2
skip = op_sites - 1
# NOTE: This may not be the optimal order if transpose costs are considered.
n_psi = reduce(tensornetwork.contract_between, nodes)
n_psi.reorder_edges(site_edges)
return n_psi.tensor
def _apply_op_network(site_edges, op, n1, pbc=False):
N = len(site_edges)
op_sites = len(op.shape) // 2
n_op = tensornetwork.Node(op, backend="tensorflow")
for m in range(op_sites):
target_site = (n1 + m) % N if pbc else n1 + m
tensornetwork.connect(n_op[op_sites + m], site_edges[target_site])
site_edges[target_site] = n_op[m]
return site_edges, n_op
def get_env_isometry_5(hamiltonian, reduced_density, isometry, unitary):
net = tn.TensorNetwork("tensorflow")
iso_l = net.add_node(isometry)
iso_c = net.add_node(isometry)
iso_l_con = net.add_node(tf.conj(isometry))
iso_c_con = net.add_node(tf.conj(isometry))
iso_r_con = net.add_node(tf.conj(isometry))
op = net.add_node(hamiltonian)
rho = net.add_node(reduced_density)
un_l = net.add_node(unitary)
un_l_con = net.add_node(tf.conj(unitary))
un_r = net.add_node(unitary)
un_r_con = net.add_node(tf.conj(unitary))
def scalar_product(bottom, top):
"""
calculate the Hilbert-schmidt inner product between `bottom` and `top'
Args:
bottom (tf.Tensor)
top (tf.Tensor)
Returns:
tf.Tensor: the inner product
"""
net = tn.TensorNetwork("tensorflow")
b = net.add_node(tf.conj(bottom))
t = net.add_node(top)
edges = [net.connect(b[n], t[n]) for n in range(len(bottom.shape))]
out = net.contract_between(b, t)
return out.get_tensor()
def two_site_descending_super_operator(rho, isometry, unitary):
"""
binary mera two-site descending super operator
Args:
rho (tf.Tensor): hamiltonian
isometry (tf.Tensor): isometry of the binary mera
unitary (tf.Tensor): disentanlger of the mera
Returns:
tf.Tensor
"""
net = tn.TensorNetwork("tensorflow")
iso_l = net.add_node(isometry)
iso_r = net.add_node(isometry)
iso_l_con = net.add_node(tf.conj(isometry))
iso_r_con = net.add_node(tf.conj(isometry))
rho = net.add_node(reduced_density)
un = net.add_node(unitary)
un_con = net.add_node(tf.conj(unitary))
out_order = [un_con[0], un_con[1], un[0], un[1]]
edges[0] = net.connect(iso_l[0], iso_l_con[0])
edges[1] = net.connect(iso_r[1], iso_r_con[1])
edges[2] = net.connect(iso_l[2], rho[0])
edges[3] = net.connect(iso_l_con[2], rho[2])
edges[4] = net.connect(iso_r[2], rho[1])
def right_ascending_super_operator(hamiltonian, isometry, unitary):
"""
binary mera right ascending super operator
Args:
hamiltonian (tf.Tensor): hamiltonian
isometry (tf.Tensor): isometry of the binary mera
unitary (tf.Tensor): disentanlger of the mera
Returns:
tf.Tensor
"""
net = tn.TensorNetwork("tensorflow")
iso_l = net.add_node(isometry)
iso_c = net.add_node(isometry)
iso_r = net.add_node(isometry)
iso_l_con = net.add_node(tf.conj(isometry))
iso_c_con = net.add_node(tf.conj(isometry))
iso_r_con = net.add_node(tf.conj(isometry))
op = net.add_node(hamiltonian)
un_l = net.add_node(unitary)
un_l_con = net.add_node(tf.conj(unitary))
un_r = net.add_node(unitary)
un_r_con = net.add_node(tf.conj(unitary))
def right_descending_super_operator(reduced_density, isometry, unitary):
"""
binary mera right descending super operator
Args:
reduced_density (tf.Tensor): reduced density matrix
isometry (tf.Tensor): isometry of the binary mera
unitary (tf.Tensor): disentanlger of the mera
Returns:
tf.Tensor
"""
net = tn.TensorNetwork("tensorflow")
iso_l = net.add_node(isometry)
iso_c = net.add_node(isometry)
iso_r = net.add_node(isometry)
iso_l_con = net.add_node(tf.conj(isometry))
iso_c_con = net.add_node(tf.conj(isometry))
iso_r_con = net.add_node(tf.conj(isometry))
rho = net.add_node(reduced_density)
un_l = net.add_node(unitary)
un_l_con = net.add_node(tf.conj(unitary))
un_r = net.add_node(unitary)
un_r_con = net.add_node(tf.conj(unitary))
"""Applies a two-site local operator to an MPS.
Takes two MPS site tensors and returns new ones, with a center matrix.
"""
if tf.executing_eagerly():
# FIXME: Not ideal, but these ops are very costly at compile time
op_shp = tf.shape(op)
tf.assert_equal(
tf.shape(A1)[1],
op_shp[2],
message="Operator dimensions do not match MPS physical dimensions.")
tf.assert_equal(
tf.shape(A2)[1],
op_shp[3],
message="Operator dimensions do not match MPS physical dimensions.")
net = tn.TensorNetwork("tensorflow")
nA1 = net.add_node(A1, axis_names=["L", "p", "R"])
nA2 = net.add_node(A2, axis_names=["L", "p", "R"])
nop = net.add_node(op, axis_names=["p_out_1", "p_out_2", "p_in_1", "p_in_2"])
net.connect(nA1["R"], nA2["L"])
net.connect(nA1["p"], nop["p_in_1"])
net.connect(nA2["p"], nop["p_in_2"])
output_order = [nA1["L"], nop["p_out_1"], nop["p_out_2"], nA2["R"]]
nA12 = net.contract_between(nA1, nA2)
n_block = net.contract_between(nop, nA12)
nA1_new, nC, nA2_new, s_rest = net.split_node_full_svd(
n_block,
output_order[:2],