QuTiP development notebook for testing steadystate solvers

Copyright (C) 2013, Paul D. Nation & Robert J. Johansson


In [1]:
%pylab inline


Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].
For more information, type 'help(pylab)'.

In [2]:
from qutip import *

In [3]:
import time

Setup


In [4]:
reps = 1

In [5]:
from IPython.display import HTML

In [6]:
def show_bm_mat(bm_mat, solvers):
    
    m = bm_mat[bm_mat > 0].min()
    
    html = "<table>"

    html += "<tr><td><b>Solver</b></td><td><b>Elapsed time</b></td><td><b>Ratio</b></td></tr>"
    
    for idx, (desc, func) in enumerate(solvers):
    
        if bm_mat[idx] == m:
            html += "<tr><td><b>%s</b></td><td><b>%.8f</b></td><td><b>%.2f</b></td></tr>" % \
                (desc, bm_mat[idx], bm_mat[idx]/m)
        else:
            html += "<tr><td>%s</td><td>%.8f</td><td>%.2f</td></tr>" % \
                (desc, bm_mat[idx], bm_mat[idx]/m)
            
    
    html += "</table>"

    return HTML(html)

In [7]:
def benchmark_steadystate_solvers(args, solvers, problem_func):

    bm_mat = zeros(len(solvers))

    H, c_ops = problem_func(args)
    
    for sol_idx, solver in enumerate(solvers):
        solver_name, solver_func = solver
        try:
            t1 = time.time()
            for r in range(reps):
                rhoss = solver_func(H, c_ops)
            t2 = time.time()
            bm_mat[sol_idx] = (t2 - t1)/reps
    
        except:
            bm_mat[sol_idx] = nan
            
    return bm_mat

In [8]:
solvers = [["power use_umfpack=True",          
            lambda H, c_ops: steadystate(H, c_ops, method='power', use_umfpack=True)],
           ["power use_umfpack=False",         
            lambda H, c_ops: steadystate(H, c_ops, method='power', use_umfpack=False)],
           ["direct sparse use_umfpack=True",  
            lambda H, c_ops: steadystate(H, c_ops, use_umfpack=True, sparse=True)],
           ["direct sparse use_umfpack=False", 
            lambda H, c_ops: steadystate(H, c_ops, use_umfpack=False, sparse=True)],
           ["iterative use_precond=True",      
            lambda H, c_ops: steadystate(H, c_ops, method='iterative', use_precond=True)],
           ["iterative use_precond=False",     
            lambda H, c_ops: steadystate(H, c_ops, method='iterative', use_precond=False)],
           ["iterative-bicg use_precond=True",  
            lambda H, c_ops: steadystate(H, c_ops, method='iterative-bicg', use_precond=True)],
           ["iterative-bicg use_precond=False", 
            lambda H, c_ops: steadystate(H, c_ops, method='iterative-bicg', use_precond=False)],
           ["direct dense use_umfpack=True",   
            lambda H, c_ops: steadystate(H, c_ops, use_umfpack=True, sparse=False)],
           ["direct dense use_umfpack=False",  
            lambda H, c_ops: steadystate(H, c_ops, use_umfpack=False, sparse=False)],
           ["svd_dense",                       
            lambda H, c_ops: steadystate(H, c_ops, method='svd')],
           ["lu",                              
            lambda H, c_ops: steadystate(H, c_ops, method='lu')],
          ]

In [9]:
large_solvers = [
    ["power use_umfpack=True",          
     lambda H, c_ops: steadystate(H, c_ops, method='power', use_umfpack=True)],
    ["power use_umfpack=False",         
     lambda H, c_ops: steadystate(H, c_ops, method='power', use_umfpack=False)],
    ["direct sparse use_umfpack=True",  
     lambda H, c_ops: steadystate(H, c_ops, use_umfpack=True, sparse=True)],
    ["direct sparse use_umfpack=False", 
     lambda H, c_ops: steadystate(H, c_ops, use_umfpack=False, sparse=True)],
    ["iterative use_precond=True",      
     lambda H, c_ops: steadystate(H, c_ops, method='iterative', use_precond=True)],
    ["iterative-bicg use_precond=True",  
     lambda H, c_ops: steadystate(H, c_ops, method='iterative-bicg', use_precond=True)],
   ]

