From 1e65c2af383368f06412fa2d351a0b7acd898835 Mon Sep 17 00:00:00 2001 From: Roger-luo Date: Tue, 5 Jun 2018 16:18:42 +0800 Subject: [PATCH 01/10] add boost --- src/Boost/Boost.jl | 7 +++ src/Boost/Control.jl | 5 ++ src/Boost/Core.jl | 79 ++++++++++++++++++++++++++++++ src/Boost/binding.jl | 38 +++++++++++++++ src/Boost/gates.jl | 111 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 240 insertions(+) create mode 100644 src/Boost/Boost.jl create mode 100644 src/Boost/Control.jl create mode 100644 src/Boost/Core.jl create mode 100644 src/Boost/binding.jl create mode 100644 src/Boost/gates.jl diff --git a/src/Boost/Boost.jl b/src/Boost/Boost.jl new file mode 100644 index 000000000..05608eb95 --- /dev/null +++ b/src/Boost/Boost.jl @@ -0,0 +1,7 @@ +module Boost + +import ..Blocks + +include("Control.jl") + +end \ No newline at end of file diff --git a/src/Boost/Control.jl b/src/Boost/Control.jl new file mode 100644 index 000000000..e1e375811 --- /dev/null +++ b/src/Boost/Control.jl @@ -0,0 +1,5 @@ +import ..Blocks: ControlBlock, MatrixBlock + +function mat(ctrl::ControlBlock{BT, N, T}) where {N, T, BT <: MatrixBlock{1, T}} + controlled_U1(N, mat(ctrl.block), ctrl.ctrl_qubits, ctrl.addr) +end diff --git a/src/Boost/Core.jl b/src/Boost/Core.jl new file mode 100644 index 000000000..f67c679b7 --- /dev/null +++ b/src/Boost/Core.jl @@ -0,0 +1,79 @@ +# gates.jl +export general_controlled_gates, hilbertkron +export xgate, ygate, zgate +export cxgate, cygate, czgate +export controlled_U1 + +""" + general_controlled_gates(num_bit::Int, projectors::Vector{Tp}, cbits::Vector{Int}, gates::Vector{AbstractMatrix}, locs::Vector{Int}) -> AbstractMatrix + +Return general multi-controlled gates in hilbert space of `num_bit` qubits, + +* `projectors` are often chosen as `P0` and `P1` for inverse-Control and Control at specific position. +* `cbits` should have the same length as `projectors`, specifing the controling positions. +* `gates` are a list of controlled single qubit gates. +* `locs` should have the same length as `gates`, specifing the gates positions. +""" +function general_controlled_gates end + +""" + hilbertkron(num_bit::Int, gates::Vector{AbstractMatrix}, locs::Vector{Int}) -> AbstractMatrix + +Return general kronecher product form of gates in Hilbert space of `num_bit` qubits. + +* `gates` are a list of single qubit gates. +* `locs` should have the same length as `gates`, specifing the gates positions. +""" +function hilbertkron end + +""" + xgate(::Type{MT}, num_bit::Int, bits::Ints) -> PermMatrix + +X Gate on multiple bits. +""" +function xgate end + +""" + ygate(::Type{MT}, num_bit::Int, bits::Ints) -> PermMatrix + +Y Gate on multiple bits. +""" +function ygate end + +""" + zgate(::Type{MT}, num_bit::Int, bits::Ints) -> Diagonal + +Z Gate on multiple bits. +""" +function zgate end + +""" + cxgate(::Type{MT}, num_bit::Int, b1::Ints, b2::Ints) -> PermMatrix + +Single (Multiple) Controlled-X Gate on single (multiple) bits. +""" +function cxgate end + +""" + cygate(::Type{MT}, num_bit::Int, b1::Int, b2::Int) -> PermMatrix + +Single Controlled-Y Gate on single bit. +""" +function cygate end + +""" + czgate(::Type{MT}, num_bit::Int, b1::Int, b2::Int) -> Diagonal + +Single Controlled-Z Gate on single bit. +""" +function czgate end + +""" + controlled_U1(num_bit::Int, gate::AbstractMatrix, cbits::Vector{Int}, b2::Int) -> AbstractMatrix + +Return general multi-controlled single qubit `gate` in hilbert space of `num_bit` qubits. + +* `cbits` specify the controling positions. +* `b2` is the controlled position. +""" +function controlled_U1 end diff --git a/src/Boost/binding.jl b/src/Boost/binding.jl new file mode 100644 index 000000000..23be3d985 --- /dev/null +++ b/src/Boost/binding.jl @@ -0,0 +1,38 @@ +import Block: XGate, YGate, ZGate + +GATES = [:X, :Y, :Z] +for G in GATES + GATE = Symbol(G, :Gate) + @eval mat(g::$GATE{MT}) where MT = $(Symbol(:PAULI_,G)) +end + +#################### Single Control Block ###################### +struct SingleControlBlock{GT<:MatrixBlock, N, MT} <: CompositeBlock{N, MT} + target::GT + cbit::Int + ibit::Int +end + +blocks(cb::SingleControlBlock) = [rb.target] + +for (G, MATFUNC) in zip(GATES, [:cxgate, :cygate, :czgate]) + GATE = Symbol(G, :Gate) + @eval function mat(cb::SingleControlBlock{$GATE, N, MT}) where {N, MT} + $MATFUNC(MT, N, cb.cbit, cb.ibit) + end +end + +#################### Repeated Block ###################### +mutable struct RepeatedBlock{GT<:MatrixBlock, N, MT} <: CompositeBlock{N, MT} + block::GT + bits::Vector{Int} +end + +for (G, MATFUNC) in zip(GATES, [:xgate, :ygate, :zgate]) + GGate = Symbol(G, :Gate) + @eval function mat(cb::RepeatedBlock{$GGate, N, MT}) where {N, MT} + $MATFUNC(MT, N, cb.bits) + end +end + +blocks(rb::RepeatedBlock) = [rb.block] diff --git a/src/Boost/gates.jl b/src/Boost/gates.jl new file mode 100644 index 000000000..ea6a7edb6 --- /dev/null +++ b/src/Boost/gates.jl @@ -0,0 +1,111 @@ +####################### Gate Utilities ###################### + +###################### X, Y, Z Gates ###################### +function xgate(::Type{MT}, num_bit::Int, bits::Ints) where MT<:Number + mask = bmask(bits...) + order = map(b->flip(b, mask) + 1, basis(num_bit)) + PermMatrix(order, ones(MT, 1<count_ones(b&mask)%2==0 ? one(MT) : -one(MT), basis(num_bit)) + Diagonal(vals) +end + +####################### Controlled Gates ####################### +general_controlled_gates(num_bit::Int, projectors::Vector{Tp}, cbits::Vector{Int}, gates::Vector{Tg}, locs::Vector{Int}) where {Tg<:AbstractMatrix, Tp<:AbstractMatrix} = I(1<testall(i, mask) ? flip(i, mask2)+1 : i+1, basis(num_bit)) + PermMatrix(order, ones(MT, 1<(testall(i, mask) ? (testany(i, b2) ? b : a) : T(1))::T, basis(num_bit)) + Diagonal(vals) +end + +function controlled_U1(num_bit::Int, gate::StridedMatrix, b1::Vector{Int}, b2::Int) + general_controlled_gates(2, [P1], b1, [gate], [b2]) +end + +# arbituary control PermMatrix gate: SparseMatrixCSC +# TODO: to interface +#toffoligate(num_bit::Int, b1::Int, b2::Int, b3::Int) = controlled_U1(num_bit, PAULI_X, [b1, b2], b3) From d3815dc3fc52644522603bcdff9a296ca57b6ce0 Mon Sep 17 00:00:00 2001 From: Roger-luo Date: Tue, 5 Jun 2018 16:55:47 +0800 Subject: [PATCH 02/10] add boost --- src/Blocks/Composite.jl | 1 + src/Blocks/Repeated.jl | 42 ++++++++++++++++++++++++ src/Boost/Boost.jl | 8 ++++- src/Boost/Control.jl | 2 -- src/Boost/Repeated.jl | 8 +++++ src/Boost/gates.jl | 4 +-- src/Yao.jl | 2 ++ test/Blocks/Control.jl | 4 +-- test/Boost/Binding.jl | 24 ++++++++++++++ test/Boost/Gates.jl | 60 +++++++++++++++++++++++++++++++++++ test/Interfaces/Interfaces.jl | 4 +-- 11 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 src/Blocks/Repeated.jl create mode 100644 src/Boost/Repeated.jl create mode 100644 test/Boost/Binding.jl create mode 100644 test/Boost/Gates.jl diff --git a/src/Blocks/Composite.jl b/src/Blocks/Composite.jl index 27bed66af..988e8c88f 100644 --- a/src/Blocks/Composite.jl +++ b/src/Blocks/Composite.jl @@ -94,3 +94,4 @@ include("ChainBlock.jl") include("KronBlock.jl") include("Control.jl") include("Roller.jl") +include("Repeated.jl") diff --git a/src/Blocks/Repeated.jl b/src/Blocks/Repeated.jl new file mode 100644 index 000000000..9d70b7a7b --- /dev/null +++ b/src/Blocks/Repeated.jl @@ -0,0 +1,42 @@ +export RepeatedBlock + +mutable struct RepeatedBlock{GT<:MatrixBlock, N, MT} <: CompositeBlock{N, MT} + block::GT + lines::Vector{Int} + + function RepeatedBlock{N, T}(block::GT) where {N, T, GT <: MatrixBlock} + new{GT, N, T}(block, Vector{Int}(1:N)) + end + + function RepeatedBlock{N, T}(block::GT, lines::Vector{Int}) where {N, T, GT <: MatrixBlock} + new{GT, N, T}(block, lines) + end +end + +start(c::RepeatedBlock) = start(c.lines) + +function next(c::RepeatedBlock, st) + line, st = next(c.lines, st) + (line, c.block), st +end + +done(c::RepeatedBlock, st) = done(c.lines, st) +length(c::RepeatedBlock) = length(c.lines) +eachindex(c::RepeatedBlock) = eachindex(c.lines) +getindex(c::RepeatedBlock, index) = c.block +blocks(rb::RepeatedBlock) = [rb.block] + +copy(x::RepeatedBlock) = RepeatedBlock + +dispatch!(f::Function, rb::RepeatedBlock, params...) = dispatch!(f, rb.block, params...) + +function hash(rb::RepeatedBlock, h::UInt) + hashkey = hash(objectid(rb), h) + hashkey = hash(rb.block, hashkey) + hashkey = hash(rb.lines, hashkey) + hashkey +end + +function ==(lhs::RepeatedBlock{BT, N, T}, rhs::RepeatedBlock{BT, N, T}) where {BT, N, T} + (lhs.block == rhs.block) && (lhs.lines == rhs.lines) +end diff --git a/src/Boost/Boost.jl b/src/Boost/Boost.jl index 05608eb95..8d7b628c9 100644 --- a/src/Boost/Boost.jl +++ b/src/Boost/Boost.jl @@ -1,7 +1,13 @@ module Boost -import ..Blocks +using ..Blocks +using ..Intrinsics +using ..LuxurySparse +import ..Blocks: mat + +include("gates.jl") include("Control.jl") +include("Repeated.jl") end \ No newline at end of file diff --git a/src/Boost/Control.jl b/src/Boost/Control.jl index e1e375811..52a7f4feb 100644 --- a/src/Boost/Control.jl +++ b/src/Boost/Control.jl @@ -1,5 +1,3 @@ -import ..Blocks: ControlBlock, MatrixBlock - function mat(ctrl::ControlBlock{BT, N, T}) where {N, T, BT <: MatrixBlock{1, T}} controlled_U1(N, mat(ctrl.block), ctrl.ctrl_qubits, ctrl.addr) end diff --git a/src/Boost/Repeated.jl b/src/Boost/Repeated.jl new file mode 100644 index 000000000..31649b196 --- /dev/null +++ b/src/Boost/Repeated.jl @@ -0,0 +1,8 @@ +GATES = [:X, :Y, :Z] + +for (G, MATFUNC) in zip(GATES, [:xgate, :ygate, :zgate]) + GGate = Symbol(G, :Gate) + @eval function mat(rb::RepeatedBlock{GT, N, MT}) where {GT <: $GGate, N, MT} + $MATFUNC(MT, N, rb.lines) + end +end diff --git a/src/Boost/gates.jl b/src/Boost/gates.jl index ea6a7edb6..cc4606530 100644 --- a/src/Boost/gates.jl +++ b/src/Boost/gates.jl @@ -27,7 +27,7 @@ function zgate(::Type{MT}, num_bit::Int, bits::Ints) where MT<:Number end ####################### Controlled Gates ####################### -general_controlled_gates(num_bit::Int, projectors::Vector{Tp}, cbits::Vector{Int}, gates::Vector{Tg}, locs::Vector{Int}) where {Tg<:AbstractMatrix, Tp<:AbstractMatrix} = I(1<c for g in gates] +for gate, psii in zip(cgates, psi[9:15]) + @test $gate(num_bit, 6, 4)*psi0 == psii +end +cnccgates = [g|>c|>nc|>c for g in gates] +for gate, psii in zip(cnccgates, psi[16:22]) + @test $gate(num_bit, 6, 2,4,5)*psi0 == psii +end +=# diff --git a/test/Interfaces/Interfaces.jl b/test/Interfaces/Interfaces.jl index 28f8a8d99..7aa3fde77 100644 --- a/test/Interfaces/Interfaces.jl +++ b/test/Interfaces/Interfaces.jl @@ -27,8 +27,8 @@ end end @testset "control" begin - @test control(3, [1, 2], X, 3) isa ControlBlock - @test control(5, 1:2, X, 3) isa ControlBlock + @test control(3, [1, 2], 3=>X) isa ControlBlock + @test control(5, 1:2, 3=>X) isa ControlBlock @test (1=>X) |> control(8, i for i in [2, 3, 6, 7]) isa ControlBlock @test ((1=>X) |> control(i for i in [2, 3, 6, 7]))(8) isa ControlBlock From 5fceb03837c45d044ad9675821c830b1ea54bcb3 Mon Sep 17 00:00:00 2001 From: Roger-luo Date: Tue, 5 Jun 2018 17:02:13 +0800 Subject: [PATCH 03/10] add applies & gates --- src/Boost/applys.jl | 271 ++++++++++++++++++++++++++++++++++++++++++++ src/Boost/gates.jl | 6 +- 2 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 src/Boost/applys.jl diff --git a/src/Boost/applys.jl b/src/Boost/applys.jl new file mode 100644 index 000000000..dba8a1d2e --- /dev/null +++ b/src/Boost/applys.jl @@ -0,0 +1,271 @@ +function xapply!(state::Matrix{T}, bits::Ints) where T + if length(bits) == 0 + return state + end + mask = bmask(bits...) + M, N = size(state) + do_mask = bmask(bits[1]) + @simd for b = basis(state) + local temp::T + local i_::Int + if testany(b, do_mask) + i = b+1 + i_ = flip(b, mask) + 1 + @inbounds for c = 1:N + temp = state[i, c] + state[i, c] = state[i_, c] + state[i_, c] = temp + end + end + end + state +end + +function xapply!(state::Vector{T}, bits::Ints) where T + if length(bits) == 0 + return state + end + mask = bmask(bits...) + do_mask = bmask(bits[1]) + @simd for b = basis(state) + local temp::T + local i_::Int + @inbounds if testany(b, do_mask) + i = b+1 + i_ = flip(b, mask) + 1 + temp = state[i] + state[i] = state[i_] + state[i_] = temp + end + end + state +end + +function yapply!(state::Vector{T}, bits::Ints) where T + if length(bits) == 0 + return state + end + mask = bmask(bits...) + do_mask = bmask(bits[1]) + factor = T(im^length(bits)) + + @inbounds @simd for b = basis(state) + local temp::T + local i_::Int + if testany(b, do_mask) + i = b+1 + i_ = flip(b, mask) + 1 + temp = state[i] + if count_ones(b&mask)%2 == 1 + state[i] = state[i_]*factor + state[i_] = -temp*factor + else + state[i] = -state[i_]*factor + state[i_] = temp*factor + end + end + end + state +end + +function yapply!(state::Matrix{T}, bits::Ints) where T + if length(bits) == 0 + return state + end + mask = bmask(bits...) + do_mask = bmask(bits[1]) + factor = T(im^length(bits)) + M, N = size(state) + + @simd for b = basis(state) + local temp::T + local factor_::T + local i_::Int + if testany(b, do_mask) + i = b+1 + i_ = flip(b, mask) + 1 + if count_ones(b&mask)%2 == 1 + factor_ = factor + else + factor_ = -factor + end + @simd for c = 1:N + temp = state[i, c] + @inbounds state[i, c] = state[i_, c]*factor_ + @inbounds state[i_, c] = -temp*factor_ + end + end + end + state +end + +function zapply!(state::Vector{T}, bits::Ints) where T + mask = bmask(bits...) + @simd for b in basis(state) + if count_ones(b&mask)%2==1 + @inbounds state[b+1] *= -1 + end + end + state +end +function zapply!(state::Matrix{T}, bits::Ints) where T + mask = bmask(bits...) + M, N = size(state) + for b in basis(state) + if count_ones(b&mask)%2==1 + @simd for j = 1:N + @inbounds state[b+1, j] *= -1 + end + end + end + state +end + +function zapply!(state::Vector{T}, bit::Int) where T + mask = bmask(bit) + @simd for b in basis(state) + if testany(b, mask) + @inbounds state[b+1] *= -1 + end + end + state +end +function zapply!(state::Matrix{T}, bit::Int) where T + mask = bmask(bit) + M, N = size(state) + for b in basis(state) + if testany(b, mask) + @simd for j = 1:N + @inbounds state[b+1, j] *= -1 + end + end + end + state +end + +function cxapply!(state::Matrix{T}, b1::Ints, b2::Ints) where T + do_mask = bmask(b1..., b2[1]) + mask2 = bmask(b2...) + M, N = size(state) + + @simd for b = basis(state) + local temp::T + local i_::Int + if testall(b, do_mask) + i = b+1 + i_ = flip(b, mask2) + 1 + @inbounds for c = 1:N + temp = state[i, c] + state[i, c] = state[i_, c] + state[i_, c] = temp + end + end + end + state +end + +function cxapply!(state::Vector{T}, b1::Ints, b2::Ints) where T + do_mask = bmask(b1..., b2[1]) + mask2 = bmask(b2...) + + @simd for b = basis(state) + local temp::T + local i_::Int + @inbounds if testall(b, do_mask) + i = b+1 + i_ = flip(b, mask2) + 1 + temp = state[i] + state[i] = state[i_] + state[i_] = temp + end + end + state +end + +function czapply!(state::Vector{T}, b1::Ints, b2::Ints) where T + mask2 = bmask(b2) + step = 1<<(b1-1) + step_2 = 1< Date: Tue, 5 Jun 2018 17:18:54 +0800 Subject: [PATCH 04/10] add applys --- src/Boost/Boost.jl | 5 ++++- src/Boost/Repeated.jl | 37 +++++++++++++++++++++++++++++++++++++ test/Blocks/Control.jl | 11 ++++++----- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/Boost/Boost.jl b/src/Boost/Boost.jl index 8d7b628c9..0ed0d7ee4 100644 --- a/src/Boost/Boost.jl +++ b/src/Boost/Boost.jl @@ -1,12 +1,15 @@ module Boost +using ..Registers using ..Blocks using ..Intrinsics using ..LuxurySparse -import ..Blocks: mat +import ..Blocks: mat, apply! include("gates.jl") +include("applys.jl") + include("Control.jl") include("Repeated.jl") diff --git a/src/Boost/Repeated.jl b/src/Boost/Repeated.jl index 31649b196..f9b8afcbc 100644 --- a/src/Boost/Repeated.jl +++ b/src/Boost/Repeated.jl @@ -6,3 +6,40 @@ for (G, MATFUNC) in zip(GATES, [:xgate, :ygate, :zgate]) $MATFUNC(MT, N, rb.lines) end end + +function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:XGate}) + if nremains(r) == 0 + xapply!(vec(state(r)), rb.lines) + else + xapply!(state(r), rb.lines) + end +end + +function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:YGate}) + if nremains(r) == 0 + yapply!(vec(state(r)), rb.lines) + else + yapply!(state(r), rb.lines) + end +end + +function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:ZGate}) + if nremains(r) == 0 + zapply!(vec(state(r)), rb.lines) + else + zapply!(state(r), rb.lines) + end +end + + +function apply!(r::AbstractRegister, rb::RepeatedBlock{<:XGate}) + xapply!(state(r), rb.lines) +end + +function apply!(r::AbstractRegister, rb::RepeatedBlock{<:YGate}) + yapply!(state(r), rb.lines) +end + +function apply!(r::AbstractRegister, rb::RepeatedBlock{<:ZGate}) + zapply!(state(r), rb.lines) +end diff --git a/test/Blocks/Control.jl b/test/Blocks/Control.jl index af8c215ac..074ed02b1 100644 --- a/test/Blocks/Control.jl +++ b/test/Blocks/Control.jl @@ -89,11 +89,12 @@ end @test mat(g) == op end -@testset "inverse control" begin - g = ControlBlock{2}([-1, ], X, 2) +# FIXME: +# @testset "inverse control" begin +# g = ControlBlock{2}([-1, ], X, 2) - op = U ⊗ mat(P0) + IMatrix(U) ⊗ mat(P1) - @test mat(g) ≈ op -end +# op = U ⊗ mat(P0) + IMatrix(U) ⊗ mat(P1) +# @test mat(g) ≈ op +# end end # control matrix form From fbbc461e29a89a844026345e13f243d93e982fc7 Mon Sep 17 00:00:00 2001 From: Roger-luo Date: Tue, 5 Jun 2018 18:04:31 +0800 Subject: [PATCH 05/10] add tests --- src/Blocks/Repeated.jl | 8 ++--- src/Boost/Boost.jl | 6 ++++ src/Boost/Core.jl | 79 ------------------------------------------ src/Boost/Repeated.jl | 15 ++++---- src/Boost/binding.jl | 38 -------------------- src/Boost/gates.jl | 65 +++++++++++++++++++++++++++++++--- src/Intrinsics/Math.jl | 8 +++-- test/Boost/Binding.jl | 30 ++++++++-------- test/Boost/Gates.jl | 29 +++++++++------- 9 files changed, 116 insertions(+), 162 deletions(-) delete mode 100644 src/Boost/Core.jl delete mode 100644 src/Boost/binding.jl diff --git a/src/Blocks/Repeated.jl b/src/Blocks/Repeated.jl index 9d70b7a7b..b109f8e1a 100644 --- a/src/Blocks/Repeated.jl +++ b/src/Blocks/Repeated.jl @@ -1,15 +1,15 @@ export RepeatedBlock -mutable struct RepeatedBlock{GT<:MatrixBlock, N, MT} <: CompositeBlock{N, MT} +mutable struct RepeatedBlock{N, T, GT<:MatrixBlock} <: CompositeBlock{N, T} block::GT lines::Vector{Int} function RepeatedBlock{N, T}(block::GT) where {N, T, GT <: MatrixBlock} - new{GT, N, T}(block, Vector{Int}(1:N)) + new{N, T, GT}(block, Vector{Int}(1:N)) end function RepeatedBlock{N, T}(block::GT, lines::Vector{Int}) where {N, T, GT <: MatrixBlock} - new{GT, N, T}(block, lines) + new{N, T, GT}(block, lines) end end @@ -37,6 +37,6 @@ function hash(rb::RepeatedBlock, h::UInt) hashkey end -function ==(lhs::RepeatedBlock{BT, N, T}, rhs::RepeatedBlock{BT, N, T}) where {BT, N, T} +function ==(lhs::RepeatedBlock{N, T, GT}, rhs::RepeatedBlock{N, T, GT}) where {N, T, GT} (lhs.block == rhs.block) && (lhs.lines == rhs.lines) end diff --git a/src/Boost/Boost.jl b/src/Boost/Boost.jl index 0ed0d7ee4..083ab0889 100644 --- a/src/Boost/Boost.jl +++ b/src/Boost/Boost.jl @@ -7,6 +7,12 @@ using ..LuxurySparse import ..Blocks: mat, apply! +export general_controlled_gates +export xgate, ygate, zgate +export cxgate, cygate, czgate +export controlled_U1 + + include("gates.jl") include("applys.jl") diff --git a/src/Boost/Core.jl b/src/Boost/Core.jl deleted file mode 100644 index f67c679b7..000000000 --- a/src/Boost/Core.jl +++ /dev/null @@ -1,79 +0,0 @@ -# gates.jl -export general_controlled_gates, hilbertkron -export xgate, ygate, zgate -export cxgate, cygate, czgate -export controlled_U1 - -""" - general_controlled_gates(num_bit::Int, projectors::Vector{Tp}, cbits::Vector{Int}, gates::Vector{AbstractMatrix}, locs::Vector{Int}) -> AbstractMatrix - -Return general multi-controlled gates in hilbert space of `num_bit` qubits, - -* `projectors` are often chosen as `P0` and `P1` for inverse-Control and Control at specific position. -* `cbits` should have the same length as `projectors`, specifing the controling positions. -* `gates` are a list of controlled single qubit gates. -* `locs` should have the same length as `gates`, specifing the gates positions. -""" -function general_controlled_gates end - -""" - hilbertkron(num_bit::Int, gates::Vector{AbstractMatrix}, locs::Vector{Int}) -> AbstractMatrix - -Return general kronecher product form of gates in Hilbert space of `num_bit` qubits. - -* `gates` are a list of single qubit gates. -* `locs` should have the same length as `gates`, specifing the gates positions. -""" -function hilbertkron end - -""" - xgate(::Type{MT}, num_bit::Int, bits::Ints) -> PermMatrix - -X Gate on multiple bits. -""" -function xgate end - -""" - ygate(::Type{MT}, num_bit::Int, bits::Ints) -> PermMatrix - -Y Gate on multiple bits. -""" -function ygate end - -""" - zgate(::Type{MT}, num_bit::Int, bits::Ints) -> Diagonal - -Z Gate on multiple bits. -""" -function zgate end - -""" - cxgate(::Type{MT}, num_bit::Int, b1::Ints, b2::Ints) -> PermMatrix - -Single (Multiple) Controlled-X Gate on single (multiple) bits. -""" -function cxgate end - -""" - cygate(::Type{MT}, num_bit::Int, b1::Int, b2::Int) -> PermMatrix - -Single Controlled-Y Gate on single bit. -""" -function cygate end - -""" - czgate(::Type{MT}, num_bit::Int, b1::Int, b2::Int) -> Diagonal - -Single Controlled-Z Gate on single bit. -""" -function czgate end - -""" - controlled_U1(num_bit::Int, gate::AbstractMatrix, cbits::Vector{Int}, b2::Int) -> AbstractMatrix - -Return general multi-controlled single qubit `gate` in hilbert space of `num_bit` qubits. - -* `cbits` specify the controling positions. -* `b2` is the controlled position. -""" -function controlled_U1 end diff --git a/src/Boost/Repeated.jl b/src/Boost/Repeated.jl index f9b8afcbc..c3c34b7fd 100644 --- a/src/Boost/Repeated.jl +++ b/src/Boost/Repeated.jl @@ -2,12 +2,12 @@ GATES = [:X, :Y, :Z] for (G, MATFUNC) in zip(GATES, [:xgate, :ygate, :zgate]) GGate = Symbol(G, :Gate) - @eval function mat(rb::RepeatedBlock{GT, N, MT}) where {GT <: $GGate, N, MT} + @eval function mat(rb::RepeatedBlock{N, MT, GT}) where {N, MT, GT <: $GGate} $MATFUNC(MT, N, rb.lines) end end -function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:XGate}) +function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{N, T, <:XGate}) where {N, T} if nremains(r) == 0 xapply!(vec(state(r)), rb.lines) else @@ -15,7 +15,7 @@ function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:XGate}) end end -function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:YGate}) +function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{N, T, <:YGate}) where {N, T} if nremains(r) == 0 yapply!(vec(state(r)), rb.lines) else @@ -23,7 +23,7 @@ function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:YGate}) end end -function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:ZGate}) +function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{N, T, <:ZGate}) where {N, T} if nremains(r) == 0 zapply!(vec(state(r)), rb.lines) else @@ -31,15 +31,14 @@ function apply!(r::AbstractRegister{1}, rb::RepeatedBlock{<:ZGate}) end end - -function apply!(r::AbstractRegister, rb::RepeatedBlock{<:XGate}) +function apply!(r::AbstractRegister, rb::RepeatedBlock{N, T, <:XGate}) where {N, T} xapply!(state(r), rb.lines) end -function apply!(r::AbstractRegister, rb::RepeatedBlock{<:YGate}) +function apply!(r::AbstractRegister, rb::RepeatedBlock{N, T, <:YGate}) where {N, T} yapply!(state(r), rb.lines) end -function apply!(r::AbstractRegister, rb::RepeatedBlock{<:ZGate}) +function apply!(r::AbstractRegister, rb::RepeatedBlock{N, T, <:ZGate}) where {N, T} zapply!(state(r), rb.lines) end diff --git a/src/Boost/binding.jl b/src/Boost/binding.jl deleted file mode 100644 index 23be3d985..000000000 --- a/src/Boost/binding.jl +++ /dev/null @@ -1,38 +0,0 @@ -import Block: XGate, YGate, ZGate - -GATES = [:X, :Y, :Z] -for G in GATES - GATE = Symbol(G, :Gate) - @eval mat(g::$GATE{MT}) where MT = $(Symbol(:PAULI_,G)) -end - -#################### Single Control Block ###################### -struct SingleControlBlock{GT<:MatrixBlock, N, MT} <: CompositeBlock{N, MT} - target::GT - cbit::Int - ibit::Int -end - -blocks(cb::SingleControlBlock) = [rb.target] - -for (G, MATFUNC) in zip(GATES, [:cxgate, :cygate, :czgate]) - GATE = Symbol(G, :Gate) - @eval function mat(cb::SingleControlBlock{$GATE, N, MT}) where {N, MT} - $MATFUNC(MT, N, cb.cbit, cb.ibit) - end -end - -#################### Repeated Block ###################### -mutable struct RepeatedBlock{GT<:MatrixBlock, N, MT} <: CompositeBlock{N, MT} - block::GT - bits::Vector{Int} -end - -for (G, MATFUNC) in zip(GATES, [:xgate, :ygate, :zgate]) - GGate = Symbol(G, :Gate) - @eval function mat(cb::RepeatedBlock{$GGate, N, MT}) where {N, MT} - $MATFUNC(MT, N, cb.bits) - end -end - -blocks(rb::RepeatedBlock) = [rb.block] diff --git a/src/Boost/gates.jl b/src/Boost/gates.jl index 29a762afe..1b53892b4 100644 --- a/src/Boost/gates.jl +++ b/src/Boost/gates.jl @@ -1,12 +1,22 @@ ####################### Gate Utilities ###################### ###################### X, Y, Z Gates ###################### +""" + xgate(::Type{MT}, num_bit::Int, bits::Ints) -> PermMatrix + +X Gate on multiple bits. +""" function xgate(::Type{MT}, num_bit::Int, bits::Ints) where MT<:Number mask = bmask(bits...) order = map(b->flip(b, mask) + 1, basis(num_bit)) PermMatrix(order, ones(MT, 1< PermMatrix + +Y Gate on multiple bits. +""" function ygate(::Type{MT}, num_bit::Int, bits::Ints) where MT<:Complex mask = bmask(bits...) order = Vector{Int}(1< Diagonal + +Z Gate on multiple bits. +""" function zgate(::Type{MT}, num_bit::Int, bits::Ints) where MT<:Number mask = bmask(bits...) vals = map(b->count_ones(b&mask)%2==0 ? one(MT) : -one(MT), basis(num_bit)) @@ -27,9 +42,33 @@ function zgate(::Type{MT}, num_bit::Int, bits::Ints) where MT<:Number end ####################### Controlled Gates ####################### -general_controlled_gates(num_bit::Int, projectors::Vector{Tp}, cbits::Vector{Int}, gates::Vector{Tg}, locs::Vector{Int}) where {Tg<:AbstractMatrix, Tp<:AbstractMatrix} = I(1< AbstractMatrix + +Return general multi-controlled gates in hilbert space of `num_bit` qubits, + +* `projectors` are often chosen as `P0` and `P1` for inverse-Control and Control at specific position. +* `cbits` should have the same length as `projectors`, specifing the controling positions. +* `gates` are a list of controlled single qubit gates. +* `locs` should have the same length as `gates`, specifing the gates positions. +""" +function general_controlled_gates( + n::Int, + projectors::Vector{<:AbstractMatrix}, + cbits::Vector{Int}, + gates::Vector{<:AbstractMatrix}, + locs::Vector{Int} +) + IMatrix(1< PermMatrix + +Single (Multiple) Controlled-X Gate on single (multiple) bits. +""" function cxgate(::Type{MT}, num_bit::Int, b1::Ints, b2::Ints) where MT<:Number mask = bmask(b1) mask2 = bmask(b2) @@ -37,6 +76,11 @@ function cxgate(::Type{MT}, num_bit::Int, b1::Ints, b2::Ints) where MT<:Number PermMatrix(order, ones(MT, 1< PermMatrix + +Single Controlled-Y Gate on single bit. +""" function cygate(::Type{MT}, num_bit::Int, b1::Int, b2::Int) where MT<:Complex mask2 = bmask(b2) order = collect(1:1< Diagonal + +Single Controlled-Z Gate on single bit. +""" function czgate(::Type{MT}, num_bit::Int, b1::Int, b2::Int) where MT<:Number mask2 = bmask(b2) vals = ones(MT, 1< AbstractMatrix + +Return general multi-controlled single qubit `gate` in hilbert space of `num_bit` qubits. + +* `cbits` specify the controling positions. +* `b2` is the controlled position. +""" +function controlled_U1 end + # general multi-control single-gate function controlled_U1(num_bit::Int, gate::PermMatrix{T}, cbits::Vector{Int}, b2::Int) where {T} @@ -109,5 +168,3 @@ end # arbituary control PermMatrix gate: SparseMatrixCSC # TODO: to interface #toffoligate(num_bit::Int, b1::Int, b2::Int, b3::Int) = controlled_U1(num_bit, PAULI_X, [b1, b2], b3) - - diff --git a/src/Intrinsics/Math.jl b/src/Intrinsics/Math.jl index 31cb10a56..ad54cd7a2 100644 --- a/src/Intrinsics/Math.jl +++ b/src/Intrinsics/Math.jl @@ -78,10 +78,14 @@ end ex end + """ - hilbertkron(nbits, ops, locs) + hilbertkron(num_bit::Int, gates::Vector{AbstractMatrix}, locs::Vector{Int}) -> AbstractMatrix + +Return general kronecher product form of gates in Hilbert space of `num_bit` qubits. -kronecker given operators `ops` in hilbert space of size `nbits` at location `locs`. +* `gates` are a list of single qubit gates. +* `locs` should have the same length as `gates`, specifing the gates positions. """ function hilbertkron(num_bit::Int, ops::Vector{T}, locs::Vector{Int}) where T<:AbstractMatrix locs = num_bit - locs + 1 diff --git a/test/Boost/Binding.jl b/test/Boost/Binding.jl index 20e126688..9246dee9f 100644 --- a/test/Boost/Binding.jl +++ b/test/Boost/Binding.jl @@ -1,24 +1,24 @@ using Compat.Test using Yao -import Yao.Intrinsics: SingleControlBlock, RepeatedBlock -import Yao.Const +using Yao.Intrinsics +using Yao.Blocks +using Yao.Boost -xg = XGate{ComplexF64}() +# @testset "Single Control" begin +# cb = SingleControlBlock{XGate, 2, ComplexF64}(X, 2,1) +# @test mat(cb) == Const.Sparse.CNOT +# end -@testset "Single Control" begin - cb = SingleControlBlock{XGate, 2, ComplexF64}(xg, 2,1) - @test mat(cb) == Const.Sparse.CNOT -end - -@testset "Single Control" begin +@testset "Repeated" begin for G in [:X, :Y, :Z] - MAT = Symbol(:(Const.Sparse.PAULI_), G) - rb = RepeatedBlock{$(Symbol(G, :Gate)), 2, Complex128}(xg, [1,2]) - @test mat(rb) == kron($MAT, $MAT) + @eval begin + rb = RepeatedBlock{2, Complex128}($G, [1,2]) + @test mat(rb) ≈ kron(mat($G), mat($G)) + end end end -@testset "Single Control" begin - mcb = ControlBlock{XGate, 3, Complex128}(xg, [3, 2], 1) - @test mat(mcb) == Const.Sparse.Toffoli +@testset "Multiple Control" begin + mcb = ControlBlock{3, Complex128}(X, [3, 2], 1) + @test mat(mcb) ≈ mat(Toffoli) end diff --git a/test/Boost/Gates.jl b/test/Boost/Gates.jl index ba0cbc707..cc5a3b676 100644 --- a/test/Boost/Gates.jl +++ b/test/Boost/Gates.jl @@ -1,32 +1,37 @@ using Compat.Test using Yao -import Yao: hilbertkron, general_controlled_gates, czgate, cygate, czgate, controlled_U1, xgate, ygate, zgate +using Yao.Blocks +using Yao.LuxurySparse +using Yao.Intrinsics +using Yao.Boost + +⊗ = kron @testset "gate utils" begin - @test hilbertkron(4, [PAULI_X, PAULI_Y], [3,2]) == II(2) ⊗ PAULI_X ⊗ PAULI_Y ⊗ II(2) - @test general_controlled_gates(2, [P1], [2], [PAULI_X], [1]) == CNOT_MAT + @test hilbertkron(4, [mat(X), mat(Y)], [3,2]) == IMatrix(2) ⊗ mat(X) ⊗ mat(Y) ⊗ IMatrix(2) + @test general_controlled_gates(2, [mat(P1)], [2], [mat(X)], [1]) == mat(CNOT) end @testset "controlled gates" begin - @test general_controlled_gates(2, [P1], [2], [PAULI_X], [1]) == CNOT_MAT - @test controlled_U1(3, PAULI_Z, [3], 2) == czgate(Complex128, 3, 3, 2) + @test general_controlled_gates(2, [mat(P1)], [2], [mat(X)], [1]) == mat(CNOT) + @test controlled_U1(3, mat(Z), [3], 2) == czgate(Complex128, 3, 3, 2) @test czgate(Complex128, 2, 1, 2) == [1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 -1] - @test general_controlled_gates(12, [P1], [7], [PAULI_Z], [3]) == czgate(Complex128, 12, 7, 3) + @test general_controlled_gates(12, [mat(P1)], [7], [mat(Z)], [3]) == czgate(Complex128, 12, 7, 3) @test cxgate(Complex128, 2, 2, 1) == [1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0] - @test general_controlled_gates(12, [P1], [7], [PAULI_X], [3]) == cxgate(Complex128, 12, 7, 3) - @test general_controlled_gates(3, [P1], [3], [PAULI_Y], [2]) == controlled_U1(3, PAULI_Y, [3], 2) == cygate(Complex128, 3, 3, 2) + @test general_controlled_gates(12, [mat(P1)], [7], [mat(X)], [3]) == cxgate(Complex128, 12, 7, 3) + @test general_controlled_gates(3, [mat(P1)], [3], [mat(Y)], [2]) == controlled_U1(3, mat(Y), [3], 2) == cygate(Complex128, 3, 3, 2) end @testset "single gate" begin - @test zgate(Complex128, 4, [1,2,3]) == hilbertkron(4, [PAULI_Z, PAULI_Z, PAULI_Z], [1,2,3]) + @test zgate(Complex128, 4, [1,2,3]) == hilbertkron(4, [mat(Z), mat(Z), mat(Z)], [1,2,3]) end @testset "basic gate" begin # check matrixes for (gate, MAT) in [ - (xgate, PAULI_X), - (ygate, PAULI_Y), - (zgate, PAULI_Z), + (xgate, mat(X)), + (ygate, mat(Y)), + (zgate, mat(Z)), #(hgate, (elem = 1 / sqrt(2); [elem elem; elem -elem])), ] @test full(gate(Complex128, 1, 1)) == MAT From 8705ea3071264428c2ebb274b7b944e132bba6ce Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 5 Jun 2018 19:40:13 +0800 Subject: [PATCH 06/10] fix ygate --- src/Boost/applys.jl | 14 +++++++------- src/Boost/gates.jl | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Boost/applys.jl b/src/Boost/applys.jl index dba8a1d2e..1a3ca9055 100644 --- a/src/Boost/applys.jl +++ b/src/Boost/applys.jl @@ -47,7 +47,7 @@ function yapply!(state::Vector{T}, bits::Ints) where T end mask = bmask(bits...) do_mask = bmask(bits[1]) - factor = T(im^length(bits)) + factor = T(-im^length(bits)) @inbounds @simd for b = basis(state) local temp::T @@ -57,11 +57,11 @@ function yapply!(state::Vector{T}, bits::Ints) where T i_ = flip(b, mask) + 1 temp = state[i] if count_ones(b&mask)%2 == 1 - state[i] = state[i_]*factor - state[i_] = -temp*factor - else state[i] = -state[i_]*factor state[i_] = temp*factor + else + state[i] = state[i_]*factor + state[i_] = -temp*factor end end end @@ -74,7 +74,7 @@ function yapply!(state::Matrix{T}, bits::Ints) where T end mask = bmask(bits...) do_mask = bmask(bits[1]) - factor = T(im^length(bits)) + factor = T(-im^length(bits)) M, N = size(state) @simd for b = basis(state) @@ -85,9 +85,9 @@ function yapply!(state::Matrix{T}, bits::Ints) where T i = b+1 i_ = flip(b, mask) + 1 if count_ones(b&mask)%2 == 1 - factor_ = factor - else factor_ = -factor + else + factor_ = factor end @simd for c = 1:N temp = state[i, c] diff --git a/src/Boost/gates.jl b/src/Boost/gates.jl index 1b53892b4..f14c3f589 100644 --- a/src/Boost/gates.jl +++ b/src/Boost/gates.jl @@ -21,11 +21,11 @@ function ygate(::Type{MT}, num_bit::Int, bits::Ints) where MT<:Complex mask = bmask(bits...) order = Vector{Int}(1< Date: Tue, 5 Jun 2018 22:00:43 +0800 Subject: [PATCH 07/10] new control-xyz --- src/Boost/controlxyz.jl | 100 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/Boost/controlxyz.jl diff --git a/src/Boost/controlxyz.jl b/src/Boost/controlxyz.jl new file mode 100644 index 000000000..c372a4dfd --- /dev/null +++ b/src/Boost/controlxyz.jl @@ -0,0 +1,100 @@ +####################### Controlled Gates ####################### +bmask() = DInt(0) +#### C-X/Y/Z Gates +function cxgate(::Type{MT}, num_bit::Int, cbits::Vector{Int}, cvals::Vector{Int}, b2::Ints) where MT<:Number + mask = bmask(cbits...) + onemask = bmask(cbits[cvals.==1]...) + mask2 = bmask(b2) + order = map(i->testval(i, mask, onemask) ? flip(i, mask2)+1 : i+1, basis(num_bit)) + PermuteMultiply(order, ones(MT, 1<testval(i, mask, onemask) ? MT(-1) : MT(1), basis(num_bit)) + Diagonal(vals) +end + + +# general multi-control single-gate +function controlled_U1(num_bit::Int, gate::PermuteMultiply{T}, cbits::Vector{Int}, cvals::Vector{Int}, b2::Int) where {T} + vals = Vector{T}(1< Date: Tue, 5 Jun 2018 22:45:49 +0800 Subject: [PATCH 08/10] update --- src/Boost/Control.jl | 3 +- src/Boost/controlxyz.jl | 100 --------------------------------------- src/Boost/gates.jl | 81 ++++++++++++++++--------------- src/Intrinsics/Basis.jl | 1 + test/Blocks/Control.jl | 11 ++--- test/Boost/controlxyz.jl | 14 ++++++ 6 files changed, 64 insertions(+), 146 deletions(-) delete mode 100644 src/Boost/controlxyz.jl create mode 100644 test/Boost/controlxyz.jl diff --git a/src/Boost/Control.jl b/src/Boost/Control.jl index 52a7f4feb..b62c43e5e 100644 --- a/src/Boost/Control.jl +++ b/src/Boost/Control.jl @@ -1,3 +1,4 @@ function mat(ctrl::ControlBlock{BT, N, T}) where {N, T, BT <: MatrixBlock{1, T}} - controlled_U1(N, mat(ctrl.block), ctrl.ctrl_qubits, ctrl.addr) + ctrl_vals = @. div(sign(ctrl.ctrl_qubits) + 1, 2) + controlled_U1(N, mat(ctrl.block), ctrl.ctrl_qubits, ctrl_vals, ctrl.addr) end diff --git a/src/Boost/controlxyz.jl b/src/Boost/controlxyz.jl deleted file mode 100644 index c372a4dfd..000000000 --- a/src/Boost/controlxyz.jl +++ /dev/null @@ -1,100 +0,0 @@ -####################### Controlled Gates ####################### -bmask() = DInt(0) -#### C-X/Y/Z Gates -function cxgate(::Type{MT}, num_bit::Int, cbits::Vector{Int}, cvals::Vector{Int}, b2::Ints) where MT<:Number - mask = bmask(cbits...) - onemask = bmask(cbits[cvals.==1]...) - mask2 = bmask(b2) - order = map(i->testval(i, mask, onemask) ? flip(i, mask2)+1 : i+1, basis(num_bit)) - PermuteMultiply(order, ones(MT, 1<testval(i, mask, onemask) ? MT(-1) : MT(1), basis(num_bit)) - Diagonal(vals) -end - - -# general multi-control single-gate -function controlled_U1(num_bit::Int, gate::PermuteMultiply{T}, cbits::Vector{Int}, cvals::Vector{Int}, b2::Int) where {T} - vals = Vector{T}(1< PermMatrix @@ -69,10 +70,11 @@ end Single (Multiple) Controlled-X Gate on single (multiple) bits. """ -function cxgate(::Type{MT}, num_bit::Int, b1::Ints, b2::Ints) where MT<:Number - mask = bmask(b1) +function cxgate(::Type{MT}, num_bit::Int, cbits::Vector{Int}, cvals::Vector{Int}, b2::Ints) where MT<:Number + mask = bmask(cbits...) + onemask = bmask(cbits[cvals.==1]...) mask2 = bmask(b2) - order = map(i->testall(i, mask) ? flip(i, mask2)+1 : i+1, basis(num_bit)) + order = map(i->testval(i, mask, onemask) ? flip(i, mask2)+1 : i+1, basis(num_bit)) PermMatrix(order, ones(MT, 1<testval(i, mask, onemask) ? MT(-1) : MT(1), basis(num_bit)) Diagonal(vals) end @@ -127,44 +126,48 @@ function controlled_U1 end # general multi-control single-gate -function controlled_U1(num_bit::Int, gate::PermMatrix{T}, cbits::Vector{Int}, b2::Int) where {T} - vals = ones(T, 1<(testall(i, mask) ? (testany(i, b2) ? b : a) : T(1))::T, basis(num_bit)) Diagonal(vals) end -function controlled_U1(num_bit::Int, gate::StridedMatrix, b1::Vector{Int}, b2::Int) - general_controlled_gates(2, [P1], b1, [gate], [b2]) +function controlled_U1(num_bit::Int, gate::AbstractMatrix, cbits::Vector{Int}, cvals::Vector{Int}, b2::Int) + general_controlled_gates(num_bit, [c==1 ? mat(P1) : mat(P0) for c in cvals], cbits, [gate], [b2]) end + # arbituary control PermMatrix gate: SparseMatrixCSC # TODO: to interface #toffoligate(num_bit::Int, b1::Int, b2::Int, b3::Int) = controlled_U1(num_bit, PAULI_X, [b1, b2], b3) diff --git a/src/Intrinsics/Basis.jl b/src/Intrinsics/Basis.jl index 11dfcf5a5..8d91c6737 100644 --- a/src/Intrinsics/Basis.jl +++ b/src/Intrinsics/Basis.jl @@ -40,6 +40,7 @@ Return an integer with specific position masked, which is offten used as a mask """ function bmask end +bmask() = DInt(0) bmask(ibit::Int...)::DInt = sum([one(DInt) << (b-1) for b in ibit]) bmask(bits::UnitRange{Int})::DInt = ((one(DInt) << (bits.stop - bits.start + 1)) - one(DInt)) << (bits.start-1) diff --git a/test/Blocks/Control.jl b/test/Blocks/Control.jl index 074ed02b1..af8c215ac 100644 --- a/test/Blocks/Control.jl +++ b/test/Blocks/Control.jl @@ -89,12 +89,11 @@ end @test mat(g) == op end -# FIXME: -# @testset "inverse control" begin -# g = ControlBlock{2}([-1, ], X, 2) +@testset "inverse control" begin + g = ControlBlock{2}([-1, ], X, 2) -# op = U ⊗ mat(P0) + IMatrix(U) ⊗ mat(P1) -# @test mat(g) ≈ op -# end + op = U ⊗ mat(P0) + IMatrix(U) ⊗ mat(P1) + @test mat(g) ≈ op +end end # control matrix form diff --git a/test/Boost/controlxyz.jl b/test/Boost/controlxyz.jl new file mode 100644 index 000000000..59d6fdd80 --- /dev/null +++ b/test/Boost/controlxyz.jl @@ -0,0 +1,14 @@ +using Compat +using Compat.Test + +using Yao.Blocks +using Yao.Boost + +@testset "control" begin + +@test cxgate(ComplexF64, 2, [2], [1], 1) == [1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0] == controlled_U1(2, Matrix(mat(X)), [2], [1], 1) +@test cxgate(ComplexF64, 2, [2], [0], 1) == [0 1 0 0; 1 0 0 0; 0 0 1 0; 0 0 0 1] == controlled_U1(2, Matrix(mat(X)), [2], [0], 1) +@test czgate(ComplexF64, 2, [1], [1], 2) == [1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 -1] == controlled_U1(2, mat(Z), [2], [1], 1) +@test general_controlled_gates(3, [mat(P1)], [3], [mat(Y)], [2]) == controlled_U1(3, mat(Y), [3], [1], 2) == cygate(ComplexF64, 3, [3], [1], 2) + +end From 8d0fc8b6585fc80ad4b6d597c5d199ea3c2b63d6 Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 5 Jun 2018 22:57:28 +0800 Subject: [PATCH 09/10] fix bug --- src/Boost/Control.jl | 2 +- src/Boost/gates.jl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Boost/Control.jl b/src/Boost/Control.jl index b62c43e5e..8669d8dd7 100644 --- a/src/Boost/Control.jl +++ b/src/Boost/Control.jl @@ -1,4 +1,4 @@ function mat(ctrl::ControlBlock{BT, N, T}) where {N, T, BT <: MatrixBlock{1, T}} ctrl_vals = @. div(sign(ctrl.ctrl_qubits) + 1, 2) - controlled_U1(N, mat(ctrl.block), ctrl.ctrl_qubits, ctrl_vals, ctrl.addr) + controlled_U1(N, mat(ctrl.block), abs.(ctrl.ctrl_qubits), ctrl_vals, ctrl.addr) end diff --git a/src/Boost/gates.jl b/src/Boost/gates.jl index 73d1beb9b..8ab0f5e85 100644 --- a/src/Boost/gates.jl +++ b/src/Boost/gates.jl @@ -147,7 +147,6 @@ end function controlled_U1(num_bit::Int, gate::Diagonal{T}, cbits::Vector{Int}, cvals::Vector{Int}, b2::Int) where {T} mask = bmask(cbits...) - mask2 = bmask(b2) onemask = bmask(cbits[cvals.==1]...) a, b = gate.diag From 2abc58f35b55d839f8e167847f1182965ef23f32 Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 5 Jun 2018 23:19:30 +0800 Subject: [PATCH 10/10] fix test Gates --- test/Boost/Gates.jl | 29 ++++++++++++++++++++--------- test/Boost/controlxyz.jl | 14 -------------- 2 files changed, 20 insertions(+), 23 deletions(-) delete mode 100644 test/Boost/controlxyz.jl diff --git a/test/Boost/Gates.jl b/test/Boost/Gates.jl index cc5a3b676..1fcee4190 100644 --- a/test/Boost/Gates.jl +++ b/test/Boost/Gates.jl @@ -1,3 +1,4 @@ +using Compat using Compat.Test using Yao using Yao.Blocks @@ -13,17 +14,27 @@ using Yao.Boost end @testset "controlled gates" begin + @test cxgate(ComplexF64, 2, [2], [1], 1) == [1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0] == controlled_U1(2, Matrix(mat(X)), [2], [1], 1) + @test cxgate(ComplexF64, 2, [2], [0], 1) == [0 1 0 0; 1 0 0 0; 0 0 1 0; 0 0 0 1] == controlled_U1(2, Matrix(mat(X)), [2], [0], 1) @test general_controlled_gates(2, [mat(P1)], [2], [mat(X)], [1]) == mat(CNOT) - @test controlled_U1(3, mat(Z), [3], 2) == czgate(Complex128, 3, 3, 2) - @test czgate(Complex128, 2, 1, 2) == [1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 -1] - @test general_controlled_gates(12, [mat(P1)], [7], [mat(Z)], [3]) == czgate(Complex128, 12, 7, 3) - @test cxgate(Complex128, 2, 2, 1) == [1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0] - @test general_controlled_gates(12, [mat(P1)], [7], [mat(X)], [3]) == cxgate(Complex128, 12, 7, 3) - @test general_controlled_gates(3, [mat(P1)], [3], [mat(Y)], [2]) == controlled_U1(3, mat(Y), [3], 2) == cygate(Complex128, 3, 3, 2) + @test controlled_U1(3, mat(Z), [3], [1], 2) == czgate(ComplexF64, 3, [3], [1], 2) + @test czgate(ComplexF64, 2, [1], [1], 2) == [1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 -1] == controlled_U1(2, mat(Z), [2], [1], 1) + @test general_controlled_gates(12, [mat(P1)], [7], [mat(Z)], [3]) == czgate(ComplexF64, 12, [7], [1], 3) + @test cxgate(ComplexF64, 2, [2], [1], 1) == [1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0] + @test general_controlled_gates(12, [mat(P1)], [7], [mat(X)], [3]) == cxgate(ComplexF64, 12, [7], [1], 3) + + @test general_controlled_gates(3, [mat(P1)], [3], [mat(X)], [2]) == controlled_U1(3, mat(X), [3], [1], 2) == cxgate(ComplexF64, 3, [3], [1], 2) + @test general_controlled_gates(3, [mat(P1)], [3], [mat(Y)], [2]) == controlled_U1(3, mat(Y), [3], [1], 2) == cygate(ComplexF64, 3, [3], [1], 2) + @test general_controlled_gates(3, [mat(P1)], [3], [mat(Z)], [2]) == controlled_U1(3, mat(Z), [3], [1], 2) == czgate(ComplexF64, 3, [3], [1], 2) + + # NC + @test general_controlled_gates(3, [mat(P1), mat(P0)], [3, 1], [mat(X)], [2]) == controlled_U1(3, mat(X), [3, 1], [1, 0], 2) == cxgate(ComplexF64, 3, [3, 1], [1, 0], 2) + @test general_controlled_gates(3, [mat(P1), mat(P0)], [3, 1], [mat(Y)], [2]) == controlled_U1(3, mat(Y), [3, 1], [1, 0], 2) == cygate(ComplexF64, 3, [3, 1], [1, 0], 2) + @test general_controlled_gates(3, [mat(P1), mat(P0)], [3, 1], [mat(Z)], [2]) == controlled_U1(3, mat(Z), [3, 1], [1, 0], 2) == czgate(ComplexF64, 3, [3, 1], [1, 0], 2) end @testset "single gate" begin - @test zgate(Complex128, 4, [1,2,3]) == hilbertkron(4, [mat(Z), mat(Z), mat(Z)], [1,2,3]) + @test zgate(ComplexF64, 4, [1,2,3]) == hilbertkron(4, [mat(Z), mat(Z), mat(Z)], [1,2,3]) end @testset "basic gate" begin @@ -34,8 +45,8 @@ end (zgate, mat(Z)), #(hgate, (elem = 1 / sqrt(2); [elem elem; elem -elem])), ] - @test full(gate(Complex128, 1, 1)) == MAT - @test hilbertkron(4, [MAT, MAT, MAT], [3,2,1]) == gate(Complex128, 4, 1:3) + @test full(gate(ComplexF64, 1, 1)) == MAT + @test hilbertkron(4, [MAT, MAT, MAT], [3,2,1]) == gate(ComplexF64, 4, 1:3) end #@test toffoligate(3, 2, 3, 1) == TOFFOLI_MAT end diff --git a/test/Boost/controlxyz.jl b/test/Boost/controlxyz.jl deleted file mode 100644 index 59d6fdd80..000000000 --- a/test/Boost/controlxyz.jl +++ /dev/null @@ -1,14 +0,0 @@ -using Compat -using Compat.Test - -using Yao.Blocks -using Yao.Boost - -@testset "control" begin - -@test cxgate(ComplexF64, 2, [2], [1], 1) == [1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0] == controlled_U1(2, Matrix(mat(X)), [2], [1], 1) -@test cxgate(ComplexF64, 2, [2], [0], 1) == [0 1 0 0; 1 0 0 0; 0 0 1 0; 0 0 0 1] == controlled_U1(2, Matrix(mat(X)), [2], [0], 1) -@test czgate(ComplexF64, 2, [1], [1], 2) == [1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 -1] == controlled_U1(2, mat(Z), [2], [1], 1) -@test general_controlled_gates(3, [mat(P1)], [3], [mat(Y)], [2]) == controlled_U1(3, mat(Y), [3], [1], 2) == cygate(ComplexF64, 3, [3], [1], 2) - -end