Operations

MimiqCircuitsBase.hilbertspacedimFunction
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

numqubits, numbits, Operation, AbstractGate

source
MimiqCircuitsBase.iswrapperFunction
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

isunitary, getoperation

source
MimiqCircuitsBase.numparamsFunction
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

parnames, getparam

source
MimiqCircuitsBase.parnamesFunction
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

numparams, getparam

source
MimiqCircuitsBase.qregsizesMethod
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

cregsizes, numqubits, numbits

source
MimiqCircuitsBase.GATESConstant
GATES

List 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.

source
MimiqCircuitsBase.GENERALIZEDConstant
GENERALIZED

Definition 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, PhaseGradient

source
MimiqCircuitsBase.OPERATIONSConstant
OPERATIONS

Phases and other unitaries

See GATES for a complete list unitary gates.

GateCustom

For gate definitions and calls, see GateDecl and GateCall

Other circuits elements

Barrier, IfStatement

Modifiers

Control, Parallel, Power, Inverse

Non-unitary operations

Measure, MeasureX, MeasureY, MeasureZ, MeasureXX, MeasureYY, MeasureZZ MeasureReset, MeasureResetX, MeasureResetY, MeasureResetZ, Reset,

Algorithms or complex gate builders

See GENERALIZED for a complete list of generalized gates or algorithms.

source

Gates

MimiqCircuitsBase.GateSYType
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 instructions:
└── 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:
├── S @ q[1]
├── S @ q[1]
├── H @ q[1]
└── U(0,0,0,π/4) @ q[1]
source
MimiqCircuitsBase.GateSYDGType
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 instructions:
└── 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
source
MimiqCircuitsBase.MeasureXXType
MeasureXX()

The MeasureXX operation measures the joint parity of two qubits in the X-basis, determining whether the qubits are in the same or different states within this basis. The operation begins by applying a controlled-X (CX) gate between the two qubits to entangle them. Following this, a Hadamard (H) gate is applied to the first qubit, rotating it into the X-basis. The second qubit, designated as the target, is then measured to extract the parity information. After the measurement, the Hadamard gate is applied again to the first qubit to reverse the rotation, and a second controlled-X (CX) gate is applied to disentangle the qubits, restoring the system to its original state. Through this sequence, the MeasureXX operation efficiently captures the parity relationship of the qubits in the X-basis.

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.

See Also MeasureYY, MeasureZZ

Examples

julia> c = Circuit()
empty circuit

julia> push!(c, MeasureXX(), 1, 2, 1)
2-qubit circuit with 1 instructions:
└── MXX @ q[1:2], c[1]
source
MimiqCircuitsBase.MeasureYYType
MeasureYY()

The MeasureYY operation measures the joint parity of two qubits in the Y-basis, determining whether they are in the same or different states in this basis. This is achieved by first applying an S gate (a π/2 phase shift) to both qubits, followed by a controlled-X (CX) gate. A Hadamard gate (H) is then applied to the first qubit, and the second qubit is measured. To restore the system, a Z gate is applied to the first qubit, followed by another Hadamard gate, another CX gate, and finally another S gate to both qubits. The measurement result reflects whether the qubits are in the same or different states in the Y-basis.

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.

See Also MeasureXX, MeasureZZ

Examples

julia> c = Circuit()
empty circuit

julia> push!(c, MeasureYY(), 1, 2, 1)
2-qubit circuit with 1 instructions:
└── MYY @ q[1:2], c[1]
source
MimiqCircuitsBase.MeasureZZType
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.

See Also MeasureYY, MeasureXX

Examples

julia> c = Circuit()
empty circuit

julia> push!(c, MeasureZZ(), 1, 2, 1)
2-qubit circuit with 1 instructions:
└── MZZ @ q[1:2], c[1]
source

Wrappers

MimiqCircuitsBase.ControlType
Control(numcontrols, gate) <: AbstractGate

Control modifier, similar to OpenQASM 3.0 ctrl @ gate. It wraps a given gate and adds a number of controls to it.

Note

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₂₄SWAP

Decomposition

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 9 instructions:
├── C(Z^(1//8)) @ q[3], q[4]
├── C₂X @ q[1:2], q[3]
├── C((Z^(1//8))†) @ q[3], q[4]
├── C₂X @ q[1:2], q[3]
├── C(Z^(1//16)) @ q[2], q[4]
├── CX @ q[1], q[2]
├── C((Z^(1//16))†) @ q[2], q[4]
├── CX @ q[1], q[2]
└── C(Z^(1//16)) @ q[1], q[4]
Detail

Some decompositions have been overrided with optimized versions, to reduce the number of gates used.

source
MimiqCircuitsBase.controlFunction
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
source
MimiqCircuitsBase.InverseType
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).

Warn

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 3 instructions:
├── H @ q[2]
├── CU1(-1π/2) @ q[1], q[2]
└── H @ q[2]
source
MimiqCircuitsBase.PowerType
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).

Note

For allowing simplifications, always prefer rational powers, such as 1//2 over floating point ones, such as 0.5.

Warn

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:
├── H @ q[1]
└── H @ q[1]

julia> decompose(Power(GateH(), 1//2))
1-qubit circuit with 1 instructions:
└── 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:
├── S† @ q[1]
├── H @ q[1]
├── S† @ q[1]
└── U(0,0,0,π/4) @ q[1]
source
MimiqCircuitsBase.ParallelType
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:
├── X @ q[1]
└── X @ q[2]

julia> decompose(Parallel(3, GateSWAP()))
6-qubit circuit with 3 instructions:
├── SWAP @ q[1:2]
├── SWAP @ q[3:4]
└── SWAP @ q[5:6]
source
MimiqCircuitsBase.numrepeatsFunction
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
source
MimiqCircuitsBase.IfStatementType
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 as GateX() or another gate.
  • bs: A BitString object representing the target state of the classical register that triggers op.

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()
julia> push!(c, if_statement, 1, 2, 3, 4, 5, 6)
1-qubit circuit with 1 instructions:
└── IF(c==01011) X @ q[1], c[2:6]
source

Decompositions

MimiqCircuitsBase.decomposeFunction
decompose(operation)
decompose(circuit)

Decompose the given operation or circuit into a circuit of more elementary gates. If applied recursively, it will decompose the given object into a circuit of GateCX and GateU gates.

See also decompose!.

source
MimiqCircuitsBase.decompose!Function
decompose!(circuit, operation[, qtargets, ctargets])

In place version of decompose.

It decomposes the given object, appending all the resulting operations to the given circuit. The optional qtargets and ctargets arguments can be used to map the qubits and classical bits of the decomposed operation to the ones of the target circuit.

source

Classical operations