Qx.Patterns (Qx - Quantum Computing Simulator v0.11.0)
View SourceUtility module: reached from Qx.* in normal use — the _all, cx_chain,
and state-prep helpers front Qx.h_all/1, Qx.cx_chain/2, Qx.bell_state/1, etc.
Composite 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.Qx.bell_state/1andQx.ghz_state/1— the documented entry points for the Bell- and GHZ-preparation circuits.bell_state_circuit/1andghz_state_circuit/1here are their delegated-to implementations and carry@doc false; call them through theQxfacade.
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.
Appends the gates that entangle qubits q0 and q1 into one of the four
Bell states onto an existing circuit.
Applies a linear cascade of CNOTs along qubits.
Appends the GHZ-preparation gates over qubits onto an existing circuit.
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, and as
the qubit selector for ghz/2.
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_pair( Qx.QuantumCircuit.t(), non_neg_integer(), non_neg_integer(), bell_state_type() ) :: Qx.QuantumCircuit.t()
Appends the gates that entangle qubits q0 and q1 into one of the four
Bell states onto an existing circuit.
Unlike Qx.bell_state/1 (which creates a fresh 2-qubit circuit), this
builder appends onto circuit at the caller-chosen qubits, so it composes
inside a larger pipeline. The gate sequence per which (with q0 the
control and q1 the target of the final CX):
which | Gates appended |
|---|---|
:phi_plus | h(q0), cx(q0, q1) (default) |
:phi_minus | x(q0), h(q0), cx(q0, q1) |
:psi_plus | x(q1), h(q0), cx(q0, q1) |
:psi_minus | x(q0), x(q1), h(q0), cx(q0, q1) |
Parameters
circuit- TheQx.QuantumCircuitto append onto.q0- Control qubit of the entanglingCX(and the Hadamard target).q1- Target qubit of the entanglingCX.which- Which Bell state to prepare (default:phi_plus).
Returns
The updated Qx.QuantumCircuit, so calls chain in a pipeline.
Examples
iex> qc = Qx.QuantumCircuit.new(3) |> Qx.Patterns.bell_pair(1, 2)
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:h, [1], []}, {:cx, [1, 2], []}]Raises
Qx.QubitIndexError- Ifq0orq1is out of range, or ifq0 == q1(surfaced by the composedQx.Operations.cx/3).Qx.OptionError- Ifwhichis not one of:phi_plus,:phi_minus,:psi_plus,:psi_minus.
@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(Qx.QuantumCircuit.t(), qubits()) :: Qx.QuantumCircuit.t()
Appends the GHZ-preparation gates over qubits onto an existing circuit.
Applies a Hadamard to the first qubit in qubits, then a linear CNOT chain
(cx_chain/2) along the rest — the |GHZ⟩ = (|0…0⟩ + |1…1⟩)/√2 recipe.
Where Qx.ghz_state/1 creates a fresh n-qubit circuit over 0..n-1,
this builder appends onto circuit at the caller-chosen qubits.
qubits may be a list or a range and must name at least two qubits — a GHZ
state needs two qubits to entangle.
Parameters
circuit- TheQx.QuantumCircuitto append onto.qubits- A list or range of at least two qubit indices; the first is the Hadamard/root qubit, and the chain follows the given order.
Returns
The updated Qx.QuantumCircuit, so calls chain in a pipeline.
Examples
iex> qc = Qx.QuantumCircuit.new(4) |> Qx.Patterns.ghz(1..3)
iex> Qx.QuantumCircuit.get_instructions(qc)
[{:h, [1], []}, {:cx, [1, 2], []}, {:cx, [2, 3], []}]Raises
Qx.QubitCountError- If fewer than two qubits are given.Qx.QubitIndexError- If any qubit index is out of range (surfaced by the composedQx.Operations.h/2andcx_chain/2).
@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], []}]