1# This file is part of QuTiP: Quantum Toolbox in Python. 2# 3# Copyright (c) 2011 and later, Paul D. Nation and Robert J. Johansson. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are 8# met: 9# 10# 1. Redistributions of source code must retain the above copyright notice, 11# this list of conditions and the following disclaimer. 12# 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 17# 3. Neither the name of the QuTiP: Quantum Toolbox in Python nor the names 18# of its contributors may be used to endorse or promote products derived 19# from this software without specific prior written permission. 20# 21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32############################################################################### 33import numpy as np 34from numpy.testing import assert_equal, assert_, run_module_suite 35import unittest 36from qutip import * 37import qutip.settings as qset 38if qset.has_openmp: 39 from qutip.cy.openmp.benchmark import _spmvpy, _spmvpy_openmp 40 41 42@unittest.skipIf(qset.has_openmp == False, 'OPENMP not available.') 43def test_openmp_spmv(): 44 "OPENMP : spmvpy_openmp == spmvpy" 45 for k in range(100): 46 L = rand_herm(10,0.25).data 47 vec = rand_ket(L.shape[0],0.25).full().ravel() 48 out = np.zeros_like(vec) 49 out_openmp = np.zeros_like(vec) 50 _spmvpy(L.data, L.indices, L.indptr, vec, 1, out) 51 _spmvpy_openmp(L.data, L.indices, L.indptr, vec, 1, out_openmp, 2) 52 assert_(np.allclose(out, out_openmp, 1e-15)) 53 54@unittest.skipIf(qset.has_openmp == False, 'OPENMP not available.') 55def test_openmp_mesolve(): 56 "OPENMP : mesolve" 57 N = 100 58 wc = 1.0 * 2 * np.pi # cavity frequency 59 wa = 1.0 * 2 * np.pi # atom frequency 60 g = 0.05 * 2 * np.pi # coupling strength 61 kappa = 0.005 # cavity dissipation rate 62 gamma = 0.05 # atom dissipation rate 63 n_th_a = 1 # temperature in frequency units 64 use_rwa = 0 65 # operators 66 a = tensor(destroy(N), qeye(2)) 67 sm = tensor(qeye(N), destroy(2)) 68 # Hamiltonian 69 if use_rwa: 70 H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() * sm + a * sm.dag()) 71 else: 72 H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() + a) * (sm + sm.dag()) 73 c_op_list = [] 74 75 rate = kappa * (1 + n_th_a) 76 if rate > 0.0: 77 c_op_list.append(np.sqrt(rate) * a) 78 79 rate = kappa * n_th_a 80 if rate > 0.0: 81 c_op_list.append(np.sqrt(rate) * a.dag()) 82 83 rate = gamma 84 if rate > 0.0: 85 c_op_list.append(np.sqrt(rate) * sm) 86 87 n = N - 2 88 psi0 = tensor(basis(N, n), basis(2, 1)) 89 tlist = np.linspace(0, 1, 100) 90 opts = Options(use_openmp=False) 91 out = mesolve(H, psi0, tlist, c_op_list, [a.dag() * a, sm.dag() * sm], options=opts) 92 opts = Options(use_openmp=True) 93 out_omp = mesolve(H, psi0, tlist, c_op_list, [a.dag() * a, sm.dag() * sm], options=opts) 94 assert_(np.allclose(out.expect[0],out_omp.expect[0])) 95 assert_(np.allclose(out.expect[1],out_omp.expect[1])) 96 97 98@unittest.skipIf(qset.has_openmp == False, 'OPENMP not available.') 99def test_openmp_mesolve_td(): 100 "OPENMP : mesolve (td)" 101 N = 100 102 wc = 1.0 * 2 * np.pi # cavity frequency 103 wa = 1.0 * 2 * np.pi # atom frequency 104 g = 0.5 * 2 * np.pi # coupling strength 105 kappa = 0.005 # cavity dissipation rate 106 gamma = 0.05 # atom dissipation rate 107 n_th_a = 1 # temperature in frequency units 108 use_rwa = 0 109 # operators 110 a = tensor(destroy(N), qeye(2)) 111 sm = tensor(qeye(N), destroy(2)) 112 # Hamiltonian 113 H0 = wc * a.dag() * a + wa * sm.dag() * sm 114 H1 = g * (a.dag() + a) * (sm + sm.dag()) 115 116 H = [H0, [H1,'sin(t)']] 117 118 c_op_list = [] 119 120 rate = kappa * (1 + n_th_a) 121 if rate > 0.0: 122 c_op_list.append(np.sqrt(rate) * a) 123 124 rate = kappa * n_th_a 125 if rate > 0.0: 126 c_op_list.append(np.sqrt(rate) * a.dag()) 127 128 rate = gamma 129 if rate > 0.0: 130 c_op_list.append(np.sqrt(rate) * sm) 131 132 n = N - 10 133 psi0 = tensor(basis(N, n), basis(2, 1)) 134 tlist = np.linspace(0, 1, 100) 135 opts = Options(use_openmp=True) 136 out_omp = mesolve(H, psi0, tlist, c_op_list, [a.dag() * a, sm.dag() * sm], options=opts) 137 opts = Options(use_openmp=False) 138 out = mesolve(H, psi0, tlist, c_op_list, [a.dag() * a, sm.dag() * sm], options=opts) 139 assert_(np.allclose(out.expect[0],out_omp.expect[0])) 140 assert_(np.allclose(out.expect[1],out_omp.expect[1])) 141 142if __name__ == "__main__": 143 run_module_suite() 144