diff --git a/Makefile b/Makefile index 8f71b14..4297b8c 100644 --- a/Makefile +++ b/Makefile @@ -31,19 +31,15 @@ test/Manifest.toml: test/Project.toml ../scripts/installorg.jl @touch $@ -docs/Manifest.toml: test/Manifest.toml - cp test/*.toml docs/ - - devrepl: ## Start an interactive REPL for testing and building documentation $(JULIA) --project=test --banner=no --startup-file=yes -i devrepl.jl -docs: docs/Manifest.toml ## Build the documentation +docs: test/Manifest.toml ## Build the documentation $(JULIA) --project=test docs/make.jl @echo "Done. Consider using 'make devrepl'" -servedocs: docs/Manifest.toml ## Build (auto-rebuild) and serve documentation at PORT=8000 +servedocs: test/Manifest.toml ## Build (auto-rebuild) and serve documentation at PORT=8000 $(JULIA) --project=test -e 'include("devrepl.jl"); servedocs(port=$(PORT), verbose=true)' clean: ## Clean up build/doc/testing artifacts diff --git a/devrepl.jl b/devrepl.jl index 536e652..e6d40b8 100644 --- a/devrepl.jl +++ b/devrepl.jl @@ -37,8 +37,6 @@ end if !isfile(joinpath("test", "Manifest.toml")) _instantiate() - cp(joinpath("test", "Project.toml"), joinpath("docs", "Project.toml"); force=true) - cp(joinpath("test", "Manifest.toml"), joinpath("docs", "Manifest.toml"); force=true) end include("test/init.jl") diff --git a/docs/download_dumps.jl b/docs/download_dumps.jl deleted file mode 100644 index 715aee3..0000000 --- a/docs/download_dumps.jl +++ /dev/null @@ -1,34 +0,0 @@ -using DrWatson -@quickactivate "KrotovTests" -import Downloads - -DOWNLOADS = Dict( - "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/DissGateOCT%23J_T%3DJ_T_re%23iter_stop%3D3000%23method%3Dkrotov.jld2" => - joinpath(datadir(), "DissGateOCT#J_T=J_T_re#iter_stop=3000#method=krotov.jld2"), - "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/parametrization%23opt_result_logisticsq.jld2" => - joinpath(datadir(), "parametrization#opt_result_logisticsq.jld2"), - "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/parametrization%23opt_result_positive.jld2" => - joinpath(datadir(), "parametrization#opt_result_positive.jld2"), - "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/parametrization%23opt_result_tanh.jld2" => - joinpath(datadir(), "parametrization#opt_result_tanh.jld2"), - "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/parametrization%23opt_result_tanhsq.jld2" => - joinpath(datadir(), "parametrization#opt_result_tanhsq.jld2"), - "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/PE_OCT.jld2" => - joinpath(datadir(), "PE_OCT.jld2"), - "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/PE_OCT_direct.jld2" => - joinpath(datadir(), "PE_OCT_direct.jld2"), -) - -function download_dump(url, destination; force=false, verbose=true) - if !isfile(destination) || force - verbose && (@info "Downloading $url => $destination") - Downloads.download(url, destination) - else - verbose && (@info "$destination OK") - end -end - -@info "Download Dumps" -for (url, destination) in DOWNLOADS - download_dump(url, destination) -end diff --git a/docs/make.jl b/docs/make.jl index 1925d68..3cf1369 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -8,7 +8,7 @@ using Plots gr() ENV["GKSwstype"] = "100" -include(joinpath(@__DIR__, "download_dumps.jl")) +include(joinpath("..", "test", "download_dumps.jl")) # Generate examples include("generate.jl") diff --git a/examples/perfect_entanglers.jl b/examples/perfect_entanglers.jl index 9486e2d..50a6df6 100644 --- a/examples/perfect_entanglers.jl +++ b/examples/perfect_entanglers.jl @@ -40,8 +40,9 @@ #nb # \newcommand{Im}[0]{\operatorname{Im}} #nb # $ -using DrWatson -@quickactivate "KrotovTests" +const PROJECTDIR = dirname(Base.active_project()); +projectdir(names...) = joinpath(PROJECTDIR, names...); +datadir(names...) = projectdir("data", names...); #jl using Test; println("") # This example illustrates the optimization towards a perfectly entangling @@ -134,8 +135,8 @@ using QuantumControl.Shapes: flattop function guess_pulses(; T=400ns, E₀=35MHz, dt=0.1ns, t_rise=15ns) tlist = collect(range(0, T, step=dt)) - Ωre = t -> E₀ * flattop(t, T=T, t_rise=t_rise) - Ωim = t -> 0.0 + Ωre(t) = E₀ * flattop(t, T=T, t_rise=t_rise) + Ωim(t) = 0.0 return tlist, Ωre, Ωim @@ -225,7 +226,7 @@ objectives = [Objective(; initial_state=Ψ, generator=H) for Ψ ∈ basis]; # the Weyl chamber. Since the logical subspace defining the qubit is embedded # in the larger Hilbert space of the transmon, there may be loss of population # from the logical subspace. To counter this possibility in the optimization, -# we add a unitarity measure to $D_PE$. The two terms are added with equal +# we add a unitarity measure to $D_{PE}$. The two terms are added with equal # weight. using TwoQubitWeylChamber: D_PE, gate_concurrence, unitarity @@ -391,7 +392,7 @@ gate_concurrence(U_opt) # concurrence and (as above) a unitarity measure to penalize loss of population # from the logical subspace: -J_T_C = U -> 0.5 * (1 - gate_concurrence(U)) + 0.5 * (1 - unitarity(U)); +J_T_C(U) = 0.5 * (1 - gate_concurrence(U)) + 0.5 * (1 - unitarity(U)); # In the optimization, we will convert this functional to one that takes the # propagated states as arguments (via the `gate_functional` routine). diff --git a/examples/rho_3states.jl b/examples/rho_3states.jl index 847d147..8272b80 100644 --- a/examples/rho_3states.jl +++ b/examples/rho_3states.jl @@ -8,6 +8,7 @@ #md # Python package](https://qucontrol.github.io/krotov/v1.2.1/notebooks/06_example_3states.html). #md # ``\gdef\op#1{\hat{#1}}`` +#md # ``\gdef\ketbra#1#2{\vert#1\rangle\langle#2\vert}`` #md # ``\gdef\init{\text{init}}`` #md # ``\gdef\tgt{\text{tgt}}`` @@ -24,6 +25,7 @@ #nb # \newcommand{rwa}[0]{\text{rwa}} #nb # \newcommand{bra}[1]{\langle#1\vert} #nb # \newcommand{ket}[1]{\vert#1\rangle} +#nb # \newcommand{ketbra}[2]{\vert#1\rangle\langle#2\vert} #nb # \newcommand{Bra}[1]{\left\langle#1\right\vert} #nb # \newcommand{Ket}[1]{\left\vert#1\right\rangle} #nb # \newcommand{Braket}[2]{\left\langle #1\vphantom{#2}\mid{#2}\vphantom{#1}\right\rangle} @@ -47,9 +49,10 @@ # quantum system, where the dynamics is governed by the Liouville-von Neumann # equation. -using DrWatson -@quickactivate "KrotovTests" -#- +const PROJECTDIR = dirname(Base.active_project()) +projectdir(names...) = joinpath(PROJECTDIR, names...) +datadir(names...) = projectdir("data", names...) + using QuantumControl using LinearAlgebra using Serialization @@ -134,8 +137,8 @@ end const T = 400ns; -Ωre = t -> 35MHz * QuantumControl.Shapes.flattop(t; T=T, t_rise=20ns); -Ωim = t -> 0.0; +Ωre(t) = 35MHz * QuantumControl.Shapes.flattop(t; T=T, t_rise=20ns); +Ωim(t) = 0.0; L = transmon_liouvillian(Ωre, Ωim); @@ -147,7 +150,7 @@ function plot_control(pulse::Vector, tlist) plot(tlist, pulse, xlabel="time", ylabel="amplitude", legend=false) end -plot_control(ϵ::T, tlist) where {T<:Function} = plot_control([ϵ(t) for t in tlist], tlist); +plot_control(ϵ::Function, tlist) = plot_control([ϵ(t) for t in tlist], tlist); #- fig = plot_control(Ωre, tlist) #jl display(fig) @@ -155,7 +158,7 @@ fig = plot_control(Ωre, tlist) # ## Optimization objectives -# Our target gate is $\Op{O} = \sqrt{\text{iSWAP}}$: +# Our target gate is $\op{O} = \sqrt{\text{iSWAP}}$: SQRTISWAP = [ 1 0 0 0 @@ -166,16 +169,16 @@ SQRTISWAP = [ # The key idea explored in the paper is that a set of three density matrices is sufficient to track the optimization # -# $$ +# ```math # \begin{align} -# \Op{\rho}_1 +# \op{\rho}_1 # &= \sum_{i=1}^{d} \frac{2 (d-i+1)}{d (d+1)} \ketbra{i}{i} \\ -# \Op{\rho}_2 +# \op{\rho}_2 # &= \sum_{i,j=1}^{d} \frac{1}{d} \ketbra{i}{j} \\ -# \Op{\rho}_3 +# \op{\rho}_3 # &= \sum_{i=1}^{d} \frac{1}{d} \ketbra{i}{i} # \end{align} -# $$ +# ``` # In our case, $d=4$ for a two qubit-gate, and the $\ket{i}$, $\ket{j}$ are the canonical basis states $\ket{00}$, $\ket{01}$, $\ket{10}$, $\ket{11}$ @@ -212,12 +215,12 @@ const ρ̂₃_tgt = sum([(1 / d) * basis_tgt[i] * adjoint(basis_tgt[i]) for i # The three density matrices play different roles in the optimization, and, as # shown in the paper, convergence may improve significantly by weighing the # states relatively to each other. For this example, we place a strong emphasis -# on the optimization $\Op{\rho}_1 \rightarrow \Op{O}^\dagger \Op{\rho}_1 -# \Op{O}$, by a factor of 20. This reflects that the hardest part of the +# on the optimization $\op{\rho}_1 \rightarrow \op{O}^\dagger \op{\rho}_1 +# \op{O}$, by a factor of 20. This reflects that the hardest part of the # optimization is identifying the basis in which the gate is diagonal. We will # be using the real-part functional ($J_{T,\text{re}}$) to evaluate the success -# of $\Op{\rho}_i \rightarrow \Op{O}\Op{\rho}_i\Op{O}^\dagger$. Because -# $\Op{\rho}_1$ and $\Op{\rho}_3$ are mixed states, the Hilbert-Schmidt overlap +# of $\op{\rho}_i \rightarrow \op{O}\op{\rho}_i\op{O}^\dagger$. Because +# $\op{\rho}_1$ and $\op{\rho}_3$ are mixed states, the Hilbert-Schmidt overlap # will take values smaller than one in the optimal case. To compensate, we # divide the weights by the purity of the respective states. # @@ -259,10 +262,10 @@ function as_matrix(ρ⃗) return reshape(ρ⃗, N, N) end; -pop00 = ρ⃗ -> real(tr(as_matrix(ρ⃗) * ρ̂₀₀)); -pop01 = ρ⃗ -> real(tr(as_matrix(ρ⃗) * ρ̂₀₁)); -pop10 = ρ⃗ -> real(tr(as_matrix(ρ⃗) * ρ̂₁₀)); -pop11 = ρ⃗ -> real(tr(as_matrix(ρ⃗) * ρ̂₁₁)); +pop00(ρ⃗) = real(tr(as_matrix(ρ⃗) * ρ̂₀₀)); +pop01(ρ⃗) = real(tr(as_matrix(ρ⃗) * ρ̂₀₁)); +pop10(ρ⃗) = real(tr(as_matrix(ρ⃗) * ρ̂₁₀)); +pop11(ρ⃗) = real(tr(as_matrix(ρ⃗) * ρ̂₁₁)); rho_00_expvals = propagate_objective( @@ -298,6 +301,3 @@ opt_result = @optimize_or_load( method = :krotov ) #- -opt_result - -# ## Optimization result diff --git a/examples/simple_state_to_state.jl b/examples/simple_state_to_state.jl index 5eccd9b..844fb3e 100644 --- a/examples/simple_state_to_state.jl +++ b/examples/simple_state_to_state.jl @@ -47,9 +47,10 @@ # simple canonical optimization problem: the transfer of population in a two # level system. -using DrWatson -@quickactivate "KrotovTests" -#- +const PROJECTDIR = dirname(Base.active_project()) +projectdir(names...) = joinpath(PROJECTDIR, names...) +datadir(names...) = projectdir("data", names...) + using QuantumControl using QuantumPropagators.Controls: substitute using LinearAlgebra @@ -112,7 +113,7 @@ function plot_control(pulse::Vector, tlist) plot(tlist, pulse, xlabel="time", ylabel="amplitude", legend=false) end -plot_control(ϵ::T, tlist) where {T<:Function} = plot_control([ϵ(t) for t in tlist], tlist); +plot_control(ϵ::Function, tlist) = plot_control([ϵ(t) for t in tlist], tlist); #- fig = plot_control(ϵ, tlist) #jl display(fig) diff --git a/examples/state_to_state_parametrizations.jl b/examples/state_to_state_parametrizations.jl index 69c130a..1c71314 100644 --- a/examples/state_to_state_parametrizations.jl +++ b/examples/state_to_state_parametrizations.jl @@ -43,9 +43,10 @@ # This example illustrates the parametrization of control pulses as a # form of amplitude constraint. -using DrWatson -@quickactivate "KrotovTests" -#- +const PROJECTDIR = dirname(Base.active_project()) +projectdir(names...) = joinpath(PROJECTDIR, names...) +datadir(names...) = projectdir("data", names...) + using QuantumControl using QuantumControl.Shapes: flattop using QuantumControl.Generators diff --git a/test/Project.toml b/test/Project.toml index c8e58f2..c760fd4 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,5 +1,3 @@ -name = "KrotovTests" - [deps] BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" ConcreteStructs = "2569d6c7-a4a2-43d3-a901-331e8e4be471" @@ -8,7 +6,6 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -DrWatson = "634d3b9d-ee7a-5ddf-bec9-22491ea816e1" GRAPE = "6b52fcaf-80fe-489a-93e9-9f92080510be" GRAPELinesearchAnalysis = "290eba36-e2d8-4488-81b6-f66cc44f2186" JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" diff --git a/test/download_dumps.jl b/test/download_dumps.jl index 715aee3..393c49c 100644 --- a/test/download_dumps.jl +++ b/test/download_dumps.jl @@ -1,22 +1,25 @@ -using DrWatson -@quickactivate "KrotovTests" import Downloads +const PROJECTDIR = dirname(Base.active_project()) +projectdir(names...) = joinpath(PROJECTDIR, names...) +datadir(names...) = projectdir("data", names...) + + DOWNLOADS = Dict( "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/DissGateOCT%23J_T%3DJ_T_re%23iter_stop%3D3000%23method%3Dkrotov.jld2" => - joinpath(datadir(), "DissGateOCT#J_T=J_T_re#iter_stop=3000#method=krotov.jld2"), + datadir("DissGateOCT#J_T=J_T_re#iter_stop=3000#method=krotov.jld2"), "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/parametrization%23opt_result_logisticsq.jld2" => - joinpath(datadir(), "parametrization#opt_result_logisticsq.jld2"), + datadir("parametrization#opt_result_logisticsq.jld2"), "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/parametrization%23opt_result_positive.jld2" => - joinpath(datadir(), "parametrization#opt_result_positive.jld2"), + datadir("parametrization#opt_result_positive.jld2"), "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/parametrization%23opt_result_tanh.jld2" => - joinpath(datadir(), "parametrization#opt_result_tanh.jld2"), + datadir("parametrization#opt_result_tanh.jld2"), "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/parametrization%23opt_result_tanhsq.jld2" => - joinpath(datadir(), "parametrization#opt_result_tanhsq.jld2"), + datadir("parametrization#opt_result_tanhsq.jld2"), "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/PE_OCT.jld2" => - joinpath(datadir(), "PE_OCT.jld2"), + datadir("PE_OCT.jld2"), "https://github.com/JuliaQuantumControl/Krotov.jl/raw/data-dump/PE_OCT_direct.jld2" => - joinpath(datadir(), "PE_OCT_direct.jld2"), + datadir("PE_OCT_direct.jld2"), ) function download_dump(url, destination; force=false, verbose=true) diff --git a/test/init.jl b/test/init.jl index 9261dfa..429340d 100644 --- a/test/init.jl +++ b/test/init.jl @@ -8,7 +8,10 @@ using LiveServer: LiveServer, serve, servedocs as _servedocs using Term include(joinpath(@__DIR__, "clean.jl")) -servedocs(; kwargs...) = _servedocs(; skip_dirs=["docs/src/examples"], kwargs...) +function servedocs(; kwargs...) + clean() + _servedocs(; skip_dirs=["docs/src/examples"], kwargs...) +end REPL_MESSAGE = """ ******************************************************************************* diff --git a/test/runtests.jl b/test/runtests.jl index 8d24360..1de52e3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,9 +4,9 @@ using Plots unicodeplots() -include(joinpath(@__DIR__, "generate_example_tests.jl")) +include("generate_example_tests.jl") -include(joinpath(@__DIR__, "download_dumps.jl")) +include("download_dumps.jl") # Note: comment outer @testset to stop after first @safetestset failure @time @testset verbose = true "Krotov.jl Package" begin