Qx.Patterns (Qx - Quantum Computing Simulator v0.8.0)
View SourceComposite circuit-building patterns: thin wrappers that emit multiple instructions in one call.
Where Qx.Operations emits exactly one instruction per call (one gate, one
qubit), this module bundles the recurring "apply X to every qubit" /
"measure every qubit" / "CNOT chain" motifs that appear in tutorials and
algorithm circuits (Grover diffuser, Bernstein-Vazirani oracle, GHZ
preparation, etc.).
All helpers are additive over Qx.Operations and Qx.QuantumCircuit; they
introduce no new exception types. Out-of-range qubit indices or insufficient
classical bits surface the existing typed errors (Qx.QubitIndexError,
Qx.ClassicalBitError) from the underlying primitives.
Each _all helper has two arities:
/1— apply to every qubit in the circuit (whole-circuit form)./2— apply to a sub-list or range of qubits (sub-register form), e.g.Qx.Patterns.h_all(qc, 0..2)orQx.Patterns.h_all(qc, [0, 2, 4]).
See also:
Qx.Operations— one-instruction-per-call gate API.Qx.StateInit— sibling module for composite state-vector recipes (Bell state, GHZ state, W state).Qx.Patternsis the circuit-instruction analogue.
Examples
# Equal superposition over all qubits (replaces a private `apply_h_all`
# helper used in tutorials).
iex> qc = Qx.create_circuit(3) |> Qx.Patterns.h_all()
iex> length(Qx.QuantumCircuit.get_instructions(qc))
3
# Equal superposition over a sub-register.
iex> qc = Qx.create_circuit(5) |> Qx.Patterns.h_all(0..2)
iex> length(Qx.QuantumCircuit.get_instructions(qc))
3
# Measure every qubit into its same-index classical bit.
iex> qc = Qx.create_circuit(2, 2) |> Qx.Patterns.measure_all()
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:measure, [0, 0], []}, {:measure, [1, 1], []}]
# GHZ-style linear CNOT chain.
iex> qc = Qx.create_circuit(4) |> Qx.Patterns.cx_chain([0, 1, 2, 3])
iex> length(Qx.QuantumCircuit.get_instructions(qc))
3
Summary
Types
Selector for which of the four Bell states a recipe builds.
A list or range of non-negative qubit indices.
Functions
Adds a single barrier instruction spanning every qubit in circuit.
Adds a single barrier instruction spanning the given list or range of qubits.
Builds a two-qubit circuit recipe that prepares one of the four Bell
states. Selector defaults to :phi_plus.
Applies a linear cascade of CNOTs along qubits.
Builds an n-qubit GHZ-state preparation circuit: H(0) followed by
a linear cx_chain([0, 1, …, n-1]). Final state on |0…0⟩ input is
(|0…0⟩ + |1…1⟩)/√2. Default is 3 qubits.
Applies a Hadamard gate to every qubit in circuit.
Applies a Hadamard gate to every qubit in the given list or range.
Measures every qubit into its same-index classical bit.
Measures every qubit in the given list or range into its same-index
classical bit (qubit i → classical bit i).
Builds an n-qubit equal-superposition circuit: H applied to every
qubit, on a |0…0⟩ input the result is the uniform superposition.
Default is 1 qubit.
Applies a Pauli-X gate to every qubit in circuit.
Applies a Pauli-X gate to every qubit in the given list or range.
Applies a Pauli-Y gate to every qubit in circuit.
Applies a Pauli-Y gate to every qubit in the given list or range.
Applies a Pauli-Z gate to every qubit in circuit.
Applies a Pauli-Z gate to every qubit in the given list or range.
Types
@type bell_state_type() :: :phi_plus | :phi_minus | :psi_plus | :psi_minus
Selector for which of the four Bell states a recipe builds.
@type qubits() :: [non_neg_integer()] | Range.t()
A list or range of non-negative qubit indices.
Used as the second argument to the /2 form of h_all, x_all, y_all,
z_all, measure_all, and barrier_all to select a sub-register.
Functions
@spec barrier_all(Qx.QuantumCircuit.t()) :: Qx.QuantumCircuit.t()
Adds a single barrier instruction spanning every qubit in circuit.
Equivalent to Qx.Operations.barrier(circuit, Enum.to_list(0..(n - 1))).
Examples
iex> qc = Qx.create_circuit(3) |> Qx.Patterns.barrier_all()
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:barrier, [0, 1, 2], []}]
@spec barrier_all(Qx.QuantumCircuit.t(), qubits()) :: Qx.QuantumCircuit.t()
Adds a single barrier instruction spanning the given list or range of qubits.
An empty list or empty range is a no-op (returns circuit unchanged).
Examples
iex> qc = Qx.create_circuit(4) |> Qx.Patterns.barrier_all([0, 2])
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:barrier, [0, 2], []}]
@spec bell_state_circuit(bell_state_type()) :: Qx.QuantumCircuit.t()
Builds a two-qubit circuit recipe that prepares one of the four Bell
states. Selector defaults to :phi_plus.
| Atom | State |
|---|
:phi_plus | ` | Φ+⟩ = ( | 00⟩ + | 11⟩)/√2` (default) |
:phi_minus | ` | Φ-⟩ = ( | 00⟩ - | 11⟩)/√2` |
:psi_plus | ` | Ψ+⟩ = ( | 01⟩ + | 10⟩)/√2` |
:psi_minus | ` | Ψ-⟩ = ( | 01⟩ - | 10⟩)/√2` |
Examples
iex> qc = Qx.Patterns.bell_state_circuit()
iex> qc.num_qubits
2
iex> qc = Qx.Patterns.bell_state_circuit(:psi_minus)
iex> qc.num_qubits
2See Also
Qx.StateInit.bell_state/2— returns the state vector directly (no circuit recipe).
@spec cx_chain(Qx.QuantumCircuit.t(), [non_neg_integer()]) :: Qx.QuantumCircuit.t()
Applies a linear cascade of CNOTs along qubits.
For qubits = [q0, q1, q2, ..., qk], emits CNOTs cx(q0, q1), cx(q1, q2), …, cx(q_{k-1}, q_k) — i.e. each qubit controls the next. This is the
shape used to build GHZ states (e.g. H(0) → cx(0,1) → cx(1,2)).
Lists of length 0 or 1 are deliberate no-ops and return circuit
unchanged.
Examples
iex> qc = Qx.create_circuit(4) |> Qx.Patterns.cx_chain([0, 1, 2, 3])
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:cx, [0, 1], []}, {:cx, [1, 2], []}, {:cx, [2, 3], []}]
iex> qc = Qx.create_circuit(2) |> Qx.Patterns.cx_chain([])
iex> Qx.QuantumCircuit.get_instructions(qc)
[]
iex> qc = Qx.create_circuit(2) |> Qx.Patterns.cx_chain([0])
iex> Qx.QuantumCircuit.get_instructions(qc)
[]
@spec ghz_state_circuit(pos_integer()) :: Qx.QuantumCircuit.t()
Builds an n-qubit GHZ-state preparation circuit: H(0) followed by
a linear cx_chain([0, 1, …, n-1]). Final state on |0…0⟩ input is
(|0…0⟩ + |1…1⟩)/√2. Default is 3 qubits.
Examples
iex> qc = Qx.Patterns.ghz_state_circuit()
iex> qc.num_qubits
3
iex> qc = Qx.Patterns.ghz_state_circuit(5)
iex> qc.num_qubits
5See Also
Qx.StateInit.ghz_state/2— returns the state vector directly.
@spec h_all(Qx.QuantumCircuit.t()) :: Qx.QuantumCircuit.t()
Applies a Hadamard gate to every qubit in circuit.
Equivalent to Enum.reduce(0..(n - 1), circuit, &Qx.h(&2, &1)) where n is
circuit.num_qubits, but expresses the intent directly.
Examples
iex> qc = Qx.create_circuit(3) |> Qx.Patterns.h_all()
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:h, [0], []}, {:h, [1], []}, {:h, [2], []}]
@spec h_all(Qx.QuantumCircuit.t(), qubits()) :: Qx.QuantumCircuit.t()
Applies a Hadamard gate to every qubit in the given list or range.
Examples
iex> qc = Qx.create_circuit(5) |> Qx.Patterns.h_all([0, 2, 4])
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:h, [0], []}, {:h, [2], []}, {:h, [4], []}]
iex> qc = Qx.create_circuit(5) |> Qx.Patterns.h_all(1..3)
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:h, [1], []}, {:h, [2], []}, {:h, [3], []}]
@spec measure_all(Qx.QuantumCircuit.t()) :: Qx.QuantumCircuit.t()
Measures every qubit into its same-index classical bit.
Emits n measurement instructions where n = circuit.num_qubits, each
mapping qubit i to classical bit i.
Raises Qx.ClassicalBitError if circuit.num_classical_bits < num_qubits —
the circuit shape is the caller's decision (made at create_circuit/2),
and no auto-grow happens.
Examples
iex> qc = Qx.create_circuit(3, 3) |> Qx.Patterns.measure_all()
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:measure, [0, 0], []}, {:measure, [1, 1], []}, {:measure, [2, 2], []}]
@spec measure_all(Qx.QuantumCircuit.t(), qubits()) :: Qx.QuantumCircuit.t()
Measures every qubit in the given list or range into its same-index
classical bit (qubit i → classical bit i).
Examples
iex> qc = Qx.create_circuit(3, 3) |> Qx.Patterns.measure_all([0, 2])
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:measure, [0, 0], []}, {:measure, [2, 2], []}]
@spec superposition_circuit(pos_integer()) :: Qx.QuantumCircuit.t()
Builds an n-qubit equal-superposition circuit: H applied to every
qubit, on a |0…0⟩ input the result is the uniform superposition.
Default is 1 qubit.
Examples
iex> qc = Qx.Patterns.superposition_circuit()
iex> qc.num_qubits
1
iex> qc = Qx.Patterns.superposition_circuit(3)
iex> length(Qx.QuantumCircuit.get_instructions(qc))
3
@spec x_all(Qx.QuantumCircuit.t()) :: Qx.QuantumCircuit.t()
Applies a Pauli-X gate to every qubit in circuit.
Examples
iex> qc = Qx.create_circuit(2) |> Qx.Patterns.x_all()
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:x, [0], []}, {:x, [1], []}]
@spec x_all(Qx.QuantumCircuit.t(), qubits()) :: Qx.QuantumCircuit.t()
Applies a Pauli-X gate to every qubit in the given list or range.
Examples
iex> qc = Qx.create_circuit(4) |> Qx.Patterns.x_all([0, 3])
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:x, [0], []}, {:x, [3], []}]
@spec y_all(Qx.QuantumCircuit.t()) :: Qx.QuantumCircuit.t()
Applies a Pauli-Y gate to every qubit in circuit.
Examples
iex> qc = Qx.create_circuit(2) |> Qx.Patterns.y_all()
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:y, [0], []}, {:y, [1], []}]
@spec y_all(Qx.QuantumCircuit.t(), qubits()) :: Qx.QuantumCircuit.t()
Applies a Pauli-Y gate to every qubit in the given list or range.
Examples
iex> qc = Qx.create_circuit(3) |> Qx.Patterns.y_all(0..1)
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:y, [0], []}, {:y, [1], []}]
@spec z_all(Qx.QuantumCircuit.t()) :: Qx.QuantumCircuit.t()
Applies a Pauli-Z gate to every qubit in circuit.
Examples
iex> qc = Qx.create_circuit(2) |> Qx.Patterns.z_all()
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:z, [0], []}, {:z, [1], []}]
@spec z_all(Qx.QuantumCircuit.t(), qubits()) :: Qx.QuantumCircuit.t()
Applies a Pauli-Z gate to every qubit in the given list or range.
Examples
iex> qc = Qx.create_circuit(3) |> Qx.Patterns.z_all([2])
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:z, [2], []}]