diff --git a/bin/test_romhom.py b/bin/test_romhom.py
index 6275e6fbaf06d884fb808e15de2bf1ea61ea9592..d48170610c5d993b3209946dc167991425b855b6 100644
--- a/bin/test_romhom.py
+++ b/bin/test_romhom.py
@@ -2,28 +2,27 @@ from pykat.utilities.maps import read_map, tiltmap, surfacemap
 from pykat.utilities.knm import *
 from pykat.utilities.optics.gaussian_beams import beam_param
 import time
+import numpy as np
 
-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]]])
+couplings = makeCouplingMatrix(5)
 
 q1 = beam_param(w0=3e-2, z=0)
 q2 = beam_param(w0=3e-2, z=0)
 
-size = np.array([200,200])
-stepsize = 0.2/(size-1)
+size = np.array([1200, 1200])
+stepsize = 0.3/(size-1)
 
 # This map has points evenly spaced about the axes
-m = tiltmap("tilt", size, stepsize, (1e-6, 0))
+m = tiltmap("tilt", size, stepsize, (1e-6, 1e-6))
 # Shifting the central point changes the results slightly
 # but this is about a 1e-7 change, probably due to extra
 # clipping
-m.center += 20
+m.center += 0
 
 print "Generating weights..."
 t0 = time.time()
 w, EI = m.generateROMWeights(isModeMatched=True)
-#w.writeToFile("testWeights.rom")
+w.writeToFile("testWeights.rom")
 print "Completed in ", time.time()-t0
 
 print "computing Riemann knm..."
@@ -31,15 +30,14 @@ t0 = time.time()
 K1 = knmHG(couplings, q1, q2, surface_map=m)
 tr = time.time()-t0
 print "Completed in ", tr
-print np.abs(K1)
+#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 np.abs(K2)
 print "Speed up", tr/tt
 
 
diff --git a/pykat/utilities/knm.py b/pykat/utilities/knm.py
index 0ebb3eaafc783596771b1d600b37dd711654b11f..7d418c4696bb366a26aa2ae43b0c4392de706969 100644
--- a/pykat/utilities/knm.py
+++ b/pykat/utilities/knm.py
@@ -8,9 +8,33 @@ import numpy as np
 import pykat
 import collections
 import math
+
 from romhom import u_star_u
+from progressbar import ProgressBar, ETA, Percentage, Bar
+
+def makeCouplingMatrix(max_order):
+    max_order = int(max_order)
+    c = []
+    for n in range(0, max_order+1):
+        for m in range(0, max_order+1):
+            if n+m <= max_order:
+                c.append([n,m])
+
+    M = []
+
+    for i in c:
+        row = []
+    
+        for j in c:
+            e = list(i)
+            e.extend(j)
+            row.append(e)
+        
+        M.append(row)
+    
+    return np.array(M)    
 
-def riemann_HG_knm(x, y, mode_in, mode_out, q1, q2, q1y=None, q2y=None, Axy=None):
+def riemann_HG_knm(x, y, mode_in, mode_out, q1, q2, q1y=None, q2y=None, Axy=None, cache=None):
 
     if Axy == None:
         Axy == np.ones((len(x), len(y)))
@@ -23,19 +47,62 @@ def riemann_HG_knm(x, y, mode_in, mode_out, q1, q2, q1y=None, q2y=None, Axy=None
         
     if len(mode_in) != 2 or len(mode_out) != 2:
         raise BasePyKatException("Both mode in and out should be a container with modes [n m]")        
-    
-    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])
-    
+
     dx = abs(x[1] - x[0])
-    dy = abs(y[1] - y[0])
+    dy = abs(y[1] - y[0])    
+        
+    if cache == 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)
-    U2 = Hg_out.Unm(x,y).conjugate()
+        U1 = Hg_in.Unm(x,y)
+        U2 = Hg_out.Unm(x,y).conjugate()
+        
+        return dx * dy * np.einsum('ij,ij', Axy, U1*U2)
+    else:
+        
+        strx = "u1[%i,%i]" % (mode_in[0], mode_out[0])
+        stry = "u2[%i,%i]" % (mode_in[1], mode_out[1])
+        
+        return dx * dy * np.einsum('ij,ij', Axy, np.outer(cache[strx], cache[stry]))
+
     
-    return dx * dy * np.einsum('ij,ij', Axy, U1*U2)
 
 
+
+def __gen_riemann_knm_cache(x, y, 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 = {}
+    
+    while not it.finished:
+        try:
+            mode_in = [int(it.next()), int(it.next())]
+            mode_out = [int(it.next()), int(it.next())]
+            
+            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])
+    
+            if strx not in cache:
+                cache[strx] = 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()
+            
+        except StopIteration:
+            break
+    
+    return cache
+    
 def __gen_ROM_HG_knm_cache(weights, couplings, q1, q2, q1y=None, q2y=None):
 
     if q1y == None:
