Added arpack with bindings from scipy sandbox.
This commit is contained in:
355
arpack/tests/test_arpack.py
Normal file
355
arpack/tests/test_arpack.py
Normal file
@@ -0,0 +1,355 @@
|
||||
#!/usr/bin/env python
|
||||
__usage__ = """
|
||||
First ensure that scipy core modules are installed.
|
||||
|
||||
Build interface to arpack
|
||||
python setup.py build
|
||||
Run tests locally:
|
||||
python tests/test_arpack.py [-l<int>] [-v<int>]
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
from numpy.testing import *
|
||||
|
||||
set_package_path()
|
||||
from arpack import *
|
||||
del sys.path[0]
|
||||
|
||||
import numpy
|
||||
from scipy.linalg import eig,eigh,norm
|
||||
|
||||
class TestEigenNonsymmetric(NumpyTestCase):
|
||||
|
||||
def get_a1(self,typ):
|
||||
mat=numpy.array([[-2., -8., 1., 2., -5.],
|
||||
[ 6., 6., 0., 2., 1.],
|
||||
[ 0., 4., -2., 11., 0.],
|
||||
[ 1., 6., 1., 0., -4.],
|
||||
[ 2., -6., 4., 9., -3]],typ)
|
||||
|
||||
w=numpy.array([-2.21691+8.59661*1j,-2.21691-8.59661*1j,\
|
||||
4.45961+3.80078*1j, 4.45961-3.80078*1j,\
|
||||
-5.48541+0j],typ.upper())
|
||||
return mat,w
|
||||
|
||||
|
||||
def large_magnitude(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='LM')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.abs(aw)
|
||||
num=numpy.abs(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num[-k:],exact[-k:],decimal=5)
|
||||
|
||||
def small_magnitude(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='SM')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.abs(aw)
|
||||
num=numpy.abs(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num[:k],exact[:k],decimal=5)
|
||||
|
||||
|
||||
def large_real(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='LR')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.real(aw)
|
||||
num=numpy.real(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num[-k:],exact[-k:],decimal=5)
|
||||
|
||||
def small_real(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='SR')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.real(aw)
|
||||
num=numpy.real(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num[:k],exact[:k],decimal=5)
|
||||
|
||||
|
||||
def large_imag(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='LI')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
print w
|
||||
print aw
|
||||
exact=numpy.imag(aw)
|
||||
num=numpy.imag(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num[-k:],exact[-k:],decimal=5)
|
||||
|
||||
def small_imag(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='SI')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.imag(aw)
|
||||
num=numpy.imag(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
print num
|
||||
assert_array_almost_equal(num[:k],exact[:k],decimal=5)
|
||||
|
||||
|
||||
def check_type(self):
|
||||
k=2
|
||||
for typ in 'fd':
|
||||
self.large_magnitude(typ,k)
|
||||
self.small_magnitude(typ,k)
|
||||
self.large_real(typ,k)
|
||||
self.small_real(typ,k)
|
||||
# Maybe my understanding of small imaginary and large imaginary
|
||||
# isn't too keen. I don't understand why these return
|
||||
# different answers than in the complex case (the latter seems correct)
|
||||
# self.large_imag(typ,k)
|
||||
# self.small_imag(typ,k)
|
||||
|
||||
|
||||
|
||||
class TestEigenComplexNonsymmetric(NumpyTestCase):
|
||||
|
||||
def get_a1(self,typ):
|
||||
mat=numpy.array([[-2., -8., 1., 2., -5.],
|
||||
[ 6., 6., 0., 2., 1.],
|
||||
[ 0., 4., -2., 11., 0.],
|
||||
[ 1., 6., 1., 0., -4.],
|
||||
[ 2., -6., 4., 9., -3]],typ)
|
||||
|
||||
w=numpy.array([-2.21691+8.59661*1j,-2.21691-8.59661*1j,\
|
||||
4.45961+3.80078*1j, 4.45961-3.80078*1j,\
|
||||
-5.48541+0j],typ.upper())
|
||||
return mat,w
|
||||
|
||||
|
||||
def large_magnitude(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='LM')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.abs(aw)
|
||||
num=numpy.abs(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num,exact[-k:],decimal=5)
|
||||
|
||||
def small_magnitude(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='SM')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.abs(aw)
|
||||
num=numpy.abs(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num,exact[:k],decimal=5)
|
||||
|
||||
|
||||
def large_real(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='LR')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.real(aw)
|
||||
num=numpy.real(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num,exact[-k:],decimal=5)
|
||||
|
||||
def small_real(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='SR')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.real(aw)
|
||||
num=numpy.real(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num,exact[:k],decimal=5)
|
||||
|
||||
|
||||
def large_imag(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='LI')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.imag(aw)
|
||||
num=numpy.imag(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num,exact[-k:],decimal=5)
|
||||
|
||||
def small_imag(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='SI')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
exact=numpy.imag(aw)
|
||||
num=numpy.imag(w)
|
||||
exact.sort()
|
||||
num.sort()
|
||||
assert_array_almost_equal(num,exact[:k],decimal=5)
|
||||
|
||||
|
||||
def check_type(self):
|
||||
k=2
|
||||
for typ in 'FD':
|
||||
self.large_magnitude(typ,k)
|
||||
self.small_magnitude(typ,k)
|
||||
self.large_real(typ,k)
|
||||
self.small_real(typ,k)
|
||||
self.large_imag(typ,k)
|
||||
self.small_imag(typ,k)
|
||||
|
||||
|
||||
|
||||
|
||||
class TestEigenSymmetric(NumpyTestCase):
|
||||
|
||||
def get_a1(self,typ):
|
||||
mat_a1=numpy.array([[ 2., 0., 0., -1., 0., -1.],
|
||||
[ 0., 2., 0., -1., 0., -1.],
|
||||
[ 0., 0., 2., -1., 0., -1.],
|
||||
[-1., -1., -1., 4., 0., -1.],
|
||||
[ 0., 0., 0., 0., 1., -1.],
|
||||
[-1., -1., -1., -1., -1., 5.]],
|
||||
typ)
|
||||
w = [0,1,2,2,5,6] # eigenvalues of a1
|
||||
return mat_a1,w
|
||||
|
||||
def large_eigenvalues(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen_symmetric(a,k,which='LM',tol=1e-7)
|
||||
assert_array_almost_equal(w,aw[-k:])
|
||||
|
||||
def small_eigenvalues(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen_symmetric(a,k,which='SM')
|
||||
assert_array_almost_equal(w,aw[:k])
|
||||
|
||||
def end_eigenvalues(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen_symmetric(a,k,which='BE')
|
||||
exact=[aw[0],aw[-1]]
|
||||
assert_array_almost_equal(w,exact)
|
||||
|
||||
def large_eigenvectors(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen_symmetric(a,k,which='LM')
|
||||
ew,ev = eigh(a)
|
||||
ind=ew.argsort()
|
||||
assert_array_almost_equal(w,numpy.take(ew,ind[-k:]))
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i])
|
||||
|
||||
def small_eigenvectors(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen_symmetric(a,k,which='SM',tol=1e-7)
|
||||
ew,ev = eigh(a)
|
||||
ind=ew.argsort()
|
||||
assert_array_almost_equal(w,numpy.take(ew,ind[:k]))
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i])
|
||||
|
||||
def end_eigenvectors(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen_symmetric(a,k,which='BE')
|
||||
ew,ev = eigh(a)
|
||||
ind=ew.argsort()
|
||||
exact=numpy.concatenate(([ind[:k/2],ind[-k/2:]]))
|
||||
assert_array_almost_equal(w,numpy.take(ew,exact))
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i])
|
||||
|
||||
def check_eigenvectors(self):
|
||||
k=2
|
||||
for typ in 'fd':
|
||||
self.large_eigenvectors(typ,k)
|
||||
self.small_eigenvectors(typ,k)
|
||||
self.end_eigenvectors(typ,k)
|
||||
|
||||
def check_type(self):
|
||||
k=2
|
||||
for typ in 'fd':
|
||||
self.large_eigenvalues(typ,k)
|
||||
self.small_eigenvalues(typ,k)
|
||||
self.end_eigenvalues(typ,k)
|
||||
|
||||
|
||||
class TestEigenComplexSymmetric(NumpyTestCase):
|
||||
|
||||
def get_a1(self,typ):
|
||||
mat_a1=numpy.array([[ 2., 0., 0., -1., 0., -1.],
|
||||
[ 0., 2., 0., -1., 0., -1.],
|
||||
[ 0., 0., 2., -1., 0., -1.],
|
||||
[-1., -1., -1., 4., 0., -1.],
|
||||
[ 0., 0., 0., 0., 1., -1.],
|
||||
[-1., -1., -1., -1., -1., 5.]],
|
||||
typ)
|
||||
w = numpy.array([0+0j,1+0j,2+0j,2+0j,5+0j,6+0j]) # eigenvalues of a1
|
||||
return mat_a1,w
|
||||
|
||||
def large_magnitude(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='LM')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
aw.real.sort()
|
||||
w.real.sort()
|
||||
assert_array_almost_equal(w,aw[-k:])
|
||||
|
||||
|
||||
def small_magnitude(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='SM')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i])
|
||||
aw.real.sort()
|
||||
w.real.sort()
|
||||
assert_array_almost_equal(w,aw[:k])
|
||||
|
||||
def large_real(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='LR')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i],decimal=5)
|
||||
aw.real.sort()
|
||||
w.real.sort()
|
||||
assert_array_almost_equal(w,aw[-k:],decimal=5)
|
||||
|
||||
|
||||
def small_real(self,typ,k):
|
||||
a,aw = self.get_a1(typ)
|
||||
w,v = eigen(a,k,which='SR')
|
||||
for i in range(k):
|
||||
assert_array_almost_equal(sb.dot(a,v[:,i]),w[i]*v[:,i])
|
||||
aw.real.sort()
|
||||
w.real.sort()
|
||||
assert_array_almost_equal(w,aw[:k])
|
||||
|
||||
def check_complex_symmetric(self):
|
||||
k=2
|
||||
for typ in 'FD':
|
||||
self.large_magnitude(typ,k)
|
||||
self.small_magnitude(typ,k)
|
||||
self.large_real(typ,k)
|
||||
self.small_real(typ,k)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
NumpyTest().run()
|
54
arpack/tests/test_speigs.py
Normal file
54
arpack/tests/test_speigs.py
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from numpy.testing import *
|
||||
set_package_path()
|
||||
from arpack.speigs import *
|
||||
restore_path()
|
||||
|
||||
import numpy as N
|
||||
|
||||
class TestEigs(NumpyTestCase):
|
||||
def test(self):
|
||||
maxn=15 # Dimension of square matrix to be solved
|
||||
# Use a PDP^-1 factorisation to construct matrix with known
|
||||
# eiegevalues/vectors. Used random eiegenvectors initially.
|
||||
P = N.mat(N.random.random((maxn,)*2))
|
||||
P /= map(N.linalg.norm, P.T) # Normalise the eigenvectors
|
||||
D = N.mat(N.zeros((maxn,)*2))
|
||||
D[range(maxn), range(maxn)] = (N.arange(maxn, dtype=float)+1)/N.sqrt(maxn)
|
||||
A = P*D*N.linalg.inv(P)
|
||||
vals = N.array(D.diagonal())[0]
|
||||
vecs = P
|
||||
uv_sortind = vals.argsort()
|
||||
vals = vals[uv_sortind]
|
||||
vecs = vecs[:,uv_sortind]
|
||||
|
||||
from scipy.linalg.iterative import get_matvec
|
||||
matvec = get_matvec(A)
|
||||
#= lambda x: N.asarray(A*x)[0]
|
||||
nev=4
|
||||
eigvs = ARPACK_eigs(matvec, A.shape[0], nev=nev)
|
||||
calc_vals = eigvs[0]
|
||||
# Ensure the calculate eigenvectors have the same sign as the refence values
|
||||
calc_vecs = eigvs[1] / [N.sign(x[0]) for x in eigvs[1].T]
|
||||
assert_array_almost_equal(calc_vals, vals[0:nev], decimal=7)
|
||||
assert_array_almost_equal(calc_vecs, N.array(vecs)[:,0:nev], decimal=7)
|
||||
|
||||
|
||||
# class TestGeneigs(NumpyTestCase):
|
||||
# def test(self):
|
||||
# import pickle
|
||||
# import scipy.linsolve
|
||||
# A,B = pickle.load(file('mats.pickle'))
|
||||
# sigma = 27.
|
||||
# sigma_solve = scipy.linsolve.splu(A - sigma*B).solve
|
||||
# w = ARPACK_gen_eigs(B.matvec, sigma_solve, B.shape[0], sigma, 10)[0]
|
||||
# assert_array_almost_equal(w,
|
||||
# [27.346442255386375, 49.100299170945405, 56.508474856551544, 56.835800191692492,
|
||||
# 65.944215785041365, 66.194792400328367, 78.003788872725238, 79.550811647295944,
|
||||
# 94.646308846854879, 95.30841709116271], decimal=11)
|
||||
|
||||
if __name__ == "__main__":
|
||||
NumpyTest().run()
|
||||
|
Reference in New Issue
Block a user