
Nous prรฉsentons Yao ( article ), un package Julia open source pour rรฉsoudre des problรจmes pratiques dans la recherche en informatique quantique. Le nom Yao vient du premier caractรจre chinois qui signifie unitรฉ (ๅนบ ๆญฃ).

Yao? , , , Julia. , :
Julia ( Zygote), , , . , , .. , !
(AD) : - . AD , โ , .
Yao - (AD), . . AD
n, d = 16, 100
circuit = dispatch!(variational_circuit(n, d),:random);
h = heisenberg(n)
@time for i in 1:100
_, grad = expect'(h, zero_state(n) => circuit)
dispatch!(-, circuit, 1e-1 * grad)
println("Step $i, energy = $(real.(expect(h, zero_state(n)=>circuit)))")
end
100- (4816 ), 16- . AD , Zygote, (). , . .
. . , , .
-, - ( , QBIR) . Yao , , . , , , CUDA CuYao , Julia CUDAnative. Yao SymEngine, .
-, Julia, Yao . Yao ( CUDA- CuYao) โ -, . .
, , . , , .
, , Yao .

.
?
, .
(, OpenQASM), (YaoIR), , ( ) !
- , , . , , !
Julia.
.
] dev https://github.com/QuantumBFS/QuAlgorithmZoo.jl.git
using Pkg
pkgs = ["Plots", "Flux", "Yao", "YaoExtensions", "StatsBase", "BitBasis", "FFTW", "SymEngine"]
for p in pkgs
Pkg.add(p)
end
using Yao, YaoExtensions, Plots, StatsBase
--

GHZ โ , ( ). , :
:
- โ . - , , , , . : , , โ , .
- . , . โ . , , , , . , , , , , , - .
- . . . โ ( ).
- Quirk โ
: , , . , IBM , , , .
, , , ! , - :

Yao:
circuit = chain(
4,
put(1=>X),
repeat(H, 2:4),
control(2, 1=>X),
control(4, 3=>X),
control(3, 1=>X),
control(4, 3=>X),
repeat(H, 1:4),
)
nqubits: 4
chain
โโ put on (1)
โ โโ X gate
โโ repeat on (2, 3, 4)
โ โโ H gate
โโ control(2)
โ โโ (1,) X gate
โโ control(4)
โ โโ (3,) X gate
โโ control(3)
โ โโ (1,) X gate
โโ control(4)
โ โโ (3,) X gate
โโ repeat on (1, 2, 3, 4)
โโ H gate
, : X, not-gate ( ), , cnot-.
(, )
results = ArrayReg(bit"0101") |> circuit |> r->measure(r, nshots=1000)
hist = fit(Histogram, Int.(results), 0:16)
bar(hist.edges[1] .- 0.5, hist.weights, legend=:none)

, - .
โ :

, .
(QFT) , :

B
(A
):
A(i, j) = control(i, j=>shift(2ฯ/(1<<(i-j+1))))
R4 = A(4, 1)
, , mat
. A
:
R4(5)
mat(R4(5))
32ร32 LinearAlgebra.Diagonal{Complex{Float64},Array{Complex{Float64},1}}:
1.0+0.0im โ
โ
โ
โฆ โ
โ
โ
1.0+0.0im โ
โ
โ
โ
โ
โ
1.0+0.0im โ
โ
โ
โ
โ
โ
1.0+0.0im โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โฆ โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โฆ โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โฎ โฑ โฎ
โ
โ
โ
โ
โฆ โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โฆ โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โฆ 1.0+0.0im โ
โ
โ
โ
โ
โ
0.92388+0.382683im
i- , i- B
. , n, k- .
, B
B(n, k) = chain(n, j==k ? put(k=>H) : A(j, k) for j in k:n)
qft(n) = chain(B(n, k) for k in 1:n)
qft(4)
nqubits: 4
chain
โโ chain
โ โโ put on (1)
โ โ โโ H
โ โโ control(2)
โ โ โโ (1,) shift(1.5707963267948966)
โ โโ control(3)
โ โ โโ (1,) shift(0.7853981633974483)
โ โโ control(4)
โ โโ (1,) shift(0.39269908169872414)
โโ chain
โ โโ put on (2)
โ โ โโ H
โ โโ control(3)
โ โ โโ (2,) shift(1.5707963267948966)
โ โโ control(4)
โ โโ (2,) shift(0.7853981633974483)
โโ chain
โ โโ put on (3)
โ โ โโ H
โ โโ control(4)
โ โโ (3,) shift(1.5707963267948966)
โโ chain
โโ put on (4)
โโ H
, A
B
, , , , .

