@@ -246,6 +246,11 @@ def normalize(dist):
246246 return [(n / total ) for n in dist ]
247247
248248
249+ def norm (X , n = 2 ):
250+ """Return the n-norm of vector X"""
251+ return sum ([x ** n for x in X ])** (1 / n )
252+
253+
249254def clip (x , lowest , highest ):
250255 """Return x clipped to the range [lowest..highest]."""
251256 return max (lowest , min (x , highest ))
@@ -270,6 +275,41 @@ def gaussian(mean, st_dev, x):
270275 return 1 / (math .sqrt (2 * math .pi )* st_dev )* math .e ** (- 0.5 * (float (x - mean )/ st_dev )** 2 )
271276
272277
278+ def truncated_svd (X , max_iter = 1000 ):
279+ """Computes the first component of SVD"""
280+
281+ def normalize_vec (X , n = 2 ):
282+ """Returns normalized vector"""
283+ norm_X = norm (X , n )
284+ Y = [x / norm_X for x in X ]
285+ return Y
286+
287+ m , n = len (X ), len (X [0 ])
288+ A = [[0 for _ in range (n + m )] for _ in range (n + m )]
289+ for i in range (m ):
290+ for j in range (n ):
291+ A [i ][j ] = A [m + j ][n + i ] = X [i ][j ]
292+
293+ X = [random .random () for _ in range (n + m )]
294+ X = normalize_vec (X )
295+ for _ in range (max_iter ):
296+ old_X = X
297+ X = matrix_multiplication (A , [[x ] for x in X ])
298+ X = [x [0 ] for x in X ]
299+ X = normalize_vec (X )
300+ # check for convergence
301+ if norm ([x1 - x2 for x1 , x2 in zip (old_X , X )]) <= 1e-10 :
302+ break
303+
304+ projected_X = matrix_multiplication (A , [[x ] for x in X ])
305+ projected_X = [x [0 ] for x in projected_X ]
306+ eival = norm (projected_X , 1 )/ norm (X , 1 )
307+ eivec_n = normalize_vec (X [:n ])
308+ eivec_m = normalize_vec (X [n :])
309+
310+ return (eivec_m , eivec_n , eival )
311+
312+
273313try : # math.isclose was added in Python 3.5; but we might be in 3.4
274314 from math import isclose
275315except ImportError :
0 commit comments