diff --git a/bin/test_romhom.py b/bin/test_romhom.py index 2482c81ff50e091d59fd5ca260cc5fefb3638a33..0b19cab2525613a5d7b80f5abd3c453e14c173e9 100644 --- a/bin/test_romhom.py +++ b/bin/test_romhom.py @@ -1,33 +1,44 @@ from pykat.utilities.maps import read_map from pykat.utilities.knm import * from pykat.utilities.optics.gaussian_beams import beam_param +import time 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) +q1 = beam_param(w0=4e-2, z=0) +q2 = beam_param(w0=4e-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.data = np.zeros((100, 100)) +m.x = np.linspace(-0.15, 0.15, m.size[0]) +m.y = np.linspace(-0.15, 0.15, 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() +t0 = time.time() +w, EI = m.generateROMWeights(isModeMatched=True) +print "Completed in ", time.time()-t0 print "computing Riemann knm..." +t0 = time.time() K1 = knmHG(couplings, q1, q2, surface_map=m) +tr = time.time()-t0 +print "Completed in ", tr print np.abs(K1) print "computing ROMHOM knm..." +t0 = time.time() K2 = knmHG(couplings, q1, q2, surface_map=m, method="romhom") +tt = time.time()-t0 +print "Completed in ", tt print np.abs(K2) +print "Speed up", tr/tt + #w.writeToFile("testWeights.rom") diff --git a/pykat/utilities/knm.py b/pykat/utilities/knm.py index f878050f59e0aa136ad455faa4af44956cb942a3..2303d6babf6c75be8fa3da8c3eab225ba2e44e61 100644 --- a/pykat/utilities/knm.py +++ b/pykat/utilities/knm.py @@ -93,55 +93,49 @@ def ROM_HG_knm(weights, mode_in, mode_out, q1, q2, q1y=None, q2y=None, cache=Non # 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) + # if cache == None: + u_xm_nodes = u_star_u(q1.z, q2.z, q1.w0, q2.w0, n, m, weights.EI["xm"].nodes-0.1e-2) + u_xp_nodes = u_star_u(q1.z, q2.z, q1.w0, q2.w0, n, m, weights.EI["xp"].nodes-0.1e-2) + u_ym_nodes = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, npr, mpr, weights.EI["ym"].nodes-0.1e-2) + u_yp_nodes = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, npr, mpr, weights.EI["yp"].nodes-0.1e-2) + + # 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] + + u_xy_Q1 = np.outer(u_xm_nodes, u_yp_nodes) + u_xy_Q2 = np.outer(u_xp_nodes, u_yp_nodes) + u_xy_Q3 = np.outer(u_xp_nodes, u_ym_nodes) + u_xy_Q4 = np.outer(u_xm_nodes, u_ym_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) + k_ROQ = np.einsum('ij,ij', u_xy_Q1, weights.w_ij_Q1) + k_ROQ += np.einsum('ij,ij', u_xy_Q2, weights.w_ij_Q2) + k_ROQ += np.einsum('ij,ij', u_xy_Q3, weights.w_ij_Q3) + k_ROQ += np.einsum('ij,ij', u_xy_Q4, weights.w_ij_Q4) + return k_ROQ diff --git a/pykat/utilities/maps.py b/pykat/utilities/maps.py index e115f4c58e2c53eefb3c19be33faed8747f748f2..d19b032788b842971bf1d91e4979c988d13ca6cd 100644 --- a/pykat/utilities/maps.py +++ b/pykat/utilities/maps.py @@ -2,6 +2,22 @@ from pykat.utilities.romhom import makeReducedBasis, makeEmpiricalInterpolant, m import numpy import math +class tiltmap(surfacemap): + + def __init__(self, name, size, step_size, tilt, center=(0,0) ): + surfacemap.__init__(name, "phase", size, center, step_sizes) + self.tilt = tilt + + @property + def tilt(self): + return self.__tilt + + @tilt.setter + def tilt(self, value): + + self.__tilt = value + + class surfacemap: def __init__(self, name, maptype, size, center, step_size, scaling, data=None): @@ -58,10 +74,25 @@ class surfacemap: 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) + + def generateROMWeights(self, isModeMatched=True): + xp = self.x[self.x>0] + yp = self.y[self.y>0] + xm = self.x[self.x<0] + ym = self.y[self.y<0] + + EI = {} + + if len(xm) > 0: EI["xm"] = makeEmpiricalInterpolant(makeReducedBasis(xm, isModeMatched=isModeMatched)) + if len(xp) > 0: EI["xp"] = makeEmpiricalInterpolant(makeReducedBasis(xp, isModeMatched=isModeMatched)) + if len(ym) > 0: EI["ym"] = makeEmpiricalInterpolant(makeReducedBasis(ym, isModeMatched=isModeMatched)) + if len(yp) > 0: EI["yp"] = makeEmpiricalInterpolant(makeReducedBasis(yp, isModeMatched=isModeMatched)) + + #if len(x0) > 0: EI["x0"] = makeEmpiricalInterpolant(makeReducedBasis(x0, isModeMatched=isModeMatched)) + #if len(y0) > 0: EI["y0"] = makeEmpiricalInterpolant(makeReducedBasis(y0, isModeMatched=isModeMatched)) + + EI["limits"] = EI["xm"].limits + self._rom_weights = makeWeights(self, EI) return self.ROMWeights, EI diff --git a/pykat/utilities/romhom.py b/pykat/utilities/romhom.py index a4677b2781a74d40d0322a7596cb62176f1a90fe..30f9e4bd9056b0176fc7cfd78d77064a6c5fd97e 100644 --- a/pykat/utilities/romhom.py +++ b/pykat/utilities/romhom.py @@ -18,12 +18,13 @@ 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, nodes, limits): + def __init__(self, w_ij_Q1, w_ij_Q2, w_ij_Q3, w_ij_Q4, EI, 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.EI = EI self.limits = limits def writeToFile(self, filename): @@ -111,7 +112,7 @@ def u_star_u(re_q1, re_q2, w0_1, w0_2, n1, n2, x): return u(re_q1, w0_1, n1, x) * u(re_q2, w0_2, n2, x).conjugate() -def makeReducedBasis(x, offset=np.array([0,0]), isModeMatched=True, tolerance = 1e-12, sigma = 1): +def makeReducedBasis(x, isModeMatched=True, tolerance = 1e-12, sigma = 1): if isModeMatched: greedypts = 'matched20.txt' @@ -246,52 +247,107 @@ def makeEmpiricalInterpolant(RB): 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) + +from progressbar import ProgressBar, ETA, Percentage, Bar + +def makeWeights(smap, EI, verbose=True): -def makeWeights(smap, EI): # get full A_xy A_xy = smap.z_xy() - hx = len(smap.x)/2 - hy = len(smap.y)/2 - fx = hx*2 - fy = hy*2 + xm = smap.x[smap.x < 0] + xp = smap.x[smap.x > 0] + + ym = smap.y[smap.y < 0] + yp = smap.y[smap.y > 0] + + Q1xy = np.ix_(smap.x < 0, smap.y > 0) + Q2xy = np.ix_(smap.x > 0, smap.y > 0) + Q3xy = np.ix_(smap.x > 0, smap.y < 0) + Q4xy = np.ix_(smap.x < 0, smap.y < 0) # get A_xy in the four quadrants of the x-y plane - A_xy_Q1 = A_xy[0:hx][0:hy, hy:fy] - A_xy_Q2 = A_xy[hx:fx][0:hy, hy:fy] - A_xy_Q3 = A_xy[hx:fx][0:hy, 0:hy] - A_xy_Q4 = A_xy[0:hx][0:hy, 0:hy] - + A_xy_Q1 = A_xy[Q1xy] + A_xy_Q2 = A_xy[Q2xy] + A_xy_Q3 = A_xy[Q3xy] + A_xy_Q4 = A_xy[Q4xy] + + # Not sure if there is a neater way to select the x=0,y=0 cross elements + A_xy_0 = np.hstack([A_xy[:,smap.x==0].flatten(), A_xy[smap.y==0,:].flatten()]) + full_x = smap.x full_y = smap.y dx = full_x[1] - full_x[0] dy = full_y[1] - full_y[0] - - B = EI.B - nodes_nv = EI.nodes - nodes_pv = - EI.nodes + if verbose: + count = len(EI["xm"].B) * len(EI["yp"].B) + count += len(EI["xp"].B) * len(EI["yp"].B) + count += len(EI["xp"].B) * len(EI["ym"].B) + count += len(EI["xm"].B) * len(EI["ym"].B) + p = ProgressBar(maxval=count, widgets=["Computing weights: ", Percentage(), Bar(), ETA()]) + + n = 0 + # make integration weights - w_ij_Q1 = np.zeros((len(B), len(B)), dtype = complex) - w_ij_Q2 = np.zeros((len(B), len(B)), dtype = complex) - w_ij_Q3 = np.zeros((len(B), len(B)), dtype = complex) - w_ij_Q4 = np.zeros((len(B), len(B)), dtype = complex) - - for i in range(len(B)): - for j in range(len(B)): - B_ij_Q1 = np.outer(B[i], B[j][::-1]) + Bx = EI["xm"].B + By = EI["yp"].B + w_ij_Q1 = np.zeros((len(Bx),len(By)), dtype = complex) + + for i in range(len(Bx)): + for j in range(len(By)): + B_ij_Q1 = np.outer(Bx[i], By[j]) w_ij_Q1[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q1, A_xy_Q1) - B_ij_Q2 = np.outer(B[i][::-1], B[j][::-1]) + if verbose: + p.update(n) + n+=1 + + Bx = EI["xp"].B + By = EI["yp"].B + w_ij_Q2 = np.zeros((len(Bx),len(By)), dtype = complex) + + for i in range(len(Bx)): + for j in range(len(By)): + B_ij_Q2 = np.outer(Bx[i], By[j]) w_ij_Q2[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q2, A_xy_Q2) - B_ij_Q3 = np.outer(B[i][::-1], B[j]) + if verbose: + p.update(n) + n+=1 + + Bx = EI["xp"].B + By = EI["ym"].B + w_ij_Q3 = np.zeros((len(Bx),len(By)), dtype = complex) + + for i in range(len(Bx)): + for j in range(len(By)): + B_ij_Q3 = np.outer(Bx[i], By[j]) w_ij_Q3[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q3, A_xy_Q3) - B_ij_Q4 = np.outer(B[i], B[j]) + if verbose: + p.update(n) + n+=1 + + Bx = EI["xm"].B + By = EI["ym"].B + w_ij_Q4 = np.zeros((len(Bx),len(By)), dtype = complex) + + for i in range(len(Bx)): + for j in range(len(By)): + B_ij_Q4 = np.outer(Bx[i], By[j]) w_ij_Q4[i][j] = dx*dy*np.einsum('ij,ij', B_ij_Q4, A_xy_Q4) + + if verbose: + p.update(n) + n+=1 + if verbose: + p.finish() + + 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, EI=EI, limits=EI["xm"].limits) + + - 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 diff --git a/requirements.txt b/requirements.txt index fd2476d4abd3185e6ada7f0ef6a85c64620faf27..1ec8c6d2b728c9c4d3e65d3c1c94a0caa6c7ffc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ numpy >= 1.6.2 -flask >= 0.10.1 \ No newline at end of file +flask >= 0.10.1 +progressbar >= 2.2