diff --git a/gwinc/suspension.py b/gwinc/suspension.py
index 2106f66ffb4ca144aba01df9c5885040747cfb87..93015f1f926955452dfb20b3b7785af216e83934 100644
--- a/gwinc/suspension.py
+++ b/gwinc/suspension.py
@@ -15,43 +15,37 @@ FIBER_TYPES = [
 ]
 
 
-def construct_eom_matrix(k, m, f):
-    """construct matrix for equations of motion.
-
-    `k` is the array for the spring constants and `f` is the freq
-    vector.
-
+# quad pendulum equation of motion matrix A =
+# [[k0+k1-m0*w**2,           -k1,             0,          0],
+#  [          -k1, k1+k2-m1*w**2,           -k2,          0],
+#  [            0,           -k2, k2+k3-m2*w**2,        -k3],
+#  [            0,             0,           -k3, k3-m3*w**2]])
+# diagonal elements: mass and restoring forces
+# off-diagonal: coupling to stages above and below
+# want TM equations of motion, so index 4
+# b = [[0], [0], [0], [1]]
+# sympy.linsolve((A, b), x) yields the following two functions
+
+
+def tst_force_to_tst_displ(k, m, f):
+    """transfer function for quad pendulum
+    
     """
-    w = 2*pi * f
-    nstages = m.size
-    A = zeros((nstages, nstages, f.size), dtype=complex)
-    for n in range(nstages-1):
-        # mass and restoring forces (diagonal elements)
-        A[n, n, :] = k[n, :] + k[n+1, :] - m[n] * w**2
-        # couplings to stages above and below
-        A[n, n+1, :] = -k[n+1, :]
-        A[n+1, n, :] = -k[n+1, :]
-    # mass and restoring force of bottom stage
-    A[-1, -1, :] = k[-1, :] - m[-1] * w**2
-    return A
-
-
-def calc_transfer_functions(A, B, k, f):
-    """calculate transfer function from A/B matrices
-
+    k0, k1, k2, k3 = k
+    m0, m1, m2, m3 = m
+    w = 2*pi*f
+    X3 = (k2**2*(k0 + k1 - m0*w**2) + (k1**2 - (k0 + k1 - m0*w**2)*(k1 + k2 - m1*w**2))*(k2 + k3 - m2*w**2))/(-k3**2*(k1**2 - (k0 + k1 - m0*w**2)*(k1 + k2 - m1*w**2)) + (k3 - m3*w**2)*(k2**2*(k0 + k1 - m0*w**2) - (-k1**2 + (k0 + k1 - m0*w**2)*(k1 + k2 - m1*w**2))*(k2 + k3 - m2*w**2)))
+    return X3
+
+def top_displ_to_tst_displ(k, m, f):
+    """transfer function for quad pendulum
+    
     """
-    vlen = A[0, 0, :].size
-    X = zeros([B.size, vlen], dtype=complex)
-    for j in range(vlen):
-        X[:, j] = np.linalg.solve(A[:, :, j], B)
-    # transfer function from the force on the TM to TM motion
-    hForce     = zeros(f.shape, dtype=complex)
-    hForce[:]  = X[-1, :]
-    # transfer function from the table motion to TM motion
-    hTable     = zeros(f.shape, dtype=complex)
-    hTable[:]  = X[0, :]
-    hTable     = hTable * k[0, :]
-    return hForce, hTable
+    k0, k1, k2, k3 = k
+    m0, m1, m2, m3 = m
+    w = 2*pi*f
+    X0 = k1*k2*k3/(k3**2*(k1**2 - (k0 + k1 - m0*w**2)*(k1 + k2 - m1*w**2)) - (k3 - m3*w**2)*(k2**2*(k0 + k1 - m0*w**2) + (k1**2 - (k0 + k1 - m0*w**2)*(k1 + k2 - m1*w**2))*(k2 + k3 - m2*w**2)))
+    return X0 * k0
 
 
 def suspQuad(f, ifo, material='Silica'):
@@ -367,57 +361,40 @@ def suspQuad(f, ifo, material='Silica'):
     # Equations of motion for the system
     ###############################################################
 
-    # want TM equations of motion, so index 4
-    B = np.array([0, 0, 0, 1])
-
-    m_list = mass
-    kh_list = kh
-    kv_list = kv
-
-    #m_list=[m1 m2 m3 m4];          # array of the mass
-    #kh_list=[kh1; kh2; kh3; kh4];  # array of the horiz spring constants
-    #kv_list=[kv1; kv2; kv3; kv4];  # array of the vert spring constants
-
     # Calculate TFs turning on the loss of each stage one by one
     hForce = Struct()
     vForce = Struct()
     hForce.singlylossy = np.zeros([len(sus.Stage), len(w)], dtype=complex)
     vForce.singlylossy = np.zeros([len(sus.Stage), len(w)], dtype=complex)
 
-    for n in range(len(m_list)):
+    for n in range(len(mass)):
         # horizontal
-        k_list = kh_list
         # only the imaginary part of the specified stage is used.
-        k_list = real(k_list) + 1j*imag([k_list[0,:]*(n==0),
-                                         k_list[1,:]*(n==1),
-                                         k_list[2,:]*(n==2),
-                                         k_list[3,:]*(n==3)])
-        # construct Eq of motion matrix
-        Ah = construct_eom_matrix(k_list, m_list, f)
+        k = real(kh) + 1j*imag([kh[0,:]*(n==0),
+                                kh[1,:]*(n==1),
+                                kh[2,:]*(n==2),
+                                kh[3,:]*(n==3)])
         # calculate TFs
-        hForce.singlylossy[n,:] = calc_transfer_functions(Ah, B, k_list, f)[0]
+        hForce.singlylossy[n,:] = tst_force_to_tst_displ(k, mass, f)
 
         # vertical
-        k_list = kv_list
         # only the imaginary part of the specified stage is used
-        k_list = real(k_list) + 1j*imag([k_list[0,:]*(n==0),
-                                         k_list[1,:]*(n==1),
-                                         k_list[2,:]*(n==2),
-                                         k_list[3,:]*(n==3)])
-        # construct Eq of motion matrix
-        Av = construct_eom_matrix(k_list, m_list, f)
+        k = real(kv) + 1j*imag([kv[0,:]*(n==0),
+                                kv[1,:]*(n==1),
+                                kv[2,:]*(n==2),
+                                kv[3,:]*(n==3)])
         # calculate TFs
-        vForce.singlylossy[n,:] = calc_transfer_functions(Av, B, k_list, f)[0]
+        vForce.singlylossy[n,:] = tst_force_to_tst_displ(k, mass, f)
 
     # calculate horizontal TFs with all losses on
-    Ah = construct_eom_matrix(kh_list, m_list, f)
-    hForce.fullylossy, hTable = calc_transfer_functions(Ah, B, kh_list, f)
+    hForce.fullylossy = tst_force_to_tst_displ(kh, mass, f)
+    hTable = top_displ_to_tst_displ(kh, mass, f)
 
     # calculate vertical TFs with all losses on
-    Av = construct_eom_matrix(kv_list, m_list, f)
-    vForce.fullylossy, vTable = calc_transfer_functions(Av, B, kv_list, f)
+    vForce.fullylossy = tst_force_to_tst_displ(kv, mass, f)
+    vTable = top_displ_to_tst_displ(kv, mass, f)
 
-    return hForce, vForce, hTable, vTable #, Ah, Av
+    return hForce, vForce, hTable, vTable
 
 
 def suspBQuad(f, ifo):