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