Commit 5a7edcb8 by Daniel Brown

### updating knm computations and adding romhom tests

parent c9f32128
 from pykat.utilities.maps import read_map from pykat.utilities.knm import * from pykat.utilities.optics.gaussian_beams import beam_param couplings = np.array([[[0,0,0,0], [0,0,1,0], [0,0,0,1]], [[1,0,0,0], [1,0,1,0], [1,0,0,1]], [[0,1,0,0], [0,1,1,0], [0,1,0,1]]]) q1 = beam_param(w0=2e-2, z=0) q2 = beam_param(w0=2e-2, z=0) m = read_map('etm08_virtual.txt') m.data = np.zeros((200, 200)) m.x = np.linspace(-0.151, 0.149, m.size[0]) m.y = np.linspace(-0.151, 0.149, m.size[1]) m.center = np.array(m.size)/2 m.step_size = (m.x[1]-m.x[0], m.y[1]-m.y[0]) print "generating weights..." w = m.generateROMWeights() print "computing Riemann knm..." K1 = knmHG(couplings, q1, q2, surface_map=m) print np.abs(K1) print "computing ROMHOM knm..." K2 = knmHG(couplings, q1, q2, surface_map=m, method="romhom") print np.abs(K2) #w.writeToFile("testWeights.rom")
 ... ... @@ -8,10 +8,7 @@ import numpy as np import pykat import collections import math def makeCouplingMatrix(max_order): pass from romhom import u_star_u def riemann_HG_knm(x, y, mode_in, mode_out, q1, q2, q1y=None, q2y=None, Axy=None): ... ... @@ -39,11 +36,124 @@ def riemann_HG_knm(x, y, mode_in, mode_out, q1, q2, q1y=None, q2y=None, Axy=None return dx * dy * np.einsum('ij,ij', Axy, U1*U2) def ROM_HG_knm(m, mode_in, mode_out, q1, q2, q1y=None, q2y=None): pass def __gen_ROM_HG_knm_cache(weights, couplings, q1, q2, q1y=None, q2y=None): if q1y == None: q1y = q1 if q2y == None: q2y = q2 it = np.nditer(couplings, flags=['refs_ok','f_index']) cache = {} cache["w_ij_Q1Q3"] = weights.w_ij_Q1 + weights.w_ij_Q3 cache["w_ij_Q2Q4"] = weights.w_ij_Q2 + weights.w_ij_Q4 cache["w_ij_Q1Q2"] = weights.w_ij_Q1 + weights.w_ij_Q2 cache["w_ij_Q1Q4"] = weights.w_ij_Q1 + weights.w_ij_Q4 cache["w_ij_Q2Q3"] = weights.w_ij_Q2 + weights.w_ij_Q3 cache["w_ij_Q3Q4"] = weights.w_ij_Q3 + weights.w_ij_Q4 cache["w_ij_Q1Q2Q3Q4"] = weights.w_ij_Q1 + weights.w_ij_Q3 + weights.w_ij_Q2 + weights.w_ij_Q4 while not it.finished: try: mode_in = [int(it.next()), int(it.next())] mode_out = [int(it.next()), int(it.next())] strx = "x[%i,%i]" % (mode_in[0], mode_out[0]) stry = "y[%i,%i]" % (mode_in[1], mode_out[1]) if strx not in cache: cache[strx] = u_star_u(q1.z, q2.z, q1.w0, q2.w0, mode_in[0], mode_out[0], weights.nodes) if q1 == q1y and q2 == q2y: cache[stry] = cache[strx] elif stry not in cache: cache[stry] = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, mode_in[1], mode_out[1], weights.nodes) except StopIteration: break return cache def ROM_HG_knm(weights, mode_in, mode_out, q1, q2, q1y=None, q2y=None, cache=None): if q1y == None: q1y = q1 def knmHG(couplings, surface_map, q1, q2, q1y=None, q2y=None, method="riemann"): if q2y == None: q2y = q2 # x modes n = mode_in[0] m = mode_out[0] # y modes npr = mode_in[1] mpr = mode_out[1] if cache == None: u_x_nodes = u_star_u(q1.z, q2.z, q1.w0, q2.w0, n, m, weights.nodes) u_y_nodes = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, npr, mpr, weights.nodes) w_ij_Q1Q3 = weights.w_ij_Q1 + weights.w_ij_Q3 w_ij_Q2Q4 = weights.w_ij_Q2 + weights.w_ij_Q4 w_ij_Q1Q2 = weights.w_ij_Q1 + weights.w_ij_Q2 w_ij_Q1Q4 = weights.w_ij_Q1 + weights.w_ij_Q4 w_ij_Q2Q3 = weights.w_ij_Q2 + weights.w_ij_Q3 w_ij_Q3Q4 = weights.w_ij_Q3 + weights.w_ij_Q4 w_ij_Q1Q2Q3Q4 = weights.w_ij_Q1 + weights.w_ij_Q3 + weights.w_ij_Q2 + weights.w_ij_Q4 else: strx = "x[%i,%i]" % (mode_in[0], mode_out[0]) stry = "y[%i,%i]" % (mode_in[1], mode_out[1]) u_x_nodes = cache[strx] u_y_nodes = cache[stry] w_ij_Q1Q3 = cache["w_ij_Q1Q3"] w_ij_Q2Q4 = cache["w_ij_Q2Q4"] w_ij_Q1Q2 = cache["w_ij_Q1Q2"] w_ij_Q1Q4 = cache["w_ij_Q1Q4"] w_ij_Q2Q3 = cache["w_ij_Q2Q3"] w_ij_Q3Q4 = cache["w_ij_Q3Q4"] w_ij_Q1Q2Q3Q4 = cache["w_ij_Q1Q2Q3Q4"] u_xy_nodes = np.outer(u_x_nodes, u_y_nodes) n_mod_2 = n % 2 m_mod_2 = m % 2 npr_mod_2 = npr % 2 mpr_mod_2 = mpr % 2 if n_mod_2 == m_mod_2 and npr_mod_2 == mpr_mod_2: k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q1Q2Q3Q4) elif n_mod_2 != m_mod_2: if npr_mod_2 == mpr_mod_2: k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q1Q4) + np.einsum('ij,ij', -u_xy_nodes, w_ij_Q2Q3) else: k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q2Q4) + np.einsum('ij,ij', -u_xy_nodes, w_ij_Q1Q3) elif npr_mod_2 != mpr_mod_2: if n_mod_2 == m_mod_2: k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q3Q4) + np.einsum('ij,ij', -u_xy_nodes, w_ij_Q1Q2) else: k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q2Q4) + np.einsum('ij,ij', -u_xy_nodes, w_ij_Q1Q3) return k_ROQ def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riemann"): if q1y == None: q1y = q1 if q2y == None: q2y = q2 assert q1.wavelength == q2.wavelength and q1y.wavelength == q2y.wavelength and q1y.wavelength == q1.wavelength couplings = np.array(couplings) ... ... @@ -52,8 +162,7 @@ def knmHG(couplings, surface_map, q1, q2, q1y=None, q2y=None, method="riemann"): if int(a) - a != 0: raise BasePyKatException("Iterator should be product of 4, each element of coupling array should be [n,m,n',m']") if "phase" in surface_map.type: Axy = np.exp(2j * 2 * math.pi / q1.wavelength * surface_map.data * surface_map.scaling) Axy = surface_map.z_xy(q1.wavelength) x = surface_map.x y = surface_map.y ... ... @@ -64,16 +173,32 @@ def knmHG(couplings, surface_map, q1, q2, q1y=None, q2y=None, method="riemann"): i = 0 if method == "romhom": if surface_map == None: raise BasePyKatException("Using 'romhom' method requires a surface map to be specified") weights = surface_map.ROMWeights if weights == None: raise BasePyKatException("The ROM weights need to be generated for this map before use.") romcache = None#__gen_ROM_HG_knm_cache(weights, couplings, q1=q1, q2=q2, q1y=q1y, q2y=q2y) else: romcache = None weights = None while not it.finished: try: mode_in = [int(it.next()), int(it.next())] mode_out = [int(it.next()), int(it.next())] if method == "riemann": K[i] = riemann_HG_knm(x, y, mode_in, mode_out, q1=q1, q2=q2, q1y=q1y, q2y=q2y, Axy=Axy) elif method == "romhom": K[i] = ROM_HG_knm(weights, mode_in, mode_out, q1=q1, q2=q2, q1y=q1y, q2y=q2y, cache=romcache) else: raise BasePyKatException("method value not accepted") raise BasePyKatException("method value '%s' not accepted" % method) i +=1 ... ...
 from pykat.utilities.romhom import makeReducedBasis, makeEmpiricalInterpolant, makeWeights import numpy import math class surfacemap: def __init__(self, name, maptype, size, center, step_size, scaling, data=None): ... ... @@ -7,7 +8,6 @@ class surfacemap: self.name = name self.type = maptype self.center = center self.size = size self.step_size = step_size self.scaling = scaling self.data = data ... ... @@ -19,7 +19,7 @@ class surfacemap: mapfile.write("% Surface map\n") mapfile.write("% Name: {0}\n".format(self.name)) mapfile.write("% Type: {0}\n".format(self.type)) mapfile.write("% Size: {0} {1}\n".format(self.size[0], self.size[1])) mapfile.write("% Size: {0} {1}\n".format(self.data.shape[0], self.data.shape[1])) mapfile.write("% Optical center (x,y): {0} {1}\n".format(self.center[0], self.center[1])) mapfile.write("% Step size (x,y): {0} {1}\n".format(self.step_size[0], self.step_size[1])) mapfile.write("% Scaling: {0}\n".format(float(self.scaling))) ... ... @@ -37,7 +37,11 @@ class surfacemap: @property def y(self): return self.step_size[1] * (numpy.array(range(1, self.data.shape[1]+1))- self.center[1]) @property def size(self): return self.data.shape @property def offset(self): return numpy.array(self.step_size)*(self.center - numpy.array(self.size)/2) ... ... @@ -45,13 +49,22 @@ class surfacemap: @property def ROMWeights(self): return self._rom_weights def z_xy(self, wavelength=1064e-9): if "phase" in self.type: k = math.pi * 2 / wavelength return numpy.exp(2j * k * self.scaling * self.data) else: raise BasePyKatException("Map type needs handling") def generateROMWeights(self): b = makeReducedBasis(self.x[0:(len(self.x)/2)], offset=self.offset) EI = makeEmpiricalInterpolant(b) self._rom_weights = makeWeights(self, EI) return self.ROMWeights return self.ROMWeights, EI def plot(self, show=True, clabel=None): ... ...
 ... ... @@ -82,7 +82,7 @@ class gauss_param(object): def w(self): return abs(self.__q)*math.sqrt(self.__lambda / (self.__nr * math.pi * self.__q.imag)) def w(self, z=None, wavelength=None, nr=None, w0=None): def beamsize(self, z=None, wavelength=None, nr=None, w0=None): if z == None: z = self.z ... ... @@ -144,7 +144,7 @@ class gauss_param(object): else: return float("inf") def Rc(self, z=None, wavelength=None, nr=None, w0=None): def curvature(self, z=None, wavelength=None, nr=None, w0=None): if z == None: z = self.z else: ... ...
 import math import maps import os.path import numpy as np import pykat import collections from itertools import combinations_with_replacement as combinations from pykat.utilities.optics.gaussian_beams import beam_param, HG_beam from scipy.linalg import inv from math import factorial from hermite import * import math import numpy as np EmpiricalInterpolant = collections.namedtuple('EmpiricalInterpolant', 'B nodes node_indices limits x') ReducedBasis = collections.namedtuple('ReducedBasis', 'RB limits x') ... ... @@ -16,11 +18,12 @@ ROMLimits = collections.namedtuple('ROMLimits', 'zmin zmax w0min w0max max_order class ROMWeights: def __init__(self, w_ij_Q1, w_ij_Q2, w_ij_Q3, w_ij_Q4, limits): def __init__(self, w_ij_Q1, w_ij_Q2, w_ij_Q3, w_ij_Q4, nodes, limits): self.w_ij_Q1 = w_ij_Q1 self.w_ij_Q2 = w_ij_Q2 self.w_ij_Q3 = w_ij_Q3 self.w_ij_Q4 = w_ij_Q4 self.nodes = nodes self.limits = limits def writeToFile(self, filename): ... ... @@ -101,7 +104,7 @@ def u(re_q1, w0_1, n1, x): wz1 = w(w0_1, im_q1, re_q1) return A_n1 * hermite(n1, np.sqrt(2.)*x / wz1) * np.exp(-1j*(2*math.pi/(1064e-9))* x**2 /(2.*q_z1)) return A_n1 * hermite(n1, np.sqrt(2.)*x / wz1) * np.exp(np.array(-1j*(2*math.pi/(1064e-9))* x**2 /(2.*q_z1))) def u_star_u(re_q1, re_q2, w0_1, w0_2, n1, n2, x): ... ... @@ -240,14 +243,14 @@ def makeEmpiricalInterpolant(RB): invV = inv(V[0:len(node_indices), 0:len(node_indices)]) B = B_matrix(invV, e_x) return EmpiricalInterpolant(B=np.array(B), nodes=np.array(x_nodes), node_indices=np.array(node_indices), limits=RB.limits, x=RB.x) return EmpiricalInterpolant(B=np.array(B), nodes=np.array(x_nodes, dtype=np.float64), node_indices=np.array(node_indices, dtype=np.int32), limits=RB.limits, x=RB.x) def makeWeights(smap, EI): # get full A_xy A_xy = smap.data A_xy = smap.z_xy() hx = len(smap.x)/2 hy = len(smap.y)/2 ... ... @@ -289,83 +292,6 @@ def makeWeights(smap, EI): B_ij_Q4 = np.outer(B[i], B[j]) w_ij_Q4[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q4, A_xy_Q4) return ROMWeights(w_ij_Q1=w_ij_Q1, w_ij_Q2=w_ij_Q2, w_ij_Q3=w_ij_Q3, w_ij_Q4=w_ij_Q4, limits=EI.limits) def ROMKnm(W, max_order, q1, q2, q1y=None, q2y=None): if q1y == None: q1y = q1 if q2y == None: q2y = q2 # get symmetric and anti-symmetric w_ij's w_ij_Q1Q3 = W.w_ij_Q1 + W.w_ij_Q3 w_ij_Q2Q4 = W.w_ij_Q2 + W.w_ij_Q4 w_ij_Q1Q2 = W.w_ij_Q1 + W.w_ij_Q2 w_ij_Q1Q4 = W.w_ij_Q1 + W.w_ij_Q4 w_ij_Q2Q3 = W.w_ij_Q2 + W.w_ij_Q3 w_ij_Q3Q4 = W.w_ij_Q3 + W.w_ij_Q4 w_ij_Q1Q2Q3Q4 = W.w_ij_Q1 + W.w_ij_Q3 + W.w_ij_Q2 + W.w_ij_Q4 num_fields = int((max_order + 1) * (max_order + 2) / 2); K_ROQ = np.array((num_fields, num_fields)) for i in range(len(nm_pairs)): for j in range(len(nm_pairs)): # full quadrature n = nm_pairs[i][0] m = nm_pairs[i][1] npr = nm_pairs[j][0] mpr = nm_pairs[j][1] u_xy = np.outer(u_star_u(re_q1, re_q2, w0_1, w0_2, n, m, full_x), u_star_u(re_q1, re_q2, w0_1, w0_2, npr, mpr, full_x)) k = dx*dy*np.einsum('ij,ij', u_xy, A_xy) # ROQ if nm_pairs[i][0] % 2 == 0 and nm_pairs[i][1] % 2 == 0 and nm_pairs[j][0] % 2 == 0 and nm_pairs[j][1] % 2 == 0: u_xy_nodes = np.outer(u_star_u(re_q1, re_q2, w0_1, w0_2, n, m, nodes_nv), u_star_u(re_q1, re_q2, w0_1, w0_2, npr, mpr, nodes_nv)) k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q1Q2Q3Q4) elif nm_pairs[i][0] % 2 == 1 and nm_pairs[i][1] % 2 == 1 and nm_pairs[j][0] % 2 == 1 and nm_pairs[j][1] % 2 == 1: u_xy_nodes = np.outer(u_star_u(re_q1, re_q2, w0_1, w0_2, n, m, nodes_nv), u_star_u(re_q1, re_q2, w0_1, w0_2, npr, mpr, nodes_nv)) k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q1Q2Q3Q4) elif nm_pairs[i][0] % 2 == 0 and nm_pairs[i][1] % 2 == 0 and nm_pairs[j][0] % 2 == 1 and nm_pairs[j][1] % 2 == 1: u_xy_nodes = np.outer(u_star_u(re_q1, re_q2, w0_1, w0_2, n, m, nodes_nv), u_star_u(re_q1, re_q2, w0_1, w0_2, npr, mpr, nodes_nv)) k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q1Q2Q3Q4) elif nm_pairs[i][0] % 2 == 1 and nm_pairs[i][1] % 2 == 1 and nm_pairs[j][0] % 2 == 0 and nm_pairs[j][1] % 2 == 0: u_xy_nodes = np.outer(u_star_u(re_q1, re_q2, w0_1, w0_2, n, m, nodes_nv), u_star_u(re_q1, re_q2, w0_1, w0_2, npr, mpr, nodes_nv)) k_ROQ = np.einsum('ij,ij', u_xy_nodes, w_ij_Q1Q2Q3Q4) elif nm_pairs[i][0] % 2 == 0 and nm_pairs[i][1] % 2 == 1 or nm_pairs[i][0] % 2 == 1 and nm_pairs[i][1] % 2 == 0: u_x_nodes = u_star_u(re_q1, re_q2, w0_1, w0_2, n,m, nodes_nv) u_y_nodes = u_star_u(re_q1, re_q2, w0_1, w0_2, npr, mpr, nodes_nv) if nm_pairs[j][0] % 2 == 0 and nm_pairs[j][1] % 2 == 0 or nm_pairs[j][0] % 2 == 1 and nm_pairs[j][1] % 2 == 1: u_xy_nodes_Q1Q4 = np.outer(u_x_nodes, u_y_nodes) u_xy_nodes_Q2Q3 = - u_xy_nodes_Q1Q4 k_ROQ = np.einsum('ij,ij', u_xy_nodes_Q1Q4, w_ij_Q1Q4) + np.einsum('ij,ij', u_xy_nodes_Q2Q3, w_ij_Q2Q3) else: u_xy_nodes_Q2Q4 = np.outer(u_x_nodes, u_y_nodes) u_xy_nodes_Q1Q3 = - u_xy_nodes_Q2Q4 k_ROQ = np.einsum('ij,ij', u_xy_nodes_Q2Q4, w_ij_Q2Q4) + np.einsum('ij,ij', u_xy_nodes_Q1Q3, w_ij_Q1Q3) elif nm_pairs[j][0] % 2 == 0 and nm_pairs[j][1] % 2 == 1 or nm_pairs[j][0] % 2 == 1 and nm_pairs[j][1] % 2 == 0: u_x_nodes = u_star_u(re_q1, re_q2, w0_1, w0_2, n, m, nodes_nv) u_y_nodes = u_star_u(re_q1, re_q2, w0_1, w0_2, npr, mpr, nodes_nv) if nm_pairs[i][0] % 2 == 0 and nm_pairs[i][1] % 2 == 0 or nm_pairs[i][0] % 2 == 1 and nm_pairs[i][1] % 2 == 1: u_xy_nodes_Q3Q4 = np.outer(u_x_nodes, u_y_nodes) u_xy_nodes_Q1Q2 = - u_xy_nodes_Q3Q4 k_ROQ = np.einsum('ij,ij', u_xy_nodes_Q3Q4, w_ij_Q3Q4) + np.einsum('ij,ij', u_xy_nodes_Q1Q2, w_ij_Q1Q2) else: u_xy_nodes_Q2Q4 = np.outer(u_x_nodes, u_y_nodes) u_xy_nodes_Q1Q3 = - u_xy_nodes_Q2Q4 k_ROQ = np.einsum('ij,ij', u_xy_nodes_Q2Q4, w_ij_Q2Q4) + np.einsum('ij,ij', u_xy_nodes_Q1Q3, w_ij_Q1Q3) return ROMWeights(w_ij_Q1=w_ij_Q1, w_ij_Q2=w_ij_Q2, w_ij_Q3=w_ij_Q3, w_ij_Q4=w_ij_Q4, nodes=EI.nodes, limits=EI.limits) \ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!