-
Notifications
You must be signed in to change notification settings - Fork 10
Adding a new solver to QuDynamics !
This page aims at providing an insight on how a new solver can be integrated into QuDynamics. So lets get started ! For example, let us try to integrate the exponential solver which uses expm
implementation from the Base
. We start by looking for the place where our new solver would fit, in this case it would be nice if we could have it in propexpmsolvers.jl
file. In any case, for the new solver if there is no domain which you find suitable, please do send in a PR and we could decide on the placing of the solver.
- We start by defining a
type
for the solver which would be a subtype ofQuPropagatorMethod
. Here in this case as we already haveQuExponential
as a subtype ofQuPropagatorMethod
we would like to haveQuExponential
as the supertype of the new exponential solver. Let us call the solver QuExpm_Base, (please do note that adding aQu
prefix would be consistent in defining new structures in QuDynamics).
# In this case, we have
QuExpm_Base <: QuExponential
# For a general solver, we have
QuName_of_the_Solver <: QuPropagatorMethod
- The next thing is to code the logic which evolves the state using the solver, which we place in the propagate method. Here in this case, we have a simple logic that is : the next state is got by exponentiation of
-im*hamiltonian*time_step
and multiplying by the evolved state from the previous step. We place this entire logic by defining a newpropagate
method, as follows:
function propagate(prob::QuExpm_Base, eq::QuEquation, t, current_t, current_qustate)
dt = t - current_t
dims = size(current_qustate)
next_state = Base.expm(-im*coeffs(operator(eq))*dt)*coeffs(vec(current_qustate))
CQST = QuBase.similar_type(current_qustate)
return CQST(reshape(next_state, dims), bases(current_qustate))
end
We drop in few lines of code along with the logic to make it a consistent structure, which should be easy to read. We also add the solver to export list at the end
export QuExpokit,
QuExpmV,
QuExpm_Base
That's it ! We have added a new solver to QuDynamics ! But we would like to test the solver locally and add these as test cases before sending in a pull request. For testing the newly added solver we do the following:
# call the file which has been edited locally, here we already have
# added the solver in one of the existing files that is propexpmsolvers.jl
# which has been included in QuDynamics.jl, calling this alone should suffice
# however, if a new file has been created for the solver then we include
# the new file in QuDynamics.jl/src/QuDynamics.jl
require("QuDynamics.jl/src/QuDynamics.jl")
# we use QuBase and QuDynamics, the former for defining the
# parameters of the system and the latter for testing the new solver
using QuBase
using QuDynamics
# Let us define a simple system
hamiltonian = sigmax
initial_state = statevec(1, FiniteBasis(2))
time_array = 0.:0.1:2*pi
# let us compare the evolved state of QuExpm_Base to that of the QuExpmV
qprop_expmv = QuPropagator(hamiltonian, initial_state, time_array, QuExpmV())
qprop_expm_base = QuPropagator(hamiltonian, initial_state, time_array, QuExpm_Base())
next_state_expmv = next(qprop_expmv, start(qprop_expmv))
next_state_expm_base = next(qprop_expm_base, start(qprop_expm_base))
println("Printing the next state using QuExpmV : ", next_state_expmv)
println("Printing the next state using QuExpm_Base : ", next_state_expm_base)
Calling the above file would result in the following :
Printing the next state using QuExpmV : 2-element QuVector in FiniteBasis{Orthonormal}:
...coefficients: Array{Complex{Float64},1}
Complex{Float64}[0.9950041652780258 + 0.0im,0.0 - 0.09983341664682817im]
Printing the next state using QuExpm_Base : 2-element QuVector in FiniteBasis{Orthonormal}:
...coefficients: Array{Complex{Float64},1}
Complex{Float64}[0.9950041652780257 + 0.0im,0.0 - 0.09983341664682811im]
And hence we have similar results ! This is just an example as we need to do the comparison other way around (please do look into the tests section of the repo). The next steps should be simple :
- Adding relevant tests
- Documenting the new types and as well adding the solver to the only place where
propagate
is documented ! (I guess we have done it inpropstepsolvers.jl
). I guess there is no need to worry about the docs being generated usingdocbuild.jl
. - Now that we have everything running smoothly on the local branch, if you wish to add this to QuDynamics (we always wish to have new solvers being added !) just create a new branch, commit the changes and send in a PR !