Wrapper utils for Solvers

This commit is contained in:
rowanc1
2014-03-19 10:34:37 -07:00
parent bc91872215
commit 44ab7de6bc
4 changed files with 107 additions and 3 deletions
+23 -3
View File
@@ -1,7 +1,7 @@
import numpy as np
import scipy.sparse as sp
import scipy.sparse.linalg as linalg
from Utils.matutils import mkvc, sdiag
from Utils import mkvc, sdiag
import warnings
DEFAULTS = {'direct':'scipy', 'iter':'scipy', 'triangular':'fortran', 'diagonal':'python'}
@@ -214,12 +214,18 @@ class Solver(object):
def solveIter(self, b, backend=None, M=None, iterSolver='CG', tol=1e-6, maxIter=50):
if backend is None: backend = DEFAULTS['iter']
algorithms = {'CG':sp.linalg.cg}
algorithms = {'CG':sp.linalg.cg, 'QMR':sp.linalg.qmr}
assert iterSolver in algorithms, "iterSolver must be 'CG', or implement it yourself and add it here!"
alg = algorithms[iterSolver]
if iterSolver == 'CG':
opts = {'M':M}
elif iterSolver == 'QMR':
#TODO: make preconditioner better.
opts = {'M1':np.sqrt(M), 'M2':np.sqrt(M)}
if len(b.shape) == 1 or b.shape[1] == 1:
x, self.info = alg(self.A, b, M=M, tol=tol, maxiter=maxIter)
x, self.info = alg(self.A, b, tol=tol, maxiter=maxIter)
else:
x = np.empty_like(b)
for i in range(b.shape[1]):
@@ -381,3 +387,17 @@ if __name__ == '__main__':
toc = time() - tic
print x
print 'Error CG = ', np.linalg.norm(x-e, np.inf), 'Time: ', toc, 'Info: ', iSolve.info
A = -D*D.T
A[0,0] *= 10 # remove the constant null space from the matrix
e = np.ones(M.nC)
b = A.dot(e)
iSolve = Solver(A, doDirect=False, options={'iterSolver': 'QMR', 'M':'J'})
tic = time()
x = iSolve.solve(b)
toc = time() - tic
print x
print 'Error QMR = ', np.linalg.norm(x-e, np.inf), 'Time: ', toc, 'Info: ', iSolve.info
+75
View File
@@ -0,0 +1,75 @@
import numpy as np
from matutils import mkvc
import warnings
def DSolverWrap(fun, factorize=True, checkAccuracy=True, accuracyTol=1e-8):
def __init__(self, A, **kwargs):
self.A = A.tocsc()
self.kwargs = kwargs
if factorize:
self.solver = fun(self.A, **kwargs)
def solve(self, b):
if len(b.shape) == 1 or b.shape[1] == 1:
# Just one RHS
if factorize:
X = self.solver.solve(b.flatten(), **self.kwargs)
else:
X = fun(self.A, b.flatten(), **self.kwargs)
else: # Multiple RHSs
X = np.empty_like(b)
for i in range(b.shape[1]):
if factorize:
X[:,i] = self.solver.solve(b[:,i])
else:
X[:,i] = fun(self.A, b[:,i], **self.kwargs)
if checkAccuracy:
nrm = np.linalg.norm(mkvc(self.A*X - b)) / np.linalg.norm(Utils.mkvc(b))
if nrm > accuracyTol:
msg = '### SolverWarning ###: Accuracy on solve is above tolerance: %e > %e' % (nrm, accuracyTol)
print msg
warnings.warn(msg, RuntimeWarning)
return X
return type(fun.__name__, (object,), {"__init__": __init__, "solve": solve})
def ISolverWrap(fun, checkAccuracy=True, accuracyTol=1e-5):
def __init__(self, A, **kwargs):
self.A = A.tocsc()
self.kwargs = kwargs
def solve(self, b):
if len(b.shape) == 1 or b.shape[1] == 1:
# Just one RHS
out = fun(self.A, b.flatten(), **self.kwargs)
if type(out) is tuple and len(out) == 2:
# We are dealing with scipy output with an info!
X = out[0]
self.info = out[1]
else:
X = out
else: # Multiple RHSs
X = np.empty_like(b)
for i in range(b.shape[1]):
out = fun(self.A, b[:,i], **self.kwargs)
if type(out) is tuple and len(out) == 2:
# We are dealing with scipy output with an info!
X[:,i] = out[0]
self.info = out[1]
else:
X[:,i] = out
if checkAccuracy:
nrm = np.linalg.norm(mkvc(self.A*X - b)) / np.linalg.norm(Utils.mkvc(b))
if nrm > accuracyTol:
msg = '### SolverWarning ###: Accuracy on solve is above tolerance: %e > %e' % (nrm, accuracyTol)
print msg
warnings.warn(msg, RuntimeWarning)
return X
return type(fun.__name__, (object,), {"__init__": __init__, "solve": solve})
+1
View File
@@ -4,6 +4,7 @@ from lrmutils import volTetra, faceInfo, indexCube
from interputils import interpmat
from ipythonutils import easyAnimate as animate
import ModelBuilder
import SolverUtils
import types
import time
+8
View File
@@ -15,6 +15,14 @@ Matrix Utilities
:members:
:undoc-members:
Solver Utilities
================
.. automodule:: SimPEG.Utils.SolverUtils
:members:
:undoc-members:
LRM Utilities
=============