Qx.Operations (Qx - Quantum Computing Simulator v0.5.0)
View SourceQuantum gate operations for quantum circuits.
This module provides functions for applying quantum gates to quantum circuits, including single-qubit gates (H, X, Y, Z), two-qubit gates (CNOT), and three-qubit gates (CCNOT/Toffoli).
Summary
Functions
Adds a barrier to the circuit for visualization purposes.
Applies gates conditionally based on a classical bit value.
Applies a controlled-controlled-X (CCNOT/Toffoli) gate.
Applies a controlled-X (CNOT) gate.
Applies a controlled-Z (CZ) gate.
Applies a Hadamard gate to the specified qubit.
Adds a measurement operation to the circuit.
Applies a phase gate with the specified phase.
Applies a rotation around the X-axis by the specified angle.
Applies a rotation around the Y-axis by the specified angle.
Applies a rotation around the Z-axis by the specified angle.
Applies an S gate (phase gate with π/2 phase).
Applies a T gate (phase gate with π/4 phase).
Inspects the circuit without breaking the pipeline.
Inspects measurement probabilities without breaking the pipeline.
Inspects the current quantum state without breaking the pipeline.
Applies a Pauli-X gate (bit flip) to the specified qubit.
Applies a Pauli-Y gate to the specified qubit.
Applies a Pauli-Z gate (phase flip) to the specified qubit.
Functions
Adds a barrier to the circuit for visualization purposes.
Barriers are used to group operations and improve circuit readability. They do not affect the quantum state.
Parameters
circuit- The quantum circuitqubits- List of qubit indices the barrier spans
Examples
iex> qc = Qx.QuantumCircuit.new(3, 0)
iex> qc = Qx.Operations.barrier(qc, [0, 1, 2])
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:barrier, [0, 1, 2]}
Applies gates conditionally based on a classical bit value.
The conditional block executes during simulation only if the specified classical bit equals the given value at runtime.
Parameters
circuit- The quantum circuitclassical_bit- Classical bit index to check (0-based)value- Value to compare (0 or 1)gate_fn- Function that applies gates: (circuit -> circuit)
Examples
iex> qc = Qx.QuantumCircuit.new(2, 2)
iex> qc = qc |> Qx.Operations.h(0) |> Qx.Operations.measure(0, 0)
iex> qc = Qx.Operations.c_if(qc, 0, 1, fn c -> Qx.Operations.x(c, 1) end)
iex> instructions = Qx.QuantumCircuit.get_instructions(qc)
iex> length(instructions)
2Constraints
- Classical bit must be valid for the circuit
- Value must be 0 or 1
- Gates in conditional block cannot contain measurements
- No nesting of conditional blocks
Applies a controlled-controlled-X (CCNOT/Toffoli) gate.
The CCNOT gate flips the target qubit if and only if both control qubits are |1⟩.
Parameters
circuit- The quantum circuitcontrol1- First control qubit indexcontrol2- Second control qubit indextarget- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(3, 0)
iex> qc = Qx.Operations.ccx(qc, 0, 1, 2)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:ccx, [0, 1, 2]}
Applies a controlled-X (CNOT) gate.
The CNOT gate flips the target qubit if and only if the control qubit is |1⟩.
Parameters
circuit- The quantum circuitcontrol_qubit- Control qubit indextarget_qubit- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(2, 0)
iex> qc = Qx.Operations.cx(qc, 0, 1)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:cx, [0, 1]}
Applies a controlled-Z (CZ) gate.
The CZ gate applies a phase of -1 if and only if both qubits are |1⟩.
Parameters
circuit- The quantum circuitcontrol_qubit- Control qubit indextarget_qubit- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(2, 0)
iex> qc = Qx.Operations.cz(qc, 0, 1)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:cz, [0, 1]}
Applies a Hadamard gate to the specified qubit.
The Hadamard gate creates superposition, transforming |0⟩ to (|0⟩ + |1⟩)/√2 and |1⟩ to (|0⟩ - |1⟩)/√2.
Parameters
circuit- The quantum circuitqubit- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(2, 0)
iex> qc = Qx.Operations.h(qc, 0)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:h, [0]}
Adds a measurement operation to the circuit.
Parameters
circuit- The quantum circuitqubit- Qubit index to measureclassical_bit- Classical bit index to store the result
Examples
iex> qc = Qx.QuantumCircuit.new(2, 2)
iex> qc = Qx.Operations.measure(qc, 0, 0)
iex> [{qubit, classical_bit}] = Qx.QuantumCircuit.get_measurements(qc)
iex> {qubit, classical_bit}
{0, 0}
Applies a phase gate with the specified phase.
Parameters
circuit- The quantum circuitqubit- Target qubit indexphi- Phase angle in radians
Examples
iex> qc = Qx.QuantumCircuit.new(1, 0)
iex> qc = Qx.Operations.phase(qc, 0, :math.pi/4)
iex> [{gate, qubits, params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits, length(params)}
{:phase, [0], 1}
Applies a rotation around the X-axis by the specified angle.
Parameters
circuit- The quantum circuitqubit- Target qubit indextheta- Rotation angle in radians
Examples
iex> qc = Qx.QuantumCircuit.new(1, 0)
iex> qc = Qx.Operations.rx(qc, 0, :math.pi/2)
iex> [{gate, qubits, params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits, length(params)}
{:rx, [0], 1}
Applies a rotation around the Y-axis by the specified angle.
Parameters
circuit- The quantum circuitqubit- Target qubit indextheta- Rotation angle in radians
Examples
iex> qc = Qx.QuantumCircuit.new(1, 0)
iex> qc = Qx.Operations.ry(qc, 0, :math.pi/2)
iex> [{gate, qubits, params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits, length(params)}
{:ry, [0], 1}
Applies a rotation around the Z-axis by the specified angle.
Parameters
circuit- The quantum circuitqubit- Target qubit indextheta- Rotation angle in radians
Examples
iex> qc = Qx.QuantumCircuit.new(1, 0) iex> qc = Qx.Operations.rz(qc, 0, :math.pi/2) iex> [{gate, qubits, params}] = Qx.QuantumCircuit.get_instructions(qc) iex> {gate, qubits, length(params)}
Applies an S gate (phase gate with π/2 phase).
Parameters
circuit- The quantum circuitqubit- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(1, 0)
iex> qc = Qx.Operations.s(qc, 0)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:s, [0]}
Applies a T gate (phase gate with π/4 phase).
Parameters
circuit- The quantum circuitqubit- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(1, 0)
iex> qc = Qx.Operations.t(qc, 0)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:t, [0]}
@spec tap_circuit(Qx.QuantumCircuit.t(), (Qx.QuantumCircuit.t() -> any())) :: Qx.QuantumCircuit.t()
Inspects the circuit without breaking the pipeline.
The provided function receives the circuit and can perform any side-effect (logging, printing, assertions), but the return value is ignored and the original circuit is returned.
Parameters
circuit- The quantum circuitfun- Function to execute:(circuit -> any())
Examples
iex> circuit = Qx.QuantumCircuit.new(2, 0)
...> |> Qx.Operations.h(0)
...> |> Qx.Operations.tap_circuit(&IO.inspect(&1.instructions, label: "After H"))
...> |> Qx.Operations.cx(0, 1)
After H: [{:h, [0], []}]
%Qx.QuantumCircuit{...}
# Create circuit and inspect depth/qubits
circuit = Qx.QuantumCircuit.new(3, 0)
|> Qx.Operations.h(0)
|> Qx.Operations.tap_circuit(fn circ ->
IO.puts("Depth: #{Qx.QuantumCircuit.depth(circ)}")
IO.puts("Qubits: #{circ.num_qubits}")
end)
|> Qx.Operations.x(1)
# Outputs:
# Depth: 1
# Qubits: 3See Also
tap_state/2- Inspect quantum statetap_probabilities/2- Inspect measurement probabilities
@spec tap_probabilities(Qx.QuantumCircuit.t(), (Nx.Tensor.t() -> any())) :: Qx.QuantumCircuit.t()
Inspects measurement probabilities without breaking the pipeline.
Convenience function that computes probabilities and passes them to your inspection function.
Parameters
circuit- The quantum circuitfun- Function to execute:(Nx.Tensor.t() -> any())
Examples
iex> circuit = Qx.QuantumCircuit.new(2, 2)
...> |> Qx.Operations.h(0)
...> |> Qx.Operations.cx(0, 1)
...> |> Qx.Operations.tap_probabilities(&IO.inspect/1)
...> |> Qx.Operations.measure(0, 0)
#Nx.Tensor<
f32[4]
[0.5, 0.0, 0.0, 0.5]
>
%Qx.QuantumCircuit{...}
# Create circuit and inspect probabilities
circuit = Qx.QuantumCircuit.new(1, 0)
|> Qx.Operations.h(0)
|> Qx.Operations.tap_probabilities(fn probs ->
prob_list = Nx.to_list(probs)
IO.puts("P(|0⟩) = #{Enum.at(prob_list, 0)}")
IO.puts("P(|1⟩) = #{Enum.at(prob_list, 1)}")
end)
# Outputs:
# P(|0⟩) = 0.5
# P(|1⟩) = 0.5See Also
tap_state/2- Inspect full quantum statetap_circuit/2- Inspect circuit metadata
@spec tap_state(Qx.QuantumCircuit.t(), (Nx.Tensor.t() -> any())) :: Qx.QuantumCircuit.t()
Inspects the current quantum state without breaking the pipeline.
Important: This executes all instructions so far to get the current state. Use sparingly in performance-critical code.
Parameters
circuit- The quantum circuitfun- Function to execute:(Nx.Tensor.t() -> any())
Examples
iex> circuit = Qx.QuantumCircuit.new(1, 0)
...> |> Qx.Operations.h(0)
...> |> Qx.Operations.tap_state(&IO.inspect(&1, label: "After H gate"))
...> |> Qx.Operations.z(0)
After H gate: #Nx.Tensor<...>
%Qx.QuantumCircuit{...}
iex> circuit = Qx.QuantumCircuit.new(2, 0)
...> |> Qx.Operations.h(0)
...> |> Qx.Operations.tap_state(fn state ->
...> probs = Qx.Math.probabilities(state)
...> IO.inspect(Nx.to_list(probs), label: "Probabilities")
...> end)
...> |> Qx.Operations.cx(0, 1)
Probabilities: [0.5, 0.5, 0.0, 0.0]
%Qx.QuantumCircuit{...}See Also
tap_circuit/2- Inspect circuit metadatatap_probabilities/2- Inspect measurement probabilities directly
Applies a Pauli-X gate (bit flip) to the specified qubit.
The X gate flips |0⟩ to |1⟩ and |1⟩ to |0⟩.
Parameters
circuit- The quantum circuitqubit- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(2, 0)
iex> qc = Qx.Operations.x(qc, 0)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:x, [0]}
Applies a Pauli-Y gate to the specified qubit.
The Y gate applies both bit flip and phase flip transformations.
Parameters
circuit- The quantum circuitqubit- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(2, 0)
iex> qc = Qx.Operations.y(qc, 0)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:y, [0]}
Applies a Pauli-Z gate (phase flip) to the specified qubit.
The Z gate leaves |0⟩ unchanged and applies a phase of -1 to |1⟩.
Parameters
circuit- The quantum circuitqubit- Target qubit index
Examples
iex> qc = Qx.QuantumCircuit.new(2, 0)
iex> qc = Qx.Operations.z(qc, 0)
iex> [{gate, qubits, _params}] = Qx.QuantumCircuit.get_instructions(qc)
iex> {gate, qubits}
{:z, [0]}