diff --git a/pykat/__init__.py b/pykat/__init__.py index 0f0686889ad479e6ff6a0ccfe59e682b02375c2f..7d2920ba0635ec19cfc8add4e073e4b3a8ec1d79 100644 --- a/pykat/__init__.py +++ b/pykat/__init__.py @@ -5,3 +5,4 @@ import components import detectors import commands +from pykat.utilities.optics.gaussian_beams import beam_param diff --git a/pykat/utilities/knm.py b/pykat/utilities/knm.py index 7d418c4696bb366a26aa2ae43b0c4392de706969..1607bc26d990bff8813f08f01536d50637f48bbd 100644 --- a/pykat/utilities/knm.py +++ b/pykat/utilities/knm.py @@ -2,12 +2,14 @@ from itertools import combinations_with_replacement as combinations from pykat.utilities.optics.gaussian_beams import beam_param, HG_beam from pykat.exceptions import BasePyKatException +import time import maps import os.path import numpy as np import pykat import collections import math +import cmath from romhom import u_star_u from progressbar import ProgressBar, ETA, Percentage, Bar @@ -32,9 +34,9 @@ def makeCouplingMatrix(max_order): M.append(row) - return np.array(M) + return np.array(M) -def riemann_HG_knm(x, y, mode_in, mode_out, q1, q2, q1y=None, q2y=None, Axy=None, cache=None): +def riemann_HG_knm(x, y, mode_in, mode_out, q1, q2, q1y=None, q2y=None, Axy=None, cache=None, delta=(0,0)): if Axy == None: Axy == np.ones((len(x), len(y))) @@ -55,7 +57,7 @@ def riemann_HG_knm(x, y, mode_in, mode_out, q1, q2, q1y=None, q2y=None, Axy=None Hg_in = HG_beam(qx=q1, qy=q1y, n=mode_in[0], m=mode_in[1]) Hg_out = HG_beam(qx=q2, qy=q2y, n=mode_out[0], m=mode_out[1]) - U1 = Hg_in.Unm(x,y) + U1 = Hg_in.Unm(x+delta[0], y+delta[1]) U2 = Hg_out.Unm(x,y).conjugate() return dx * dy * np.einsum('ij,ij', Axy, U1*U2) @@ -66,11 +68,10 @@ 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, np.outer(cache[strx], cache[stry])) - - -def __gen_riemann_knm_cache(x, y, couplings, q1, q2, q1y=None, q2y=None): + +def __gen_riemann_knm_cache(x, y, couplings, q1, q2, q1y=None, q2y=None, delta=(0,0)): if q1y == None: q1y = q1 @@ -89,20 +90,24 @@ def __gen_riemann_knm_cache(x, y, couplings, q1, q2, q1y=None, q2y=None): strx = "u1[%i,%i]" % (mode_in[0], mode_out[0]) stry = "u2[%i,%i]" % (mode_in[1], mode_out[1]) - Hg_in = HG_beam(qx=q1, qy=q1y, n=mode_in[0], m=mode_in[1]) - Hg_out = HG_beam(qx=q2, qy=q2y, n=mode_out[0], m=mode_out[1]) + #Hg_in = HG_beam(qx=q1, qy=q1y, n=mode_in[0], m=mode_in[1]) + #Hg_out = HG_beam(qx=q2, qy=q2y, n=mode_out[0], m=mode_out[1]) if strx not in cache: - cache[strx] = Hg_in.Un(x) * Hg_out.Un(x).conjugate() + cache[strx] = u_star_u(q1.z, q2.z, q1.w0, q2.w0, mode_in[0], mode_out[0], x, x+delta[0]) + #Hg_in.Un(x) * Hg_out.Un(x).conjugate() if stry not in cache: - cache[stry] = Hg_in.Um(y) * Hg_out.Um(y).conjugate() + cache[stry] = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, mode_in[1], mode_out[1], y, y+delta[1]) + #Hg_in.Um(y) * Hg_out.Um(y).conjugate() except StopIteration: break return cache + + def __gen_ROM_HG_knm_cache(weights, couplings, q1, q2, q1y=None, q2y=None): if q1y == None: @@ -141,7 +146,9 @@ def __gen_ROM_HG_knm_cache(weights, couplings, q1, q2, q1y=None, q2y=None): 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 @@ -157,82 +164,154 @@ def ROM_HG_knm(weights, mode_in, mode_out, q1, q2, q1y=None, q2y=None, cache=Non npr = mode_in[1] mpr = mode_out[1] - foundSymmetry = np.all(weights.EI["ym"].nodes == weights.EI["xm"].nodes) and np.all(weights.EI["xp"].nodes == -weights.EI["xm"].nodes) and np.all(weights.EI["yp"].nodes == -weights.EI["ym"].nodes) - - if foundSymmetry: + if cache == None: + u_x_nodes = u_star_u(q1.z, q2.z, q1.w0, q2.w0, n, m, weights.EI["xm"].nodes) + u_y_nodes = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, npr, mpr, weights.EI["ym"].nodes) - if cache == None: - u_x_nodes = u_star_u(q1.z, q2.z, q1.w0, q2.w0, n, m, weights.EI["xm"].nodes) - u_y_nodes = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, npr, mpr, weights.EI["ym"].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_Q2 + weights.w_ij_Q3 + 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]) + 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_Q2 + weights.w_ij_Q3 + 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_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) - u_xy_nodes = np.outer(u_x_nodes, u_y_nodes) + 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) - n_mod_2 = n % 2 - m_mod_2 = m % 2 - npr_mod_2 = npr % 2 - mpr_mod_2 = mpr % 2 + + return k_ROQ - 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) +__fac_cache = [] - 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) +def fac(n): + global __fac_cache + return __fac_cache[n] + #return math.factorial(int(n)) - 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) - +def m_1_pow(n): + if n % 2 == 0: + return 1 else: - # If there is no symmetry about the axes then each quadrant is different - u_xm_nodes = u_star_u(q1.z, q2.z, q1.w0, q2.w0, n, m, weights.EI["xm"].nodes) - u_xp_nodes = u_star_u(q1.z, q2.z, q1.w0, q2.w0, n, m, weights.EI["xp"].nodes) - u_ym_nodes = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, npr, mpr, weights.EI["ym"].nodes) - u_yp_nodes = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, npr, mpr, weights.EI["yp"].nodes) - - 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) + return -1 + + +def __Ss(u, _u, F, _F, d=0): + r = 0 + + for s in range(0, min(u,_u)+1): + r += m_1_pow(s) * _F ** (u-s) * _F ** (_u-s) / (fac(2*s+d)*fac(u-s)*fac(_u-s)) - 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 + return r + + +def __S(m, _m, X, _X, F, _F, d=0): + if m % 2 == 1: + lim1 = (m-1)/2 + else: + lim1 = m/2 + + if _m % 2 == 1: + lim2 = (_m-1)/2 + else: + lim2 = _m/2 + + r = 0 + + for u in range(0, lim1+1): + for _u in range(0, lim2+1): + r += m_1_pow(u) * _X**(m-2*u) * X**(_m-2*_u) / ( fac(m-2*u)*fac(_m-2*_u) ) * __Ss(u, _u, F, _F, d=d) + + return r + + +def __bayerhelms_kn(n, _n, q1, q2, gamma=0.0): + + K0 = (q1.zr - q2.zr)/q2.zr + K2 = (q1.z - q2.z)/q2.zr + K = (K0 + 1j*K2)/2.0 + + Ktilde = abs(K / (1+K)) + + if gamma != 0: + a = q2.zr * math.sin(gamma) / (cmath.sqrt(1+K.conjugate()) * q2.w0) + + _X = - a * (q2.z/q2.zr - 1j) + X = - a * (q2.z/q2.zr + 1j*(1+2*K.conjugate())) + Ex = cmath.exp(-_X*X / 2.0) + else: + _X = 0.0 + X = 0.0 + Ex = 1.0 + _F = K / (2.0 * (1.0+K0)) + F = K.conjugate() / 2.0 + Sg = __S(n, _n, X, _X, F, _F) -def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riemann", verbose=True): + if n > 0 and _n > 0: + Su = __S(n-1, _n-1, X, _X, F, _F, 1) + else: + Su = 0 + + b = m_1_pow(_n) * cmath.sqrt(fac(n) * fac(_n) * (1.0 + K.real)**(n+0.5) * (1.0 + K.conjugate()) ** (-(n+_n+1))) + + return b * Ex * (Sg - Su) + + +def bayerhelms_HG_knm(mode_in, mode_out, q1, q2, q1y=None, q2y=None, gamma=(0,0)): + if q1y == None: + q1y = q1 + + if q2y == None: + q2y = q2 + + # x modes + n = mode_in[0] + _n = mode_out[0] + + # y modes + m = mode_in[1] + _m = mode_out[1] + + return __bayerhelms_kn(n,_n, q1, q2, 2*gamma[0]) * __bayerhelms_kn(m, _m, q1y, q2y, 2*gamma[1]) + +def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riemann", verbose=False, profile=False, gamma=(0,0), delta=(0,0)): if q1y == None: q1y = q1 @@ -247,17 +326,32 @@ def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riema if int(a) - a != 0: raise BasePyKatException("Iterator should be product of 4, each element of coupling array should be [n,m,n',m']") - - Axy = surface_map.z_xy(q1.wavelength) - x = surface_map.x - y = surface_map.y + maxtem = 0 + c = couplings.flatten() + + for i in range(0, c.size/2): + maxtem = max(sum(c[i*2:(i*2+2)]), maxtem) + + global __fac_cache + + for n in range(0, maxtem+1): + __fac_cache.append(math.factorial(n)) + + if surface_map != None: + Axy = surface_map.z_xy(q1.wavelength) + + x = surface_map.x + y = surface_map.y K = np.zeros((couplings.size/4,), dtype=np.complex128) it = np.nditer(couplings, flags=['refs_ok','f_index']) i = 0 + + if profile: + t0 = time.time() if method == "romhom": if surface_map == None: @@ -268,32 +362,44 @@ def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riema if weights == None: raise BasePyKatException("The ROM weights need to be generated for this map before use.") - if verbose: print "Computing caches" - cache = __gen_ROM_HG_knm_cache(weights, couplings, q1=q1, q2=q2, q1y=q1y, q2y=q2y) elif method == "riemann": - if verbose: print "Computing caches" - cache = __gen_riemann_knm_cache(x, y, couplings, q1, q2, q1y=None, q2y=None) + if surface_map == None: + raise BasePyKatException("Using 'riemann' method requires a surface map to be specified") + + cache = __gen_riemann_knm_cache(x, y, couplings, q1, q2, q1y=None, q2y=None, delta=delta) else: cache = None weights = None + if profile: + cache_time = time.time() - t0 + Ktime = np.zeros((couplings.size/4,), dtype=np.float64) + if verbose: p = ProgressBar(maxval=couplings.size, widgets=["Knm (%s): " % method, Percentage(), Bar(), ETA()]) while not it.finished: try: + if profile: + t0 = time.time() + 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, cache=cache) + K[i] = riemann_HG_knm(x, y, mode_in, mode_out, q1=q1, q2=q2, q1y=q1y, q2y=q2y, Axy=Axy, cache=cache, delta=delta) elif method == "romhom": K[i] = ROM_HG_knm(weights, mode_in, mode_out, q1=q1, q2=q2, q1y=q1y, q2y=q2y, cache=cache) + elif method == "bayerhelms": + K[i] = bayerhelms_HG_knm(mode_in, mode_out, q1=q1, q2=q2, q1y=q1y, q2y=q2y, gamma=gamma) else: raise BasePyKatException("method value '%s' not accepted" % method) - + + if profile: + Ktime[i] = time.time() - t0 + i +=1 if verbose: @@ -303,19 +409,41 @@ def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riema except StopIteration: break - return K.reshape(couplings.shape[:-1]) - - - - - - - - - - - + if profile: + return K.reshape(couplings.shape[:-1]), Ktime.reshape(couplings.shape[:-1]), cache_time + else: + return K.reshape(couplings.shape[:-1]) +def plot_knm_matrix(couplings, knm): + import pylab as plt + + fig = plt.figure() + ax = fig.add_subplot(111) + cax = ax.imshow(knm, interpolation='nearest') + fig.colorbar(cax) + + numrows, numcols = knm.shape + + c = couplings[:, 0, :2] + c_ = [] + + for d in c: + c_.append("%i,%i"%(d[0], d[1])) + + ax.set_xticklabels(c_) + ax.set_yticklabels(c_) + + def format_coord(x, y): + col = int(x+0.5) + row = int(y+0.5) + + if col>=0 and col<numcols and row>=0 and row<numrows: + z = knm[row,col] + return 'x=%s, y=%s, z=%1.4f' % (c_[col], c_[row], z) + else: + return 'x=%1.4f, y=%1.4f'%(x, y) + ax.format_coord = format_coord + plt.show() diff --git a/pykat/utilities/maps.py b/pykat/utilities/maps.py index eb663bbc72c1d61d41fc25f9ee95917643c8ae48..8debfd706fa7379b980bbdcd0fc72e6fbece4522 100644 --- a/pykat/utilities/maps.py +++ b/pykat/utilities/maps.py @@ -65,25 +65,18 @@ class surfacemap(object): raise BasePyKatException("Map type needs handling") - def generateROMWeights(self, isModeMatched=True): - xp = self.x[self.x>0] - yp = self.y[self.y>0] + def generateROMWeights(self, isModeMatched=True, verbose=False): 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) + self._rom_weights = makeWeights(self, EI, verbose=verbose) return self.ROMWeights, EI @@ -129,7 +122,7 @@ class tiltmap(surfacemap): xx, yy = np.meshgrid(self.x, self.y) - self.data = xx * self.tilt[0] + yy * self.tilt[1] + self.data = xx * self.tilt[1] + yy * self.tilt[0] diff --git a/pykat/utilities/romhom.py b/pykat/utilities/romhom.py index e134a7b502e1ba6cdea605b8b01ddbafa75d0861..ae77c020c611dc66de1b6865c49823e1fa6d3447 100644 --- a/pykat/utilities/romhom.py +++ b/pykat/utilities/romhom.py @@ -1,9 +1,8 @@ import math -import maps import os.path import pykat import collections - + from progressbar import ProgressBar, ETA, Percentage, Bar from itertools import combinations_with_replacement as combinations from pykat.utilities.optics.gaussian_beams import beam_param, HG_beam @@ -109,8 +108,11 @@ def u(re_q1, w0_1, n1, x): 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): - return u(re_q1, w0_1, n1, x) * u(re_q2, w0_2, n2, x).conjugate() +def u_star_u(re_q1, re_q2, w0_1, w0_2, n1, n2, x, x2=None): + if x2 == None: + x2 = x + + return u(re_q1, w0_1, n1, x) * u(re_q2, w0_2, n2, x2).conjugate() def makeReducedBasis(x, isModeMatched=True, tolerance = 1e-12, sigma = 1): @@ -142,7 +144,7 @@ def makeReducedBasis(x, isModeMatched=True, tolerance = 1e-12, sigma = 1): params = np.loadtxt(greedyfile, skiprows=5) TS_size = len(params) # training space of TS_size number of waveforms - + #### allocate memory for training space #### TS = np.zeros(TS_size*len(x), dtype = complex).reshape(TS_size, len(x)) # store training space in TS_size X len(x) array @@ -150,14 +152,13 @@ def makeReducedBasis(x, isModeMatched=True, tolerance = 1e-12, sigma = 1): IDx = 0 #TS index for i in range(len(params)): - - q1 = beam_param(w0=float(params[i][0]), z=float(params[i][2])) - if isModeMatched: + q1 = beam_param(w0=float(params[i][0]), z=float(params[i][1])) q2 = q1 n = int(params[i][2]) m = int(params[i][3]) else: + q1 = beam_param(w0=float(params[i][0]), z=float(params[i][2])) q2 = beam_param(w0=float(params[i][1]), z=float(params[i][3])) n = int(params[i][4]) m = int(params[i][5]) @@ -180,34 +181,32 @@ def makeReducedBasis(x, isModeMatched=True, tolerance = 1e-12, sigma = 1): #### Begin greedy: see Field et al. arXiv:1308.3565v2 #### - tolerance = 1e-12 # set maximum RB projection error - - sigma = 1 # projection error at 0th iteration - RB_matrix = [TS[0]] # seed greedy algorithm (arbitrary) proj_coefficients = np.zeros(TS_size*TS_size, dtype = complex).reshape(TS_size, TS_size) projections = np.zeros(TS_size*len(x), dtype = complex).reshape(TS_size, len(x)) iter = 0 - + while sigma > tolerance: #for k in range(TS_size-1): # go through training set and find worst projection error projections = project_onto_basis(dx, RB_matrix, TS, projections, proj_coefficients, iter) residual = TS - projections + projection_errors = [np.vdot(dx* residual[i], residual[i]) for i in range(len(residual))] sigma = abs(max(projection_errors)) index = np.argmax(projection_errors) - + #Gram-Schmidt to get the next basis and normalize next_basis = TS[index] - projections[index] next_basis /= np.sqrt(abs(np.vdot(dx* next_basis, next_basis))) RB_matrix.append(next_basis) - - iter += 1 - + + iter += 1 + + return ReducedBasis(RB=np.array(RB_matrix), limits=romlimits, x=x) def makeEmpiricalInterpolant(RB): @@ -282,42 +281,39 @@ def makeWeights(smap, EI, verbose=True): dy = full_y[1] - full_y[0] 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) + count = 4*len(EI["xm"].B) * len(EI["ym"].B) p = ProgressBar(maxval=count, widgets=["Computing weights: ", Percentage(), Bar(), ETA()]) n = 0 # make integration weights Bx = EI["xm"].B - By = EI["yp"].B + By = EI["ym"].B[:,::-1] 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) - + if verbose: p.update(n) n+=1 - Bx = EI["xp"].B - By = EI["yp"].B + Bx = EI["xm"].B[:,::-1] + By = EI["ym"].B[:,::-1] 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) - + if verbose: p.update(n) n+=1 - Bx = EI["xp"].B + Bx = EI["xm"].B[:,::-1] By = EI["ym"].B w_ij_Q3 = np.zeros((len(Bx),len(By)), dtype = complex)