Operations
MimiqCircuitsBase.Operation
— TypeOperation{N,M}
Abstract supertype for all the quantum operations acting on N
qubits and M
classical bits.
Methods
iswrapper
, isunitary
, numbits
, numqubits
, opname
See also
MimiqCircuitsBase.cregsizes
— Methodcregsizes(operation)
cregsizes(operationtype)
Length of the classicalregisters the given operation acts on.
See also
MimiqCircuitsBase.getparam
— Functiongetparam(operation, name)
Value of the corresponding parameter in the given parametric operation.
Examples
getparam(GateRX(π/8), :θ)
See also
MimiqCircuitsBase.getparams
— Functiongetparams(operation)
Value of the parameters in the given parametric operation.
Examples
getparam(GateU(π/8, 3.1, sqrt(2)))
See also
MimiqCircuitsBase.hilbertspacedim
— Functionhilbertspacedim(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
— Functioniswrapper(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
— Functionnumparams(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
— Functionparnames(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
— Methodqregsizes(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.GATES
— ConstantGATES
List of gates provided by the library.
Single qubit gates
GateID
, GateX
, GateY
, GateZ
, GateH
, GateS
, GateSDG
, GateT
, GateTDG
, GateSX
, GateSXDG
.
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.
MimiqCircuitsBase.GENERALIZED
— ConstantGENERALIZED
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
MimiqCircuitsBase.OPERATIONS
— ConstantOPERATIONS
Phases and other unitaries
See GATES
for a complete list unitary gates.
For gate definitions and calls, see GateDecl
and GateCall
Other circuits elements
Modifiers
Control
, Parallel
, Power
, Inverse
Non-unitary operations
Algorithms or complex gate builders
See GENERALIZED
for a complete list of generalized gates or algorithms.
Gates
MimiqCircuitsBase.AbstractGate
— TypeAbstractGate{N} <: Operation{N,0}
Supertype for all the N
-qubit unitary gates.
See also hilbertspacedim
, inverse
, isunitary
, matrix
, numqubits
, opname
MimiqCircuitsBase.matrix
— Functionmatrix(gate)
Matrix associated to the given gate.
if the gate is parametric, the matrix elements are is wrapped in a Symbolics.Num
object. To manipulate expressions use the Symbolics
package.
Examples
Matrix of a simple gate
julia> matrix(GateH())
2×2 Matrix{Float64}:
0.707107 0.707107
0.707107 -0.707107
julia> matrix(GateRX(π/2))
2×2 Matrix{ComplexF64}:
0.707107+0.0im 0.0-0.707107im
0.0-0.707107im 0.707107+0.0im
julia> matrix(GateCX())
4×4 Matrix{Float64}:
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0
Wrappers
MimiqCircuitsBase.Control
— TypeControl(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.
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]
Some decompositions have been overrided with optimized versions, to reduce the number of gates used.
MimiqCircuitsBase.Control
— MethodControl(gate)
Build a controlled gate with 1 control.
MimiqCircuitsBase.control
— Functioncontrol([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
— Functionnumcontrols(control)
Number of controls of a given multicontrolled gate.
See also
MimiqCircuitsBase.numtargets
— Functionnumtargets(control)
Get the number of targets of a given multicontrolled gate.
Examples
numcontro
See also
MimiqCircuitsBase.Inverse
— TypeInverse(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 3 instructions:
├── H @ q[2]
├── CU1(-1π/2) @ q[1], q[2]
└── H @ q[2]
MimiqCircuitsBase.Power
— TypePower(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)
.
For allowing simplifications, always prefer rational powers, such as 1//2
over floating point ones, such as 0.5
.
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(π/2, 0, π)^(1//2) @ 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]
MimiqCircuitsBase.Parallel
— TypeParallel(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())
Parallel(5, X)
julia> Parallel(3, GateRX(λ))
Parallel(3, RX(λ))
julia> Parallel(2, Parallel(3, GateX()))
Parallel(2, Parallel(3, 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]
MimiqCircuitsBase.numrepeats
— Functionnumrepeats(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
— Functionparallel(repeats, operation)
Build a parallel operation.
The resulting operation is applied over N * repeats
qubits.
MimiqCircuitsBase.IfStatement
— TypeIfStatement(numbits, op, num)
Applies the wrapper operation, only if the classical register is equal to num
.
Currentely not supported by the state vector and MPS simulators.
Examples
push!(IfStatement(GateX(), 10), 1,1,2,3,4,5)
is the equivalent of OpenQASM 2.0
creg c[5];
if (c==10) x q[0];
julia> IfStatement(10, GateX(), 999)
IF(c == 999) X
Decompositions
MimiqCircuitsBase.decompose
— Functiondecompose(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!
.
MimiqCircuitsBase.decompose!
— Functiondecompose!(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.