Operations
MimiqCircuitsBase.cregsizes — Method
cregsizes(operation)
cregsizes(operationtype)Length of the classicalregisters the given operation acts on.
See also
MimiqCircuitsBase.getparam — Function
getparam(operation, name)Value of the corresponding parameter in the given parametric operation.
Examples
getparam(GateRX(π/8), :θ)See also
MimiqCircuitsBase.getparams — Function
getparams(operation)Value of the parameters in the given parametric operation.
Examples
getparam(GateU(π/8, 3.1, sqrt(2)))See also
MimiqCircuitsBase.hilbertspacedim — Function
hilbertspacedim(operation)
hilbertspacedim(operationtype)
hilbertspacedim(N::Integer)Hilbert space dimension for the given operation. For an operation actiing on N qubits, it is 2^N.
Examples
hilbertspacedim(Operation{2, 1})
hilbertspacedim(GateH)
hilbertspacedim(GateH())
hilbertspacedim(GateRX)
hilbertspacedim(GateCX)
hilbertspacedim(4)See also
MimiqCircuitsBase.iswrapper — Function
iswrapper(operation)
iswrapper(operationtype)Checks if a given operation is a wrapper or not.
Examples
iswrapper(Control)
iswrapper(GateX)
iswrapper(GateSX) # SX is defined as Power(1//2, GateX())
iswrapper(GateCX) # CX is defined as Control(1, GateX())See also
MimiqCircuitsBase.numparams — Function
numparams(operation)
numparams(operationtype)Number of parameters for the given parametric operation. Zero for non parametric operations.
By default it returns the number of fields of the operations.
Examples
julia> numparams(GateH)
0
julia> numparams(GateU)
4
julia> numparams(GateRX)
1
julia> numparams(Measure)
0
See also
MimiqCircuitsBase.parnames — Function
parnames(operation)
parnames(operationtype)Name of the parameters allowed for the given operation.
By default it returns the fieldnames of the operation type.
Examples
parnames(GateH)
parnames(GateRX)
parnames(GateCRX)
parnames(Measure)See also
MimiqCircuitsBase.qregsizes — Method
qregsizes(operation)
qregsizes(operationtype)Length of the quantum registers the given operation acts on.
Details
Some operations, such as adders or multipliers, acts on different groups of qubits (quantum registers).
Examples
julia> qregsizes(GateRX(0.1))
(1,)
julia> qregsizes(GateCRX(0.1))
(1, 1)
julia> qregsizes(QFT(4))
(4,)See also
MimiqCircuitsBase.zregsizes — Method
zregsizes(operation)
zregsizes(operationtype)Length of the zregisters the given operation acts on.
MimiqCircuitsBase.GATES — Constant
GATESList of gates provided by the library.
Single qubit gates
GateID, GateX, GateY, GateZ, GateH, GateS, GateSDG, GateT, GateTDG, GateSX, GateSXDG. GateSY, GateSYDG.
Single qubit parametric gates
GateU, GateP, GateRX, GateRY, GateRZ, GateR, GateU1, GateU2, GateU3.
Two qubit gates
GateCX, GateCY, GateCZ, GateCH, GateSWAP, GateISWAP, GateCS, GateCSDG, GateCSX, GateCSXDG, GateECR, GateDCX,
Two qubit parametric gates
GateCP, GateCU, GateCRX, GateCRY, GateCRZ, GateRXX, GateRYY, GateRZZ, GateRZX, GateXXplusYY, GateXXminusYY.
Multi qubit Gates
GateCCX, GateC3X, GateCCP, GateCSWAP.
Generalized gates
These defines an unitary quantum operation on non fixed number of qubits.
See GENERALIZED for a list of them.
Operations
See OPERATIONS for a complete list of operations.
Noise channels
These define a non-unitary quantum operation based on the Kraus representation.
See NOISECHANNELS for a list of them.
MimiqCircuitsBase.GENERALIZED — Constant
GENERALIZEDDefinition of complex unitary quantum opteration on a not fixed number of qubits, or on multiple groups of qubits (registers).
Usually they are initialized with the number of qubits they operate on, or with the size of each group of qubits they act on
QFT related
Pauli strings
Custom Gates
MimiqCircuitsBase.NOISECHANNELS — Constant
NOISECHANNELSList of noise channels provided by the library.
Not mixed-unitary noise channels
Kraus, AmplitudeDamping, GeneralizedAmplitudeDamping, PhaseAmplitudeDamping, ThermalNoise, Reset, PrepareStateT,
Mixed-Unitary noise channels
MixedUnitary, PauliNoise, PauliX, PauliY, PauliZ, Depolarizing,
MimiqCircuitsBase.OPERATIONS — Constant
OPERATIONSPhases and other unitaries
See GATES for a complete list unitary gates.
GateCustom, GateCustomDiagonal
For gate definitions and calls, see GateDecl and GateCall
Other circuits elements
Modifiers
Control, Parallel, Power, Inverse
Non-unitary operations
Measure, MeasureX, MeasureY, MeasureZ, MeasureXX, MeasureYY, MeasureZZ, MeasurePauli, MeasureReset, MeasureResetX, MeasureResetY, MeasureResetZ, Reset, PrepareStateT
Classical bits (c-register) and complex variables (z-register) operations
Amplitude, Not, ExpectationValue, Multiply, Add, Pow
Entanglement and entropies
SchmidtRank, BondDim, VonNeumannEntropy
Algorithms or complex gate builders
See GENERALIZED for a complete list of generalized gates or algorithms.
MimiqCircuitsBase.show_mimiq_hierarchy — Function
show_mimiq_hierarchy()
show_mimiq_hierarchy([type])
show_mimiq_hierarchy([type, [module]])Show an hierarchy of the MIMIQ type and its subtypes.
julia> show_mimiq_hierarchy()
└── Operation
├── AbstractAnnotation
│ ├── Detector
│ ├── Lost
│ ├── ObservableInclude
│ ├── QubitCoordinates
│ ├── Reloaded
│ ├── ShiftCoordinates
│ └── Tick
├── AbstractClassical
│ ├── And
│ ├── Not
│ ├── Or
│ ├── ParityCheck
│ ├── SetBit0
│ ├── SetBit1
│ └── Xor
├── AbstractKrausChannel
│ ├── AmplitudeDamping
│ ├── Depolarizing
│ ├── Depolarizing1
│ ├── Depolarizing2
│ ├── GeneralizedAmplitudeDamping
│ ├── Kraus
│ ├── MixedUnitary
│ ├── PauliNoise
│ ├── PauliX
│ ├── PauliY
│ ├── PauliZ
│ ├── PhaseAmplitudeDamping
│ ├── PrepareStateT
│ ├── ProjectiveNoiseX
│ ├── ProjectiveNoiseY
│ ├── ProjectiveNoiseZ
│ ├── Reset
│ ├── ResetX
│ ├── ResetY
│ ├── ResetZ
│ └── ThermalNoise
├── AbstractMeasurement
│ ├── Measure
│ ├── MeasurePauli
│ ├── MeasureReset
│ ├── MeasureResetX
│ ├── MeasureResetY
│ ├── MeasureResetZ
│ ├── MeasureX
│ ├── MeasureXX
│ ├── MeasureY
│ ├── MeasureYY
│ ├── MeasureZ
│ └── MeasureZZ
├── AbstractOperator
│ ├── AbstractGate
│ │ ├── Control
│ │ │ ├── GateC3X
│ │ │ ├── GateCCP
│ │ │ ├── GateCCX
│ │ │ ├── GateCH
│ │ │ ├── GateCP
│ │ │ ├── GateCRX
│ │ │ ├── GateCRY
│ │ │ ├── GateCRZ
│ │ │ ├── GateCS
│ │ │ ├── GateCSDG
│ │ │ ├── GateCSWAP
│ │ │ ├── GateCSX
│ │ │ ├── GateCSXDG
│ │ │ ├── GateCU
│ │ │ ├── GateCX
│ │ │ ├── GateCY
│ │ │ └── GateCZ
│ │ ├── Delay
│ │ ├── Diffusion
│ │ ├── GateCall
│ │ ├── GateCustom
│ │ ├── GateCustomDiagonal
│ │ ├── GateDCX
│ │ ├── GateECR
│ │ ├── GateH
│ │ ├── GateHXY
│ │ ├── GateHXZ
│ │ ├── GateHYZ
│ │ ├── GateID
│ │ ├── GateISWAP
│ │ ├── GateP
│ │ ├── GateR
│ │ ├── GateRNZ
│ │ ├── GateRX
│ │ ├── GateRXX
│ │ ├── GateRY
│ │ ├── GateRYY
│ │ ├── GateRZ
│ │ ├── GateRZX
│ │ ├── GateRZZ
│ │ ├── GateSWAP
│ │ ├── GateU
│ │ ├── GateU1
│ │ ├── GateU2
│ │ ├── GateU3
│ │ ├── GateX
│ │ ├── GateXXminusYY
│ │ ├── GateXXplusYY
│ │ ├── GateY
│ │ ├── GateZ
│ │ ├── Inverse
│ │ │ ├── GateISWAPDG
│ │ │ ├── GateSDG
│ │ │ ├── GateSXDG
│ │ │ ├── GateSYDG
│ │ │ └── GateTDG
│ │ ├── Parallel
│ │ ├── PauliString
│ │ ├── PhaseGradient
│ │ ├── PolynomialOracle
│ │ ├── Power
│ │ │ ├── GateS
│ │ │ ├── GateSX
│ │ │ ├── GateSY
│ │ │ └── GateT
│ │ ├── QFT
│ │ └── RPauli
│ ├── DiagonalOp
│ ├── LossyOperator
│ ├── Operator
│ ├── Projector0
│ ├── Projector00
│ ├── Projector01
│ ├── Projector1
│ ├── Projector10
│ ├── Projector11
│ ├── ProjectorX0
│ ├── ProjectorX1
│ ├── ProjectorY0
│ ├── ProjectorY1
│ ├── ProjectorZ0
│ ├── ProjectorZ1
│ ├── RescaledGate
│ ├── SigmaMinus
│ └── SigmaPlus
├── Add
├── Amplitude
├── Barrier
├── Block
├── BondDim
├── Check
├── ExpectationValue
├── IfStatement
├── Loss
├── MeasureCheck
├── Multiply
├── Pow
├── ReadoutErr
├── Reload
├── Repeat
├── SchmidtRank
├── VonNeumannEntropy
└── WhileStatementGates
MimiqCircuitsBase.AbstractGate — Type
AbstractGate{N} <: AbstractOperator{N}Supertype for all the N-qubit unitary gates.
See also hilbertspacedim, inverse, isunitary, matrix, numqubits, opname
MimiqCircuitsBase.RescaledGate — Type
RescaledGate(gate, m)The operator $m \cdot U$: a gate $U$ whose matrix is multiplied by the scalar m.
The result is in general not unitary, so it is an operator rather than a gate. It is used to describe the terms of a mixed unitary channel, where each unitary $U_k$ is applied with probability $p_k$ and enters as the Kraus operator $\sqrt{p_k} U_k$.
m is a real number between 0 and 1, or a symbolic expression. getscale returns it and getoperation returns the gate.
Throws ArgumentError if m is numeric and outside $[0, 1]$.
Examples
julia> op = RescaledGate(GateX(), 0.5)
0.5 * X
julia> matrix(op)
2×2 Matrix{Float64}:
0.0 0.5
0.5 0.0
julia> getscale(op), getoperation(op)
(0.5, GateX())
julia> rescale(GateH(), 0.25)
0.25 * HSee also MixedUnitary, rescale.
MimiqCircuitsBase.getscale — Method
getscale(op::RescaledGate)Return the scalar a RescaledGate multiplies its gate by.
MimiqCircuitsBase.rescale! — Function
rescale!(op, scale)Multiply the operator op by scale in place and return it.
Only Operator and LossyOperator, which store their matrix, can be rescaled in place. Every other operation is an immutable value and throws an ArgumentError; use rescale, which returns a new operation.
Examples
julia> op = Operator([1 0; 0 1]);
julia> rescale!(op, 2) === op
true
julia> matrix(op)
2×2 Matrix{ComplexF64}:
2.0+0.0im 0.0+0.0im
0.0+0.0im 2.0+0.0im
julia> rescale!(Projector0(), 2)
ERROR: ArgumentError: Cannot rescale P₀ in place. Use `rescale` instead.
[...]MimiqCircuitsBase.GateSY — Type
GateSY()Single qubit $\sqrt{Y}$ gate.
See also GateSYDG, GateY, Power
Matrix representation
\[\operatorname{SY} = \sqrt{\operatorname{Y}} = \frac{1}{2} \begin{pmatrix} 1+i & -1-i \\ 1+i & 1+i \end{pmatrix}\]
Examples
julia> GateSY()
SY
julia> matrix(GateSY())
2×2 Matrix{ComplexF64}:
0.5+0.5im -0.5-0.5im
0.5+0.5im 0.5+0.5im
julia> c = push!(Circuit(), GateSY(), 1)
1-qubit circuit with 1 instruction:
└── SY @ q[1]
julia> push!(c, GateSY, 2)
2-qubit circuit with 2 instructions:
├── SY @ q[1]
└── SY @ q[2]
julia> power(GateSY(), 2)
Y
Decomposition
julia> decompose(GateSY())
1-qubit circuit with 4 instructions:
├── U(0,0,π/2) @ q[1]
├── U(0,0,π/2) @ q[1]
├── U(π/2,0,π) @ q[1]
└── U(0,0,0,π/4) @ q[1]MimiqCircuitsBase.GateSYDG — Type
GateSYDG()Single qubit $\sqrt{Y}^\dagger$ gate (conjugate transpose of the $\sqrt{Y}$ gate)
See also GateSY, GateY, Power, Inverse
Matrix representation
\[\operatorname{SYDG} = \sqrt{\operatorname{Y}}^\dagger = \frac{1}{2} \begin{pmatrix} 1-i & 1-i \\ -1+i & 1-i \end{pmatrix}\]
Examples
julia> GateSYDG()
SY†
julia> matrix(GateSYDG())
2×2 adjoint(::Matrix{ComplexF64}) with eltype ComplexF64:
0.5-0.5im 0.5-0.5im
-0.5+0.5im 0.5-0.5im
julia> c = push!(Circuit(), GateSYDG(), 1)
1-qubit circuit with 1 instruction:
└── SY† @ q[1]
julia> push!(c, GateSYDG, 2)
2-qubit circuit with 2 instructions:
├── SY† @ q[1]
└── SY† @ q[2]
julia> power(GateSYDG(), 2)
(SY†)^2
julia> inverse(GateSYDG())
SY
MimiqCircuitsBase.MeasureXX — Type
MeasureXX()The MeasureXX operation measures the joint parity of two qubits in the X-basis, that is the two-qubit Pauli operator $X \otimes X$. Its decomposition applies a controlled-X (CX) gate from the first qubit to the second and a Hadamard (H) gate on the first qubit. Together they map $X \otimes X$ to $Z$ on the first qubit, which is then measured. The H and CX gates are applied again afterwards to undo the basis change, so the qubits are left in the post-measurement state of the $X \otimes X$ measurement.
A result of 0 indicates that the qubits are in the same state, while a result of 1 indicates that they are in different states.
Examples
julia> c = Circuit()
empty circuit
julia> push!(c, MeasureXX(), 1, 2, 1)
2-qubit, 1-bit circuit with 1 instruction:
└── MXX @ q[1:2], c[1]MimiqCircuitsBase.MeasureYY — Type
MeasureYY()The MeasureYY operation measures the joint parity of two qubits in the Y-basis, that is the two-qubit Pauli operator $Y \otimes Y$. Its decomposition applies an S gate to both qubits, a controlled-X (CX) gate from the first qubit to the second and a Hadamard (H) gate on the first qubit. Together they map $Y \otimes Y$ to $Z$ on the first qubit, which is then measured. The H and CX gates and an S† gate on both qubits are applied afterwards to undo the basis change, so the qubits are left in the post-measurement state of the $Y \otimes Y$ measurement.
A result of 0 indicates that the qubits are in the same state, while a result of 1 indicates that they are in different states.
Examples
julia> c = Circuit()
empty circuit
julia> push!(c, MeasureYY(), 1, 2, 1)
2-qubit, 1-bit circuit with 1 instruction:
└── MYY @ q[1:2], c[1]MimiqCircuitsBase.MeasureZZ — Type
MeasureZZ()The MeasureZZ operation measures the joint parity of two qubits in the Z-basis. This is achieved by applying a controlled-X (CX) gate, measuring the target qubit, and then applying another CX gate to undo the entanglement. The measurement result indicates whether the qubits are in the same or different states in the Z-basis.
Examples
julia> c = Circuit()
empty circuit
julia> push!(c, MeasureZZ(), 1, 2, 1)
2-qubit, 1-bit circuit with 1 instruction:
└── MZZ @ q[1:2], c[1]MimiqCircuitsBase.MeasurePauli — Type
MeasurePauli(pauli)Pauli product measurement: projective measurement of the $N$-qubit observable $P = P_1 \otimes P_2 \otimes \dots \otimes P_N$, with each $P_i \in \{I, X, Y, Z\}$.
The instruction targets $N$ qubits and one classical bit. The state is projected onto the $+1$ or $-1$ eigenspace of $P$ and the bit records the outcome: 0 for $+1$, 1 for $-1$. Qubits marked I are targets of the instruction but are not measured.
To measure $-P$, measure $P$ and flip the bit with Not.
Arguments
pauli: aPauliString, or a string ofI,X,Y,Z.
Throws an ArgumentError if pauli is the identity, since there is nothing to measure.
See also PauliString, RPauli, MeasureZZ, MeasureXX, MeasureYY, pauli_based_computation.
Examples
Measure $X_1 Z_3$ on qubits 1 to 3 and store the outcome in bit 1. Qubit 2 is a target, but is left untouched:
julia> c = push!(Circuit(), MeasurePauli("XIZ"), 1, 2, 3, 1)
3-qubit, 1-bit circuit with 1 instruction:
└── MP(XIZ) @ q[1:3], c[1]Decomposition
Each measured qubit is rotated to the Z basis (H for X, SDG then H for Y), CX gates collect the parity of the measured qubits on the last one, that qubit is measured, and the CX gates and rotations are undone:
julia> decompose_step(MeasurePauli("XZ"))
2-qubit, 1-bit circuit with 5 instructions:
├── H @ q[1]
├── CX @ q[1], q[2]
├── M @ q[2], c[1]
├── CX @ q[1], q[2]
└── H @ q[1]Only H, S, SDG, CX and Measure appear, so QASMBasis decomposes it. StimBasis keeps it, as Stim measures Pauli products natively (MPP), and so does CliffordTBasis.
Wrappers
MimiqCircuitsBase.Control — Type
Control(numcontrols, gate) <: AbstractGateControl modifier, similar to OpenQASM 3.0 ctrl @ gate. It wraps a given gate and adds a number of controls to it.
By default the first numcontrols qubits are used as controls, and the remaining ones as targets for the wrapped gate.
See also Power, Inverse, getoperation, iswrapper, numcontrols, numtargets.
Examples
julia> Control(1, GateX())
CX
julia> Control(3, GateH())
C₃H
julia> Control(24, GateSWAP())
C₂₄SWAPDecomposition
The default decomposition of a Control gate is build by applying recursively Lemma 7.3 of [1]. This requires to decompose multicontrolled-$X$ gates, which is done recursively, according to Lemma 7.2 and 7.3 of [1].
Here we give a simple example of a decomposition of a $C_5T$ gate.
julia> decompose(Control(3,GateT()))
4-qubit circuit with 57 instructions:
├── U(0,0,π/16) @ q[3]
├── CX @ q[3], q[4]
├── U(0,0,(-1//16)*π) @ q[4]
├── CX @ q[3], q[4]
├── U(0,0,π/16) @ q[4]
├── U(π/2,0,π) @ q[3]
├── CX @ q[2], q[3]
├── U(0,0,-1π/4) @ q[3]
├── CX @ q[1], q[3]
⋮ ⋮
├── CX @ q[2], q[4]
├── U(0,0,π/32) @ q[4]
├── CX @ q[2], q[4]
├── U(0,0,(-1//32)*π) @ q[4]
├── CX @ q[1], q[2]
├── U(0,0,π/32) @ q[1]
├── CX @ q[1], q[4]
├── U(0,0,(-1//32)*π) @ q[4]
├── CX @ q[1], q[4]
└── U(0,0,π/32) @ q[4]MimiqCircuitsBase.Control — Method
Control(gate)Build a controlled gate with 1 control.
MimiqCircuitsBase.control — Function
control([numcontrols], gate)Build a multicontrolled gate.
The number of controls can be omitted to be lazily evaluated later.
Examples
Standard examples, with all the arguments spefcified.
julia> control(1, GateX())
CX
julia> control(2, GateX())
C₂X
julia> control(3, GateCH())
C₄H
MimiqCircuitsBase.numcontrols — Function
numcontrols(control)Number of controls of a given multicontrolled gate.
See also
MimiqCircuitsBase.numtargets — Function
numtargets(control)Get the number of targets of a given multicontrolled gate.
Examples
numcontro
See also
MimiqCircuitsBase.Inverse — Type
Inverse(operation)Inverse of the wrapped quantum operation.
The inversion is not performed right away, but only when the circuit is cached or executed.
Some simplifications are already carried out at construction, for example, Inverse(Inverse(op)) is simplified as Inverse(op).
Users should not use directly Inverse but the inverse method, which performs already all the simplifications.
See also inverse, iswrapper, Control, Power.
Examples
julia> Inverse(GateX())
X†
julia> Inverse(GateH())
H†
julia> Inverse(GateSX())
SX†
julia> Inverse(GateCSX())
CSX†
julia> Inverse(QFT(4))
QFT†
Decomposition
Decomposition of the inverse is carring out by inverting the decomposition of the wrapped operation.
julia> decompose(Inverse(GateCSX()))
2-qubit circuit with 7 instructions:
├── U(π/2,0,π) @ q[2]
├── U(0,0,-1π/4) @ q[1]
├── CX @ q[1], q[2]
├── U(0,0,π/4) @ q[2]
├── CX @ q[1], q[2]
├── U(0,0,-1π/4) @ q[2]
└── U(π/2,0,π) @ q[2]MimiqCircuitsBase.Power — Type
Power(pow, operation)Wraps an operation and raises it to the given power.
Some simplifications are already carried out at construction, for example Power(pow2, Power(pow1, op)) is simplified as Power(pow1 * pow2, op).
A floating point exponent that is exactly a fraction with denominator at most 1000 is stored as that fraction, so Power(GateX(), 0.5) is GateSX(). Other floats, such as sqrt(2), are kept as they are.
Users should not use directly Power but the power method, which performs already all the simplifications. Gates should implement the _power method instead.
See also power, Inverse , inverse.
Example
julia> Power(GateZ(), 1//2)
S
julia> Power(GateZ(), 2)
Z^2
julia> Power(GateCH(), 1//2)
CH^(1//2)
julia> Power(GateCX(), 1//2)
CX^(1//2)Decomposition
In the general case, if a decomposition is not known for a given operation and power, the Power operation is not decomposed.
If the exponent is an integer, then the gate is decomposed by repeating it.
julia> decompose(Power(GateH(), 2))
1-qubit circuit with 2 instructions:
├── U(π/2,0,π) @ q[1]
└── U(π/2,0,π) @ q[1]
julia> decompose(Power(GateH(), 1//2))
1-qubit circuit with 1 instruction:
└── U(1.0471975511966005,-0.9553166181245096,2.1862760354652835,0.16991845472706107) @ q[1]
julia> decompose(Power(GateX(), 1//2)) # same as decomposing GateSX
1-qubit circuit with 4 instructions:
├── U(0,0,-1π/2) @ q[1]
├── U(π/2,0,π) @ q[1]
├── U(0,0,-1π/2) @ q[1]
└── U(0,0,0,π/4) @ q[1]MimiqCircuitsBase.Parallel — Type
Parallel(repeats, operation)Wrapper that applies the same operation on multiple qubits.
If the operation is a N-qubit operation, then the resulting operation is applied over N * repeats qubits.
Examples
julia> Parallel(5, GateX())
⨷ ⁵ X
julia> Parallel(3, GateRX(λ))
⨷ ³ RX(λ)
julia> Parallel(2, Parallel(3, GateX()))
⨷ ² (⨷ ³ X)
Decomposition
A parallel is decomposed into a sequence of operation, one for each group of qubits.
julia> decompose(Parallel(2, GateX()))
2-qubit circuit with 2 instructions:
├── U(π,0,π) @ q[1]
└── U(π,0,π) @ q[2]
julia> decompose(Parallel(3, GateSWAP()))
6-qubit circuit with 9 instructions:
├── CX @ q[1], q[2]
├── CX @ q[2], q[1]
├── CX @ q[1], q[2]
├── CX @ q[3], q[4]
├── CX @ q[4], q[3]
├── CX @ q[3], q[4]
├── CX @ q[5], q[6]
├── CX @ q[6], q[5]
└── CX @ q[5], q[6]MimiqCircuitsBase.numrepeats — Function
numrepeats(paralleloperation)Get the number of repetitions of a parallel operation.
See also Parallel.
Examples
julia> numrepeats(Parallel(5, GateX()))
5
julia> numrepeats(Parallel(3, GateSWAP()))
3
MimiqCircuitsBase.parallel — Function
parallel(repeats, operation)Build a parallel operation.
The resulting operation is applied over N * repeats qubits.
MimiqCircuitsBase.IfStatement — Type
IfStatement(op, bs::BitString)Applies the provided operation only if the classical register matches the specified BitString.
IfStatement enables conditional operations in a quantum circuit based on the state of a classical register. If the classical register's state matches the BitString, the operation (op) is applied to the target qubits.
Arguments
op: The quantum operation to apply, such asGateX()or another operation.bs: ABitStringobject representing the target state of the classical register that triggersop.
Examples
Basic Usage
julia> using MimiqCircuitsBase
# Define a condition as a BitString
julia> condition = BitString("01011")
5-bits BitString with integer value 26:
01011
# Apply GateX only if the condition is met
julia> if_statement = IfStatement(GateX(), condition)
IF(c==01011) X
# Add this conditional operation to a circuit
julia> c = Circuit()
empty circuit
julia> push!(c, if_statement, 1, 2, 3, 4, 5, 6)
1-qubit, 6-bit circuit with 1 instructions:
└── IF(c==01011) X @ q[1], condition[2:6]
julia> push!(c, IfStatement(Measure(),BitString("010")),1,1,3,4,5)
1-qubit, 6-bit circuit with 2 instructions:
├── IF(c==01011) X @ q[1], condition[2:6]
└── IF(c==010) M @ q[1], c[1], condition[3:5]
julia> push!(c,IfStatement(Amplitude(BitString("01")),BitString("01")),1,2,1)
1-qubit, 6-bit, 1-vars circuit with 3 instructions:
├── IF(c==01011) X @ q[1], condition[2:6]
├── IF(c==010) M @ q[1], c[1], condition[3:5]
└── IF(c==01) Amplitude(bs"01") @ condition[1:2], z[1]
MimiqCircuitsBase.WhileStatement — Type
WhileStatement(op, bs::BitString)Repeatedly applies the provided operation while the classical register matches the specified BitString.
WhileStatement is the loop counterpart of IfStatement. The body operation op is executed once for every iteration in which the classical register's state equals the BitString. For the loop to terminate, op must mutate at least one of the bits used in the condition (see allow_bit_aliasing — WhileStatement allows body bits to alias condition bits, which is the only way to make progress).
There is no built-in iteration cap: a non-terminating circuit is the user's responsibility, mirroring how every classical language treats while.
Arguments
op: The operation to apply each iteration.bs: ABitStringrepresenting the condition. The loop runs as long as the selected condition bits match this pattern.
Examples
julia> using MimiqCircuitsBase
# Decrement c[1] until it reaches zero (assuming c[1] starts at 1)
julia> while_statement = WhileStatement(Not(), BitString("1"))
WHILE(c==1) X̲
julia> c = Circuit()
empty circuit
julia> push!(c, while_statement, 1, 1)
1-bit circuit with 1 instruction:
└── WHILE(c==1) X̲ @ c[1], condition[1]See also IfStatement.
MimiqCircuitsBase.Repeat — Type
Repeat(repeats, operation)Wrapper that applies the same operation multiple times, on the same qubits, bits, and variables.
Examples
julia> Repeat(5, GateX())
∏⁵ X
julia> Repeat(3, GateRX(λ))
∏³ RX(λ)
julia> Repeat(2, Repeat(3, GateX()))
∏² (∏³ X)
Decomposition
A repeated operation is decomposed by repeating the same operation multiple times
julia> decompose(Repeat(2, GateX()))
1-qubit circuit with 2 instructions:
├── U(π,0,π) @ q[1]
└── U(π,0,π) @ q[1]
julia> decompose(Repeat(3, GateSWAP()))
2-qubit circuit with 9 instructions:
├── CX @ q[1], q[2]
├── CX @ q[2], q[1]
├── CX @ q[1], q[2]
├── CX @ q[1], q[2]
├── CX @ q[2], q[1]
├── CX @ q[1], q[2]
├── CX @ q[1], q[2]
├── CX @ q[2], q[1]
└── CX @ q[1], q[2]Using repeat
The repeat function is a shorthand for creating a Repeat operation. The main difference between using repeat and Repeat is that the former tries to infer any simplification that can be done on the operation before creating a Repeat operation.
Classical operations
MimiqCircuitsBase.AbstractClassical — Type
Abstract Type for all classical OperationsMimiqCircuitsBase.Not — Type
struct Not <: AbstractClassical{1}Classical operation that flips a classical bit: 0 → 1 and 1 → 0.
Acts only on classical registers and performs a deterministic logical inversion.
Examples
julia> Not()
~
julia> push!(Circuit(), Not(),1)
1-bit circuit with 1 instruction:
└── c[1] = ~c[1]MimiqCircuitsBase.Xor — Type
struct Xor{N} <: AbstractClassical{N}Computes the bitwise XOR of N-1 classical bits and stores the result in the first given bit.
Examples
julia> Xor()
c[?1] = c[?2] ⊻ c[?3]
julia> push!(Circuit(), Xor(),1, 3, 4)
4-bit circuit with 1 instruction:
└── c[1] = c[3] ⊻ c[4]
julia> push!(Circuit(), Xor(5), 1, 3, 5, 8, 13)
13-bit circuit with 1 instruction:
└── c[1] = c[3] ⊻ c[5] ⊻ c[8] ⊻ c[13]
julia> push!(Circuit(), Xor(8), 1, 2, 3, 4, 5, 6, 7, 8)
8-bit circuit with 1 instruction:
└── c[1] = ⊻ @ c[2, 3, 4, 5, 6, 7, 8]
MimiqCircuitsBase.Or — Type
struct Or{N} <: AbstractClassical{N}Computes the bitwise OR of N-1 classical bits and stores the result in the first given bit.
Examples
julia> Or()
c[?1] = c[?2] | c[?3]
julia> push!(Circuit(), Or(),1, 3, 4)
4-bit circuit with 1 instruction:
└── c[1] = c[3] | c[4]
julia> push!(Circuit(), Or(5), 1, 3, 5, 8, 13)
13-bit circuit with 1 instruction:
└── c[1] = c[3] | c[5] | c[8] | c[13]
julia> push!(Circuit(), Or(8), 1, 2, 3, 4, 5, 6, 7, 8)
8-bit circuit with 1 instruction:
└── c[1] = | @ c[2, 3, 4, 5, 6, 7, 8]
MimiqCircuitsBase.And — Type
struct And{N} <: AbstractClassical{N}Computes the bitwise AND of N-1 classical bits and stores the result in the first given bit.
Examples
julia> And()
c[?1] = c[?2] & c[?3]
julia> push!(Circuit(), And(),1, 3, 4)
4-bit circuit with 1 instruction:
└── c[1] = c[3] & c[4]
julia> push!(Circuit(), And(5), 1, 3, 5, 8, 13)
13-bit circuit with 1 instruction:
└── c[1] = c[3] & c[5] & c[8] & c[13]
julia> push!(Circuit(), And(8), 1, 2, 3, 4, 5, 6, 7, 8)
8-bit circuit with 1 instruction:
└── c[1] = & @ c[2, 3, 4, 5, 6, 7, 8]
MimiqCircuitsBase.SetBit0 — Type
struct SetBit0 <: AbstractClassical{1}Classical operation that sets a classical bit to 0. 0 → 0 and 1 → 0.
Examples
julia> SetBit0()
Set0
julia> push!(Circuit(), SetBit0(),1)
1-bit circuit with 1 instruction:
└── c[1] = 0MimiqCircuitsBase.SetBit1 — Type
struct SetBit1 <: AbstractClassical{1}Classical operation that sets a classical bit to 1. 0 → 1 and 1 → 1.
Examples
julia> SetBit1()
Set1
julia> push!(Circuit(), SetBit1(),1)
1-bit circuit with 1 instruction:
└── c[1] = 1MimiqCircuitsBase.ParityCheck — Type
ParityCheck(N=3)Deprecated alias of Xor.
ParityCheck(N) returns Xor(N), which computes the same parity of N-1 classical bits into the first bit, and emits a deprecation warning. No operation is ever of type ParityCheck.
Examples
julia> ParityCheck(5)
c[?1] = c[?2] ⊻ c[?3] ⊻ c[?4] ⊻ c[?5]