Test problem 1


In [10]:
def bm_problem1(N):

    a = tensor(destroy(N), identity(2))
    b = tensor(identity(N), destroy(2))

    H = a.dag() * a + b.dag() * b + 0.25 * (a + a.dag()) * (b + b.dag())

    c_ops = [sqrt(0.1) * a, sqrt(0.075) * a.dag(), sqrt(0.1) * b]
    
    return H, c_ops

In [11]:
bm_mat = benchmark_steadystate_solvers(10, solvers, bm_problem1)
show_bm_mat(bm_mat, solvers)


Out[11]:
SolverElapsed timeRatio
power use_umfpack=True0.029301171.86
power use_umfpack=False0.027691841.76
direct sparse use_umfpack=True0.016577721.05
direct sparse use_umfpack=False0.015777111.00
iterative use_precond=True0.018871311.20
iterative use_precond=False0.4271519227.07
iterative-bicg use_precond=True0.018245221.16
iterative-bicg use_precond=False0.059676653.78
direct dense use_umfpack=True0.036807062.33
direct dense use_umfpack=False0.035973552.28
svd_dense0.4354958527.60
lu0.015813591.00

In [12]:
bm_mat = benchmark_steadystate_solvers(50, large_solvers, bm_problem1)
show_bm_mat(bm_mat, large_solvers)


Out[12]:
SolverElapsed timeRatio
power use_umfpack=True0.308600662.16
power use_umfpack=False0.309067492.16
direct sparse use_umfpack=True0.262234451.83
direct sparse use_umfpack=False0.304351572.13
iterative use_precond=True0.143191581.00
iterative-bicg use_precond=True0.144336701.01

Test problem 2: high temperature harmonic oscillator


In [13]:
def bm_problem2(N):
    
    a = destroy(N)
    H = a.dag() * a
    nth = N / 4
    gamma = 0.05
    c_ops = [sqrt(gamma * (nth + 1)) * a, sqrt(gamma * nth) * a.dag()]

    return H, c_ops

In [14]:
bm_mat = benchmark_steadystate_solvers(50, solvers, bm_problem2)
show_bm_mat(bm_mat, solvers)


Out[14]:
SolverElapsed timeRatio
power use_umfpack=True0.030913832.33
power use_umfpack=False0.027934312.11
direct sparse use_umfpack=True0.015746591.19
direct sparse use_umfpack=False0.013266801.00
iterative use_precond=True0.018147471.37
iterative use_precond=False0.087285526.58
iterative-bicg use_precond=True0.017312291.30
iterative-bicg use_precond=False0.031406402.37
direct dense use_umfpack=True3.13456941236.27
direct dense use_umfpack=False3.13574004236.36
svd_dense71.838504085414.91
lu0.013910771.05

Test problem 3: Coupled oscillators


In [15]:
def bm_problem3(N):
    
    a = tensor(destroy(N), identity(N))
    b = tensor(identity(N), destroy(N))
    
    H = a.dag() * a + 0.25 * b.dag() * b + 0.05 * a.dag() * a * (b + b.dag()) + 0.1 * (a + a.dag()) 

    c_ops = [sqrt(0.05) * a, sqrt(0.015) * a.dag(), sqrt(0.1) * b, sqrt(0.075) * b.dag()]

    return H, c_ops

In [16]:
bm_mat = benchmark_steadystate_solvers(10, large_solvers, bm_problem3)
show_bm_mat(bm_mat, large_solvers)


Out[16]:
SolverElapsed timeRatio
power use_umfpack=True5.094226367.99
power use_umfpack=False35.7943534956.16
direct sparse use_umfpack=True5.805845029.11
direct sparse use_umfpack=False30.2062852447.40
iterative use_precond=True0.716620211.12
iterative-bicg use_precond=True0.637322901.00

Test problem 4: a two level system


