Skip to content

Commit 7d5c239

Browse files
committed
move QSVD to examples folder
1 parent 2d43931 commit 7d5c239

File tree

6 files changed

+76
-30
lines changed

6 files changed

+76
-30
lines changed

examples/PortZygote/gate_learning.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using YaoExtensions, Yao
22
using Test, Random
33
using Optim: LBFGS, optimize
4+
using Optim
45

56
# port the `Matrix` function to Yao's AD.
67
include("zygote_patch.jl")
@@ -28,4 +29,4 @@ end
2829
using Random
2930
Random.seed!(2)
3031
u = rand_unitary(4)
31-
c = learn_u4(u)
32+
c = learn_u4(u; niter=150)

src/QSVD.jl renamed to examples/QSVD/QSVD.jl

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
# Quantum SVD
2-
# Reference: https://arxiv.org/abs/1905.01353
3-
export QuantumSVD, circuit_qsvd, train_qsvd!, readout_qsvd
1+
using QuAlgorithmZoo, Yao,YaoExtensions
2+
using BitBasis: log2i
3+
using Test
4+
using Random, LinearAlgebra
45

56
"""
67
Quantum singular value decomposition algorithm.
@@ -14,12 +15,12 @@ Quantum singular value decomposition algorithm.
1415
"""
1516
function train_qsvd!(reg, circuit_a::AbstractBlock{Na}, circuit_b::AbstractBlock{Nb}, optimizer; Nc::Int=min(Na, Nb), maxiter::Int=100) where {Na, Nb}
1617
nbit = Na+Nb
17-
c = circuit_qsvd(circuit_a, circuit_b, Nc) |> autodiff(:QC) # construct a differentiable circuit for training
18+
c = circuit_qsvd(circuit_a, circuit_b, Nc)
1819

1920
obs = -mapreduce(i->put(nbit, i=>Z), +, (1:Na..., Na+Nc+1:Na+Nb...))
2021
params = parameters(c)
2122
for i = 1:maxiter
22-
grad = opdiff.(() -> copy(reg) |> c, collect_blocks(Diff, c), Ref(obs))
23+
grad = expect'(obs, reg => c).second
2324
QuAlgorithmZoo.update!(params, grad, optimizer)
2425
println("Iter $i, Loss = $(Na+expect(obs, copy(reg) |> c))")
2526
dispatch!(c, params)
@@ -54,8 +55,8 @@ kwargs includes
5455
* `optimizer`, default is `Adam(lr=0.1)`.
5556
"""
5657
function QuantumSVD(M::AbstractMatrix; Nc::Int=log2i(min(size(M)...)),
57-
circuit_a=variational_circuit(log2i(size(M, 1)), 5, pair_ring(log2i(size(M, 1)))),
58-
circuit_b=variational_circuit(log2i(size(M, 2)), 5, pair_ring(log2i(size(M, 2)))),
58+
circuit_a=variational_circuit(log2i(size(M, 1))),
59+
circuit_b=variational_circuit(log2i(size(M, 2))),
5960
maxiter=200, optimizer=Adam(lr=0.1))
6061

6162
dispatch!(circuit_a, :random)
@@ -64,3 +65,21 @@ function QuantumSVD(M::AbstractMatrix; Nc::Int=log2i(min(size(M)...)),
6465
train_qsvd!(reg, circuit_a, circuit_b, optimizer, Nc=Nc, maxiter=maxiter)
6566
readout_qsvd(reg, circuit_a, circuit_b, Nc)
6667
end
68+
69+
@testset "QSVD" begin
70+
Random.seed!(2)
71+
# define a matrix of size (2^Na, 2^Nb)
72+
Na = 2
73+
Nb = 2
74+
75+
# the exact result
76+
M = reshape(rand_state(Na+Nb).state, 1<<Na, 1<<Nb)
77+
U_exact, S_exact, V_exact = svd(M)
78+
79+
U, S, V = QuantumSVD(M; maxiter=400)
80+
81+
@test isapprox(U*Diagonal(S)*V', M, atol=1e-2)
82+
@test isapprox(abs.(S), S_exact, atol=1e-2)
83+
@test isapprox(U'*U_exact .|> abs2, I, atol=1e-2)
84+
@test isapprox(V'*V_exact .|> abs2, I, atol=1e-2)
85+
end

examples/QSVD/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Quantum SVD
2+
## Reference: https://arxiv.org/abs/1905.01353
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using Yao, YaoExtensions
2+
using YaoBlocks.Optimise: replace_block
3+
using YaoBlocks.ConstGate
4+
using YaoBlocks
5+
using Test
6+
using LinearAlgebra
7+
8+
"""
9+
TODO:
10+
* optimize to optimal value,
11+
* if this optimal value's loss is close to `θ = 0.0`, kill it.
12+
"""
13+
performance(params, gradient) = abs.(params .* gradient)
14+
15+
nbit = 5
16+
c = variational_circuit(nbit, 50)
17+
18+
dispatch!(c, :random)
19+
h = heisenberg(nbit)
20+
cc = replace_block(x->x isa RotationGate ? Bag(x) : x, c)
21+
22+
function train(h, c; kill_rate=0.1, kill_step=10, niter=100)
23+
bags = blockfilter(b->b isa Bag && isenabled(b), c)
24+
for i=1:niter
25+
regδ, paramsδ = expect'(h, zero_state(nbit) => c)
26+
dispatch!(-, c, 0.01 .* paramsδ)
27+
loss = expect(h, zero_state(nbit)=>c) |> real
28+
29+
Nk = round(Int, kill_rate*length(paramsδ))
30+
31+
if i%kill_step == 0 && kill_rate != 0
32+
ps = performance(parameters(c), paramsδ)
33+
cut = sort(ps)[Nk]
34+
disable_block!.(bags[ps .<= cut])
35+
bags = bags[ps .> cut]
36+
end
37+
@show i,nparameters(c), loss
38+
end
39+
end
40+
41+
42+
train(h, cc; kill_rate=0.01, niter=200)
43+
44+
cr = variational_circuit(nbit, 5)
45+
dispatch!(cr, :random)
46+
train(h, cr; kill_rate=0.0, niter=200)

src/QuAlgorithmZoo.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ include("Adam.jl")
88
include("PhaseEstimation.jl")
99
include("hamiltonian_solvers.jl")
1010
include("HadamardTest.jl")
11-
include("QSVD.jl")
1211
include("number_theory.jl")
1312

1413
@deprecate random_diff_circuit variational_circuit

test/QSVD.jl

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)