Qx.Step (Qx - Quantum Computing Simulator v0.10.1)

View Source

One executed operation from Qx.steps/2: what ran, where in the circuit, and the state right after it.

The struct is raw data. inspect/1 gives you the readable one-liner, and show/1 a display map (Dirac string, amplitudes, probabilities), so printing each step of Qx.steps(qc) is already a usable circuit walkthrough.

Steps come in 3 kinds:

  • :gate - a unitary gate was applied
  • :measurement - a qubit was measured and the state collapsed; classical_bits holds the outcome
  • :conditional - a gate inside a c_if block; condition says which classical bit was tested and whether the block ran

A word on measured circuits: each step carries the state of one sampled trajectory. After a measurement step the state is collapsed, so what you see differs from the ensemble probabilities Qx.run/2 reports. That's the point of stepping, but don't confuse the two.

Displaying a step reads all 2^n amplitudes host-side. Cheap at teaching scale; noticeable when you print steps of a 20-qubit circuit in a tight loop.

Fields

  • kind - :gate, :measurement, or :conditional
  • operation - the instruction just applied, as {gate, qubits, params}; nil for a not-taken conditional block
  • index - 0-based position in the executed timeline
  • state - the statevector after this step (:c64 tensor, same shape Qx.get_state/1 returns)
  • probabilities - Qx.Math.probabilities/1 of that state
  • classical_bits - classical register contents so far (defaults to [] for circuits without measurements)
  • condition - nil, or {cbit, value, :taken | :not_taken} on conditional steps

Summary

Functions

Returns the display map for a step's state: a Dirac string plus per-basis amplitudes and probabilities.

Types

condition()

@type condition() :: {non_neg_integer(), 0 | 1, :taken | :not_taken}

kind()

@type kind() :: :gate | :measurement | :conditional

operation()

@type operation() :: {atom(), [non_neg_integer()], [number()]}

t()

@type t() :: %Qx.Step{
  classical_bits: [0 | 1],
  condition: condition() | nil,
  index: non_neg_integer() | nil,
  kind: kind() | nil,
  operation: operation() | nil,
  probabilities: Nx.Tensor.t() | nil,
  state: Nx.Tensor.t() | nil
}

Functions

show(step)

@spec show(t()) :: %{state: String.t(), amplitudes: list(), probabilities: list()}

Returns the display map for a step's state: a Dirac string plus per-basis amplitudes and probabilities.

The shape is %{state: dirac, amplitudes: [{basis, "a+bi"}], probabilities: [{basis, p}]}.

For steps after a measurement the Dirac string shows the collapsed state of that sampled trajectory.

Examples

iex> qc = Qx.create_circuit(2) |> Qx.h(0) |> Qx.cx(0, 1)
iex> state = Qx.Simulation.get_state(qc)
iex> step = %Qx.Step{kind: :gate, operation: {:cx, [0, 1], []}, index: 1,
...>   state: state, probabilities: Qx.Math.probabilities(state)}
iex> Qx.Step.show(step).state
"0.707|00⟩ + 0.707|11⟩"