
Wir prรคsentieren Yao ( Artikel ), ein Open-Source-Paket von Julia zur Lรถsung praktischer Probleme in der Quantencomputerforschung. Der Name Yao stammt vom ersten chinesischen Schriftzeichen und bedeutet Einheitlichkeit (ๅนบ ๆญฃ).

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

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