Hello,I have a program using Numeric and weave developed with Python2.3. I just switched to Python2.4 and numpy. The Numeric/weave version is almost a factor of 2 faster compared to numpy/weave. Is that what is to be expected or are there options to improve the speed of numpy/weave? I would be very appreciative for any help. Please find the source attached.
Regards Rolf -- ------------------------------------ # Dr. Rolf Wester # Fraunhofer Institut f. Lasertechnik # Steinbachstrasse 15, D-52074 Aachen, Germany. # Tel: + 49 (0) 241 8906 401, Fax: +49 (0) 241 8906 121 # EMail: [EMAIL PROTECTED] # WWW: http://www.ilt.fraunhofer.de
import math import sys if sys.version[0:3] == '2.3': from Numeric import * import weave else: from numpy import * import scipy.weave as weave Float64 = float64 Complex64 = complex128 cc = 2.997924e14 # mum/s mu0 = 1.256637e-12 # Vs/(A mum) eps0 = 1.0/(mu0*cc**2) # As/(V mum) Z0 = sqrt(mu0/eps0) pi = math.pi def make_spaces(n): s = "" for i in range(n): s = s + ' ' return s def split2(str, sep = ' \t\n\r', trimp = 'yes'): vstr = [] n0 = len(str) n = len(sep) ipos0 = 0 ipos1 = 0 while ipos1 < n0 and ipos0 < n0: ipos0 = ipos1 flag = 0 c2 = str[ipos0] for i in range(n): if(c2 == sep[i]): flag = 1 break while(flag == 1): ipos0 = ipos0+1 if(ipos0 > n0-1): break flag = 0 c2 = str[ipos0] for i in range(n): if(c2 == sep[i]): flag = 1 break if(ipos0 > n0-1): break ipos1 = ipos0 flag = 0 c2 = str[ipos1] for i in range(n): if c2 == sep[i]: flag = 1 break while flag == 0: ipos1 = ipos1+1 if ipos1 > n0-1: break flag = 0 c2 = str[ipos1] for i in range(n): if c2 == sep[i]: flag = 1 break if(ipos0 < ipos1): teil = str[ipos0:ipos1] if(trimp == 'yes'): teil = string.strip(teil) vstr.append(teil) return vstr class LSSOLV: def __init__(self, N): self.N = N self.gamma = zeros(N, Complex64) self.betai = zeros(N, Complex64) def inline_solve(self, a, b, c, d, y): betai = self.betai gamma = self.gamma N = self.N code = """ int i; betai[0] = 1.0/b[0]; for(i=1; i < N; i++) betai[i] = 1.0/(b[i]-a[i]*c[i-1]*betai[i-1]); gamma[0] = d[0]*betai[0]; for(i=1; i < N; i++) gamma[i] = (d[i]-a[i]*gamma[i-1])*betai[i]; y[N-1] = gamma[N-1]; for(i=N-2; i >= 0; i--) y[i] = gamma[i]-c[i]*y[i+1]*betai[i]; return_val = y[300]; """ err = weave.inline(code, ['a', 'b', 'c', 'd', 'betai', 'gamma', 'y', 'N'], #type_converters = weave.converters.blitz, compiler = 'gcc',verbose=2) return err def blitz_solve(self, a, b, c, d, y): betai = self.betai gamma = self.gamma N = self.N code = """ int i; betai(0) = 1.0/b(0); for(i=1; i < N; i++) betai(i) = 1.0/(b(i)-a(i)*c(i-1)*betai(i-1)); gamma(0) = d(0)*betai(0); for(i=1; i < N; i++) gamma(i) = (d(i)-a(i)*gamma(i-1))*betai(i); y(N-1) = gamma(N-1); for(i=N-2; i >= 0; i--) y(i) = gamma(i)-c(i)*y(i+1)*betai(i); return_val = y(300); """ err = weave.inline(code, ['a', 'b', 'c', 'd', 'betai', 'gamma', 'y', 'N'], type_converters = weave.converters.blitz, compiler = 'gcc') return err def solve(self, a, b, c, d, y): betai = self.betai gamma = self.gamma N = self.N betai[0] = 1.0/b[0] for i in range(1,N): betai[i] = 1.0/(b[i]-a[i]*c[i-1]*betai[i-1]) gamma[0] = d[0]*betai[0] for i in range(1,N): gamma[i] = (d[i]-a[i]*gamma[i-1])*betai[i] y[self.N-1] = gamma[N-1] for i in range(N-2,-1,-1): y[i] = gamma[i]-c[i]*y[i+1]*betai[i] class Parameter: def __init__(self, filename): self.map = {} ein = file(filename, 'r') inhalt = ein.readlines() head = '' for line in inhalt: line = split2(line,sep = '=#', trimp = 'yes') if len(line) > 0 and len(line[0]) > 0 and line[0][0] == '[' and line[0][len(line[0])-1] == ']': head = line[0][1:len(line[0])-1] if len(line) >= 2: self.map[head + '.' + line[0]] = line[1] def get(self, key, val): ret = val if self.map.has_key(key): if type(val) == type(1.0): ret = float(self.map[key]) elif type(val) == type(1): ret = int(self.map[key]) else: ret = self.map[key] return ret def set(self, key, val): if type(val) == type(1.0): self.map[key] = "%e" % val elif type(val) == type(1): self.map[key] = "%i" % val else: self.map[key] = val def print_parameter(self, out = None): list = [] for key in self.map: list.append([key, self.map[key]]) list.sort() lmax = 0 for key in self.map: n = len(key) if (n > lmax): lmax = n ausgabe = "---- parameter begin ----\n" for l in list: n = len(l[0]) spaces = make_spaces(lmax+2-n) ausgabe = ausgabe + l[0] + spaces + " = " + l[1] + '\n' ausgabe = ausgabe + "---- parameter end ----\n" if out == None: print ausgabe else: out.write("%s", ausgabe) class Crystal: def __init__(self): self.d_eff = 34.1e-6 #microm/V uebliche Angabe in pm/V -> 10^-12 m/V -> 10^-9 mm/V -> 10^-6 microm/V def get_deff(self): return self.d_eff def get_no(self, lamb): #lamb = lamb * 1.0e3 l2 = lamb*lamb n2 = self.Ae*l2/(l2-self.Be) + self.Ce*l2/(l2-self.De) + self.Ee*l2/(l2-self.Fe) if(n2+1 >= 0.0): return sqrt(n2+1) return 1.0 def get_ne(self, lamb): #lamb = lamb * 1.0e3 l2 = lamb*lamb n2 = self.Ao*l2/(l2-self.Bo) + self.Co*l2/(l2-self.Do) + self.Eo*l2/(l2-self.Fo) if(n2+1 >= 0.0): return sqrt(n2+1) return 1.0 def get_alpha(self, lamb): if (lamb <= 1.5 ): alpha = 0.005 elif (lamb >= 1.5 and lamb < 2.0): alpha = 0.005 elif (lamb >= 2.0 and lamb < 2.5): alpha = 0.009 elif (lamb >= 2.5 and lamb < 3.0): alpha = 0.012 elif (lamb >= 3.0 and lamb < 3.5): alpha = 0.018 elif (lamb >= 3.5 and lamb < 4.0): alpha = 0.03 elif (lamb >= 4.0 and lamb < 4.5): alpha = 0.08 elif (lamb >= 4.5 and lamb < 5.0): alpha = 0.12 elif (lamb >= 5.0): alpha = 0.12 return alpha*1.0e-3 class LiNbO3(Crystal): def __init__(self): self.Ao = 2.6734; self.Bo = 0.01764; self.Co = 1.2290; self.Do = 0.05914; self.Eo = 12.614; self.Fo = 474.6; self.Ae = 2.9804; self.Be = 0.02047; self.Ce = 0.5981; self.De = 0.0666; self.Ee = 8.9543; self.Fe = 416.08; Crystal.__init__(self) class LiNbO3Mg(Crystal): def __init__(self): self.Ae = 2.4372; self.Ao = 2.2454; self.Be = 0.01478; self.Bo = 0.01242; self.Ce = 1.4617; self.Co = 1.3005; self.De = 0.05612; self.Do = 0.05313; self.Ee = 9.6536; self.Eo = 6.8972; self.Fe = 416.08; self.Fo = 331.33; Crystal.__init__(self) class NLO: def __init__(self, par, log): self.k1 = zeros(3, Complex64) self.k2 = zeros(3, Complex64) self.k3 = zeros(3, Complex64) self.k4 = zeros(3, Complex64) self.y0 = zeros(3, Complex64) self.y = zeros(3, Complex64) self.log = log self.par = par self.lambda_s = self.par.get("beam.lambda_s", -1.0) self.lambda_i = self.par.get("beam.lambda_i", -1.0) self.lambda_p = self.par.get("beam.lambda_p", -1.0) if(self.lambda_s < 0.0): self.lambda_s = 1.0/(1.0/self.lambda_p - 1.0/self.lambda_i) if(self.lambda_i < 0.0): self.lambda_i = 1.0/(1.0/self.lambda_p - 1.0/self.lambda_s) if(self.lambda_p < 0.0): self.lambda_p = 1.0/(1.0/self.lambda_s + 1.0/self.lambda_i) self.par.set("beam.lambda_s", self.lambda_s) self.par.set("beam.lambda_i", self.lambda_i) self.par.set("beam.lambda_p", self.lambda_p) cr_type = self.par.get("crystal.type", "LiNbO3Mg") cr_oe = self.par.get("crystal.oe" , "o") if(cr_type == "LiNbO3"): cr = LiNbO3() else: cr = LiNbO3Mg() self.n_s = self.par.get("crystal.n_s", -1.5) self.n_i = self.par.get("crystal.n_i", -1.5) self.n_p = self.par.get("crystal.n_p", -1.5) if(self.n_s < 0.0): if(cr_oe == "e"): self.n_s = cr.get_ne(self.lambda_s) else: self.n_s = cr.get_no(self.lambda_s) if(self.n_i < 0.0): if(cr_oe == "e"): self.n_i = cr.get_ne(self.lambda_i) else: self.n_i = cr.get_no(self.lambda_i) if(self.n_p < 0.0): if(cr_oe == "e"): self.n_p = cr.get_ne(self.lambda_p) else: self.n_p = cr.get_no(self.lambda_p) self.par.set("crystal.n_s", self.n_s) self.par.set("crystal.n_p", self.n_p) self.par.set("crystal.n_i", self.n_i) self.nq_s = self.par.get("waveguide.nq_s", -1.0) self.nq_i = self.par.get("waveguide.nq_i", -1.0) self.nq_p = self.par.get("waveguide.nq_p", -1.0) if self.nq_s < 0.0: self.nq_s = self.n_s if self.nq_i < 0.0: self.nq_i = self.n_i if self.nq_p < 0.0: self.nq_p = self.n_p self.par.set("waveguide.nq_s", self.nq_s) self.par.set("waveguide.nq_i", self.nq_i) self.par.set("waveguide.nq_p", self.nq_p) self.alpha_s = self.par.get("crystal.alpha_s", -1.5) # 1/mm self.alpha_i = self.par.get("crystal.alpha_i", -1.5) # 1/mm self.alpha_p = self.par.get("crystal.alpha_p", -1.5) # 1/mm if(self.alpha_s < 0.0): self.alpha_s = cr.get_alpha(self.lambda_s) if(self.alpha_i < 0.0): self.alpha_i = cr.get_alpha(self.lambda_i) if(self.alpha_p < 0.0): self.alpha_p = cr.get_alpha(self.lambda_p) self.par.set("crystal.alpha_s", self.alpha_s); self.par.set("crystal.alpha_i", self.alpha_i); self.par.set("crystal.alpha_p", self.alpha_p); self.alpha_s = self.alpha_s * 0.5 self.alpha_i = self.alpha_i * 0.5 self.alpha_p = self.alpha_p * 0.5 self.k_s = 2.0*pi/self.lambda_s*self.n_s; self.k_i = 2.0*pi/self.lambda_i*self.n_i; self.k_p = 2.0*pi/self.lambda_p*self.n_p; self.par.set("waveguide.k_s", self.k_s) self.par.set("waveguide.k_i", self.k_i) self.par.set("waveguide.k_p", self.k_p) self.kq_s = 2.0*pi/self.lambda_s*self.nq_s; self.kq_i = 2.0*pi/self.lambda_i*self.nq_i; self.kq_p = 2.0*pi/self.lambda_p*self.nq_p; self.par.set("waveguide.kq_s", self.kq_s) self.par.set("waveguide.kq_i", self.kq_i) self.par.set("waveguide.kq_p", self.kq_p) self.omega_s = 2.0*pi * cc/self.lambda_s; self.omega_i = 2.0*pi * cc/self.lambda_i; self.omega_p = 2.0*pi * cc/self.lambda_p; self.dk0 = self.kq_p - self.kq_i - self.kq_s; if(abs(self.dk0) < 1.0e-7): self.dk = 0.0; else: self.dk = self.dk0; self.par.set("beam.dk" , self.dk); #1/mm self.deff = self.par.get("crystal.deff", -1.0) if(self.deff < 0.0): self.deff = cr.get_deff() self.par.set("crystal.deff", self.deff) self.cs = self.deff * self.omega_s / (cc * self.nq_s); self.ci = self.deff * self.omega_i / (cc * self.nq_i); self.cp = self.deff * self.omega_p / (cc * self.nq_p); self.par.set("crystal.cs", self.cs); self.par.set("crystal.ci", self.ci); self.par.set("crystal.cp", self.cp); self.z_coh = par.get("crystal.z_coh" , -1.0) if(self.z_coh < 0.0): if(self.dk != 0.0): self.z_coh = abs(pi/self.dk) else: self.z_coh = 1.0e20 self.par.set("crystal.z_coh", self.z_coh) self.dz = self.par.get("par.dz", -1.0) self.nsteps = self.par.get("par.nsteps", 0) self.naus = self.par.get("par.naus", 0) if(self.dz < 0.0): self.dz = self.z_coh/nsteps self.par.set("par.dz", self.dz) self.length = par.get("crystal.length", -1.0) h1 = -1.0e3 if(self.length > 0.0): h1 = self.length/(self.dz*self.nsteps) self.naus = int( h1+0.1 ) par.set("par.nsteps", self.nsteps) par.set("par.naus", self.naus) self.par.print_parameter() self.z = 0.0 def get_z_coh(self): return self.z_coh def get_dk(self): return dk def get_cs(self): return self.cs def get_ci(self): return self.ci def get_cp(self): return self.cp def inline_step(self, Es, Ei, Ep, ix1, ix2): k1 = self.k1 k2 = self.k2 k3 = self.k3 k4 = self.k4 y = self.y y0 = self.y0 alpha_s = self.alpha_s alpha_i = self.alpha_i alpha_p = self.alpha_p cs = self.cs ci = self.ci cp = self.cp dz = self.dz dkz = self.dk * dz a1 = int(floor(self.z/self.z_coh)) sign_c = -1.0; if int(floor(float(a1/2))) * 2 == a1: sign_c = 1.0 code = """ double h = dz; double hd3 = dz/3.0; double hd6 = dz/6.0; double hh = 0.5*dz; std::complex<double> im(0.0,1.0); std::complex<double> cs_ = im * sign_c * cs; std::complex<double> ci_ = im * sign_c * ci; std::complex<double> cp_ = im * sign_c * cp; std::complex<double> exp_parg = exp( im * dkz); std::complex<double> exp_marg = exp(- im * dkz); double as = alpha_s*0.5; double ai = alpha_i*0.5; double ap = alpha_p*0.5; int i,ix; int n = 3; for(ix = ix1; ix <= ix2; ix++) { y0[0] = Es[ix]; y0[1] = Ei[ix]; y0[2] = Ep[ix]; k1[0] = cs_ * y0[2] * conj(y0[1]) * exp_marg - as*y0[0]; k1[1] = ci_ * y0[2] * conj(y0[0]) * exp_marg - ai*y0[1]; k1[2] = cp_ * y0[0] * y0[1] * exp_parg - ap*y0[2]; for(i=0; i < n; i++) y[i] = y0[i] + hh * k1[i]; k2[0] = cs_ * y[2] * conj(y[1]) * exp_marg - as*y[0]; k2[1] = ci_ * y[2] * conj(y[0]) * exp_marg - ai*y[1]; k2[2] = cp_ * y[0] * y[1] * exp_parg - ap*y[2]; for(i=0; i < n; i++) y[i] = y0[i] + hh * k2[i]; k3[0] = cs_ * y[2] * conj(y[1]) * exp_marg - as*y[0]; k3[1] = ci_ * y[2] * conj(y[0]) * exp_marg - ai*y[1]; k3[2] = cp_ * y[0] * y[1] * exp_parg - ap*y[2]; for(i=0; i < n; i++) y[i] = y0[i] + h * k3[i]; k4[0] = cs_ * y[2] * conj(y[1]) * exp_marg - as*y[0]; k4[1] = ci_ * y[2] * conj(y[0]) * exp_marg - ai*y[1]; k4[2] = cp_ * y[0] * y[1] * exp_parg - ap*y[2]; Es[ix] = y0[0] + hd6 * (k1[0] + k4[0]) + hd3 * (k2[0] + k3[0]); Ei[ix] = y0[1] + hd6 * (k1[1] + k4[1]) + hd3 * (k2[1] + k3[1]); Ep[ix] = y0[2] + hd6 * (k1[2] + k4[2]) + hd3 * (k2[2] + k3[2]); } """ weave.inline(code, ['k1', 'k2', 'k3', 'k4', 'y', 'y0', 'Es', 'Ei', 'Ep', 'dz', 'ix1', 'ix2', 'dkz', 'cs', 'ci', 'cp', 'alpha_s', 'alpha_i', 'alpha_p', 'sign_c'], #type_converters = weave.converters.blitz, compiler = 'gcc') self.z = self.z + self.dz def step(self, Es, Ei, Ep, ix1, ix2, dkz): k1 = self.k1 k2 = self.k2 k3 = self.k3 k4 = self.k4 y = self.y y0 = self.y0 alpha_s = self.alpha_s alpha_i = self.alpha_i alpha_p = self.alpha_p cs = self.cs ci = self.ci cp = self.cp dz = self.dz h = dz hd3 = dz/3.0 hd6 = dz/6.0 hh = 0.5*dz im = 0.0+1.0j sign_c = 1.0 + 0.0j cs_ = im * sign_c * cs ci_ = im * sign_c * ci cp_ = im * sign_c * cp exp_parg = exp( im * dkz) exp_marg = exp(- im * dkz) as = alpha_s*0.5 ai = alpha_i*0.5 ap = alpha_p*0.5 n = 3 #print Es[300], Ei[300], Ep[300], exp_parg, cs_, ci_, cp_ for ix in range(ix1,ix2+1): y0[0] = Es[ix] y0[1] = Ei[ix] y0[2] = Ep[ix] k1[0] = cs_ * y0[2] * conjugate(y0[1]) * exp_marg - as*y0[0] k1[1] = ci_ * y0[2] * conjugate(y0[0]) * exp_marg - ai*y0[1] k1[2] = cp_ * y0[0] * y0[1] * exp_parg - ap*y0[2] for i in range(n): y[i] = y0[i] + hh * k1[i] k2[0] = cs_ * y[2] * conjugate(y[1]) * exp_marg - as*y[0] k2[1] = ci_ * y[2] * conjugate(y[0]) * exp_marg - ai*y[1] k2[2] = cp_ * y[0] * y[1] * exp_parg - ap*y[2] for i in range(n): y[i] = y0[i] + hh * k2[i] k3[0] = cs_ * y[2] * conjugate(y[1]) * exp_marg - as*y[0] k3[1] = ci_ * y[2] * conjugate(y[0]) * exp_marg - ai*y[1] k3[2] = cp_ * y[0] * y[1] * exp_parg - ap*y[2] for i in range(n): y[i] = y0[i] + h * k3[i] k4[0] = cs_ * y[2] * conjugate(y[1]) * exp_marg - as*y[0] k4[1] = ci_ * y[2] * conjugate(y[0]) * exp_marg - ai*y[1] k4[2] = cp_ * y[0] * y[1] * exp_parg - ap*y[2] Es[ix] = y0[0] + hd6 * (k1[0] + k4[0]) + hd3 * (k2[0] + k3[0]) Ei[ix] = y0[1] + hd6 * (k1[1] + k4[1]) + hd3 * (k2[1] + k3[1]) Ep[ix] = y0[2] + hd6 * (k1[2] + k4[2]) + hd3 * (k2[2] + k3[2]) self.z = self.z + self.dz class BPM1D: def __init__(self, par, wave, log): self.par = par self.log = log self.dz = self.par.get("par.dz", -1.0) self.nsteps = self.par.get("par.nsteps", 0) self.naus = self.par.get("par.naus", 0) self.w_core = self.par.get("waveguide.w_core", -1.0) self.w_cladding = self.par.get("waveguide.w_cladding", -1.0) self.nx = self.par.get("waveguide.nx", 1) self.alpha = self.par.get("waveguide.alpha", -1.0) self.n_cladding = self.par.get("waveguide.n_cladding", -1.0) self.nq = self.par.get("waveguide.nq_" + wave, -1.0) self.n_core = self.par.get("crystal.n_" + wave, -1.5) self.lamb = self.par.get("beam.lambda_" + wave, -1.0) self.P = self.par.get("beam.P_" + wave, -1.0) self.w0 = self.par.get("beam.w0_" + wave, -1.0) self.shape = self.par.get("beam.shape_" + wave, "gauss") self.omega = 2.0*math.pi/self.lamb*cc self.dx = (self.w_core + 2.0*self.w_cladding) / (self.nx-1) nkk = int(floor(self.w_cladding / self.dx)); self.E = zeros(self.nx, Complex64) self.n2 = zeros(self.nx, Complex64) for i in range(self.nx): self.n2[i] = self.n_cladding*self.n_cladding for i in range(nkk,self.nx-nkk): self.n2[i] = self.n_core*self.n_core self.ix1 = nkk self.ix2 = self.nx-nkk-1 self.a = zeros(self.nx, Complex64) self.b = zeros(self.nx, Complex64) self.c = zeros(self.nx, Complex64) self.d = zeros(self.nx, Complex64) self.k0 = self.k(1.0) + 0.0j self.k02 = self.k(1.0)*self.k(1.0) + 0.0j self.nq2 = self.nq*self.nq + 0.0j self.beta = self.k0*self.nq ## m_im = complex<double>(0.0, 1.0); ## m_cc0 = complex<double>(0.0, 0.0); ## m_cc1 = complex<double>(1.0, 0.0); self.ddx2 = 1.0/self.dx**2 self.x = zeros(self.nx, Float64) self.xmin = -(self.w_cladding+0.5*self.w_core) for i in range(self.nx): self.x[i] = self.xmin + i * self.dx; # init E for i in range(self.nx): self.E[i] = 0.0 + 0.0j if self.shape == "gauss": for i in range(self.nx): arg = self.x[i]*self.x[i]/(self.w0*self.w0) if arg < 700.0: self.E[i] = exp(- arg) + 0.0j elif self.shape == "sin": for i in range(nkk,self.nx-nkk): a = sin((i-nkk)*self.dx/self.w_core*pi) self.E[i] = a + 0.0j else: for i in range(self.nx): if abs(self.x[i]) <= self.w0: self.E[i] = 1.0 + 0.0j P = self.get_P() factor = sqrt(self.P/P) for i in range(self.nx): self.E[i] = self.E[i] * factor self.z = 0.0 self.lssolv = LSSOLV(self.nx) def k(self, n): return 2.0*pi / self.lamb * n def get_kq(self): return self.nq*self.k0 def set_E(self, E): for i in range(self.nx): self.E[i] = E[i] def get_E(self, E): for i in range(self.nx): E[i] = self.E[i] def get_I(self): dZq = 0.5*self.nq/Z0 I = dZq*((self.E*conjugate(self.E)).real) return I def get_phase(self): phase = zeros(self.nx, Float64) for i in range(self.nx): x = self.E[i].real y = self.E[i].imag if x > 0.0 and y >= 0.0: phase[i] = math.atan(y/x) elif x < 0.0 and y >= 0.0: phase[i] = pi - math.atan(-y/x) elif x < 0.0 and y <= 0.0: phase[i] = pi + math.atan(y/x) elif x > 0.0 and y <= 0.0: phase[i] = 2.0*pi - math.atan(-y/x) elif x == 0.0 and y >= 0.0: phase[i] = pi*0.5 elif x == 0.0 and y < 0.0: phase[i] = pi*1.5 return phase def get_P(self): I = self.get_I() P = 0.0 for i in range(self.nx): P = P + I[i] return P def compute_res(self): i = self.nx/2 ddx2 = self.ddx2 k02 = self.k02 n2 = self.n2 nq2 = self.nq2 a = ddx2*(self.E[i-1] + self.E[i+1]) - 2.0*ddx2 * self.E[i] c = pi**2/5.0**2*self.E[i] b = k02*(n2[i] - nq2)*self.E[i] return a,c,(c-b)/(2.0*self.beta),(a-b)/(2.0*self.beta) def blitz_set_matrix(self): im = 0.0 + 1.0j #(1,1) Pade # ? -> siehe Randbedingungen c1 = 1.0/(4.0 * self.k02*self.nq2) + im * self.dz* self.alpha / (2.0*self.k0*self.nq) c2 = 1.0/(4.0 * self.k02*self.nq2) - im * self.dz*(1.0-self.alpha) / (2.0*self.k0*self.nq) #paraxial approximation # ? -> siehe Randbedingungen #c1 = + im * self.dz* self.alpha / (2.0*self.k0*self.nq) #c2 = - im * self.dz*(1.0-self.alpha) / (2.0*self.k0*self.nq) a = self.a b = self.b c = self.c d = self.d E = self.E ddx2 = self.ddx2 k02 = self.k02 n2 = self.n2 nq2 = self.nq2 nx = self.nx code = """ int i; for(i = 0; i < nx; i++) { a(i) = c1*ddx2; c(i) = c1*ddx2; b(i) = 1.0 - 2.0*c1*ddx2 + c1*k02*(n2(i) - nq2); } for(i = 1; i < nx-1; i++) { d(i) = E(i) * (1.0 - 2.0*c2*ddx2 + c2*k02*(n2(i) - nq2)) + c2*ddx2*(E(i-1) + E(i+1)); } std::complex<double> gl(1.0,0.0); std::complex<double> gr(1.0,0.0); if (abs(E(1)) > 1.0e-20) gl = E(0)/E(1); if (abs(E(nx-2)) > 1.0e-20) gr = E(nx-1)/E(nx-2); std::complex<double> kr_g = log(gl); if(kr_g.imag() > 0.0) { kr_g = conj(kr_g); gl = exp(kr_g); } kr_g = log(gr); if(kr_g.imag() > 0.0) { kr_g = conj(kr_g); gr = exp(kr_g); } a(0) = std::complex<double>(0.0, 0.0); b(0) = b(0) + c1*ddx2*gl; d(0) = E(0) * (1.0 - 2.0*c2*ddx2 + c2*k02*(n2(0) - nq2)) + c2*ddx2*(gl*E(0) + E(1)); b(nx-1) = b(nx-1) + c1*ddx2*gr; c(nx-1) = std::complex<double>(0.0, 0.0); d(nx-1) = E(nx-1) * (1.0 - 2.0*c2*ddx2 + c2*k02*(n2(nx-1) - nq2)) + c2*ddx2*(gr*E(nx-1) + E(nx-2)); return_val = E(nx/2); """ err = weave.inline(code, ['a', 'b', 'c', 'd', 'E', 'ddx2', 'k02', 'n2', 'nq2', 'nx', 'c1', 'c2'], type_converters = weave.converters.blitz, compiler = 'gcc') return err def inline_set_matrix(self): im = 0.0 + 1.0j #(1,1) Pade # ? -> siehe Randbedingungen c1 = 1.0/(4.0 * self.k02*self.nq2) + im * self.dz* self.alpha / (2.0*self.k0*self.nq) c2 = 1.0/(4.0 * self.k02*self.nq2) - im * self.dz*(1.0-self.alpha) / (2.0*self.k0*self.nq) #paraxial approximation # ? -> siehe Randbedingungen #c1 = + im * self.dz* self.alpha / (2.0*self.k0*self.nq) #c2 = - im * self.dz*(1.0-self.alpha) / (2.0*self.k0*self.nq) a = self.a b = self.b c = self.c d = self.d E = self.E ddx2 = self.ddx2 k02 = self.k02 n2 = self.n2 nq2 = self.nq2 nx = self.nx code = """ int i; for(i = 0; i < nx; i++) { a[i] = c1*ddx2; c[i] = c1*ddx2; b[i] = 1.0 - 2.0*c1*ddx2 + c1*k02*(n2[i] - nq2); } for(i = 1; i < nx-1; i++) { d[i] = E[i] * (1.0 - 2.0*c2*ddx2 + c2*k02*(n2[i] - nq2)) + c2*ddx2*(E[i-1] + E[i+1]); } std::complex<double> gl(1.0,0.0); std::complex<double> gr(1.0,0.0); if (abs(E[1]) > 1.0e-20) gl = E[0]/E[1]; if (abs(E[nx-2]) > 1.0e-20) gr = E[nx-1]/E[nx-2]; std::complex<double> kr_g = log(gl); //wenn die Vorzeichen bei ? umgekehrt werden -> < statt > if(kr_g.imag() > 0.0) { kr_g = conj(kr_g); gl = exp(kr_g); } kr_g = log(gr); //wenn die Vorzeichen bei ? umgekehrt werden -> < statt > if(kr_g.imag() > 0.0) { kr_g = conj(kr_g); gr = exp(kr_g); } a[0] = std::complex<double>(0.0, 0.0); b[0] = b[0] + c1*ddx2*gl; d[0] = E[0] * (1.0 - 2.0*c2*ddx2 + c2*k02*(n2[0] - nq2)) + c2*ddx2*(gl*E[0] + E[1]); b[nx-1] = b[nx-1] + c1*ddx2*gr; c[nx-1] = std::complex<double>(0.0, 0.0); d[nx-1] = E[nx-1] * (1.0 - 2.0*c2*ddx2 + c2*k02*(n2[nx-1] - nq2)) + c2*ddx2*(gr*E[nx-1] + E[nx-2]); return_val = E[nx/2]; """ err = weave.inline(code, ['a', 'b', 'c', 'd', 'E', 'ddx2', 'k02', 'n2', 'nq2', 'nx', 'c1', 'c2'], #type_converters = weave.converters.blitz, compiler = 'gcc') return err def set_matrix(self): im = 0.0 + 1.0j #(1,1) Pade # ? -> siehe Randbedingungen c1 = 1.0/(4.0 * self.k02*self.nq2) + im * self.dz* self.alpha / (2.0*self.k0*self.nq) c2 = 1.0/(4.0 * self.k02*self.nq2) - im * self.dz*(1.0-self.alpha) / (2.0*self.k0*self.nq) #paraxial approximation # ? -> siehe Randbedingungen #c1 = + im * self.dz* self.alpha / (2.0*self.k0*self.nq) #c2 = - im * self.dz*(1.0-self.alpha) / (2.0*self.k0*self.nq) for i in range(self.nx): self.a[i] = c1*self.ddx2 self.c[i] = c1*self.ddx2 self.b[i] = 1.0 - 2.0*c1*self.ddx2 + c1* self.k02*(self.n2[i] - self.nq2) for i in range(1,self.nx-1): self.d[i] = self.E[i] * (1.0 - 2.0*c2*self.ddx2 + c2* self.k02*(self.n2[i] - self.nq2) ) \ + c2*self.ddx2*(self.E[i-1] + self.E[i+1]) if (abs(self.E[1]) > 1.0e-20): gl = self.E[0]/self.E[1] else: gl = 1.0+0.0j if (abs(self.E[self.nx-2]) > 1.0e-20): gr = self.E[self.nx-1]/self.E[self.nx-2] else: gr = 1.0+0.0j kr_g = log(gl) if(kr_g.imag > 0.0): kr_g = conjugate(kr_g) gl = exp(kr_g) kr_g = log(gr) if(kr_g.imag > 0.0): kr_g = conjugate(kr_g) gr = exp(kr_g) self.a[0] = 0.0 + 0.0j self.b[0] = self.b[0] + c1*self.ddx2*gl self.d[0] = self.E[0] * (1.0 - 2.0*c2*self.ddx2 + c2* self.k02*(self.n2[0] - self.nq2)) + \ c2*self.ddx2*(gl*self.E[0] + self.E[1]) self.b[self.nx-1] = self.b[self.nx-1] + c1*self.ddx2*gr self.c[self.nx-1] = 0.0 + 0.0j self.d[self.nx-1] = self.E[self.nx-1] * (1.0 - 2.0*c2*self.ddx2 + c2* self.k02*(self.n2[self.nx-1] - self.nq2)) + \ c2*self.ddx2*(gr*self.E[self.nx-1] + self.E[self.nx-2]) def solve(self): self.lssolv.solve(self.a, self.b, self.c, self.d, self.E) self.z = self.z + self.dz def blitz_solve(self): self.lssolv.blitz_solve(self.a, self.b, self.c, self.d, self.E) self.z = self.z + self.dz def inline_solve(self): self.lssolv.inline_solve(self.a, self.b, self.c, self.d, self.E) self.z = self.z + self.dz class WG_OPO: def __init__(self, parameterfile): self.par = Parameter(parameterfile) logfilename = self.par.get("log.logfilename", "wg_opo.log") self.log = file(logfilename,'w') self.nlo = NLO(self.par, self.log) self.bpm_s = BPM1D(self.par, "s", self.log) self.bpm_i = BPM1D(self.par, "i", self.log) self.bpm_p = BPM1D(self.par, "p", self.log) print self.bpm_s.get_I()[300], self.bpm_s.get_I()[350] def run(self): Ps = [] Pi = [] Pp = [] z = [] print self.bpm_s.get_I()[300], self.bpm_s.get_I()[350] self.naus = self.par.get("par.naus", 100) self.nsteps = self.par.get("par.nsteps", 1000) for i in range(self.naus): for j in range(self.nsteps): self.bpm_s.inline_set_matrix() self.bpm_s.inline_solve() self.bpm_i.inline_set_matrix() self.bpm_i.inline_solve() self.bpm_p.inline_set_matrix() self.bpm_p.inline_solve() self.nlo.inline_step(self.bpm_s.E, self.bpm_i.E, self.bpm_p.E, self.bpm_p.ix1, self.bpm_p.ix2) Ps.append(self.bpm_s.get_P()) Pi.append(self.bpm_i.get_P()) Pp.append(self.bpm_p.get_P()) z.append(self.bpm_s.z) iz = len(z)-1 phase_s = self.bpm_s.get_phase()[self.bpm_s.nx/2] phase_i = self.bpm_i.get_phase()[self.bpm_s.nx/2] phase_p = self.bpm_p.get_phase()[self.bpm_s.nx/2] print "%4i %10.6e %10.6e %10.6e %10.6e %10.6e %10.6e" % (i, z[iz], Ps[iz], Pi[iz], Pp[iz], phase_s, phase_p) out = file("x_I.dat",'w') x = self.bpm_s.x nx = self.bpm_s.nx Is = self.bpm_s.get_I() Ii = self.bpm_s.get_I() Ip = self.bpm_s.get_I() for i in range(nx): out.write("%10.6e %10.6e %10.6e %10.6e\n" % (x[i],Is[i],Ii[i],Ip[i])) out.close() out = file("z_P.dat",'w') for i in range(len(z)): out.write("%10.6e %10.6e %10.6e %10.6e\n" % (z[i],Ps[i],Pi[i],Pp[i])) out.close() wg_opo = WG_OPO("parameter.par") wg_opo.run()
------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpy-discussion