Quick Start
In this quick start, we list several common use cases for Yao before you go deeper into the manual.
Create a quantum register/state
A register is an object that describes a device with an internal state. See Registers for more details. Yao use registers to represent quantum states. The most common register is the ArrayReg
, you can create it by feeding a state vector to it, e.g
julia> using Yao
julia> ArrayReg(rand(ComplexF64, 2^3))
ArrayReg{2, ComplexF64, Array...} active qubits: 3/3 nlevel: 2
julia> zero_state(5)
ArrayReg{2, ComplexF64, Array...} active qubits: 5/5 nlevel: 2
julia> rand_state(5)
ArrayReg{2, ComplexF64, Array...} active qubits: 5/5 nlevel: 2
julia> product_state(bit"10100")
ArrayReg{2, ComplexF64, Array...} active qubits: 5/5 nlevel: 2
julia> ghz_state(5)
ArrayReg{2, ComplexF64, Array...} active qubits: 5/5 nlevel: 2
the internal quantum state can be accessed via statevec
method
julia> statevec(ghz_state(2))
4-element Vector{ComplexF64}: 0.7071067811865476 - 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.7071067811865476 - 0.0im
for more functionalities about registers please refer to the manual of registers
.
Create quantum circuit with Yao blocks
Yao uses the quantum "block"s to describe quantum circuits, e.g the following code creates a 2-qubit circuit
julia> chain(2, put(1=>H), put(2=>X))
nqubits: 2 chain ├─ put on (1) │ └─ H └─ put on (2) └─ X
where H
gate is at 1st qubit, X
gate is at 2nd qubit. A more advanced example is the quantum Fourier transform circuit
julia> A(i, j) = control(i, j=>shift(2π/(1<<(i-j+1))))
A (generic function with 1 method)
julia> B(n, k) = chain(n, j==k ? put(k=>H) : A(j, k) for j in k:n)
B (generic function with 1 method)
julia> qft(n) = chain(B(n, k) for k in 1:n)
qft (generic function with 1 method)
julia> qft(3)
nqubits: 3 chain ├─ chain │ ├─ put on (1) │ │ └─ H │ ├─ control(2) │ │ └─ (1,) shift(1.5707963267948966) │ └─ control(3) │ └─ (1,) shift(0.7853981633974483) ├─ chain │ ├─ put on (2) │ │ └─ H │ └─ control(3) │ └─ (2,) shift(1.5707963267948966) └─ chain └─ put on (3) └─ H
Create Hamiltonian with Yao blocks
the quantum "block"s are expressions on quantum operators, thus, it can also be used to represent a Hamiltonian, e.g we can create a simple Ising Hamiltonian on 1D chain as following
julia> sum(kron(5, i=>Z, mod1(i+1, 5)=>Z) for i in 1:5)
nqubits: 5 + ├─ + │ ├─ + │ │ ├─ + │ │ │ ├─ kron │ │ │ │ ├─ 1=>Z │ │ │ │ └─ 2=>Z │ │ │ └─ kron │ │ │ ├─ 2=>Z │ │ │ └─ 3=>Z │ │ └─ kron │ │ ├─ 3=>Z │ │ └─ 4=>Z │ └─ kron │ ├─ 4=>Z │ └─ 5=>Z └─ kron ├─ 1=>Z └─ 5=>Z
Automatic differentiate a Yao block
Yao has its own automatic differentiation rule implemented, this allows one obtain gradients of a loss function by simply putting a '
mark behind expect
or fidelity
, e.g
julia> expect'(X, zero_state(1)=>Rx(0.2))
ArrayReg{2, ComplexF64, Array...} active qubits: 1/1 nlevel: 2 => Any[-0.0]
or for fiedlity
julia> fidelity'(zero_state(1)=>Rx(0.1), zero_state(1)=>Rx(0.2))
(ArrayReg{2, ComplexF64, Array...} active qubits: 1/1 nlevel: 2 => Any[0.02498958463533917], ArrayReg{2, ComplexF64, Array...} active qubits: 1/1 nlevel: 2 => Any[-0.02498958463533917])
Combine Yao with ChainRules/Zygote
Symbolic calculation with Yao block
Yao supports symbolic calculation of quantum circuit via SymEngine
. We can show
Plot quantum circuits
The YaoPlots in Yao's ecosystem provides plotting for quantum circuits and ZX diagrams.
using Yao.EasyBuild, YaoPlots
using Compose
# show a qft circuit
Compose.SVG(plot(qft_circuit(5)))