diff --git a/.travis.yml b/.travis.yml index 234d2cc..5a4ac00 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,8 @@ os: - linux - osx julia: - - 1.2 - - 1.3 - 1.4 - - nightly + - 1.5 notifications: email: false @@ -23,7 +21,7 @@ after_success: jobs: include: - stage: "Documentation" - julia: 1.0 + julia: 1.5 os: linux script: - julia --project=docs/ -e 'using Pkg; Pkg.add("SCS"); Pkg.add("Documenter"); Pkg.instantiate(); diff --git a/Project.toml b/Project.toml index e67a265..e1000b8 100644 --- a/Project.toml +++ b/Project.toml @@ -15,10 +15,11 @@ StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [compat] -julia = "0.7, 1.0, 1.1, 1.2" +julia = "1.4, 1.5" [extras] +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test"] +test = ["SparseArrays", "Test"] diff --git a/REQUIRE b/REQUIRE deleted file mode 100644 index 1ef1067..0000000 --- a/REQUIRE +++ /dev/null @@ -1,9 +0,0 @@ -julia 1 -StatsBase -DocStringExtensions -TensorOperations -Convex -SCS -Pkg -Requires -IsApprox \ No newline at end of file diff --git a/bench.jl b/bench.jl new file mode 100644 index 0000000..39f17ef --- /dev/null +++ b/bench.jl @@ -0,0 +1,17 @@ +using CuArrays, CuTensorOperations, QuantumInformation + +for (fname, f) in ((:bench_device, QuantumInformation.curand), (:bench_cpu, rand)) + @eval begin + function $fname(d=256) + c = HaarKet(d^2) + psi = $f(c) + @time ptrace(psi, [d, d], 1) + @time ptrace(psi, [d, d], 2) + end + end +end + +bench_device() +bench_device() +bench_cpu() +bench_cpu() \ No newline at end of file diff --git a/curandommatrices/src/CuRandomMatrices.jl b/curandommatrices/src/CuRandomMatrices.jl deleted file mode 100644 index c982c42..0000000 --- a/curandommatrices/src/CuRandomMatrices.jl +++ /dev/null @@ -1,15 +0,0 @@ -module CuRandomMatrices -export curand - -using LinearAlgebra -using ..CuArrays -using CUDAnative - -include("../../randommatrices/src/RandomMatrices.jl") -using ..RandomMatrices - -include("ginibre.jl") -include("circular.jl") -include("wigner.jl") -include("wishart.jl") -end \ No newline at end of file diff --git a/curandommatrices/src/circular.jl b/curandommatrices/src/circular.jl deleted file mode 100644 index be61802..0000000 --- a/curandommatrices/src/circular.jl +++ /dev/null @@ -1,42 +0,0 @@ -for T in (ComplexF32, ComplexF64, ComplexF16) - @eval begin - @inline CUDAnative.abs(x::$T) = CUDAnative.hypot(x.re, x.im) - end -end - - -function _qr_fix!(z::CuMatrix) - q, r = CuArrays.qr!(z) - ph = CuArrays.diag(r) - ph = ph ./ CUDAnative.abs.(ph) - idim = size(r, 1) - q = CuMatrix(q)[:, 1:idim] - q = CuArrays.transpose(ph) .* q -end - -function _qr_fix(z::CuMatrix) - a = copy(z) - _qr_fix!(a) -end - -function curand(c::COE) - z = curand(c.g) - u = _qr_fix!(z) - transpose(u)*u -end - -function curand(c::CSE) - z = curand(c.g) - u = _qr_fix!(z) - ur = cat([CuMatrix{Float32}([0 -1; 1 0]) for _=1:c.d÷2]..., dims=[1,2]) - ur*u*ur'*transpose(u) -end - -for T in (CUE, CircularRealEnsemble, CircularQuaternionEnsemble, HaarIsometry) - @eval begin - function curand(c::$T) - z = curand(c.g) - _qr_fix!(z) - end - end -end \ No newline at end of file diff --git a/curandommatrices/src/ginibre.jl b/curandommatrices/src/ginibre.jl deleted file mode 100644 index 3d8e138..0000000 --- a/curandommatrices/src/ginibre.jl +++ /dev/null @@ -1,10 +0,0 @@ -curand(g::GinibreEnsemble{1}) = CuArrays.randn(g.m, g.n) -curand(g::GinibreEnsemble{2}) = CuArrays.randn(g.m, g.n)+1im*CuArrays.randn(g.m, g.n) - -function curand(g::GinibreEnsemble{4}) - q0=CuArrays.randn(g.m, g.n) - q1=CuArrays.randn(g.m, g.n) - q2=CuArrays.randn(g.m, g.n) - q3=CuArrays.randn(g.m, g.n) - [q0+1im*q1 q2+1im*q3; -q2+1im*q3 q0-1im*q1] -end diff --git a/curandommatrices/src/wigner.jl b/curandommatrices/src/wigner.jl deleted file mode 100644 index b9a0aa2..0000000 --- a/curandommatrices/src/wigner.jl +++ /dev/null @@ -1,4 +0,0 @@ -function curand(w::WignerEnsemble{β}) where β - z = curand(w.g) - (z + z') / 2sqrt(2β * w.d) -end \ No newline at end of file diff --git a/curandommatrices/src/wishart.jl b/curandommatrices/src/wishart.jl deleted file mode 100644 index 202656d..0000000 --- a/curandommatrices/src/wishart.jl +++ /dev/null @@ -1,4 +0,0 @@ -function curand(w::WishartEnsemble{β, K}) where {β, K} - z = curand(w.g)/sqrt(2β * w.d) - z*z' -end diff --git a/curandommatrices/test/circular.jl b/curandommatrices/test/circular.jl deleted file mode 100644 index d7fbcdb..0000000 --- a/curandommatrices/test/circular.jl +++ /dev/null @@ -1,74 +0,0 @@ -Random.seed!(42) - -@testset "CircularEnsemble" begin - @testset "CUE" begin - n = 10 - c = CUE(n) - u = CuRandomMatrices.curand(c) - @test norm(u*u' - I) ≈ 0 atol=1e-5 - - n = 100 - c = CUE(n) - steps = 100 - r = zeros(steps, n) - - for i=1:steps - u = collect(CuRandomMatrices.curand(c)) - r[i, :] = angle.(eigvals(u)) - end - r = vec(r) - h = normalize(fit(Histogram, r, weights(ones(size(r))), -π:0.1π:π, closed=:left)) - @test all(isapprox.(h.weights, 1/2π, atol=0.01)) - end - - @testset "COE" begin - n = 10 - c = COE(n) - o = CuRandomMatrices.curand(c) - @test norm(o*o' - I) ≈ 0 atol=1e-5 - - n = 100 - c = COE(n) - steps = 100 - r = zeros(steps, n) - for i=1:steps - o = collect(CuRandomMatrices.curand(c)) - r[i, :] = angle.(eigvals(o)) - end - r = vec(r) - h = normalize(fit(Histogram, r, weights(ones(size(r))), -π:0.1π:π, closed=:left)) - @test all(isapprox.(h.weights, 1/2π, atol=0.1)) - end - - @testset "CircularRealEnsemble" begin - c = CircularRealEnsemble(10) - o = CuRandomMatrices.curand(c) - @test size(o) == (10, 10) - @test eltype(o) <: Real - end -end - - @testset "HaarIsometry" begin - idim = 2 - odim = 3 - c = HaarIsometry(idim, odim) - u = CuRandomMatrices.curand(c) - @test size(u) == (odim, idim) - @test isapprox(norm(u'*u - I), 0, atol=1e-6) - @test_throws ArgumentError HaarIsometry(odim, idim) - - @testset "CSE" begin - n = 10 - c = CSE(n) - o = CuRandomMatrices.curand(c) - @test norm(o*o' - I) ≈ 0 atol=1e-5 - @test size(o) == (n, n) - end - - @testset "Circular quaternion ensemble" begin - c = CircularQuaternionEnsemble(10) - u = CuRandomMatrices.curand(c) - @test size(u) == (20, 20) - @test isapprox(norm(u'*u - I), 0, atol=1e-5) - end -end \ No newline at end of file diff --git a/curandommatrices/test/ginibre.jl b/curandommatrices/test/ginibre.jl deleted file mode 100644 index 2a43caf..0000000 --- a/curandommatrices/test/ginibre.jl +++ /dev/null @@ -1,23 +0,0 @@ -Random.seed!(42) - -@testset "GinibreEnsemble" begin - g = GinibreEnsemble{1}(10, 20) - z = rand(g) - @test eltype(z) <: Real - @test size(z) == (10, 20) - @test GinibreEnsemble(10, 20) == GinibreEnsemble{2}(10, 20) - @test GinibreEnsemble(10) == GinibreEnsemble{2}(10, 10) - - @test_throws ArgumentError GinibreEnsemble{4}(11, 21) - g = GinibreEnsemble{4}(10, 20) - z = rand(g) - @test size(z) == (20, 40) - @test eltype(z) == ComplexF64 - -@testset "_qr_fix" begin - a = rand(2, 2) - u1 = RandomMatrices._qr_fix(a) - u2 = RandomMatrices._qr_fix!(a) - @test norm(u1 - u2) ≈ 0 -end -end diff --git a/curandommatrices/test/runtests.jl b/curandommatrices/test/runtests.jl deleted file mode 100644 index 487964c..0000000 --- a/curandommatrices/test/runtests.jl +++ /dev/null @@ -1,17 +0,0 @@ -using Test -using Random -using StatsBase -using LinearAlgebra -using CuArrays - -include("../../randommatrices/src/RandomMatrices.jl") -using ..RandomMatrices - -include("../src/CuRandomMatrices.jl") -using .CuRandomMatrices - -my_tests = ["circular.jl", "ginibre.jl", "wigner.jl", "wishart.jl"] - -for my_test in my_tests - include(my_test) -end diff --git a/curandommatrices/test/wigner.jl b/curandommatrices/test/wigner.jl deleted file mode 100644 index 33ce00f..0000000 --- a/curandommatrices/test/wigner.jl +++ /dev/null @@ -1,11 +0,0 @@ -Random.seed!(42) - -@testset "WignerEnsemble" begin - w = WignerEnsemble{1}(10) - z = rand(w) - - @test size(z) == (10, 10) - @test eltype(z) <: Real - @test ishermitian(z) - @test WignerEnsemble(10) == WignerEnsemble{2}(10) -end diff --git a/curandommatrices/test/wishart.jl b/curandommatrices/test/wishart.jl deleted file mode 100644 index c49e2ae..0000000 --- a/curandommatrices/test/wishart.jl +++ /dev/null @@ -1,15 +0,0 @@ -Random.seed!(42) - -@testset "WishartEnsemble" begin - w = WishartEnsemble{1, 0.1}(10) - z = rand(w) - ev = eigvals(z) - - @test size(z) == (10, 10) - @test eltype(z) <: Real - @test length(ev[ev.>1e-5]) == 1 - @test all(ev[ev.>1e-5] .> 0) - - @test WishartEnsemble{1}(10) == WishartEnsemble{1, 1}(10) - @test WishartEnsemble(10) == WishartEnsemble{2, 1}(10) -end diff --git a/docs/make.jl b/docs/make.jl index f1fa22d..79eaaba 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,8 +1,12 @@ using Documenter, QuantumInformation +format = Documenter.HTML(edit_link = "master", + prettyurls = get(ENV, "CI", nothing) == "true", +) + makedocs( clean = true, - format = :html, + format = format, sitename = "QuantumInformation.jl", authors = "Piotr Gawron, Dariusz Kurzyk, Łukasz Pawela", assets = ["assets/favicon.ico"], @@ -31,5 +35,5 @@ makedocs( deploydocs( deps = Deps.pip("pygments", "mkdocs", "python-markdown-math"), target = "build", - repo = "github.com/ZKSI/QuantumInformation.jl.git" + repo = "github.com/iitis/QuantumInformation.jl.git" ) diff --git a/src/QuantumInformation.jl b/src/QuantumInformation.jl index 9a0feff..4094067 100644 --- a/src/QuantumInformation.jl +++ b/src/QuantumInformation.jl @@ -19,11 +19,6 @@ include("../randommatrices/src/RandomMatrices.jl") using .RandomMatrices eval(Expr(:export, names(RandomMatrices)...)) -using Requires -@init @require CuArrays = "3a865a2d-5b23-5a0f-bc46-62713ec82fae" include("../curandommatrices/src/CuRandomMatrices.jl") -@init @require CuArrays = "3a865a2d-5b23-5a0f-bc46-62713ec82fae" using ..CuRandomMatrices -@init @require CuArrays = "3a865a2d-5b23-5a0f-bc46-62713ec82fae" export curand - include("base.jl") include("randomqobjects.jl") include("gates.jl") diff --git a/src/convex.jl b/src/convex.jl index 975710f..a3976b1 100644 --- a/src/convex.jl +++ b/src/convex.jl @@ -6,15 +6,9 @@ $(SIGNATURES) Return [diamond norm](https://arxiv.org/pdf/1207.5726.pdf) of dynamical matrix `Φ`. """ -function norm_diamond(Φ::AbstractQuantumOperation{T}, method=:primal, eps=1e-7) where T<:AbstractMatrix{<:Number} - ψ = convert(DynamicalMatrix{T}, Φ) - (method == :primal || method == :dual) || throw(ArgumentError("method must be either :primal or :dual")) +norm_diamond(Φ::AbstractQuantumOperation, method::Symbol=:primal, eps=1e-7) = norm_diamond(Φ, Val(method), eps) - method == :dual ? norm_diamond_dual(Φ,eps) : norm_diamond_primal(Φ,eps) -end - - -function norm_diamond_primal(Φ::DynamicalMatrix{T}, eps) where T<:AbstractMatrix{<:Number} +function norm_diamond(Φ::DynamicalMatrix, ::Val{:primal}, eps) J = Φ.matrix # TODO: compare d1, d2 with idim, odim d1 = Φ.idim @@ -31,12 +25,12 @@ function norm_diamond_primal(Φ::DynamicalMatrix{T}, eps) where T<:AbstractMatri constraints += [𝕀(d2) ⊗ ρ₀ X; X' 𝕀(d2) ⊗ ρ₁] in :SDP problem = maximize(t, constraints) - solve!(problem, SCSSolver(verbose=0, eps=eps)) + solve!(problem, () -> SCS.Optimizer(verbose=false, eps=eps)) problem.optval end -function norm_diamond_dual(Φ::DynamicalMatrix{T}, eps) where T<:AbstractMatrix{<:Number} +function norm_diamond(Φ::DynamicalMatrix, ::Val{:dual}, eps) J = Φ.matrix # TODO: compare d1, d2 with idim, odim d1 = Φ.idim @@ -52,7 +46,7 @@ function norm_diamond_dual(Φ::DynamicalMatrix{T}, eps) where T<:AbstractMatrix{ constraints += Z+Z' in :SDP problem = minimize(t, constraints) - solve!(problem, SCSSolver(verbose=0, eps=eps)) + solve!(problem, () -> SCS.Optimizer(verbose=false, eps=eps)) problem.optval end diff --git a/src/ptrace.jl b/src/ptrace.jl index ef43f42..2d38522 100644 --- a/src/ptrace.jl +++ b/src/ptrace.jl @@ -52,9 +52,9 @@ function ptrace(ψ::AbstractVector{<:Number}, idims::Vector{Int}, sys::Int) m = unres(ψ, cols) length(idims) == 2 ? () : throw(ArgumentError("idims has to be of length 2")) if sys == 1 - return m'*m + return transpose(m) * conj.(m) elseif sys == 2 - return m*m' + return m * transpose(conj.(m)) else throw(ArgumentError("sys must be 1 or 2")) end diff --git a/src/randomqobjects.jl b/src/randomqobjects.jl index bab2ff7..c980c09 100644 --- a/src/randomqobjects.jl +++ b/src/randomqobjects.jl @@ -127,7 +127,7 @@ struct WishartPOVM{V} <: QIContinuousMatrixDistribution end function WishartPOVM(idim::Int, odim::Int, K::Real=1) - V = Tuple(K .* ones(odim)) + V = Tuple(round.(Int, K .* ones(odim))) WishartPOVM{V}(idim) end diff --git a/test/ptrace.jl b/test/ptrace.jl index 9e2bfe9..d3be224 100644 --- a/test/ptrace.jl +++ b/test/ptrace.jl @@ -28,5 +28,10 @@ end ξ = ptrace(ϕ, [2, 2], 1) @test ξ ≈ I/2 atol=1e-15 @test_throws ArgumentError ptrace(ϕ, [2, 2], 3) + + ψ = [sqrt(1 / 3), sqrt(2 / 3)] + ϕ = [sqrt(2 / 3), sqrt(1 / 3)] + @test ptrace(ψ⊗ϕ, [2, 2], 1) ≈ proj(ϕ) atol=1e-15 + @test ptrace(ψ⊗ϕ, [2, 2], 2) ≈ proj(ψ) atol=1e-15 end end diff --git a/test/runtests.jl b/test/runtests.jl index 32b0a90..97b9257 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,7 +2,7 @@ using QuantumInformation using Random using LinearAlgebra -using SparseArrays +# using SparseArrays using Test my_tests = ["utils.jl", "base.jl", "ptrace.jl", "ptranspose.jl", "reshuffle.jl",