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

Reply via email to