Question

I am having trouble sovling the optical bloch equation, which is a first order ODE system with complex values. I have found scipy may solve such system, but their webpage offers too little information and I can hardly understand it.

I have 8 coupled first order ODEs, and I should generate a function like:

def derv(y):
    compute the time dervative of elements in y
    return answers as an array

then do complex_ode(derv)

My questions are:

  1. my y is not a list but a matrix, how can i give a corrent output fits into complex_ode()?
  2. complex_ode() needs a jacobian, I have no idea how to start constructing one and what type it should be?
  3. Where should I put the initial conditions like in the normal ode and time linspace?

this is scipy's complex_ode link: http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.complex_ode.html

Could anyone provide me with more infomation so that I can learn a bit more.

Was it helpful?

Solution

I think we can at least point you in the right direction. The optical bloch equation is a problem which is well understood in the scientific community, although not by me :-), so there are already solutions on the internet to this particular problem.

http://massey.dur.ac.uk/jdp/code.html

However, to address your needs, you spoke of using complex_ode, which I suppose is fine, but I think just plain scipy.integrate.ode will work just fine as well according to their documentation:

 from scipy import eye
 from scipy.integrate import ode

 y0, t0 = [1.0j, 2.0], 0

 def f(t, y, arg1):
     return [1j*arg1*y[0] + y[1], -arg1*y[1]**2]
 def jac(t, y, arg1):
     return [[1j*arg1, 1], [0, -arg1*2*y[1]]]
 r = ode(f, jac).set_integrator('zvode', method='bdf', with_jacobian=True)
 r.set_initial_value(y0, t0).set_f_params(2.0).set_jac_params(2.0)
 t1 = 10
 dt = 1
 while r.successful() and r.t < t1:
     r.integrate(r.t+dt)
     print r.t, r.y

You also have the added benefit of an older more established and better documented function. I am surprised you have 8 and not 9 coupled ODE's, but I'm sure you understand this better than I. Yes, you are correct, your function should be of the form ydot = f(t,y), which you call def derv() but you're going to need to make sure your function takes at least two parameters like derv(t,y). If your y is in matrix, no problem! Just "reshape" it in the derv(t,y) function like so:

Y = numpy.reshape(y,(num_rows,num_cols));

As long as num_rows*num_cols = 8, your number of ODE's you should be fine. Then use the matrix in your computations. When you're all done, just be sure to return a vector and not a matrix like:

out = numpy.reshape(Y,(8,1));

The Jacobian is not required, but it will likely allow the computation to proceed much more quickly. If you do not know how to compute this you may want to consult wikipedia or a calculus text book. It's pretty simple, but can be time consuming.

As far as initial conditions, you should probably already know what those should be, whether it's complex or real valued. As long as you select values that are within reason, it shouldn't matter much.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top