Quantum Circuits and Instructions
MimiqCircuitsBase.AbstractInstruction
— TypeAbstractInstruction
Abstract super type for all the instrcutions.
An instruction applies one or more operations to a set of qubits and classical bits.
Methods
getqubit
, getqubits
, getbits
, getbit
inverse
, opname
, numqubits
, numbits
See also
MimiqCircuitsBase.Instruction
— TypeInstruction(op, qtargets, ctargets) <: AbstractInstruction
Representation of an operation applied to specific qubit and bit targets.
Example
julia> Instruction(GateX(), (1,), (), ())
X @ q[1]
julia> Instruction(GateCX(), (1,2), (), ())
CX @ q[1], q[2]
julia> Instruction(Measure(), (3,), (3,), ())
M @ q[3], c[3]
See also
MimiqCircuitsBase.Instruction
— MethodInstruction(op, targets...)
Constructors an instruction from an operation and a list of targets.
By convention, if op
is an N
-qubit and M
-bit operations, then the first N
targets are used as qubits and the last M
as bits.
Examples
julia> Instruction(GateX(), 1)
X @ q[1]
julia> Instruction(GateCX(), 1,2)
CX @ q[1], q[2]
julia> Instruction(Measure(), 3, 3)
M @ q[3], c[3]
MimiqCircuitsBase.getbit
— Functiongetbit(instruction, i)
i
-th target classical bit of an instruction.
Examples
julia> inst = Instruction(Measure(), 1, 3)
M @ q[1], c[3]
julia> getbit(inst, 1)
3
See also
MimiqCircuitsBase.getbits
— Functiongetbits(instruction)
Tuple of the classical bits which the instruction is applied to.
Examples
julia> inst = Instruction(Measure(), 1, 3)
M @ q[1], c[3]
julia> getbits(inst)
(3,)
See also
MimiqCircuitsBase.getqubit
— Functiongetqubit(instruction, i)
i
-th target qubit of an instruction.
Examples
julia> inst = Instruction(GateCX(), 1, 3)
CX @ q[1], q[3]
julia> getqubit(inst, 2)
3
See also
MimiqCircuitsBase.getqubits
— Functiongetqubits(instruction)
Tuple of quantum bits which the instruction is applied to.
julia> inst = Instruction(GateCX(), 1, 3)
CX @ q[1], q[3]
julia> getqubits(inst)
(1, 3)
See also
MimiqCircuitsBase.getztarget
— Functiongetztarget(instruction)
Tuple of the classical bits which the instruction is applied to.
Examples
julia> inst = Instruction(ExpectationValue(pauli"ZZ"), 1, 2, 1)
⟨ZZ⟩ @ q[1:2], z[1]
julia> getztarget(inst,1)
1
See also
MimiqCircuitsBase.Circuit
— TypeCircuit([instructions])
Representation of a quantum circuit as a vector of instructions applied to the qubits.
The circuit can be initialized with an optional vector of instructions.
See OPERATIONS
, GATES
, or GENERALIZED
for the list of operations to add to circuits.
Examples
Operation can be added one by one to a circuit with the push!(circuit, operation, targets...)
function
julia> c = Circuit()
empty circuit
julia> push!(c, GateH(), 1)
1-qubit circuit with 1 instructions:
└── H @ q[1]
julia> push!(c, GateCX(), 1, 2)
2-qubit circuit with 2 instructions:
├── H @ q[1]
└── CX @ q[1], q[2]
julia> push!(c, GateRX(π / 4), 1)
2-qubit circuit with 3 instructions:
├── H @ q[1]
├── CX @ q[1], q[2]
└── RX(π/4) @ q[1]
julia> push!(c, Barrier(2), 1, 3)
3-qubit circuit with 4 instructions:
├── H @ q[1]
├── CX @ q[1], q[2]
├── RX(π/4) @ q[1]
└── Barrier @ q[1,3]
julia> push!(c, Measure(), 1, 1)
3-qubit circuit with 5 instructions:
├── H @ q[1]
├── CX @ q[1], q[2]
├── RX(π/4) @ q[1]
├── Barrier @ q[1,3]
└── M @ q[1], c[1]
Targets are not restricted to be single values, but also vectors. In this case a single push!
will add multiple operations.
julia> push!(Circuit(), GateCCX(), 1, 2:4, 4:10)
6-qubit circuit with 3 instructions:
├── C₂X @ q[1:2], q[4]
├── C₂X @ q[1,3], q[5]
└── C₂X @ q[1,4], q[6]
is equivalent to
for (i, j) in zip(2:4, 4:10)
push!(c, GateCX(), 1, i)
end
Notice how the range 4:10
is not fully used, since 2:4
is shorter.
Display
To display a a LaTeX representation of the circuit, we can just use Quantikz.jl
using Quantikz
c = Circuit()
...
displaycircuit(c)
or
savecircuit(c, "circuit.pdf")
MimiqCircuitsBase.numbits
— Methodnumbits(insts::Vector{<:Instruction})
numbits(c::Circuit) -> Int
Compute the highest index of c-targets in the given circuit.
Examples
julia> c = Circuit()
empty circuit
julia> push!(c, Measure(), 1:2, 1:2)
2-qubit circuit with 2 instructions:
├── M @ q[1], c[1]
└── M @ q[2], c[2]
julia> numbits(c)
2
MimiqCircuitsBase.numqubits
— Methodnumqubits(insts::Vector{<:Instruction})
numqubits(c::Circuit) -> Int
Compute the highest index of q-targets in the given vector of instructions or circuit.
Examples
julia> c = Circuit()
empty circuit
julia> push!(c, Measure(), 1:2, 1:2)
2-qubit circuit with 2 instructions:
├── M @ q[1], c[1]
└── M @ q[2], c[2]
julia> numqubits(c)
2
MimiqCircuitsBase.numzvars
— Methodnumzvars(insts::Vector{<:Instruction})
numzvars(c::Circuit) -> Int
Compute the highest index of z-targets in the given circuit.
Examples
julia> c = Circuit()
empty circuit
julia> push!(c, Amplitude(bs"01"), 1:2)
0-qubit circuit with 2 instructions:
├── Amplitude(bs"01") @ z[1]
└── Amplitude(bs"01") @ z[2]
julia> numzvars(c)
2
MimiqCircuitsBase.depth
— Methoddepth(circuit)
Compute the depth of a quantum circuit.
The depth of a quantum circuit is a metric computing the maximum time (in units of quantum gates application) between the input and output of the circuit.
MimiqCircuitsBase.emplace!
— Functionemplace!(circuit, operation, registers...)
Emplace an operation at the end of a circuit and applies it to the given registers.
julia> emplace!(Circuit(), control(3, GateSWAP()), [1,2,3], [4,5])
5-qubit circuit with 1 instructions:
└── C₃SWAP @ q[1:3], q[4:5]
julia> QFT()
lazy QFT(?)
julia> emplace!(Circuit(), QFT(), [1,2,3])
3-qubit circuit with 1 instructions:
└── QFT @ q[1:3]
MimiqCircuitsBase.draw
— Functiondraw(circuit)
Draw an ascii representation of a circuit.
NOTE it automatically detects the screen width and will split the circuit if it is too wide.