Added symmetric poweriterations to sandbox
This commit is contained in:
@ -30,7 +30,7 @@ class get_matvec:
|
||||
if isinstance(obj, sb.ndarray):
|
||||
self.callfunc = self.type1
|
||||
return
|
||||
meth = getattr(obj,self.methname,None)
|
||||
meth = getattr(obj, self.methname, None)
|
||||
if not callable(meth):
|
||||
raise ValueError, "Object must be an array "\
|
||||
"or have a callable %s attribute." % (self.methname,)
|
||||
@ -48,12 +48,12 @@ class get_matvec:
|
||||
return sb.dot(self.obj.A, x)
|
||||
|
||||
def type2(self, x):
|
||||
return self.obj(x,*self.args)
|
||||
return self.obj(x, *self.args)
|
||||
|
||||
|
||||
def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
maxiter=None,tol=0, return_eigenvectors=True):
|
||||
""" Return k eigenvalues and eigenvectors of the matrix A.
|
||||
def eigen(A, k=6, M=None, ncv=None, which='LM',
|
||||
maxiter=None, tol=0, return_eigenvectors=True, v0=None):
|
||||
"""Return k eigenvalues and eigenvectors of the matrix A.
|
||||
|
||||
Solves A * x[i] = w[i] * x[i], the standard eigenvalue problem for
|
||||
w[i] eigenvalues with corresponding eigenvectors x[i].
|
||||
@ -69,6 +69,7 @@ def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
M -- (Not implemented)
|
||||
A symmetric positive-definite matrix for the generalized
|
||||
eigenvalue problem A * x = w * M * x
|
||||
v0 -- Initial starting solution (n x 1)
|
||||
|
||||
Outputs:
|
||||
|
||||
@ -99,8 +100,8 @@ def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
|
||||
"""
|
||||
try:
|
||||
n,ny=A.shape
|
||||
n==ny
|
||||
n, ny = A.shape
|
||||
n == ny
|
||||
except:
|
||||
raise AttributeError("matrix is not square")
|
||||
if M is not None:
|
||||
@ -108,12 +109,12 @@ def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
|
||||
# some defaults
|
||||
if ncv is None:
|
||||
ncv=2*k+1
|
||||
ncv=min(ncv,n)
|
||||
if maxiter==None:
|
||||
maxiter=n*10
|
||||
ncv = 2*k + 1
|
||||
ncv = min(ncv, n)
|
||||
if maxiter == None:
|
||||
maxiter = n*10
|
||||
|
||||
# guess type
|
||||
# guess type
|
||||
resid = sb.zeros(n,'f')
|
||||
try:
|
||||
typ = A.dtype.char
|
||||
@ -129,7 +130,7 @@ def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
raise ValueError("k must be less than rank(A), k=%d"%k)
|
||||
if maxiter <= 0:
|
||||
raise ValueError("maxiter must be positive, maxiter=%d"%maxiter)
|
||||
whiches=['LM','SM','LR','SR','LI','SI']
|
||||
whiches = ['LM','SM','LR','SR','LI','SI']
|
||||
if which not in whiches:
|
||||
raise ValueError("which must be one of %s"%' '.join(whiches))
|
||||
if ncv > n or ncv < k:
|
||||
@ -141,17 +142,26 @@ def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
eigextract = _arpack.__dict__[ltr+'neupd']
|
||||
matvec = get_matvec(A)
|
||||
|
||||
v = sb.zeros((n,ncv),typ) # holds Ritz vectors
|
||||
resid = sb.zeros(n,typ) # residual
|
||||
workd = sb.zeros(3*n,typ) # workspace
|
||||
workl = sb.zeros(3*ncv*ncv+6*ncv,typ) # workspace
|
||||
iparam = sb.zeros(11,'int') # problem parameters
|
||||
ipntr = sb.zeros(14,'int') # pointers into workspaces
|
||||
info = 0
|
||||
v = sb.zeros((n, ncv), typ) # holds Ritz vectors
|
||||
if v0 == None:
|
||||
resid = sb.zeros(n, typ) # residual
|
||||
info = 0
|
||||
else: # starting vector is given
|
||||
nn, kk = v0.shape
|
||||
if nn != n:
|
||||
raise ValueError("starting vector must be: (%d, 1), got: (%d, %d)" %(n, nn, kk))
|
||||
resid = v0[:,0].astype(typ)
|
||||
info = 1
|
||||
|
||||
workd = sb.zeros(3*n, typ) # workspace
|
||||
workl = sb.zeros(3*ncv*ncv+6*ncv, typ) # workspace
|
||||
iparam = sb.zeros(11, 'int') # problem parameters
|
||||
ipntr = sb.zeros(14, 'int') # pointers into workspaces
|
||||
|
||||
ido = 0
|
||||
|
||||
if typ in 'FD':
|
||||
rwork = sb.zeros(ncv,typ.lower())
|
||||
rwork = sb.zeros(ncv, typ.lower())
|
||||
|
||||
# only supported mode is 1: Ax=lx
|
||||
ishfts = 1
|
||||
@ -160,7 +170,7 @@ def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
iparam[0] = ishfts
|
||||
iparam[2] = maxiter
|
||||
iparam[6] = mode1
|
||||
|
||||
|
||||
while True:
|
||||
if typ in 'fd':
|
||||
ido,resid,v,iparam,ipntr,info =\
|
||||
@ -173,9 +183,9 @@ def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
|
||||
if (ido == -1 or ido == 1):
|
||||
# compute y = A * x
|
||||
xslice = slice(ipntr[0]-1, ipntr[0]-1+n)
|
||||
yslice = slice(ipntr[1]-1, ipntr[1]-1+n)
|
||||
workd[yslice]=matvec(workd[xslice])
|
||||
xslice = slice(ipntr[0] - 1, ipntr[0] - 1 + n)
|
||||
yslice = slice(ipntr[1] - 1, ipntr[1] - 1 + n)
|
||||
workd[yslice] = matvec(workd[xslice])
|
||||
else: # done
|
||||
break
|
||||
|
||||
@ -233,7 +243,7 @@ def eigen(A,k=6,M=None,ncv=None,which='LM',
|
||||
|
||||
|
||||
def eigen_symmetric(A,k=6,M=None,ncv=None,which='LM',
|
||||
maxiter=None,tol=0, return_eigenvectors=True):
|
||||
maxiter=None,tol=0, return_eigenvectors=True, v0=None):
|
||||
""" Return k eigenvalues and eigenvectors of the real symmetric matrix A.
|
||||
|
||||
Solves A * x[i] = w[i] * x[i], the standard eigenvalue problem for
|
||||
@ -253,6 +263,8 @@ def eigen_symmetric(A,k=6,M=None,ncv=None,which='LM',
|
||||
A symmetric positive-definite matrix for the generalized
|
||||
eigenvalue problem A * x = w * M * x
|
||||
|
||||
v0 -- Starting vector (n, 1)
|
||||
|
||||
Outputs:
|
||||
|
||||
w -- An real array of k eigenvalues
|
||||
@ -325,12 +337,22 @@ def eigen_symmetric(A,k=6,M=None,ncv=None,which='LM',
|
||||
matvec = get_matvec(A)
|
||||
|
||||
v = sb.zeros((n,ncv),typ)
|
||||
resid = sb.zeros(n,typ)
|
||||
if v0 == None:
|
||||
resid = sb.zeros(n, typ) # residual
|
||||
info = 0
|
||||
else: # starting solution is given
|
||||
nn, kk = v0.shape
|
||||
if nn != n:
|
||||
raise ValueError("starting vectors must be: (%d, %d), got: (%d, %d)" %(n, k, nn, kk))
|
||||
resid = v0[:,0].astype(typ)
|
||||
info = 1
|
||||
|
||||
#resid = sb.zeros(n,typ)
|
||||
workd = sb.zeros(3*n,typ)
|
||||
workl = sb.zeros(ncv*(ncv+8),typ)
|
||||
iparam = sb.zeros(11,'int')
|
||||
ipntr = sb.zeros(11,'int')
|
||||
info = 0
|
||||
#info = 0
|
||||
ido = 0
|
||||
|
||||
# only supported mode is 1: Ax=lx
|
||||
@ -340,8 +362,7 @@ def eigen_symmetric(A,k=6,M=None,ncv=None,which='LM',
|
||||
iparam[0] = ishfts
|
||||
iparam[2] = maxiter
|
||||
iparam[6] = mode1
|
||||
|
||||
|
||||
|
||||
while True:
|
||||
ido,resid,v,iparam,ipntr,info =\
|
||||
eigsolver(ido,bmat,which,k,tol,resid,v,iparam,ipntr,
|
||||
|
Reference in New Issue
Block a user