In [17]:
def bm_problem4(args=None):

    sz = sigmaz()    
    sx = sigmax()
    
    H = sz
    c_ops = [sqrt(0.05) * sx]

    return H, c_ops

In [18]:
bm_mat = benchmark_steadystate_solvers(None, solvers, bm_problem4)
show_bm_mat(bm_mat, solvers)


Out[18]:
SolverElapsed timeRatio
power use_umfpack=True0.018521793.05
power use_umfpack=False0.017549752.89
direct sparse use_umfpack=True0.007075311.17
direct sparse use_umfpack=False0.006877901.13
iterative use_precond=True0.007096771.17
iterative use_precond=False0.007111071.17
iterative-bicg use_precond=True0.016734362.76
iterative-bicg use_precond=False0.006780621.12
direct dense use_umfpack=True0.006115441.01
direct dense use_umfpack=False0.006063941.00
svd_dense0.007694961.27
lu0.006518361.07

Test problem 5: spin chain


In [19]:
def bm_problem5(N=1):

    H = 0
    for m in range(N):
        H += tensor([sigmaz() if n == m else identity(2) for n in range(N)])

    for m in range(N-1):
        H += tensor([sigmax() if n in [m,m+1] else identity(2) for n in range(N)])      
        
    c_ops = [sqrt(0.05) * tensor([sigmam() if n == m else identity(2) for n in range(N)])
             for m in range(N)]
   
    return H, c_ops

In [20]:
bm_mat = benchmark_steadystate_solvers(2, solvers, bm_problem5)
show_bm_mat(bm_mat, solvers)


Out[20]:
SolverElapsed timeRatio
power use_umfpack=True0.021501302.35
power use_umfpack=False0.020940782.28
direct sparse use_umfpack=True0.010230061.12
direct sparse use_umfpack=False0.009975911.09
iterative use_precond=True0.010204791.11
iterative use_precond=False0.010334491.13
iterative-bicg use_precond=True0.009714841.06
iterative-bicg use_precond=False0.010103461.10
direct dense use_umfpack=True0.009189841.00
direct dense use_umfpack=False0.009165531.00
svd_dense0.010971311.20
lu0.009572031.04

In [21]:
bm_mat = benchmark_steadystate_solvers(4, solvers, bm_problem5)
show_bm_mat(bm_mat, solvers)


Out[21]:
SolverElapsed timeRatio
power use_umfpack=True0.031192781.59
power use_umfpack=False0.030974861.58
direct sparse use_umfpack=True0.019570111.00
direct sparse use_umfpack=False0.019614461.00
iterative use_precond=True0.025650021.31
iterative use_precond=False0.2790315214.26
iterative-bicg use_precond=True0.024167301.23
iterative-bicg use_precond=False0.066788433.41
direct dense use_umfpack=True0.024587151.26
direct dense use_umfpack=False0.024188281.24
svd_dense0.165172348.44
lu0.019600631.00

In [22]:
bm_mat = benchmark_steadystate_solvers(6, large_solvers, bm_problem5)
show_bm_mat(bm_mat, large_solvers)


/usr/local/lib/python3.3/dist-packages/qutip/steadystate.py:314: UserWarning: Preconditioning failed. Continuing without.
  UserWarning)
Out[22]:
SolverElapsed timeRatio
power use_umfpack=True1.099171881.08
power use_umfpack=False9.799975409.60
direct sparse use_umfpack=True1.021354201.00
direct sparse use_umfpack=False9.188909779.00
iterative use_precond=True13.4802668113.20
iterative-bicg use_precond=True2.671352622.62

Software versions


In [23]:
from qutip.ipynbtools import version_table

version_table()


Out[23]:
SoftwareVersion
OSposix [linux]
IPython1.0.dev
Numpy1.8.0.dev-c5694c5
QuTiP2.3.0.dev-169f358
Cython0.19.1
SciPy0.13.0.dev-38faf7c
Python3.3.1 (default, Apr 17 2013, 22:30:32) [GCC 4.7.3]
matplotlib1.4.x
Fri Jul 19 14:08:27 2013 JST