From 49df44ed827c89273ef1a95c846260f5e2f477b3 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Fri, 2 Aug 2019 07:51:48 +0800 Subject: [PATCH 1/7] fix-reg type --- src/density_matrix.jl | 2 +- src/register.jl | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/density_matrix.jl b/src/density_matrix.jl index 9b7d2c4..0d89037 100644 --- a/src/density_matrix.jl +++ b/src/density_matrix.jl @@ -8,7 +8,7 @@ Density Matrix. - `B`: batch size - `T`: element type """ -struct DensityMatrix{B, T, MT<:AbstractArray{T, 3}} <: AbstractRegister{B, T} +struct DensityMatrix{B, T, MT<:AbstractArray{T, 3}} <: AbstractRegister{B} state::MT end diff --git a/src/register.jl b/src/register.jl index 1500327..6ee123a 100644 --- a/src/register.jl +++ b/src/register.jl @@ -39,18 +39,18 @@ export ArrayReg, oneto """ - ArrayReg{B, T, MT <: AbstractMatrix{T}} <: AbstractRegister{B, T} + ArrayReg{B, T, MT <: AbstractMatrix{T}} <: AbstractRegister{B} Simulated full amplitude register type, it uses an array to represent corresponding one or a batch of quantum states. `B` is the batch size, `T` is the numerical type for each amplitude, it is `ComplexF64` by default. """ -mutable struct ArrayReg{B, T, MT <: AbstractMatrix{T}} <: AbstractRegister{B, T} +mutable struct ArrayReg{B, T, MT <: AbstractMatrix{T}} <: AbstractRegister{B} state::MT end -const AdjointArrayReg{B, T, MT} = AdjointRegister{B, T, ArrayReg{B, T, MT}} -const ArrayRegOrAdjointArrayReg{B, T, MT} = Union{ArrayReg{B, T, MT}, AdjointRegister{B, T, ArrayReg{B, T, MT}}} +const AdjointArrayReg{B, T, MT} = AdjointRegister{B, ArrayReg{B, T, MT}} +const ArrayRegOrAdjointArrayReg{B, T, MT} = Union{ArrayReg{B, T, MT}, AdjointRegister{B, ArrayReg{B, T, MT}}} """ ArrayReg{B}(raw) @@ -73,6 +73,19 @@ function ArrayReg{B}(raw::MT) where {B, T, MT <: AbstractMatrix{T}} return ArrayReg{B, T, MT}(raw) end +""" + datatype(register) -> Int + +Returns the numerical data type used by register. + +!!! note + + `datatype` is not the same with `eltype`, since `AbstractRegister` family + is not exactly the same with `AbstractArray`, it is an iterator of several + registers. +""" +YaoBase.@interface datatype(r::ArrayReg{B, T}) where {B, T} = T + function _warn_type(raw::AbstractArray{T}) where T T <: Complex || @warn "Input type of `ArrayReg` is not Complex, got $(eltype(raw))" end From 979b906752d109f4f7560d1d817acd20b5232946 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 5 Aug 2019 01:18:02 +0800 Subject: [PATCH 2/7] update measure --- src/density_matrix.jl | 20 ++++++++++++++++++++ src/deprecations.jl | 4 ++++ src/focus.jl | 12 +++++++++++- src/instruct.jl | 5 ----- src/measure.jl | 33 +++++++++++++++++---------------- src/register.jl | 2 +- test/density_matrix.jl | 18 ++++++++++++++++++ 7 files changed, 71 insertions(+), 23 deletions(-) diff --git a/src/density_matrix.jl b/src/density_matrix.jl index 0d89037..8612ef0 100644 --- a/src/density_matrix.jl +++ b/src/density_matrix.jl @@ -1,4 +1,5 @@ export DensityMatrix, density_matrix, ρ +export purify """ DensityMatrix{B, T, MT} @@ -60,3 +61,22 @@ function YaoBase.probs(m::DensityMatrix{B, T}) where {B, T} end YaoBase.probs(m::DensityMatrix{1})= diag(view(m.state, :,:,1)) + +""" + purify(r::DensityMatrix{B}; nbit_env::Int=nactive(r)) -> ArrayReg + +Get a purification of target density matrix. +""" +function purify(r::DensityMatrix{B}; nbit_env::Int=nactive(r)) where B + Ne = 1< ArrayReg + +Exchange system (focused qubits) and environment (remaining qubits). +""" +function exchange_sysenv(reg::ArrayReg{B}) where B + ArrayReg{B}(reshape(permutedims(rank3(reg), (2,1,3)), :,size(reg.state, 1)*B)) +end diff --git a/src/instruct.jl b/src/instruct.jl index 7c9342b..d76db6e 100644 --- a/src/instruct.jl +++ b/src/instruct.jl @@ -17,11 +17,6 @@ A list of symbol for specialized gates/operators. """ const SPECIALIZATION_LIST = Symbol[:X, :Y, :Z, :S, :T, :Sdag, :Tdag] -# to avoid potential ambiguity, we limit them to tuple for now -# but they only has to be an iterator over integers -const Locations{T} = NTuple{N, T} where N -const BitConfigs{T} = NTuple{N, T} where N - function YaoBase.instruct!( state::AbstractVecOrMat{T1}, operator::AbstractMatrix{T2}, diff --git a/src/measure.jl b/src/measure.jl index 3d8e1e2..1ca0739 100644 --- a/src/measure.jl +++ b/src/measure.jl @@ -6,10 +6,14 @@ export measure, select, select! -_measure(rng::AbstractRNG, pl::AbstractVector, nshots::Int) = sample(rng, 0:length(pl)-1, Weights(pl), nshots) +function _measure(rng::AbstractRNG, pl::AbstractVector, nshots::Int) + N = log2i(length(pl)) + sample(rng, basis(BitStr{N}), Weights(pl), nshots) +end + function _measure(rng::AbstractRNG, pl::AbstractMatrix, nshots::Int) B = size(pl, 2) - res = Matrix{Int}(undef, nshots, B) + res = Matrix{BitStr{log2i(length(pl))}}(undef, nshots, B) for ib=1:B @inbounds res[:,ib] = _measure(rng, view(pl,:,ib), nshots) end @@ -27,10 +31,11 @@ function YaoBase.measure_remove!(rng::AbstractRNG, ::ComputationalBasis, reg::Ar state = reg |> rank3 nstate = similar(reg.state, 1< abs2, dims=2), dims=2) - res = Vector{Int}(undef, B) + res = Vector{BitStr{nactive(reg)}}(undef, B) @inbounds for ib = 1:B ires = _measure(rng, view(pl, :, ib), 1)[] - nstate[:,ib] = view(state, ires+1,:,ib)./sqrt(pl[ires+1, ib]) + # notice ires is `BitStr` type, can be use as indices directly. + nstate[:,ib] = view(state, ires,:,ib)./sqrt(pl[ires, ib]) res[ib] = ires end reg.state = reshape(nstate,1,:) @@ -43,7 +48,7 @@ function YaoBase.measure!(rng::AbstractRNG, ::ComputationalBasis, reg::ArrayReg{ res = measure_remove!(rng, reg) _nstate = reshape(reg.state, :, B) for ib in 1:B - @inbounds nstate[res[ib]+1, :, ib] .= view(_nstate, :,ib) + @inbounds nstate[res[ib], :, ib] .= view(_nstate, :,ib) end reg.state = reshape(nstate, size(state, 1), :) return res @@ -54,22 +59,18 @@ function YaoBase.measure_collapseto!(rng::AbstractRNG, ::ComputationalBasis, reg M, N, B1 = size(state) nstate = zero(state) res = measure_remove!(rng, reg) - nstate[config+1, :, :] = reshape(reg.state, :, B) + nstate[Int(config)+1, :, :] = reshape(reg.state, :, B) reg.state = reshape(nstate, M, N*B) return res end -YaoBase.select(r::ArrayReg{B}, bits) where B = ArrayReg{B}(r.state[map(to_location, bits), :]) -YaoBase.select(r::ArrayReg{B}, bit::Union{Integer, BitStr}) where B = select(r, [bit]) - -function YaoBase.select!(r::ArrayReg, bits) - r.state = r.state[map(to_location, bits), :] - return r -end +import YaoBase: select, select! +select(r::ArrayReg{B}, bits::AbstractVector{T}) where {B, T<:BitStr} = ArrayReg{B}(r.state[bits, :]) +select(r::ArrayReg{B}, bit::BitStr) where B = select(r, [bit]) -function YaoBase.select!(r::ArrayReg, bits::Integer) - r.state = reshape(r.state[bits+1, :], 1, :) +function select!(r::ArrayReg, bits::AbstractVector{T}) where T<:BitStr + r.state = r.state[bits, :] return r end -YaoBase.select!(r::ArrayReg, bits::BitStr) = select!(r, bits.val) +select!(r::ArrayReg, bit::BitStr) = select!(r, [bit]) diff --git a/src/register.jl b/src/register.jl index 6ee123a..8b2082c 100644 --- a/src/register.jl +++ b/src/register.jl @@ -190,7 +190,7 @@ end function YaoBase.collapseto!(r::ArrayReg, bit_config::Integer=0) fill!(r.state, 0) - @inbounds r.state[bit_config+1,:] .= 1 + @inbounds r.state[Int(bit_config)+1,:] .= 1 return r end diff --git a/test/density_matrix.jl b/test/density_matrix.jl index 6eb8c44..72b2512 100644 --- a/test/density_matrix.jl +++ b/test/density_matrix.jl @@ -39,3 +39,21 @@ end @test isapprox(tracedist(dm, dm_)[], tracedist(dm4, dm5)[], atol=1e-5) @test isapprox.(tracedist(dm, dm_)[], tracedist(repeat(reg4, 3)|>density_matrix, repeat(reg5, 3)|>density_matrix), atol=1e-5) |> all end + +@testset "purify" begin + reg = rand_state(6) + reg_p = purify(reg |> ρ) + @test reg_p |> isnormalized + @test reg_p |> exchange_sysenv |> probs |> maximum ≈ 1 + reg_p = purify(reg |> ρ; nbit_env=0) + @test Yao.fidelity(reg, reg_p) ≈ [1] + + reg = rand_state(6; nbatch=10) + reg_p = purify(reg |> ρ) + @test reg_p |> isnormalized + @test reg_p |> exchange_sysenv |> probs |> maximum ≈ 1 + reg_p = purify(reg |> ρ; nbit_env=0) + @test Yao.fidelity(reg, reg_p) ≈ ones(10) + reg_p = purify(reg |> ρ; nbit_env=2) + @test reg_p |> nqubits == 8 +end From 45076f7cb34e320298b1f6afa776a87b2be7d85d Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Tue, 6 Aug 2019 03:23:08 +0800 Subject: [PATCH 3/7] fix collapseto --- src/register.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/register.jl b/src/register.jl index 8b2082c..5381ed4 100644 --- a/src/register.jl +++ b/src/register.jl @@ -188,9 +188,9 @@ function YaoBase.reorder!(r::ArrayReg, orders) return r end -function YaoBase.collapseto!(r::ArrayReg, bit_config::Integer=0) +function YaoBase.collapseto!(r::ArrayReg, bit_config::BitStr=0) fill!(r.state, 0) - @inbounds r.state[Int(bit_config)+1,:] .= 1 + r.state[bit_config,:] .= 1 return r end From 25b52c7cbe37f6fd2222acf3c4f2269519559b54 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Thu, 8 Aug 2019 18:25:04 +0800 Subject: [PATCH 4/7] BitStr64 --- src/deprecations.jl | 8 ++++---- src/measure.jl | 6 +++--- src/register.jl | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/deprecations.jl b/src/deprecations.jl index 5858acd..2e81128 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -1,5 +1,5 @@ # deprecations -@deprecate select!(r::ArrayReg, bit::Integer) select!(r, BitStr{nactive(r)}(bit)) -@deprecate select(r::ArrayReg, bit::Integer) select(r, BitStr{nactive(r)}(bit)) -@deprecate select!(r::ArrayReg, bits::AbstractVector{<:Integer}) select!(r, reinterpret(BitStr{nactive(r)}, bits)) -@deprecate select(r::ArrayReg, bits::AbstractVector{<:Integer}) select(r, reinterpret(BitStr{nactive(r)}, bits)) +@deprecate select!(r::ArrayReg, bit::Integer) select!(r, BitStr64{nactive(r)}(bit)) +@deprecate select(r::ArrayReg, bit::Integer) select(r, BitStr64{nactive(r)}(bit)) +@deprecate select!(r::ArrayReg, bits::AbstractVector{<:Integer}) select!(r, reinterpret(BitStr64{nactive(r)}, bits)) +@deprecate select(r::ArrayReg, bits::AbstractVector{<:Integer}) select(r, reinterpret(BitStr64{nactive(r)}, bits)) diff --git a/src/measure.jl b/src/measure.jl index 1ca0739..63e90af 100644 --- a/src/measure.jl +++ b/src/measure.jl @@ -8,12 +8,12 @@ export measure, function _measure(rng::AbstractRNG, pl::AbstractVector, nshots::Int) N = log2i(length(pl)) - sample(rng, basis(BitStr{N}), Weights(pl), nshots) + sample(rng, basis(BitStr64{N}), Weights(pl), nshots) end function _measure(rng::AbstractRNG, pl::AbstractMatrix, nshots::Int) B = size(pl, 2) - res = Matrix{BitStr{log2i(length(pl))}}(undef, nshots, B) + res = Matrix{BitStr64{log2i(length(pl))}}(undef, nshots, B) for ib=1:B @inbounds res[:,ib] = _measure(rng, view(pl,:,ib), nshots) end @@ -31,7 +31,7 @@ function YaoBase.measure_remove!(rng::AbstractRNG, ::ComputationalBasis, reg::Ar state = reg |> rank3 nstate = similar(reg.state, 1< abs2, dims=2), dims=2) - res = Vector{BitStr{nactive(reg)}}(undef, B) + res = Vector{BitStr64{nactive(reg)}}(undef, B) @inbounds for ib = 1:B ires = _measure(rng, view(pl, :, ib), 1)[] # notice ires is `BitStr` type, can be use as indices directly. diff --git a/src/register.jl b/src/register.jl index 5381ed4..6ecaa09 100644 --- a/src/register.jl +++ b/src/register.jl @@ -1,5 +1,5 @@ using YaoBase, BitBasis -import BitBasis: BitStr +import BitBasis: BitStr, BitStr64 export ArrayReg, AdjointArrayReg, From 99a001989249ded1c27bda9e13fabb17ebea0069 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Sat, 10 Aug 2019 11:52:55 +0800 Subject: [PATCH 5/7] update for BitStr --- Project.toml | 2 +- src/measure.jl | 8 ++++---- src/register.jl | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Project.toml b/Project.toml index 4210860..4e8327c 100644 --- a/Project.toml +++ b/Project.toml @@ -15,7 +15,7 @@ YaoBase = "a8f54c17-34bc-5a9d-b050-f522fe3f755f" [compat] BitBasis = "^0.5.0" LuxurySparse = "~0.4.0" -YaoBase = "~0.10.0" +YaoBase = "~0.11.0" julia = "^1.0.0" [extras] diff --git a/src/measure.jl b/src/measure.jl index 63e90af..c3c515d 100644 --- a/src/measure.jl +++ b/src/measure.jl @@ -35,7 +35,7 @@ function YaoBase.measure_remove!(rng::AbstractRNG, ::ComputationalBasis, reg::Ar @inbounds for ib = 1:B ires = _measure(rng, view(pl, :, ib), 1)[] # notice ires is `BitStr` type, can be use as indices directly. - nstate[:,ib] = view(state, ires,:,ib)./sqrt(pl[ires, ib]) + nstate[:,ib] = view(state, Int64(ires)+1,:,ib)./sqrt(pl[Int64(ires)+1, ib]) res[ib] = ires end reg.state = reshape(nstate,1,:) @@ -48,7 +48,7 @@ function YaoBase.measure!(rng::AbstractRNG, ::ComputationalBasis, reg::ArrayReg{ res = measure_remove!(rng, reg) _nstate = reshape(reg.state, :, B) for ib in 1:B - @inbounds nstate[res[ib], :, ib] .= view(_nstate, :,ib) + @inbounds nstate[Int64(res[ib])+1, :, ib] .= view(_nstate, :,ib) end reg.state = reshape(nstate, size(state, 1), :) return res @@ -65,11 +65,11 @@ function YaoBase.measure_collapseto!(rng::AbstractRNG, ::ComputationalBasis, reg end import YaoBase: select, select! -select(r::ArrayReg{B}, bits::AbstractVector{T}) where {B, T<:BitStr} = ArrayReg{B}(r.state[bits, :]) +select(r::ArrayReg{B}, bits::AbstractVector{T}) where {B, T<:BitStr} = ArrayReg{B}(r.state[Int64.(bits) .+ 1, :]) select(r::ArrayReg{B}, bit::BitStr) where B = select(r, [bit]) function select!(r::ArrayReg, bits::AbstractVector{T}) where T<:BitStr - r.state = r.state[bits, :] + r.state = r.state[Int64.(bits) .+ 1, :] return r end diff --git a/src/register.jl b/src/register.jl index 6ecaa09..d941e4c 100644 --- a/src/register.jl +++ b/src/register.jl @@ -190,7 +190,7 @@ end function YaoBase.collapseto!(r::ArrayReg, bit_config::BitStr=0) fill!(r.state, 0) - r.state[bit_config,:] .= 1 + r.state[Int64(bit_config)+1,:] .= 1 return r end From 8b2fd400a34b65cbf01e06ac3e21676cb61e7f9c Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Sun, 18 Aug 2019 18:41:45 +0800 Subject: [PATCH 6/7] remove deprecation of select normal integer --- src/deprecations.jl | 4 ---- src/measure.jl | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/deprecations.jl b/src/deprecations.jl index 2e81128..ff33f5b 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -1,5 +1 @@ # deprecations -@deprecate select!(r::ArrayReg, bit::Integer) select!(r, BitStr64{nactive(r)}(bit)) -@deprecate select(r::ArrayReg, bit::Integer) select(r, BitStr64{nactive(r)}(bit)) -@deprecate select!(r::ArrayReg, bits::AbstractVector{<:Integer}) select!(r, reinterpret(BitStr64{nactive(r)}, bits)) -@deprecate select(r::ArrayReg, bits::AbstractVector{<:Integer}) select(r, reinterpret(BitStr64{nactive(r)}, bits)) diff --git a/src/measure.jl b/src/measure.jl index c3c515d..b42a7ac 100644 --- a/src/measure.jl +++ b/src/measure.jl @@ -65,12 +65,12 @@ function YaoBase.measure_collapseto!(rng::AbstractRNG, ::ComputationalBasis, reg end import YaoBase: select, select! -select(r::ArrayReg{B}, bits::AbstractVector{T}) where {B, T<:BitStr} = ArrayReg{B}(r.state[Int64.(bits) .+ 1, :]) -select(r::ArrayReg{B}, bit::BitStr) where B = select(r, [bit]) +select(r::ArrayReg{B}, bits::AbstractVector{T}) where {B, T<:Integer} = ArrayReg{B}(r.state[Int64.(bits) .+ 1, :]) +select(r::ArrayReg{B}, bit::Integer) where B = select(r, [bit]) -function select!(r::ArrayReg, bits::AbstractVector{T}) where T<:BitStr +function select!(r::ArrayReg, bits::AbstractVector{T}) where T<:Integer r.state = r.state[Int64.(bits) .+ 1, :] return r end -select!(r::ArrayReg, bit::BitStr) = select!(r, [bit]) +select!(r::ArrayReg, bit::Integer) = select!(r, [bit]) From ffe4ed81c69ea823cfd3e807a1d40b737e031228 Mon Sep 17 00:00:00 2001 From: Rogerluo Date: Sun, 18 Aug 2019 18:44:04 -0400 Subject: [PATCH 7/7] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 4e8327c..54f9e57 100644 --- a/Project.toml +++ b/Project.toml @@ -13,7 +13,7 @@ TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" YaoBase = "a8f54c17-34bc-5a9d-b050-f522fe3f755f" [compat] -BitBasis = "^0.5.0" +BitBasis = "^0.6.0" LuxurySparse = "~0.4.0" YaoBase = "~0.11.0" julia = "^1.0.0"