@@ -65,14 +132,10 @@ def __gen_ROM_HG_knm_cache(weights, couplings, q1, q2, q1y=None, q2y=None):
             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)
-            
+                cache[strx] = u_star_u(q1.z,   q2.z,  q1.w0,  q2.w0, mode_in[0], mode_out[0], weights.EI["xm"].nodes)   
             
+            if stry not in cache:
+                cache[stry] = u_star_u(q1y.z, q2y.z, q1y.w0, q2y.w0, mode_in[1], mode_out[1], weights.EI["ym"].nodes)
             
         except StopIteration:
             break
@@ -94,12 +157,14 @@ 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)
+    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(q1.z,   q2.z,  q1.w0,  q2.w0, n,   m,   weights.EI["ym"].nodes)
+            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
@@ -107,12 +172,22 @@ def ROM_HG_knm(weights, mode_in, mode_out, q1, q2, q1y=None, q2y=None, cache=Non
             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_xy_nodes = np.outer(u_x_nodes, u_y_nodes)
     
@@ -157,7 +232,7 @@ def ROM_HG_knm(weights, mode_in, mode_out, q1, q2, q1y=None, q2y=None, cache=Non
     
 
 
-def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riemann"):
+def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riemann", verbose=True):
     if q1y == None:
         q1y = q1
         
@@ -183,7 +258,7 @@ def knmHG(couplings, q1, q2, surface_map=None, q1y=None, q2y=None, method="riema
     it = np.nditer(couplings, flags=['refs_ok','f_index'])
     
     i = 0
-    
+        
     if method == "romhom":
         if surface_map == None:
             raise BasePyKatException("Using 'romhom' method requires a surface map to be specified")
@@ -192,28 +267,55 @@ 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)
         
-        romcache = None#__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)
     else:
-        romcache = None
+        cache = None
         weights = None
-        
+    
+    if verbose:
+        p = ProgressBar(maxval=couplings.size, widgets=["Knm (%s): " % method, Percentage(), Bar(), ETA()])
+    
     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)
+                K[i] = riemann_HG_knm(x, y, mode_in, mode_out, q1=q1, q2=q2, q1y=q1y, q2y=q2y, Axy=Axy, cache=cache)
             elif method == "romhom":
-                K[i] = ROM_HG_knm(weights, mode_in, mode_out, q1=q1, q2=q2, q1y=q1y, q2y=q2y, cache=romcache)
+                K[i] = ROM_HG_knm(weights, mode_in, mode_out, q1=q1, q2=q2, q1y=q1y, q2y=q2y, cache=cache)
             else:
                 raise BasePyKatException("method value '%s' not accepted" % method)
-        
+                
             i +=1
+            
+            if verbose:
+                p.update(i*4)
+                
                  
         except StopIteration:
             break
 
-    return K.reshape(couplings.shape[:-1])
\ No newline at end of file
+    return K.reshape(couplings.shape[:-1])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pykat/utilities/romhom.py b/pykat/utilities/romhom.py
index 30f9e4bd9056b0176fc7cfd78d77064a6c5fd97e..e134a7b502e1ba6cdea605b8b01ddbafa75d0861 100644
--- a/pykat/utilities/romhom.py
+++ b/pykat/utilities/romhom.py
@@ -4,6 +4,7 @@ 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
 from scipy.linalg import inv
@@ -150,21 +151,22 @@ def makeReducedBasis(x, isModeMatched=True, tolerance = 1e-12, sigma = 1):
 
     for i in range(len(params)):
 
-        q1 = beam_param(w0=params[i][0], z=params[i][2])
+        q1 = beam_param(w0=float(params[i][0]), z=float(params[i][2]))
 
         if isModeMatched:
             q2 = q1
             n = int(params[i][2])
             m = int(params[i][3])
-            w0_1 = params[i][0]
-            w0_2 = w0_1
-            re_q1 = params[i][1]
-            re_q2 = re_q1
         else:
-            q2 = beam_param(w0=params[i][1], z=params[i][3])            
+            q2 = beam_param(w0=float(params[i][1]), z=float(params[i][3]))            
             n = int(params[i][4])
             m = int(params[i][5])
             
+        w0_1 = q1.w0
+        w0_2 = q2.w0
+        re_q1 = q1.z
+        re_q2 = q2.z
+            
         TS[IDx] = u_star_u(re_q1, re_q2, w0_1, w0_2, n, m, x)
         
         # normalize
@@ -248,11 +250,8 @@ 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):
     
-    
     # get full A_xy
     A_xy = smap.z_xy()