Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Circuit JSON Conventions

Every CLI example in yao-rs consumes and produces JSON documents. This page documents the schema, the gate names, the bit ordering, and the result formats. If you want to write your own circuit from Python, a notebook, or a text editor, this is the only page you need.

Schema at a glance

A circuit is a JSON object with two fields:

{
  "num_qubits": 2,
  "elements": [
    {"type": "gate", "gate": "H", "targets": [0]},
    {"type": "gate", "gate": "X", "targets": [1], "controls": [0]}
  ]
}
  • num_qubits: the integer number of qubits. (The underlying Circuit type also supports qudit dimensions, but the CLI simulator is qubit-only.)
  • elements: an ordered array of circuit elements applied left-to-right.

Each element has a type field. For CLI examples, type is always "gate"; the "annotation" and "channel" variants exist for diagram labels and noise channels but are not used in the example catalog.

Gate elements

A gate element has these fields:

FieldRequired?TypeMeaning
typeyes"gate"Marks this as an applied gate.
gateyesstringGate name (see table below).
targetsyesint[]Qubits the gate matrix acts on.
controlsnoint[]Control qubits. Omit for uncontrolled gates.
control_configsnobool[]One flag per control; true = trigger on |1⟩, false = trigger on |0⟩. Defaults to all true.
paramsfor Rx, Ry, Rz, Phasefloat[]Gate parameters in radians.

Worked example — Bell state (H on qubit 0, then CNOT with 0 as control and 1 as target):

{
  "num_qubits": 2,
  "elements": [
    {"type": "gate", "gate": "H", "targets": [0]},
    {"type": "gate", "gate": "X", "targets": [1], "controls": [0]}
  ]
}

The CNOT gate is not a primitive; it is an X with a control.

Gate names

NameArityDescription
X, Y, Z1Pauli gates.
H1Hadamard.
S, T1Diagonal phase gates (S = diag(1, i); T = diag(1, e^{iπ/4})).
SqrtX, SqrtY, SqrtW1√X, √Y, √W gates.
Rx, Ry, Rz1Rotations about X/Y/Z; params: [theta] in radians.
Phase1Diagonal phase gate; params: [phi]; matrix diag(1, e^{iφ}).
SWAP2Swap two qubits.
ISWAP2iSWAP entangling gate.
FSim2fSim(θ, φ); params: [theta, phi].

For the full Rust-side enum and matrix definitions, see Gates.

Bit ordering

The basis state labeled by integer k is \( |q_0,q_1,\dots,q_{n-2},q_{n-1}\rangle \) with q_0 the most significant bit. To read a basis state from an integer index, write the index in binary with enough leading zeros to fill n bits; the leftmost bit is q_0, the next is q_1, and so on. Equivalently \( k = \sum_{i=0}^{n-1} q_i \cdot 2^{n-1-i} \).

Worked example on three qubits: apply X on qubit 0 and X on qubit 1, starting from \( |000\rangle \). The result is \( |110\rangle \), which lives at probabilities[6] because \( 6 = 110_2 \) reads as \( q_0=1,,q_1=1,,q_2=0 \).

This bites everyone once: when a circuit acts on qubit 0 it is acting on the most-significant bit of the index, which is the opposite of the convention used in Qiskit and several other libraries. Mind the convention when porting circuits across frameworks.

Result JSON

yao simulate produces a state vector; yao probs post-processes into:

{"num_qubits": 2, "locs": null, "probabilities": [0.5, 0.0, 0.0, 0.5]}

yao run --shots N produces measurement samples:

{"num_qubits": 2, "samples": [0, 3, 0, 3, 3, 0, ...]}

yao run --op "..." produces an expectation value:

{"operator": "Z(0)Z(1)", "value": -1.0}

Operator syntax

For yao run --op and related commands, the operator string is a product of single-qubit Paulis. Z(0)Z(1) is \( Z_0 \otimes Z_1 \) extended by identity on every other qubit. Supported single-qubit symbols are I, X, Y, Z. Real coefficients can be prepended, e.g. 0.5*Z(0).

Where to get JSON

  • yao example <name> emits a ready-made circuit for common cases (bell, ghz, qft). See CLI Tool for the catalog.
  • yao fromqasm circuit.qasm imports an OpenQASM 2.0 file.
  • Hand-write the JSON in any editor.
  • Generate the JSON programmatically from any language — the schema is plain data, so json.dump(...) from Python, JSON.stringify from JavaScript, or jq pipelines all work.