qojulia / QuantumOptics.jl

Library for the numerical simulation of closed as well as open quantum systems.
http://qojulia.org
Other
518 stars 101 forks source link

usability/documentation improvement: MethodError typehints when picking the wrong master equation function and better `see also` sections in the documentation #386

Closed Krastanov closed 3 weeks ago

Krastanov commented 2 months ago

See https://discourse.julialang.org/t/quantumoptics-jl-time-dependent-hamiltonian-cannot-run/113448

When someone picks master instead of master_dynamic, the MethodError message is not particularly clear. We can use the error message hint functionality to tell them they should probably use master_dynamic. We should also add references in a see also section so that people looking into one of the methods can easily see there is a related method.

gfq960906 commented 2 months ago

Provide an example to supplement this question:

When we use the time-dependent Hamiltonian

function Hami(t,rho)
    detuning = Delta_0*t + (2*delta*sin((omega_0*t)/2)^2)/omega_0

    H1 = Omega/2*exp(-1im*(beta*pi/2-alpha-pi/2))*exp(-1im*detuning)*sr⊗dagger(minus) + Omega/2*exp(1im*(beta*pi/2-alpha-pi/2))*exp(1im*detuning)*minus⊗dagger(sr)
    H2 = Omega/2*exp(-1im*(beta*pi/2-alpha-pi/2))*exp(-1im*detuning)*sr⊗dagger(s1) + Omega/2*exp(1im*(beta*pi/2-alpha-pi/2))*exp(1im*detuning)*s1⊗dagger(sr)

    return tensor(H1, eye4) + tensor(eye4, H2) + Urr*tensor(sr⊗dagger(sr), sr⊗dagger(sr))
end

we need to run the evolution by

tout, pops = timeevolution.schroedinger_dynamic(tlist, psi_0, Hami)
a-eghrari commented 2 months ago

I would like to work on this as my first issue. From the discussion, I understood that we want to add See also: master_dynamic to the documentation of the function master. Something like

"""
    timeevolution.master(tspan, rho0, L; <keyword arguments>)

Time-evolution according to a master equation with a Liouvillian superoperator `L`.
# Arguments
* `tspan`: Vector specifying the points of time for which output should
        be displayed.
* `rho0`: Initial density operator. Can also be a state vector which is
        automatically converted into a density operator.
* `L`: Superoperator defining the right-hand-side of the master equation.
* `fout=nothing`: If given, this function `fout(t, rho)` is called every time
        an output should be displayed. ATTENTION: The given state rho is not
        permanent! It is still in use by the ode solver and therefore must not
        be changed.
* `kwargs...`: Further arguments are passed on to the ode solver.

See also: [`master_dynamic`](@ref)
"""

But to address the first task, I have a question: is it acceptable to have the message hint (by using register_error_hint) every time there is a MethodError related to master? For example

julia> timeevolution.master(0:100, 2)
ERROR: MethodError: no method matching master(::UnitRange{Int64}, ::Int64)
  HINT: If your Hamiltonian is time-dependent, you may want to use master_dynamic instead of master to solve time evolution.

Closest candidates are:
  master(::Any, ::Operator, ::AbstractOperator, ::Any; rates, Jdagger, fout, kwargs...)
   @ QuantumOptics ~/.julia/dev/QuantumOptics/src/master.jl:83
  master(::Any, ::Operator, ::SuperOperator; fout, kwargs...)
   @ QuantumOptics ~/.julia/dev/QuantumOptics/src/master.jl:123
  master(::Any, ::Ket, ::Any...; kwargs...)
   @ QuantumOptics ~/.julia/dev/QuantumOptics/src/master.jl:232

Stacktrace:
 [1] top-level scope
   @ REPL[3]:1
Krastanov commented 1 month ago

Thanks for submitting the pull request, @a-eghrari , it is greatly appreciated!

My initial reaction was that we probably want more checks to avoid giving the hint when it is not appropriate. But given that we never enter the method, that might be too cumbersome. Do you have any thoughts on that?

Krastanov commented 3 weeks ago

fixed by #395