Skip to content
This repository has been archived by the owner on Aug 21, 2020. It is now read-only.

Adding a new solver to QuDynamics !

Amit edited this page Aug 28, 2015 · 1 revision

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 of QuPropagatorMethod. Here in this case as we already have QuExponential as a subtype of QuPropagatorMethod we would like to have QuExponential as the supertype of the new exponential solver. Let us call the solver QuExpm_Base, (please do note that adding a Qu 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 new propagate 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 in propstepsolvers.jl). I guess there is no need to worry about the docs being generated using docbuild.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 !
Clone this wiki locally