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]
Returns:
The energy.
"""
backend = "jax"
out = []
for dirn in ('left', 'right'):
iso_l = tensornetwork.Node(isometry, backend=backend)
iso_c = tensornetwork.Node(isometry, backend=backend)
iso_r = tensornetwork.Node(isometry, backend=backend)
iso_l_con = tensornetwork.conj(iso_l)
iso_c_con = tensornetwork.conj(iso_c)
iso_r_con = tensornetwork.conj(iso_r)
op = tensornetwork.Node(hamiltonian, backend=backend)
rho = tensornetwork.Node(state, backend=backend)
un_l = tensornetwork.Node(disentangler, backend=backend)
un_l_con = tensornetwork.conj(un_l)
un_r = tensornetwork.Node(disentangler, backend=backend)
un_r_con = tensornetwork.conj(un_r)
tensornetwork.connect(iso_l[2], rho[0])
tensornetwork.connect(iso_c[2], rho[1])
tensornetwork.connect(iso_r[2], rho[2])
tensornetwork.connect(iso_l[0], iso_l_con[0])
tensornetwork.connect(iso_l[1], un_l[2])
tensornetwork.connect(iso_c[0], un_l[3])
tensornetwork.connect(iso_c[1], un_r[2])
n1: The number of the leftmost site at which to apply the operator.
pbc: If `True`, use periodic boundary conditions, so that site `N` is
identified with site `0`. Otherwise, site `N-1` has no neighbors to the
right.
Returns:
expval: The expectation value.
"""
n_psi = tensornetwork.Node(psi, backend="tensorflow")
site_edges = n_psi.get_all_edges()
site_edges, n_op = _apply_op_network(site_edges, op, n1, pbc)
n_op_psi = n_op @ n_psi
n_psi_conj = tensornetwork.Node(tf.math.conj(psi), backend="tensorflow")
for i in range(len(site_edges)):
tensornetwork.connect(site_edges[i], n_psi_conj[i])
res = n_psi_conj @ n_op_psi
return res.tensor
The circuit consists of a sequence of layers, with each layer consisting
of non-overlapping gates.
Args:
psi: An `N`-dimensional tensor representing the initial wavefunction.
layers: A sequence of layers. Each layer is a sequence of gates, with
each index of a layer corresponding to a site in `psi`. The `i`th gate
of a layer acts on sites `i` to `i + k - 1`, where `k` is the range of
the gate. Gates may not overlap within a layer.
Returns:
psi_t: The final wavefunction.
"""
num_sites = len(psi.shape)
n_psi = tensornetwork.Node(psi, backend="tensorflow")
site_edges = n_psi.get_all_edges()
nodes = [n_psi]
for gates in layers:
skip = 0
for n in range(num_sites):
if n < len(gates):
gate = gates[n]
else:
gate = None
if skip > 0:
if gate is not None:
raise ValueError(
"Overlapping gates in same layer at site {}!".format(n))
skip -= 1
The energy.
"""
backend = "jax"
out = []
for dirn in ('left', 'right'):
iso_l = tensornetwork.Node(isometry, backend=backend)
iso_c = tensornetwork.Node(isometry, backend=backend)
iso_r = tensornetwork.Node(isometry, backend=backend)
iso_l_con = tensornetwork.conj(iso_l)
iso_c_con = tensornetwork.conj(iso_c)
iso_r_con = tensornetwork.conj(iso_r)
op = tensornetwork.Node(hamiltonian, backend=backend)
rho = tensornetwork.Node(state, backend=backend)
un_l = tensornetwork.Node(disentangler, backend=backend)
un_l_con = tensornetwork.conj(un_l)
un_r = tensornetwork.Node(disentangler, backend=backend)
un_r_con = tensornetwork.conj(un_r)
tensornetwork.connect(iso_l[2], rho[0])
tensornetwork.connect(iso_c[2], rho[1])
tensornetwork.connect(iso_r[2], rho[2])
tensornetwork.connect(iso_l[0], iso_l_con[0])
tensornetwork.connect(iso_l[1], un_l[2])
tensornetwork.connect(iso_c[0], un_l[3])
tensornetwork.connect(iso_c[1], un_r[2])
tensornetwork.connect(iso_r[0], un_r[3])
def inline_stitch(targets: List[int], tensor: np.ndarray, name: str):
"""Applies an operation to the targeted axis indices."""
op_node = tn.Node(tensor, name)
for k, t in enumerate(targets):
incoming_state = state[t]
receiving_port = op_node[k]
output_port = op_node[k + len(targets)]
incoming_state ^ receiving_port
state[t] = output_port
MERA layer.
state: The 3-site reduced state (rank-6 tensor) defined at the top of the
MERA layer.
isometry: The isometry tensor (rank 3) of the binary MERA.
disentangler: The disentangler tensor (rank 4) of the binary MERA.
Returns:
The energy.
"""
backend = "jax"
out = []
for dirn in ('left', 'right'):
iso_l = tensornetwork.Node(isometry, backend=backend)
iso_c = tensornetwork.Node(isometry, backend=backend)
iso_r = tensornetwork.Node(isometry, backend=backend)
iso_l_con = tensornetwork.conj(iso_l)
iso_c_con = tensornetwork.conj(iso_c)
iso_r_con = tensornetwork.conj(iso_r)
op = tensornetwork.Node(hamiltonian, backend=backend)
rho = tensornetwork.Node(state, backend=backend)
un_l = tensornetwork.Node(disentangler, backend=backend)
un_l_con = tensornetwork.conj(un_l)
un_r = tensornetwork.Node(disentangler, backend=backend)
un_r_con = tensornetwork.conj(un_r)
tensornetwork.connect(iso_l[2], rho[0])
tensornetwork.connect(iso_c[2], rho[1])