Fixed bug in esvd for m>n

This commit is contained in:
Arnar Flatberg 2007-07-26 18:32:48 +00:00
parent 7fd4ac6225
commit 47b89cc411

View File

@ -8,7 +8,12 @@ from scipy.linalg import svd,inv
from scipy import dot,empty,eye,newaxis,zeros,sqrt,diag,\
apply_along_axis,mean,ones,randn,empty_like,outer,c_,\
rand,sum,cumsum,matrix
has_sym=True
try:
import symmeig
except:
has_sym = False
def pca(a, aopt, scale='scores', mode='normal'):
""" Principal Component Analysis model
mode:
@ -18,11 +23,11 @@ def pca(a, aopt, scale='scores', mode='normal'):
"""
m, n = a.shape
if m*3>n:
#print "rows: %s cols: %s" %(m,n)
if m>(n+100) or n>(m+100):
u, s, v = esvd(a)
else:
u, s, vt = svd(a, full_matrices=0)
u, s, vt = svd(a, 0)
v = vt.T
eigvals = (1./m)*s
T = u*s
@ -250,6 +255,7 @@ def nipals_lpls(X, Y, Z, a_max, alpha=.7, mean_ctr=[2, 0, 1], mode='normal', sca
X, mnX = center(X, xctr)
Y, mnY = center(Y, xctr)
Z, mnZ = center(Z, zctr)
print Z.mean(1)
varX = pow(X, 2).sum()
varY = pow(Y, 2).sum()
@ -343,28 +349,29 @@ def nipals_lpls(X, Y, Z, a_max, alpha=.7, mean_ctr=[2, 0, 1], mode='normal', sca
def m_shape(array):
return matrix(array).shape
def esvd(data, economy=1):
def esvd(data):
"""SVD with the option of economy sized calculation
Calculate subspaces of X'X or XX' depending on the shape
of the matrix.
Good for extreme fat or thin matrices
:notes:
Numpy supports this by setting full_matrices=0
"""
m, n = data.shape
if m>=n:
data = dot(data.T, data)
u, s, vt = svd(data)
kernel = dot(data.T, data)
u, s, vt = svd(kernel)
u = dot(data, vt.T)
v = vt.T
for i in xrange(n):
s[i] = vnorm(u[:,i])
u[:,i] = u[:,i]/s[i]
else:
data = dot(data, data.T)
data = (data + data.T)/2.0
u, s, vt = svd(data)
kernel = dot(data, data.T)
#data = (data + data.T)/2.0
u, s, vt = svd(kernel)
v = dot(u.T, data)
for i in xrange(m):
s[i] = vnorm(v[i,:])