Fixed bug in esvd for m>n
This commit is contained in:
parent
7fd4ac6225
commit
47b89cc411
@ -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,:])
|
||||
|
Reference in New Issue
Block a user