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.

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.

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

Gates

MimiqCircuitsBase.matrixFunction
matrix(gate)

Matrix associated to the given gate.

Note

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
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(π/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]
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())
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]
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(numbits, op, num)

Applies the wrapper operation, only if the classical register is equal to num.

Warn

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