# 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 Yaojulia> ArrayReg(rand(ComplexF64, 2^3))ArrayReg{2, ComplexF64, Array...}
active qubits: 3/3
nlevel: 2julia> zero_state(5)ArrayReg{2, ComplexF64, Array...}
active qubits: 5/5
nlevel: 2julia> rand_state(5)ArrayReg{2, ComplexF64, Array...}
active qubits: 5/5
nlevel: 2julia> product_state(bit"10100")ArrayReg{2, ComplexF64, Array...}
active qubits: 5/5
nlevel: 2julia> 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 => [-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 => [0.02498958463533917], ArrayReg{2, ComplexF64, Array...}
active qubits: 1/1
nlevel: 2 => [-0.02498958463533917])

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