quimb.tensor.circuit_gen

Functions for generating specific, e.g. ansatz, circuits.

Module Contents

Functions

inject_u3s(ent_gates[, gate2, avoid_doubling, seed])

Take a sequence of pairs denoting qubits to entangle and interleave one

gates_to_param_circuit(gates, n[, parametrize])

Turn the sequence gates into a Circuit of n qubits, with any

circ_ansatz_1D_zigzag(n, depth[, gate2, seed])

A 1D circuit ansatz with forward and backward layers of entangling

circ_ansatz_1D_brickwork(n, depth[, cyclic, gate2, seed])

A 1D circuit ansatz with odd and even layers of entangling

circ_ansatz_1D_rand(n, depth[, seed, cyclic, gate2, ...])

A 1D circuit ansatz with randomly place entangling gates interleaved

circ_qaoa(terms, depth, gammas, betas, **circuit_opts)

Generate the QAOA circuit for weighted graph described by terms.

quimb.tensor.circuit_gen.inject_u3s(ent_gates, gate2='cz', avoid_doubling=False, seed=None)[source]

Take a sequence of pairs denoting qubits to entangle and interleave one single qubit gate inbetween every leg. For example:

ent_gates = [(0, 1), (2, 3), (1, 2)]

Would go get made into a circuit like:

|  |  |  |        |  |  |  |
|  |  |  |        |  u  u  |
|  |  |  |        |  |  |  |
|  o++o  |        u  o++o  u
|  |  |  |        |  |  |  |
|  |  |  |  -->   |  u  u  |
|  |  |  |        |  |  |  |
o++o  o++o        o++o  o++o
|  |  |  |        |  |  |  |
|  |  |  |        u  u  u  u
|  |  |  |        |  |  |  |

Technically, this generates a bipartite graph between single qubit and two qubit tensors, and should be the most expressive circuit possible for that ‘budget’ of entangling gates.

Parameters:
  • ent_gates (sequence[tuple[int]]) – A ‘stack’ of entangling gate pairs to apply.

  • gate2 ({'cx', 'cy', 'cz', 'iswap', ..., str}, optional) – The gate to use for the entanling pairs.

  • avoid_doubling (bool, optional) – Whether to avoid placing an entangling gate directly above the same entangling gate (there will still be single qubit gates interleaved).

Return type:

Circuit

quimb.tensor.circuit_gen.gates_to_param_circuit(gates, n, parametrize='U3', **circuit_opts)[source]

Turn the sequence gates into a Circuit of n qubits, with any gates that appear in parametrize being… parametrized.

Parameters:
  • gates (sequence[tuple[str, float, int]]) – The gates describing the circuit.

  • n (int) – The number of qubits to make the circuit act one.

  • parametrize (str or sequence[str], optional) – Which gates to parametrize.

  • circuit_opts – Supplied to Circuit.

Return type:

Circuit

quimb.tensor.circuit_gen.circ_ansatz_1D_zigzag(n, depth, gate2='cz', seed=None, **circuit_opts)[source]

A 1D circuit ansatz with forward and backward layers of entangling gates interleaved with U3 single qubit unitaries:

|  |  |  |
u  u  |  |
o++o  u  |
|  |  |  u
|  o++o  |
|  |  u  |
|  |  o++o
u  u  u  u
|  |  o++o
|  |  u  |
|  o++o  |
|  u  |  u
o++o  u  |
u  u  |  |
|  |  |  |
Parameters:
  • n (int) – The number of qubits.

  • depth (int) – The number of entangling gates per pair.

  • gate2 ({'cx', 'cy', 'cz', 'iswap', ..., str}, optional) – The gate to use for the entanling pairs.

  • seed (int, optional) – Random seed for parameters.

  • opts – Supplied to gates_to_param_circuit().

Return type:

Circuit

quimb.tensor.circuit_gen.circ_ansatz_1D_brickwork(n, depth, cyclic=False, gate2='cz', seed=None, **circuit_opts)[source]

A 1D circuit ansatz with odd and even layers of entangling gates interleaved with U3 single qubit unitaries:

|  |  |  |  |
|  u  u  u  u
u  o++o  o++o
|  u  u  u  |
o++o  o++o  u
|  u  u  u  |
u  o++o  o++o
|  u  u  u  |
o++o  o++o  u
|  u  u  u  u
u  o++o  o++o
|  u  u  u  |
o++o  o++o  u
u  u  u  u  |
|  |  |  |  |
Parameters:
  • n (int) – The number of qubits.

  • depth (int) – The number of entangling gates per pair.

  • cyclic (bool, optional) – Whether to add entangling gates between qubits 0 and n - 1.

  • gate2 ({'cx', 'cy', 'cz', 'iswap', ..., str}, optional) – The gate to use for the entanling pairs.

  • seed (int, optional) – Random seed for parameters.

  • opts – Supplied to gates_to_param_circuit().

Return type:

Circuit

quimb.tensor.circuit_gen.circ_ansatz_1D_rand(n, depth, seed=None, cyclic=False, gate2='cz', avoid_doubling=True, **circuit_opts)[source]

A 1D circuit ansatz with randomly place entangling gates interleaved with U3 single qubit unitaries.

Parameters:
  • n (int) – The number of qubits.

  • depth (int) – The number of entangling gates per pair.

  • seed (int, optional) – Random seed.

  • cyclic (bool, optional) – Whether to add entangling gates between qubits 0 and n - 1.

  • gate2 ({'cx', 'cy', 'cz', 'iswap', ..., str}, optional) – The gate to use for the entanling pairs.

  • avoid_doubling (bool, optional) – Whether to avoid placing an entangling gate directly above the same entangling gate (there will still be single qubit gates interleaved).

  • opts – Supplied to gates_to_param_circuit().

Return type:

Circuit

quimb.tensor.circuit_gen.circ_qaoa(terms, depth, gammas, betas, **circuit_opts)[source]

Generate the QAOA circuit for weighted graph described by terms.

\[|{\bar{\gamma}, \bar{\beta}}\rangle = U_B (\beta _p) U_C (\gamma _p) \cdots U_B (\beta _1) U_C (\gamma _1) |{+}\rangle\]

with

\[U_C (\gamma) = e^{-i \gamma \mathcal{C}} = \prod \limits_{i, j \in E(G)} e^{-i \gamma w_{i j} Z_i Z_j}\]

and

\[U_B (\beta) = \prod \limits_{i \in G} e^{-i \beta X_i}\]
Parameters:
  • terms (dict[tuple[int], float]) – The mapping of integer pair keys (i, j) to the edge weight values, wij. The integers should be a contiguous range enumerated from zero, with the total number of qubits being inferred from this.

  • depth (int) – The number of layers of gates to apply, p above.

  • gammas (iterable of float) – The interaction angles for each layer.

  • betas (iterable of float) – The rotation angles for each layer.

  • circuit_opts – Supplied to Circuit. Note gate_opts={'contract': False} is set by default (it can be overridden) since the RZZ gate, even though it has a rank-2 decomposition, is also diagonal.