-, PrimitiveBlock
, QFT
. , CompositeBlock
.
struct QFT{N} <: PrimitiveBlock{N} end
QFT(n::Int) = QFT{n}()
circuit2(::QFT{N}) where N = qft(N)
YaoBlocks.mat(::Type{T}, x::QFT) where T = mat(T, circuit2(x))
YaoBlocks.print_block(io::IO, x::QFT{N}) where N = print(io, "QFT($N)")
using FFTW, LinearAlgebra
function YaoBlocks.apply!(r::ArrayReg, x::QFT)
ฮฑ = sqrt(length(statevec(r)))
invorder!(r)
lmul!(ฮฑ, ifft!(statevec(r)))
return r
end
print_block
, QFT . , ,
r = rand_state(5)
r1 = r |> copy |> QFT(5)
r2 = r |> copy |> circuit2(QFT(5))
r1 โ r2

, , .

. , , ( ). L
. , ver
Val(:quantum)
Val(:classical)
, .
using Yao, BitBasis
using YaoExtensions: KMod, QFTCircuit
using QuAlgorithmZoo: NumberTheory
function shor(L::Int, ver=Val(:quantum); maxtry=100)
L%2 == 0 && return 2
res = NumberTheory.factor_a_power_b(L)
res !== nothing && return res[1]
for i in 1:maxtry
x = NumberTheory.rand_primeto(L)
r = get_order(ver, x, L; )
if r%2 == 0 && powermod(x, rรท2, L) != L-1
f1, f2 = gcd(powermod(x, rรท2, L)-1, L), gcd(powermod(x, rรท2, L)+1, L)
if f1!=1
return f1
elseif f2!=1
return f2
else
error("Algorithm Fail!")
end
end
end
end
, :
, L
, . . gcd(x, L) == 1
. .
x, . . r, mod(x^r, L) == 1
. r , x^(rรท2) , , . , L-1 (mod L)
.
5.2 ,
- gcd(x^(rรท2)-1, L)
gcd (x^(rรท2)+1, L)
(!=1) L. , powermod(x, rรท2, L)
-1, 1, r/2
.

โ . NumberTheory, .
- ,
- s / r. , , .
- nshot
, nbit
( ) ncbit
( ). nbit
, ncbit
""" ."""
estimate_ncbit(nbit::Int, ฯต::Real) = 2*nbit + 1 + ceil(Int,log2(2+1/2ฯต))
get_order(::Val{:classical}, x::Int, L::Int; kwargs...) = NumberTheory.find_order(x, L)
function get_order(::Val{:quantum}, x::Int, L::Int; nshots::Int=10,
nbit::Int=bit_length(L-1), ncbit::Int=estimate_ncbit(nbit, 0.25))
c = order_finding_circuit(x, L; nbit=nbit, ncbit=ncbit)
reg = join(product_state(nbit, 1), zero_state(ncbit))
res = measure(copy(reg) |> c; nshots=nshots)
for r in res
mask = bmask(1:ncbit)
k,i = r&mask, r>>ncbit
ฯ = bfloat(k)
ฯ == 0 && continue
order = NumberTheory.order_from_float(ฯ, x, L)
if order === nothing
continue
else
return order
end
end
return nothing
end
order_finding_circuit(x::Int, L::Int; nbit::Int=bit_length(L-1), ncbit::Int=estimate_ncbit(nbit, 0.25)) -> AbstractBlock
x
L
,
|1>โ|0>
"" .
function order_finding_circuit(x::Int, L::Int; nbit::Int, ncbit::Int)
N = nbit+ncbit
chain(N, repeat(N, H, 1:ncbit), KMod{N, ncbit}(x, L),
subroutine(N, qft_circuit(ncbit)', 1:ncbit))
end
KMod
mod(a^k*x, L)
.
k
โ , k
( ncbit
) , N-K
a
. , , , Yao. , , .- .
, - - :
@time shor(35, Val(:quantum))
@time shor(35, Val(:classical))

, . : , , .. , , .
, , .
