mirror of
https://github.com/wassname/simpeg.git
synced 2026-10-29 13:40:11 +08:00
Merge branch 'origin/master'
This commit is contained in:
commit
1a14ed3b04
36 files changed
+3180
-1223
No files matched your search
+5
-3
@@ -1,4 +1,6 @@
|
||||
*.pyc
|
||||
SimPEG.sublime-project
|
||||
SimPEG.sublime-workspace
|
||||
docs/_build/
|
||||
*.so
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
docs/_build/
|
||||
myNotebooks/*
|
||||
@@ -5,3 +5,4 @@ import inverse
|
||||
import visulize
|
||||
import forward
|
||||
import regularization
|
||||
import examples
|
||||
Whitespace-only changes.
@@ -5,7 +5,6 @@ from SimPEG.utils import ModelBuilder, sdiag, mkvc
|
||||
from SimPEG import Solver
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
import scipy.sparse.linalg as linalg
|
||||
|
||||
|
||||
class DCProblem(ModelTransforms.LogModel, Problem):
|
||||
@@ -16,7 +15,7 @@ class DCProblem(ModelTransforms.LogModel, Problem):
|
||||
|
||||
"""
|
||||
def __init__(self, mesh):
|
||||
super(DCProblem, self).__init__(mesh)
|
||||
Problem.__init__(self, mesh)
|
||||
self.mesh.setCellGradBC('neumann')
|
||||
|
||||
def reshapeFields(self, u):
|
||||
|
||||
@@ -13,13 +13,13 @@ class LinearProblem(Problem):
|
||||
return self.G.dot(m)
|
||||
|
||||
def J(self, m, v, u=None):
|
||||
return G.dot(v)
|
||||
return self.G.dot(v)
|
||||
|
||||
def Jt(self, m, v, u=None):
|
||||
return G.T.dot(v)
|
||||
return self.G.T.dot(v)
|
||||
|
||||
if __name__ == '__main__':
|
||||
N = 100
|
||||
|
||||
def example(N):
|
||||
h = np.ones(N)/N
|
||||
M = TensorMesh([h])
|
||||
|
||||
@@ -28,8 +28,6 @@ if __name__ == '__main__':
|
||||
p = -0.25
|
||||
q = 0.25
|
||||
|
||||
|
||||
|
||||
g = lambda k: np.exp(p*jk[k]*M.vectorCCx)*np.cos(2*np.pi*q*jk[k]*M.vectorCCx)
|
||||
|
||||
G = np.empty((nk, M.nC))
|
||||
@@ -38,12 +36,6 @@ if __name__ == '__main__':
|
||||
G[i,:] = g(i)
|
||||
|
||||
|
||||
|
||||
plt.figure(1)
|
||||
for i in range(nk):
|
||||
plt.plot(G[i,:])
|
||||
|
||||
|
||||
m_true = np.zeros(M.nC)
|
||||
m_true[M.vectorCCx > 0.3] = 1.
|
||||
m_true[M.vectorCCx > 0.45] = -0.5
|
||||
@@ -55,29 +47,29 @@ if __name__ == '__main__':
|
||||
|
||||
d_obs = d_true + noise
|
||||
|
||||
# plt.figure(3)
|
||||
# plt.plot(d_true,'-o')
|
||||
# plt.plot(d_obs,'r-o')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
prob = LinearProblem(M)
|
||||
prob.G = G
|
||||
prob.dobs = d_obs
|
||||
prob.std = np.ones_like(d_obs)*0.1
|
||||
|
||||
return prob, m_true
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
prob, m_true = example(100)
|
||||
M = prob.mesh
|
||||
|
||||
reg = Regularization(M)
|
||||
|
||||
opt = InexactGaussNewton(maxIter=20)
|
||||
|
||||
inv = Inversion(prob,reg,opt,beta0=1e-4)
|
||||
|
||||
m0 = np.zeros_like(m_true)
|
||||
|
||||
mrec = inv.run(m0)
|
||||
|
||||
plt.figure(1)
|
||||
for i in range(prob.G.shape[0]):
|
||||
plt.plot(prob.G[i,:])
|
||||
|
||||
plt.figure(2)
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ class Problem(object):
|
||||
This can often be computed given a vector (i.e. J(v)) rather than stored, as J is a large dense matrix.
|
||||
|
||||
"""
|
||||
pass
|
||||
raise NotImplementedError('J is not yet implemented.')
|
||||
|
||||
def Jt(self, m, v, u=None):
|
||||
"""
|
||||
@@ -152,7 +152,7 @@ class Problem(object):
|
||||
|
||||
Effect of transpose of J on a vector v.
|
||||
"""
|
||||
pass
|
||||
raise NotImplementedError('Jt is not yet implemented.')
|
||||
|
||||
|
||||
def J_approx(self, m, v, u=None):
|
||||
|
||||
@@ -8,5 +8,5 @@ class Cooling(object):
|
||||
|
||||
def getBeta(self):
|
||||
if self._beta is None:
|
||||
return beta0
|
||||
return self._beta / beta_coolingFactor
|
||||
return self.beta0
|
||||
return self._beta / self.beta_coolingFactor
|
||||
+94
-38
@@ -1,35 +1,33 @@
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
from SimPEG.utils import sdiag, mkvc
|
||||
import SimPEG
|
||||
from SimPEG.utils import sdiag, mkvc, setKwargs, checkStoppers, printStoppers
|
||||
from Optimize import Remember
|
||||
from BetaSchedule import Cooling
|
||||
|
||||
class Inversion(object):
|
||||
"""docstring for Inversion"""
|
||||
class BaseInversion(object):
|
||||
"""docstring for BaseInversion"""
|
||||
|
||||
maxIter = 10
|
||||
name = 'SimPEG Inversion'
|
||||
maxIter = 1
|
||||
name = 'BaseInversion'
|
||||
debug = False
|
||||
beta0 = 1e4
|
||||
|
||||
def __init__(self, prob, reg, opt, **kwargs):
|
||||
setKwargs(self, **kwargs)
|
||||
self.prob = prob
|
||||
self.reg = reg
|
||||
self.opt = opt
|
||||
self.opt.parent = self
|
||||
self.setKwargs(**kwargs)
|
||||
|
||||
def setKwargs(self, **kwargs):
|
||||
"""Sets key word arguments (kwargs) that are present in the object, throw an error if they don't exist."""
|
||||
for attr in kwargs:
|
||||
if hasattr(self, attr):
|
||||
setattr(self, attr, kwargs[attr])
|
||||
else:
|
||||
raise Exception('%s attr is not recognized' % attr)
|
||||
self.stoppers = [SimPEG.inverse.StoppingCriteria.iteration, SimPEG.inverse.StoppingCriteria.phi_d_target_Inversion]
|
||||
|
||||
def printInit(self):
|
||||
print "%s %s %s" % ('='*22, self.name, '='*22)
|
||||
print " # beta phi_d phi_m f norm(dJ) #LS"
|
||||
print "%s" % '-'*62
|
||||
|
||||
def printIter(self):
|
||||
print "%3d %1.2e %1.2e %1.2e %1.2e %1.2e %3d" % (self.opt._iter, self._beta, self._phi_d_last, self._phi_m_last, self.opt.f, np.linalg.norm(self.opt.g), self.opt._iterLS)
|
||||
# Check if we have inserted printers into the optimization
|
||||
if not np.any([p is SimPEG.inverse.IterationPrinters.phi_d for p in self.opt.printers]):
|
||||
self.opt.printers.insert(1,SimPEG.inverse.IterationPrinters.beta)
|
||||
self.opt.printers.insert(2,SimPEG.inverse.IterationPrinters.phi_d)
|
||||
self.opt.printers.insert(3,SimPEG.inverse.IterationPrinters.phi_m)
|
||||
self.opt.stoppers.append(SimPEG.inverse.StoppingCriteria.phi_d_target_Minimize)
|
||||
|
||||
@property
|
||||
def Wd(self):
|
||||
@@ -53,34 +51,85 @@ class Inversion(object):
|
||||
if getattr(self, '_phi_d_target', None) is None:
|
||||
return self.prob.dobs.size #
|
||||
return self._phi_d_target
|
||||
|
||||
@phi_d_target.setter
|
||||
def phi_d_target(self, value):
|
||||
self._phi_d_target = value
|
||||
|
||||
def run(self, m0):
|
||||
m = m0
|
||||
self._iter = 0
|
||||
self._beta = None
|
||||
self.startup(m0)
|
||||
while True:
|
||||
self._beta = self.getBeta()
|
||||
m = self.opt.minimize(self.evalFunction,m)
|
||||
self.m = self.opt.minimize(self.evalFunction, self.m)
|
||||
self.doEndIteration()
|
||||
if self.stoppingCriteria(): break
|
||||
self._iter += 1
|
||||
return m
|
||||
|
||||
beta0 = 1.e2
|
||||
beta_coolingFactor = 5.
|
||||
self.printDone()
|
||||
return self.m
|
||||
|
||||
def startup(self, m0):
|
||||
"""
|
||||
**startup** is called at the start of any new run call.
|
||||
|
||||
If you have things that also need to run on startup, you can create a method::
|
||||
|
||||
def _startup*(self, x0):
|
||||
pass
|
||||
|
||||
Where the * can be any string. If present, _startup* will be called at the start of the default startup call.
|
||||
You may also completely overwrite this function.
|
||||
|
||||
:param numpy.ndarray x0: initial x
|
||||
:rtype: None
|
||||
:return: None
|
||||
"""
|
||||
for method in [posible for posible in dir(self) if '_startup' in posible]:
|
||||
if self.debug: print 'startup is calling self.'+method
|
||||
getattr(self,method)(m0)
|
||||
|
||||
self.m = m0
|
||||
self._iter = 0
|
||||
self._beta = None
|
||||
|
||||
def doEndIteration(self):
|
||||
"""
|
||||
**doEndIteration** is called at the end of each run iteration.
|
||||
|
||||
If you have things that also need to run at the end of every iteration, you can create a method::
|
||||
|
||||
def _doEndIteration*(self, xt):
|
||||
pass
|
||||
|
||||
Where the * can be any string. If present, _doEndIteration* will be called at the start of the default doEndIteration call.
|
||||
You may also completely overwrite this function.
|
||||
|
||||
:param numpy.ndarray xt: tested new iterate that ensures a descent direction.
|
||||
:rtype: None
|
||||
:return: None
|
||||
"""
|
||||
for method in [posible for posible in dir(self) if '_doEndIteration' in posible]:
|
||||
if self.debug: print 'doEndIteration is calling self.'+method
|
||||
getattr(self,method)()
|
||||
|
||||
# store old values
|
||||
self.phi_d_last = self.phi_d
|
||||
self.phi_m_last = self.phi_m
|
||||
self._iter += 1
|
||||
|
||||
def getBeta(self):
|
||||
if self._beta is None:
|
||||
return self.beta0
|
||||
return self._beta / self.beta_coolingFactor
|
||||
return self.beta0
|
||||
|
||||
def stoppingCriteria(self):
|
||||
self._STOP = np.zeros(2,dtype=bool)
|
||||
self._STOP[0] = self._iter >= self.maxIter
|
||||
self._STOP[1] = self._phi_d_last <= self.phi_d_target
|
||||
return np.any(self._STOP)
|
||||
if self.debug: print 'checking stoppingCriteria'
|
||||
return checkStoppers(self, self.stoppers)
|
||||
|
||||
|
||||
def printDone(self):
|
||||
"""
|
||||
**printDone** is called at the end of the inversion routine.
|
||||
|
||||
"""
|
||||
printStoppers(self, self.stoppers)
|
||||
|
||||
|
||||
def evalFunction(self, m, return_g=True, return_H=True):
|
||||
@@ -89,8 +138,8 @@ class Inversion(object):
|
||||
phi_d = self.dataObj(m, u)
|
||||
phi_m = self.reg.modelObj(m)
|
||||
|
||||
self._phi_d_last = phi_d
|
||||
self._phi_m_last = phi_m
|
||||
self.phi_d = phi_d
|
||||
self.phi_m = phi_m
|
||||
|
||||
f = phi_d + self._beta * phi_m
|
||||
|
||||
@@ -111,7 +160,7 @@ class Inversion(object):
|
||||
|
||||
operator = sp.linalg.LinearOperator( (m.size, m.size), H_fun, dtype=float )
|
||||
out += (operator,)
|
||||
return out
|
||||
return out if len(out) > 1 else out[0]
|
||||
|
||||
|
||||
def dataObj(self, m, u=None):
|
||||
@@ -219,3 +268,10 @@ class Inversion(object):
|
||||
|
||||
return dmisfit
|
||||
|
||||
class Inversion(Cooling, Remember, BaseInversion):
|
||||
|
||||
maxIter = 10
|
||||
name = "SimPEG Inversion"
|
||||
|
||||
def __init__(self, prob, reg, opt, **kwargs):
|
||||
BaseInversion.__init__(self, prob, reg, opt, **kwargs)
|
||||
+351
-79
@@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from SimPEG.utils import mkvc, sdiag
|
||||
from SimPEG.utils import mkvc, sdiag, setKwargs, printTitles, printLine, printStoppers, checkStoppers
|
||||
norm = np.linalg.norm
|
||||
import scipy.sparse as sp
|
||||
from SimPEG import Solver
|
||||
@@ -12,6 +12,75 @@ except Exception, e:
|
||||
print 'Warning: you may not have the required pubsub installed, use pypubsub. You will not be able to listen to events.'
|
||||
doPub = False
|
||||
|
||||
class StoppingCriteria(object):
|
||||
"""docstring for StoppingCriteria"""
|
||||
|
||||
iteration = { "str": "%d : maxIter = %3d <= iter = %3d",
|
||||
"left": lambda M: M.maxIter, "right": lambda M: M._iter,
|
||||
"stopType": "critical"}
|
||||
|
||||
iterationLS = { "str": "%d : maxIterLS = %3d <= iterLS = %3d",
|
||||
"left": lambda M: M.maxIterLS, "right": lambda M: M._iterLS,
|
||||
"stopType": "critical"}
|
||||
|
||||
armijoGoldstein = { "str": "%d : ft = %1.4e <= alp*descent = %1.4e",
|
||||
"left": lambda M: M._LS_ft, "right": lambda M: M.f + M.LSreduction * M._LS_descent,
|
||||
"stopType": "optimal"}
|
||||
|
||||
tolerance_f = { "str": "%d : |fc-fOld| = %1.4e <= tolF*(1+|f0|) = %1.4e",
|
||||
"left": lambda M: 1 if M._iter==0 else abs(M.f-M.f_last), "right": lambda M: 0 if M._iter==0 else M.tolF*(1+abs(M.f0)),
|
||||
"stopType": "optimal"}
|
||||
|
||||
moving_x = { "str": "%d : |xc-x_last| = %1.4e <= tolX*(1+|x0|) = %1.4e",
|
||||
"left": lambda M: 1 if M._iter==0 else norm(M.xc-M.x_last), "right": lambda M: 0 if M._iter==0 else M.tolX*(1+norm(M.x0)),
|
||||
"stopType": "optimal"}
|
||||
|
||||
tolerance_g = { "str": "%d : |proj(x-g)-x| = %1.4e <= tolG = %1.4e",
|
||||
"left": lambda M: norm(M.projection(M.xc - M.g) - M.xc), "right": lambda M: M.tolG,
|
||||
"stopType": "optimal"}
|
||||
|
||||
norm_g = { "str": "%d : |proj(x-g)-x| = %1.4e <= 1e3*eps = %1.4e",
|
||||
"left": lambda M: norm(M.projection(M.xc - M.g) - M.xc), "right": lambda M: 1e3*M.eps,
|
||||
"stopType": "critical"}
|
||||
|
||||
bindingSet = { "str": "%d : probSize = %3d <= bindingSet = %3d",
|
||||
"left": lambda M: M.xc.size, "right": lambda M: np.sum(M.bindingSet(M.xc)),
|
||||
"stopType": "critical"}
|
||||
|
||||
bindingSet_LS = { "str": "%d : probSize = %3d <= bindingSet = %3d",
|
||||
"left": lambda M: M._LS_xt.size, "right": lambda M: np.sum(M.bindingSet(M._LS_xt)),
|
||||
"stopType": "critical"}
|
||||
|
||||
phi_d_target_Minimize = { "str": "%d : phi_d = %1.4e <= phi_d_target = %1.4e ",
|
||||
"left": lambda M: M.parent.phi_d, "right": lambda M: M.parent.phi_d_target,
|
||||
"stopType": "critical"}
|
||||
|
||||
phi_d_target_Inversion = { "str": "%d : phi_d = %1.4e <= phi_d_target = %1.4e ",
|
||||
"left": lambda I: I.phi_d, "right": lambda I: I.phi_d_target,
|
||||
"stopType": "critical"}
|
||||
|
||||
|
||||
class IterationPrinters(object):
|
||||
"""docstring for IterationPrinters"""
|
||||
|
||||
iteration = {"title": "#", "value": lambda M: M._iter, "width": 5, "format": "%3d"}
|
||||
f = {"title": "f", "value": lambda M: M.f, "width": 10, "format": "%1.2e"}
|
||||
norm_g = {"title": "|proj(x-g)-x|", "value": lambda M: norm(M.projection(M.xc - M.g) - M.xc), "width": 15, "format": "%1.2e"}
|
||||
totalLS = {"title": "LS", "value": lambda M: M._iterLS, "width": 5, "format": "%d"}
|
||||
|
||||
iterationLS = {"title": "#", "value": lambda M: (M._iter, M._iterLS), "width": 5, "format": "%3d.%d"}
|
||||
LS_ft = {"title": "ft", "value": lambda M: M._LS_ft, "width": 10, "format": "%1.2e"}
|
||||
LS_t = {"title": "t", "value": lambda M: M._LS_t, "width": 10, "format": "%0.5f"}
|
||||
LS_armijoGoldstein = {"title": "f + alp*g.T*p", "value": lambda M: M.f + M.LSreduction*M._LS_descent, "width": 16, "format": "%1.2e"}
|
||||
|
||||
itType = {"title": "itType", "value": lambda M: M._itType, "width": 8, "format": "%s"}
|
||||
aSet = {"title": "aSet", "value": lambda M: np.sum(M.activeSet(M.xc)), "width": 8, "format": "%d"}
|
||||
bSet = {"title": "bSet", "value": lambda M: np.sum(M.bindingSet(M.xc)), "width": 8, "format": "%d"}
|
||||
comment = {"title": "Comment", "value": lambda M: M.projComment, "width": 7, "format": "%s"}
|
||||
|
||||
beta = {"title": "beta", "value": lambda M: M.parent._beta, "width": 10, "format": "%1.2e"}
|
||||
phi_d = {"title": "phi_d", "value": lambda M: M.parent.phi_d, "width": 10, "format": "%1.2e"}
|
||||
phi_m = {"title": "phi_m", "value": lambda M: M.parent.phi_m, "width": 10, "format": "%1.2e"}
|
||||
|
||||
|
||||
class Minimize(object):
|
||||
@@ -22,7 +91,7 @@ class Minimize(object):
|
||||
|
||||
"""
|
||||
|
||||
name = "GeneralOptimizationAlgorithm"
|
||||
name = "General Optimization Algorithm"
|
||||
|
||||
maxIter = 20
|
||||
maxIterLS = 10
|
||||
@@ -34,17 +103,18 @@ class Minimize(object):
|
||||
tolG = 1e-1
|
||||
eps = 1e-5
|
||||
|
||||
debug = False
|
||||
debugLS = False
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self._id = int(np.random.rand()*1e6) # create a unique identifier to this program to be used in pubsub
|
||||
self.setKwargs(**kwargs)
|
||||
self.stoppers = [StoppingCriteria.tolerance_f, StoppingCriteria.moving_x, StoppingCriteria.tolerance_g, StoppingCriteria.norm_g, StoppingCriteria.iteration]
|
||||
self.stoppersLS = [StoppingCriteria.armijoGoldstein, StoppingCriteria.iterationLS]
|
||||
|
||||
def setKwargs(self, **kwargs):
|
||||
"""Sets key word arguments (kwargs) that are present in the object, throw an error if they don't exist."""
|
||||
for attr in kwargs:
|
||||
if hasattr(self, attr):
|
||||
setattr(self, attr, kwargs[attr])
|
||||
else:
|
||||
raise Exception('%s attr is not recognized' % attr)
|
||||
self.printers = [IterationPrinters.iteration, IterationPrinters.f, IterationPrinters.norm_g, IterationPrinters.totalLS]
|
||||
self.printersLS = [IterationPrinters.iterationLS, IterationPrinters.LS_ft, IterationPrinters.LS_t, IterationPrinters.LS_armijoGoldstein]
|
||||
|
||||
setKwargs(self, **kwargs)
|
||||
|
||||
def minimize(self, evalFunction, x0):
|
||||
"""
|
||||
@@ -59,6 +129,14 @@ class Minimize(object):
|
||||
|
||||
(f[, g][, H]) = evalFunction(x, return_g=False, return_H=False )
|
||||
|
||||
def evalFunction(x, return_g=False, return_H=False):
|
||||
out = (f,)
|
||||
if return_g:
|
||||
out += (g,)
|
||||
if return_H:
|
||||
out += (H,)
|
||||
return out if len(out) > 1 else out[0]
|
||||
|
||||
|
||||
Events are fired with the following inputs via pypubsub::
|
||||
|
||||
@@ -146,19 +224,33 @@ class Minimize(object):
|
||||
xc = x0
|
||||
_iter = _iterLS = 0
|
||||
|
||||
If you have things that also need to run on startup, you can create a method::
|
||||
|
||||
def _startup*(self, x0):
|
||||
pass
|
||||
|
||||
Where the * can be any string. If present, _startup* will be called at the start of the default startup call.
|
||||
You may also completely overwrite this function.
|
||||
|
||||
:param numpy.ndarray x0: initial x
|
||||
:rtype: None
|
||||
:return: None
|
||||
"""
|
||||
for method in [posible for posible in dir(self) if '_startup' in posible]:
|
||||
if self.debug: print 'startup is calling self.'+method
|
||||
getattr(self,method)(x0)
|
||||
|
||||
self._iter = 0
|
||||
self._iterLS = 0
|
||||
self._STOP = np.zeros((5,1),dtype=bool)
|
||||
|
||||
x0 = self.projection(x0) # ensure that we start of feasible.
|
||||
self.x0 = x0
|
||||
self.xc = x0
|
||||
self.xOld = x0
|
||||
self.f_last = np.nan
|
||||
self.x_last = x0
|
||||
|
||||
def printInit(self):
|
||||
|
||||
def printInit(self, inLS=False):
|
||||
"""
|
||||
**printInit** is called at the beginning of the optimization routine.
|
||||
|
||||
@@ -166,15 +258,12 @@ class Minimize(object):
|
||||
parent.printInit function and call that.
|
||||
|
||||
"""
|
||||
if doPub: pub.sendMessage('Minimize.printInit', minimize=self)
|
||||
if self.parent is not None and hasattr(self.parent, 'printInit'):
|
||||
self.parent.printInit()
|
||||
return
|
||||
print "%s %s %s" % ('='*22, self.name, '='*22)
|
||||
print "iter\tJc\t\tnorm(dJ)\tLS"
|
||||
print "%s" % '-'*57
|
||||
if doPub and not inLS: pub.sendMessage('Minimize.printInit', minimize=self)
|
||||
pad = ' '*10 if inLS else ''
|
||||
name = self.name if not inLS else self.nameLS
|
||||
printTitles(self, self.printers if not inLS else self.printersLS, name, pad)
|
||||
|
||||
def printIter(self):
|
||||
def printIter(self, inLS=False):
|
||||
"""
|
||||
**printIter** is called directly after function evaluations.
|
||||
|
||||
@@ -182,13 +271,11 @@ class Minimize(object):
|
||||
parent.printIter function and call that.
|
||||
|
||||
"""
|
||||
if doPub: pub.sendMessage('Minimize.printIter', minimize=self)
|
||||
if self.parent is not None and hasattr(self.parent, 'printIter'):
|
||||
self.parent.printIter()
|
||||
return
|
||||
print "%3d\t%1.2e\t%1.2e\t%d" % (self._iter, self.f, norm(self.g), self._iterLS)
|
||||
if doPub and not inLS: pub.sendMessage('Minimize.printIter', minimize=self)
|
||||
pad = ' '*10 if inLS else ''
|
||||
printLine(self, self.printers if not inLS else self.printersLS, pad=pad)
|
||||
|
||||
def printDone(self):
|
||||
def printDone(self, inLS=False):
|
||||
"""
|
||||
**printDone** is called at the end of the optimization routine.
|
||||
|
||||
@@ -196,31 +283,19 @@ class Minimize(object):
|
||||
parent.printDone function and call that.
|
||||
|
||||
"""
|
||||
if doPub: pub.sendMessage('Minimize.printDone', minimize=self)
|
||||
if self.parent is not None and hasattr(self.parent, 'printDone'):
|
||||
self.parent.printDone()
|
||||
return
|
||||
print "%s STOP! %s" % ('-'*25,'-'*25)
|
||||
# TODO: put controls on gradient value, min model update, and function value
|
||||
if self._iter > 0:
|
||||
print "%d : |fc-fOld| = %1.4e <= tolF*(1+|fStop|) = %1.4e" % (self._STOP[0], abs(self.f-self.fOld), self.tolF*(1+abs(self.fStop)))
|
||||
print "%d : |xc-xOld| = %1.4e <= tolX*(1+|x0|) = %1.4e" % (self._STOP[1], norm(self.xc-self.xOld), self.tolX*(1+norm(self.x0)))
|
||||
print "%d : |g| = %1.4e <= tolG*(1+|fStop|) = %1.4e" % (self._STOP[2], norm(self.g), self.tolG*(1+abs(self.fStop)))
|
||||
print "%d : |g| = %1.4e <= 1e3*eps = %1.4e" % (self._STOP[3], norm(self.g), 1e3*self.eps)
|
||||
print "%d : iter = %3d\t <= maxIter\t = %3d" % (self._STOP[4], self._iter, self.maxIter)
|
||||
print "%s DONE! %s\n" % ('='*25,'='*25)
|
||||
if doPub and not inLS: pub.sendMessage('Minimize.printDone', minimize=self)
|
||||
pad = ' '*10 if inLS else ''
|
||||
stop, done = (' STOP! ', ' DONE! ') if not inLS else ('----------------', ' End Linesearch ')
|
||||
stoppers = self.stoppers if not inLS else self.stoppersLS
|
||||
printStoppers(self, stoppers, pad='', stop=stop, done=done)
|
||||
|
||||
def stoppingCriteria(self):
|
||||
|
||||
def stoppingCriteria(self, inLS=False):
|
||||
if self._iter == 0:
|
||||
self.fStop = self.f # Save this for stopping criteria
|
||||
self.f0 = self.f
|
||||
self.g0 = self.g
|
||||
return checkStoppers(self, self.stoppers if not inLS else self.stoppersLS)
|
||||
|
||||
# check stopping rules
|
||||
self._STOP[0] = self._iter > 0 and (abs(self.f-self.fOld) <= self.tolF*(1+abs(self.fStop)))
|
||||
self._STOP[1] = self._iter > 0 and (norm(self.xc-self.xOld) <= self.tolX*(1+norm(self.x0)))
|
||||
self._STOP[2] = norm(self.g) <= self.tolG*(1+abs(self.fStop))
|
||||
self._STOP[3] = norm(self.g) <= 1e3*self.eps
|
||||
self._STOP[4] = self._iter >= self.maxIter
|
||||
return all(self._STOP[0:3]) | any(self._STOP[3:])
|
||||
|
||||
def projection(self, p):
|
||||
"""
|
||||
@@ -278,6 +353,8 @@ class Minimize(object):
|
||||
p = self.maxStep*p/np.abs(p.max())
|
||||
return p
|
||||
|
||||
nameLS = "Armijo linesearch"
|
||||
|
||||
def modifySearchDirection(self, p):
|
||||
"""
|
||||
**modifySearchDirection** changes the search direction based on some sort of linesearch or trust-region criteria.
|
||||
@@ -296,20 +373,23 @@ class Minimize(object):
|
||||
:rtype: numpy.ndarray,bool
|
||||
:return: (xt, passLS)
|
||||
"""
|
||||
# Armijo linesearch
|
||||
descent = np.inner(self.g, p)
|
||||
t = 1
|
||||
iterLS = 0
|
||||
while iterLS < self.maxIterLS:
|
||||
xt = self.projection(self.xc + t*p)
|
||||
ft = self.evalFunction(xt, return_g=False, return_H=False)
|
||||
if ft < self.f + t*self.LSreduction*descent:
|
||||
break
|
||||
iterLS += 1
|
||||
t = self.LSshorten*t
|
||||
# Projected Armijo linesearch
|
||||
self._LS_t = 1
|
||||
self._iterLS = 0
|
||||
while self._iterLS < self.maxIterLS:
|
||||
self._LS_xt = self.projection(self.xc + self._LS_t*p)
|
||||
self._LS_ft = self.evalFunction(self._LS_xt, return_g=False, return_H=False)
|
||||
self._LS_descent = np.inner(self.g, self._LS_xt - self.xc) # this takes into account multiplying by t, but is important for projection.
|
||||
if self.stoppingCriteria(inLS=True): break
|
||||
self._iterLS += 1
|
||||
self._LS_t = self.LSshorten*self._LS_t
|
||||
if self.debugLS:
|
||||
if self._iterLS == 1: self.printInit(inLS=True)
|
||||
self.printIter(inLS=True)
|
||||
|
||||
self._iterLS = iterLS
|
||||
return xt, iterLS < self.maxIterLS
|
||||
if self.debugLS and self._iterLS > 0: self.printDone(inLS=True)
|
||||
|
||||
return self._LS_xt, self._iterLS < self.maxIterLS
|
||||
|
||||
def modifySearchDirectionBreak(self, p):
|
||||
"""
|
||||
@@ -327,35 +407,227 @@ class Minimize(object):
|
||||
:rtype: numpy.ndarray,bool
|
||||
:return: (xt, breakCaught)
|
||||
"""
|
||||
self.printDone(inLS=True)
|
||||
print 'The linesearch got broken. Boo.'
|
||||
return p, False
|
||||
|
||||
def doEndIteration(self, xt):
|
||||
"""
|
||||
**doEndIteration** is called at the end of each minimize iteration.
|
||||
**doEndIteration** is called at the end of each minimize iteration.
|
||||
|
||||
By default, function values and x locations are shuffled to store 1 past iteration in memory.
|
||||
By default, function values and x locations are shuffled to store 1 past iteration in memory.
|
||||
|
||||
self.xc must be updated in this code.
|
||||
self.xc must be updated in this code.
|
||||
|
||||
:param numpy.ndarray xt: tested new iterate that ensures a descent direction.
|
||||
:rtype: None
|
||||
:return: None
|
||||
|
||||
If you have things that also need to run at the end of every iteration, you can create a method::
|
||||
|
||||
def _doEndIteration*(self, xt):
|
||||
pass
|
||||
|
||||
Where the * can be any string. If present, _doEndIteration* will be called at the start of the default doEndIteration call.
|
||||
You may also completely overwrite this function.
|
||||
|
||||
:param numpy.ndarray xt: tested new iterate that ensures a descent direction.
|
||||
:rtype: None
|
||||
:return: None
|
||||
"""
|
||||
for method in [posible for posible in dir(self) if '_doEndIteration' in posible]:
|
||||
if self.debug: print 'doEndIteration is calling self.'+method
|
||||
getattr(self,method)(xt)
|
||||
|
||||
# store old values
|
||||
self.fOld = self.f
|
||||
self.xOld, self.xc = self.xc, xt
|
||||
self.f_last = self.f
|
||||
self.x_last, self.xc = self.xc, xt
|
||||
self._iter += 1
|
||||
if self.debug: self.printDone()
|
||||
|
||||
|
||||
class GaussNewton(Minimize):
|
||||
name = 'GaussNewton'
|
||||
|
||||
class Remember(object):
|
||||
"""
|
||||
This mixin remembers all the things you tend to forget.
|
||||
|
||||
You can remember parameters directly, naming the str in Minimize,
|
||||
or pass a tuple with the name and the function that takes Minimize.
|
||||
|
||||
For Example::
|
||||
|
||||
opt.remember('f',('norm_g', lambda M: np.linalg.norm(M.g)))
|
||||
|
||||
opt.minimize(evalFunction, x0)
|
||||
|
||||
opt.recall('f')
|
||||
|
||||
The param name (str) can also be located in the parent (if no conflicts),
|
||||
and it will be looked up by default.
|
||||
"""
|
||||
|
||||
_rememberThese = []
|
||||
|
||||
def remember(self, *args):
|
||||
self._rememberThese = args
|
||||
|
||||
def recall(self, param):
|
||||
assert param in self._rememberList, "You didn't tell me to remember "+param+", you gotta tell me what to remember!"
|
||||
return self._rememberList[param]
|
||||
|
||||
def _startupRemember(self, x0):
|
||||
self._rememberList = {}
|
||||
for param in self._rememberThese:
|
||||
if type(param) is str:
|
||||
self._rememberList[param] = []
|
||||
elif type(param) is tuple:
|
||||
self._rememberList[param[0]] = []
|
||||
|
||||
def _doEndIterationRemember(self, *args):
|
||||
for param in self._rememberThese:
|
||||
if type(param) is str:
|
||||
if self.debug: print 'Remember is remembering: ' + param
|
||||
val = getattr(self, param, None)
|
||||
if val is None and getattr(self, 'parent', None) is not None:
|
||||
# Look to the parent for the param if not found here.
|
||||
val = getattr(self.parent, param, None)
|
||||
self._rememberList[param].append( val )
|
||||
elif type(param) is tuple:
|
||||
if self.debug: print 'Remember is remembering: ' + param[0]
|
||||
self._rememberList[param[0]].append( param[1](self) )
|
||||
|
||||
|
||||
|
||||
class ProjectedGradient(Minimize, Remember):
|
||||
name = 'Projected Gradient'
|
||||
|
||||
maxIterCG = 10
|
||||
tolCG = 1e-3
|
||||
|
||||
lower = -np.inf
|
||||
upper = np.inf
|
||||
|
||||
def __init__(self,**kwargs):
|
||||
super(ProjectedGradient, self).__init__(**kwargs)
|
||||
|
||||
self.stoppers.append(StoppingCriteria.bindingSet)
|
||||
self.stoppersLS.append(StoppingCriteria.bindingSet_LS)
|
||||
|
||||
self.printers.extend([ IterationPrinters.itType, IterationPrinters.aSet, IterationPrinters.bSet, IterationPrinters.comment ])
|
||||
|
||||
|
||||
def _startup(self, x0):
|
||||
# ensure bound vectors are the same size as the model
|
||||
if type(self.lower) is not np.ndarray:
|
||||
self.lower = np.ones_like(x0)*self.lower
|
||||
if type(self.upper) is not np.ndarray:
|
||||
self.upper = np.ones_like(x0)*self.upper
|
||||
|
||||
self.explorePG = True
|
||||
self.exploreCG = False
|
||||
self.stopDoingPG = False
|
||||
|
||||
self._itType = 'SD'
|
||||
self.projComment = ''
|
||||
|
||||
self.aSet_prev = self.activeSet(x0)
|
||||
|
||||
def projection(self, x):
|
||||
"""Make sure we are feasible."""
|
||||
return np.median(np.c_[self.lower,x,self.upper],axis=1)
|
||||
|
||||
def activeSet(self, x):
|
||||
"""If we are on a bound"""
|
||||
return np.logical_or(x == self.lower, x == self.upper)
|
||||
|
||||
def inactiveSet(self, x):
|
||||
"""The free variables."""
|
||||
return np.logical_not(self.activeSet(x))
|
||||
|
||||
def bindingSet(self, x):
|
||||
"""
|
||||
If we are on a bound and the negative gradient points away from the feasible set.
|
||||
|
||||
Optimality condition. (Satisfies Kuhn-Tucker) MoreToraldo91
|
||||
|
||||
"""
|
||||
bind_up = np.logical_and(x == self.lower, self.g >= 0)
|
||||
bind_low = np.logical_and(x == self.upper, self.g <= 0)
|
||||
return np.logical_or(bind_up, bind_low)
|
||||
|
||||
def findSearchDirection(self):
|
||||
self.aSet_prev = self.activeSet(self.xc)
|
||||
allBoundsAreActive = sum(self.aSet_prev) == self.xc.size
|
||||
|
||||
if self.debug: print 'findSearchDirection: stopDoingPG: ', self.stopDoingPG
|
||||
if self.debug: print 'findSearchDirection: explorePG: ', self.explorePG
|
||||
if self.debug: print 'findSearchDirection: exploreCG: ', self.exploreCG
|
||||
if self.debug: print 'findSearchDirection: aSet', np.sum(self.activeSet(self.xc))
|
||||
if self.debug: print 'findSearchDirection: bSet', np.sum(self.bindingSet(self.xc))
|
||||
if self.debug: print 'findSearchDirection: allBoundsAreActive: ', allBoundsAreActive
|
||||
|
||||
if self.explorePG or not self.exploreCG or allBoundsAreActive:
|
||||
if self.debug: print 'findSearchDirection.PG: doingPG'
|
||||
self._itType = 'SD'
|
||||
p = -self.g
|
||||
else:
|
||||
if self.debug: print 'findSearchDirection.CG: doingCG'
|
||||
# Reset the max decrease each time you do a CG iteration
|
||||
self.f_decrease_max = -np.inf
|
||||
|
||||
self._itType = '.CG.'
|
||||
|
||||
iSet = self.inactiveSet(self.xc) # The inactive set (free variables)
|
||||
bSet = self.bindingSet(self.xc)
|
||||
shape = (self.xc.size, np.sum(iSet))
|
||||
v = np.ones(shape[1])
|
||||
i = np.where(iSet)[0]
|
||||
j = np.arange(shape[1])
|
||||
if self.debug: print 'findSearchDirection.CG: Z.shape', shape
|
||||
Z = sp.csr_matrix((v, (i, j)), shape=shape)
|
||||
|
||||
def reduceHess(v):
|
||||
# Z is tall and skinny
|
||||
return Z.T*(self.H*(Z*v))
|
||||
operator = sp.linalg.LinearOperator( (shape[1], shape[1]), reduceHess, dtype=float )
|
||||
p, info = sp.linalg.cg(operator, -Z.T*self.g, tol=self.tolCG, maxiter=self.maxIterCG)
|
||||
p = Z*p # bring up to full size
|
||||
# aSet_after = self.activeSet(self.xc+p)
|
||||
return p
|
||||
|
||||
def _doEndIteration_ProjectedGradient(self, xt):
|
||||
aSet = self.activeSet(xt)
|
||||
bSet = self.bindingSet(xt)
|
||||
|
||||
self.explorePG = not np.all(aSet == self.aSet_prev) # explore proximal gradient
|
||||
self.exploreCG = np.all(aSet == bSet) # explore conjugate gradient
|
||||
|
||||
f_current_decrease = self.f_last - self.f
|
||||
self.projComment = ''
|
||||
if self._iter < 1:
|
||||
# Note that this is reset on every CG iteration.
|
||||
self.f_decrease_max = -np.inf
|
||||
else:
|
||||
self.f_decrease_max = max(self.f_decrease_max, f_current_decrease)
|
||||
self.stopDoingPG = f_current_decrease < 0.25 * self.f_decrease_max
|
||||
if self.stopDoingPG:
|
||||
self.projComment = 'Stop SD'
|
||||
self.explorePG = False
|
||||
self.exploreCG = True
|
||||
# implement 3.8, MoreToraldo91
|
||||
#self.eta_2 * max_decrease where max decrease
|
||||
# if true go to CG
|
||||
# don't do too many steps of PG in a row.
|
||||
|
||||
if self.debug: print 'doEndIteration.ProjGrad, f_current_decrease: ', f_current_decrease
|
||||
if self.debug: print 'doEndIteration.ProjGrad, f_decrease_max: ', self.f_decrease_max
|
||||
if self.debug: print 'doEndIteration.ProjGrad, stopDoingSD: ', self.stopDoingSD
|
||||
|
||||
class GaussNewton(Minimize, Remember):
|
||||
name = 'Gauss Newton'
|
||||
def findSearchDirection(self):
|
||||
return Solver(self.H).solve(-self.g)
|
||||
|
||||
|
||||
class InexactGaussNewton(Minimize):
|
||||
name = 'InexactGaussNewton'
|
||||
class InexactGaussNewton(Minimize, Remember):
|
||||
name = 'Inexact Gauss Newton'
|
||||
|
||||
maxIterCG = 10
|
||||
tolCG = 1e-5
|
||||
@@ -366,8 +638,8 @@ class InexactGaussNewton(Minimize):
|
||||
return p
|
||||
|
||||
|
||||
class SteepestDescent(Minimize):
|
||||
name = 'SteepestDescent'
|
||||
class SteepestDescent(Minimize, Remember):
|
||||
name = 'Steepest Descent'
|
||||
def findSearchDirection(self):
|
||||
return -self.g
|
||||
|
||||
@@ -377,9 +649,9 @@ if __name__ == '__main__':
|
||||
x0 = np.array([2.6, 3.7])
|
||||
checkDerivative(Rosenbrock, x0, plotIt=False)
|
||||
|
||||
def listener1(minimize,p):
|
||||
print 'hi: ', p
|
||||
if doPub: pub.subscribe(listener1, 'Minimize.searchDirection')
|
||||
# def listener1(minimize,p):
|
||||
# print 'hi: ', p
|
||||
# if doPub: pub.subscribe(listener1, 'Minimize.searchDirection')
|
||||
|
||||
xOpt = GaussNewton(maxIter=20,tolF=1e-10,tolX=1e-10,tolG=1e-10).minimize(Rosenbrock,x0)
|
||||
print "xOpt=[%f, %f]" % (xOpt[0], xOpt[1])
|
||||
|
||||
+38
-13
@@ -102,7 +102,7 @@ class BaseMesh(object):
|
||||
elif xType in ['F', 'E']:
|
||||
# This will only deal with components of fields, not full 'F' or 'E'
|
||||
xx = mkvc(xx) # unwrap it in case it is a matrix
|
||||
nn = self.nF if xType == 'F' else self.nE
|
||||
nn = self.nFv if xType == 'F' else self.nEv
|
||||
nn = np.r_[0, nn]
|
||||
|
||||
nx = [0, 0, 0]
|
||||
@@ -331,7 +331,7 @@ class BaseMesh(object):
|
||||
return locals()
|
||||
nEz = property(**nEz())
|
||||
|
||||
def nE():
|
||||
def nEv():
|
||||
doc = """
|
||||
Total number of edges in each direction
|
||||
|
||||
@@ -346,6 +346,18 @@ class BaseMesh(object):
|
||||
"""
|
||||
fget = lambda self: np.array([np.prod(x) for x in [self.nEx, self.nEy, self.nEz] if not x is None])
|
||||
return locals()
|
||||
nEv = property(**nEv())
|
||||
|
||||
def nE():
|
||||
doc = """
|
||||
Total number of edges.
|
||||
|
||||
:rtype: int
|
||||
:return: sum([prod(nEx), prod(nEy), prod(nEz)])
|
||||
|
||||
"""
|
||||
fget = lambda self: np.sum(self.nEv)
|
||||
return locals()
|
||||
nE = property(**nE())
|
||||
|
||||
def nFx():
|
||||
@@ -391,7 +403,7 @@ class BaseMesh(object):
|
||||
return locals()
|
||||
nFz = property(**nFz())
|
||||
|
||||
def nF():
|
||||
def nFv():
|
||||
doc = """
|
||||
Total number of faces in each direction
|
||||
|
||||
@@ -406,6 +418,19 @@ class BaseMesh(object):
|
||||
"""
|
||||
fget = lambda self: np.array([np.prod(x) for x in [self.nFx, self.nFy, self.nFz] if not x is None])
|
||||
return locals()
|
||||
nFv = property(**nFv())
|
||||
|
||||
|
||||
def nF():
|
||||
doc = """
|
||||
Total number of faces.
|
||||
|
||||
:rtype: int
|
||||
:return: sum([prod(nFx), prod(nFy), prod(nFz)])
|
||||
|
||||
"""
|
||||
fget = lambda self: np.sum(self.nFv)
|
||||
return locals()
|
||||
nF = property(**nF())
|
||||
|
||||
def normals():
|
||||
@@ -418,13 +443,13 @@ class BaseMesh(object):
|
||||
|
||||
def fget(self):
|
||||
if self.dim == 2:
|
||||
nX = np.c_[np.ones(self.nF[0]), np.zeros(self.nF[0])]
|
||||
nY = np.c_[np.zeros(self.nF[1]), np.ones(self.nF[1])]
|
||||
nX = np.c_[np.ones(self.nFv[0]), np.zeros(self.nFv[0])]
|
||||
nY = np.c_[np.zeros(self.nFv[1]), np.ones(self.nFv[1])]
|
||||
return np.r_[nX, nY]
|
||||
elif self.dim == 3:
|
||||
nX = np.c_[np.ones(self.nF[0]), np.zeros(self.nF[0]), np.zeros(self.nF[0])]
|
||||
nY = np.c_[np.zeros(self.nF[1]), np.ones(self.nF[1]), np.zeros(self.nF[1])]
|
||||
nZ = np.c_[np.zeros(self.nF[2]), np.zeros(self.nF[2]), np.ones(self.nF[2])]
|
||||
nX = np.c_[np.ones(self.nFv[0]), np.zeros(self.nFv[0]), np.zeros(self.nFv[0])]
|
||||
nY = np.c_[np.zeros(self.nFv[1]), np.ones(self.nFv[1]), np.zeros(self.nFv[1])]
|
||||
nZ = np.c_[np.zeros(self.nFv[2]), np.zeros(self.nFv[2]), np.ones(self.nFv[2])]
|
||||
return np.r_[nX, nY, nZ]
|
||||
return locals()
|
||||
normals = property(**normals())
|
||||
@@ -439,13 +464,13 @@ class BaseMesh(object):
|
||||
|
||||
def fget(self):
|
||||
if self.dim == 2:
|
||||
tX = np.c_[np.ones(self.nE[0]), np.zeros(self.nE[0])]
|
||||
tY = np.c_[np.zeros(self.nE[1]), np.ones(self.nE[1])]
|
||||
tX = np.c_[np.ones(self.nEv[0]), np.zeros(self.nEv[0])]
|
||||
tY = np.c_[np.zeros(self.nEv[1]), np.ones(self.nEv[1])]
|
||||
return np.r_[tX, tY]
|
||||
elif self.dim == 3:
|
||||
tX = np.c_[np.ones(self.nE[0]), np.zeros(self.nE[0]), np.zeros(self.nE[0])]
|
||||
tY = np.c_[np.zeros(self.nE[1]), np.ones(self.nE[1]), np.zeros(self.nE[1])]
|
||||
tZ = np.c_[np.zeros(self.nE[2]), np.zeros(self.nE[2]), np.ones(self.nE[2])]
|
||||
tX = np.c_[np.ones(self.nEv[0]), np.zeros(self.nEv[0]), np.zeros(self.nEv[0])]
|
||||
tY = np.c_[np.zeros(self.nEv[1]), np.ones(self.nEv[1]), np.zeros(self.nEv[1])]
|
||||
tZ = np.c_[np.zeros(self.nEv[2]), np.zeros(self.nEv[2]), np.ones(self.nEv[2])]
|
||||
return np.r_[tX, tY, tZ]
|
||||
return locals()
|
||||
tangents = property(**tangents())
|
||||
|
||||
@@ -110,6 +110,12 @@ class Cyl1DMesh(object):
|
||||
return locals()
|
||||
nFz = property(**nFz())
|
||||
|
||||
def nFv():
|
||||
doc = "Total number of faces in each direction"
|
||||
fget = lambda self: np.array([self.nFr, self.nFz])
|
||||
return locals()
|
||||
nFv = property(**nFv())
|
||||
|
||||
def nF():
|
||||
doc = "Total number of faces"
|
||||
fget = lambda self: self.nFr + self.nFz
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import numpy as np
|
||||
from scipy import sparse as sp
|
||||
from SimPEG.utils import mkvc, sdiag, speye, kron3, spzeros
|
||||
|
||||
|
||||
def ddx(n):
|
||||
"""Define 1D derivatives, inner, this means we go from n+1 to n+1"""
|
||||
return sp.spdiags((np.ones((n+1, 1))*[-1, 1]).T, [0, 1], n, n+1, format="csr")
|
||||
from SimPEG.utils import mkvc, sdiag, speye, kron3, spzeros, ddx, av
|
||||
|
||||
|
||||
def checkBC(bc):
|
||||
@@ -39,11 +34,6 @@ def ddxCellGrad(n, bc):
|
||||
return D
|
||||
|
||||
|
||||
def av(n):
|
||||
"""Define 1D averaging operator from cell-centres to nodes."""
|
||||
return sp.spdiags((0.5*np.ones((n+1, 1))*[1, 1]).T, [0, 1], n, n+1, format="csr")
|
||||
|
||||
|
||||
class DiffOperators(object):
|
||||
"""
|
||||
Class creates the differential operators that you need!
|
||||
@@ -107,6 +97,38 @@ class DiffOperators(object):
|
||||
_nodalGrad = None
|
||||
nodalGrad = property(**nodalGrad())
|
||||
|
||||
def nodalLaplacian():
|
||||
doc = "Construct laplacian operator (nodes to edges)."
|
||||
|
||||
def fget(self):
|
||||
if(self._nodalLaplacian is None):
|
||||
print 'Warning: Laplacian has not been tested rigorously.'
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
# Compute divergence operator on faces
|
||||
if(self.dim == 1):
|
||||
D1 = sdiag(1./self.hx) * ddx(mesh.nCx)
|
||||
L = - D1.T*D1
|
||||
elif(self.dim == 2):
|
||||
D1 = sdiag(1./self.hx) * ddx(n[0])
|
||||
D2 = sdiag(1./self.hy) * ddx(n[1])
|
||||
L1 = sp.kron(speye(n[1]+1), - D1.T * D1)
|
||||
L2 = sp.kron(- D2.T * D2, speye(n[0]+1))
|
||||
L = L1 + L2
|
||||
elif(self.dim == 3):
|
||||
D1 = sdiag(1./self.hx) * ddx(n[0])
|
||||
D2 = sdiag(1./self.hy) * ddx(n[1])
|
||||
D3 = sdiag(1./self.hz) * ddx(n[2])
|
||||
L1 = kron3(speye(n[2]+1), speye(n[1]+1), - D1.T * D1)
|
||||
L2 = kron3(speye(n[2]+1), - D2.T * D2, speye(n[0]+1))
|
||||
L3 = kron3(- D3.T * D3, speye(n[1]+1), speye(n[0]+1))
|
||||
L = L1 + L2 + L3
|
||||
self._nodalLaplacian = L
|
||||
return self._nodalLaplacian
|
||||
return locals()
|
||||
_nodalLaplacian = None
|
||||
nodalLaplacian = property(**nodalLaplacian())
|
||||
|
||||
def setCellGradBC(self, BC):
|
||||
"""
|
||||
Function that sets the boundary conditions for cell-centred derivative operators.
|
||||
@@ -182,7 +204,6 @@ class DiffOperators(object):
|
||||
return locals()
|
||||
cellGradx = property(**cellGradx())
|
||||
|
||||
|
||||
def cellGrady():
|
||||
doc = "Cell centered Gradient in the x dimension. Has neumann boundary conditions."
|
||||
def fget(self):
|
||||
@@ -203,8 +224,6 @@ class DiffOperators(object):
|
||||
return locals()
|
||||
cellGrady = property(**cellGrady())
|
||||
|
||||
|
||||
|
||||
def cellGradz():
|
||||
doc = "Cell centered Gradient in the x dimension. Has neumann boundary conditions."
|
||||
def fget(self):
|
||||
@@ -222,7 +241,6 @@ class DiffOperators(object):
|
||||
return locals()
|
||||
cellGradz = property(**cellGradz())
|
||||
|
||||
|
||||
def edgeCurl():
|
||||
doc = "Construct the 3D curl operator."
|
||||
|
||||
@@ -265,6 +283,8 @@ class DiffOperators(object):
|
||||
_edgeCurl = None
|
||||
edgeCurl = property(**edgeCurl())
|
||||
|
||||
# --------------- Averaging ---------------------
|
||||
|
||||
def aveF2CC():
|
||||
doc = "Construct the averaging operator on cell faces to cell centers."
|
||||
|
||||
@@ -274,10 +294,10 @@ class DiffOperators(object):
|
||||
if(self.dim == 1):
|
||||
self._aveF2CC = av(n[0])
|
||||
elif(self.dim == 2):
|
||||
self._aveF2CC = sp.hstack((sp.kron(speye(n[1]), av(n[0])),
|
||||
self._aveF2CC = (0.5)*sp.hstack((sp.kron(speye(n[1]), av(n[0])),
|
||||
sp.kron(av(n[1]), speye(n[0]))), format="csr")
|
||||
elif(self.dim == 3):
|
||||
self._aveF2CC = sp.hstack((kron3(speye(n[2]), speye(n[1]), av(n[0])),
|
||||
self._aveF2CC = (1./3.)*sp.hstack((kron3(speye(n[2]), speye(n[1]), av(n[0])),
|
||||
kron3(speye(n[2]), av(n[1]), speye(n[0])),
|
||||
kron3(av(n[2]), speye(n[1]), speye(n[0]))), format="csr")
|
||||
return self._aveF2CC
|
||||
@@ -295,10 +315,10 @@ class DiffOperators(object):
|
||||
if(self.dim == 1):
|
||||
raise Exception('Edge Averaging does not make sense in 1D: Use Identity?')
|
||||
elif(self.dim == 2):
|
||||
self._aveE2CC = sp.hstack((sp.kron(av(n[1]), speye(n[0])),
|
||||
self._aveE2CC = 0.5*sp.hstack((sp.kron(av(n[1]), speye(n[0])),
|
||||
sp.kron(speye(n[1]), av(n[0]))), format="csr")
|
||||
elif(self.dim == 3):
|
||||
self._aveE2CC = sp.hstack((kron3(av(n[2]), av(n[1]), speye(n[0])),
|
||||
self._aveE2CC = (1./3)*sp.hstack((kron3(av(n[2]), av(n[1]), speye(n[0])),
|
||||
kron3(av(n[2]), speye(n[1]), av(n[0])),
|
||||
kron3(speye(n[2]), av(n[1]), av(n[0]))), format="csr")
|
||||
return self._aveE2CC
|
||||
@@ -316,37 +336,57 @@ class DiffOperators(object):
|
||||
if(self.dim == 1):
|
||||
self._aveN2CC = av(n[0])
|
||||
elif(self.dim == 2):
|
||||
self._aveN2CC = sp.hstack((sp.kron(av(n[1]), av(n[0])),
|
||||
sp.kron(av(n[1]), av(n[0]))), format="csr")
|
||||
self._aveN2CC = sp.kron(av(n[1]), av(n[0])).tocsr()
|
||||
elif(self.dim == 3):
|
||||
self._aveN2CC = sp.hstack((kron3(av(n[2]), av(n[1]), av(n[0])),
|
||||
kron3(av(n[2]), av(n[1]), av(n[0])),
|
||||
kron3(av(n[2]), av(n[1]), av(n[0]))), format="csr")
|
||||
self._aveN2CC = kron3(av(n[2]), av(n[1]), av(n[0])).tocsr()
|
||||
return self._aveN2CC
|
||||
return locals()
|
||||
_aveN2CC = None
|
||||
aveN2CC = property(**aveN2CC())
|
||||
|
||||
def aveN2CCv():
|
||||
doc = "Construct the averaging operator on cell nodes to cell centers, keeping each dimension separate."
|
||||
def aveN2E():
|
||||
doc = "Construct the averaging operator on cell nodes to cell edges, keeping each dimension separate."
|
||||
|
||||
def fget(self):
|
||||
if(self._aveN2CCv is None):
|
||||
if(self._aveN2E is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
if(self.dim == 1):
|
||||
self._aveN2CCv = av(n[0])
|
||||
self._aveN2E = av(n[0])
|
||||
elif(self.dim == 2):
|
||||
self._aveN2CCv = sp.block_diag((sp.kron(av(n[1]), av(n[0])),
|
||||
sp.kron(av(n[1]), av(n[0]))), format="csr")
|
||||
self._aveN2E = sp.vstack((sp.kron(speye(n[1]+1), av(n[0])),
|
||||
sp.kron(av(n[1]), speye(n[0]+1))), format="csr")
|
||||
elif(self.dim == 3):
|
||||
self._aveN2CCv = sp.block_diag((kron3(av(n[2]), av(n[1]), av(n[0])),
|
||||
kron3(av(n[2]), av(n[1]), av(n[0])),
|
||||
kron3(av(n[2]), av(n[1]), av(n[0]))), format="csr")
|
||||
return self._aveN2CCv
|
||||
self._aveN2E = sp.vstack((kron3(speye(n[2]+1), speye(n[1]+1), av(n[0])),
|
||||
kron3(speye(n[2]+1), av(n[1]), speye(n[0]+1)),
|
||||
kron3(av(n[2]), speye(n[1]+1), speye(n[0]+1))), format="csr")
|
||||
return self._aveN2E
|
||||
return locals()
|
||||
_aveN2CCv = None
|
||||
aveN2CCv = property(**aveN2CCv())
|
||||
_aveN2E = None
|
||||
aveN2E = property(**aveN2E())
|
||||
|
||||
def aveN2F():
|
||||
doc = "Construct the averaging operator on cell nodes to cell faces, keeping each dimension separate."
|
||||
|
||||
def fget(self):
|
||||
if(self._aveN2F is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
if(self.dim == 1):
|
||||
self._aveN2F = av(n[0])
|
||||
elif(self.dim == 2):
|
||||
self._aveN2F = sp.vstack((sp.kron(av(n[1]), speye(n[0]+1)),
|
||||
sp.kron(speye(n[1]+1), av(n[0]))), format="csr")
|
||||
elif(self.dim == 3):
|
||||
self._aveN2F = sp.vstack((kron3(av(n[2]), av(n[1]), speye(n[0]+1)),
|
||||
kron3(av(n[2]), speye(n[1]+1), av(n[0])),
|
||||
kron3(speye(n[2]+1), av(n[1]), av(n[0]))), format="csr")
|
||||
return self._aveN2F
|
||||
return locals()
|
||||
_aveN2F = None
|
||||
aveN2F = property(**aveN2F())
|
||||
|
||||
# --------------- Methods ---------------------
|
||||
|
||||
def getMass(self, materialProp=None, loc='e'):
|
||||
""" Produces mass matricies.
|
||||
|
||||
@@ -174,8 +174,8 @@ def getFaceInnerProduct(mesh, mu=None, returnP=False):
|
||||
|
||||
def Pxxx(pos):
|
||||
ind1 = sub2ind(mesh.nFx, np.c_[ii + pos[0][0], jj + pos[0][1], kk + pos[0][2]])
|
||||
ind2 = sub2ind(mesh.nFy, np.c_[ii + pos[1][0], jj + pos[1][1], kk + pos[1][2]]) + mesh.nF[0]
|
||||
ind3 = sub2ind(mesh.nFz, np.c_[ii + pos[2][0], jj + pos[2][1], kk + pos[2][2]]) + mesh.nF[0] + mesh.nF[1]
|
||||
ind2 = sub2ind(mesh.nFy, np.c_[ii + pos[1][0], jj + pos[1][1], kk + pos[1][2]]) + mesh.nFv[0]
|
||||
ind3 = sub2ind(mesh.nFz, np.c_[ii + pos[2][0], jj + pos[2][1], kk + pos[2][2]]) + mesh.nFv[0] + mesh.nFv[1]
|
||||
|
||||
IND = np.r_[ind1, ind2, ind3].flatten()
|
||||
|
||||
@@ -286,7 +286,7 @@ def getFaceInnerProduct2D(mesh, mu=None, returnP=False):
|
||||
|
||||
def Pxx(pos):
|
||||
ind1 = sub2ind(mesh.nFx, np.c_[ii + pos[0][0], jj + pos[0][1]])
|
||||
ind2 = sub2ind(mesh.nFy, np.c_[ii + pos[1][0], jj + pos[1][1]]) + mesh.nF[0]
|
||||
ind2 = sub2ind(mesh.nFy, np.c_[ii + pos[1][0], jj + pos[1][1]]) + mesh.nFv[0]
|
||||
|
||||
IND = np.r_[ind1, ind2].flatten()
|
||||
|
||||
@@ -387,8 +387,8 @@ def getEdgeInnerProduct(mesh, sigma=None, returnP=False):
|
||||
|
||||
def Pxxx(pos):
|
||||
ind1 = sub2ind(mesh.nEx, np.c_[ii + pos[0][0], jj + pos[0][1], kk + pos[0][2]])
|
||||
ind2 = sub2ind(mesh.nEy, np.c_[ii + pos[1][0], jj + pos[1][1], kk + pos[1][2]]) + mesh.nE[0]
|
||||
ind3 = sub2ind(mesh.nEz, np.c_[ii + pos[2][0], jj + pos[2][1], kk + pos[2][2]]) + mesh.nE[0] + mesh.nE[1]
|
||||
ind2 = sub2ind(mesh.nEy, np.c_[ii + pos[1][0], jj + pos[1][1], kk + pos[1][2]]) + mesh.nEv[0]
|
||||
ind3 = sub2ind(mesh.nEz, np.c_[ii + pos[2][0], jj + pos[2][1], kk + pos[2][2]]) + mesh.nEv[0] + mesh.nEv[1]
|
||||
|
||||
IND = np.r_[ind1, ind2, ind3].flatten()
|
||||
|
||||
@@ -499,7 +499,7 @@ def getEdgeInnerProduct2D(mesh, sigma=None, returnP=False):
|
||||
|
||||
def Pxx(pos):
|
||||
ind1 = sub2ind(mesh.nEx, np.c_[ii + pos[0][0], jj + pos[0][1]])
|
||||
ind2 = sub2ind(mesh.nEy, np.c_[ii + pos[1][0], jj + pos[1][1]]) + mesh.nE[0]
|
||||
ind2 = sub2ind(mesh.nEy, np.c_[ii + pos[1][0], jj + pos[1][1]]) + mesh.nEv[0]
|
||||
|
||||
IND = np.r_[ind1, ind2].flatten()
|
||||
|
||||
|
||||
@@ -45,8 +45,7 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
|
||||
def fget(self):
|
||||
if self._gridCC is None:
|
||||
ccV = (self.aveN2CCv*mkvc(self.gridN))
|
||||
self._gridCC = ccV.reshape((-1, self.dim), order='F')
|
||||
self._gridCC = np.concatenate([self.aveN2CC*self.gridN[:,i] for i in range(self.dim)]).reshape((-1,self.dim), order='F')
|
||||
return self._gridCC
|
||||
return locals()
|
||||
_gridCC = None # Store grid by default
|
||||
|
||||
@@ -396,7 +396,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
ind = 0 if 'x' in locType else 1 if 'y' in locType else 2 if 'z' in locType else -1
|
||||
if locType in ['Fx','Fy','Fz','Ex','Ey','Ez'] and self.dim >= ind:
|
||||
nF_nE = self.nF if 'F' in locType else self.nE
|
||||
nF_nE = self.nFv if 'F' in locType else self.nEv
|
||||
components = [spzeros(loc.shape[0], n) for n in nF_nE]
|
||||
components[ind] = interpmat(loc, *self.getTensor(locType))
|
||||
Q = sp.hstack(components)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import os
|
||||
print 'Compiling TriSolve.'
|
||||
os.system('f2py -c utils/TriSolve.f -m TriSolve')
|
||||
print 'TriSolve Compiled! yay.'
|
||||
print 'Moving TriSolve into Utils.'
|
||||
os.system('mv TriSolve.so utils/TriSolve.so')
|
||||
print 'Thats it. Well Done Computer.'
|
||||
|
||||
@@ -5,11 +5,17 @@ from SimPEG.utils import mkvc, sdiag
|
||||
from SimPEG import utils
|
||||
from SimPEG.mesh import TensorMesh, LogicallyOrthogonalMesh
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
import unittest
|
||||
import inspect
|
||||
|
||||
happiness = ['The test be workin!', 'You get a gold star!', 'Yay passed!', 'Happy little convergence test!', 'That was easy!', 'Testing is important.', 'You are awesome.', 'Go Test Go!', 'Once upon a time, a happy little test passed.', 'And then everyone was happy.']
|
||||
sadness = ['No gold star for you.','Try again soon.','Thankfully, persistence is a great substitute for talent.','It might be easier to call this a feature...','Coffee break?', 'Boooooooo :(', 'Testing is important. Do it again.']
|
||||
try:
|
||||
import getpass
|
||||
name = getpass.getuser()[0].upper() + getpass.getuser()[1:]
|
||||
except Exception, e:
|
||||
name = 'You'
|
||||
happiness = ['The test be workin!', 'You get a gold star!', 'Yay passed!', 'Happy little convergence test!', 'That was easy!', 'Testing is important.', 'You are awesome.', 'Go Test Go!', 'Once upon a time, a happy little test passed.', 'And then everyone was happy.','Not just a pretty face '+name,'You deserve a pat on the back!','Well done '+name+'!', 'Awesome, '+name+', just awesome.']
|
||||
sadness = ['No gold star for you.','Try again soon.','Thankfully, persistence is a great substitute for talent.','It might be easier to call this a feature...','Coffee break?', 'Boooooooo :(', 'Testing is important. Do it again.',"Did you put your clever trousers on today?",'Just think about a dancing dinosaur and life will get better!','You had so much promise '+name+', oh well...', name.upper()+' ERROR!','Get on it '+name+'!', 'You break it, you fix it.']
|
||||
|
||||
class OrderTest(unittest.TestCase):
|
||||
"""
|
||||
@@ -174,14 +180,14 @@ def Rosenbrock(x, return_g=True, return_H=True):
|
||||
|
||||
f = 100*(x[1]-x[0]**2)**2+(1-x[0])**2
|
||||
g = np.array([2*(200*x[0]**3-200*x[0]*x[1]+x[0]-1), 200*(x[1]-x[0]**2)])
|
||||
H = np.array([[-400*x[1]+1200*x[0]**2+2, -400*x[0]], [-400*x[0], 200]])
|
||||
H = sp.csr_matrix(np.array([[-400*x[1]+1200*x[0]**2+2, -400*x[0]], [-400*x[0], 200]]))
|
||||
|
||||
out = (f,)
|
||||
if return_g:
|
||||
out += (g,)
|
||||
if return_H:
|
||||
out += (H,)
|
||||
return out
|
||||
return out if len(out) > 1 else out[0]
|
||||
|
||||
def checkDerivative(fctn, x0, num=7, plotIt=True, dx=None):
|
||||
"""
|
||||
@@ -269,6 +275,28 @@ def checkDerivative(fctn, x0, num=7, plotIt=True, dx=None):
|
||||
return passTest
|
||||
|
||||
|
||||
|
||||
def getQuadratic(A, b):
|
||||
"""
|
||||
Given A and b, this returns a quadratic, Q
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{Q( x ) = 0.5 x A x + b x}
|
||||
"""
|
||||
def Quadratic(x, return_g=True, return_H=True):
|
||||
f = 0.5 * x.dot( A.dot(x)) + b.dot( x )
|
||||
out = (f,)
|
||||
if return_g:
|
||||
g = A.dot(x) + b
|
||||
out += (g,)
|
||||
if return_H:
|
||||
H = A
|
||||
out += (H,)
|
||||
return out if len(out) > 1 else out[0]
|
||||
return Quadratic
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
def simplePass(x):
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
import TestUtils
|
||||
from TestUtils import checkDerivative, Rosenbrock, OrderTest
|
||||
from TestUtils import checkDerivative, Rosenbrock, OrderTest, getQuadratic
|
||||
@@ -1,355 +0,0 @@
|
||||
.. _api_TestResults:
|
||||
|
||||
.. raw:: html
|
||||
<style type="text/css" media="screen">
|
||||
body { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }
|
||||
table { font-size: 100%; }
|
||||
pre { }
|
||||
|
||||
/* -- heading ---------------------------------------------------------------------- */
|
||||
h1 {
|
||||
font-size: 16pt;
|
||||
color: gray;
|
||||
}
|
||||
.heading {
|
||||
margin-top: 0ex;
|
||||
margin-bottom: 1ex;
|
||||
}
|
||||
|
||||
.heading .attribute {
|
||||
margin-top: 1ex;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.heading .description {
|
||||
margin-top: 4ex;
|
||||
margin-bottom: 6ex;
|
||||
}
|
||||
|
||||
/* -- css div popup ------------------------------------------------------------------------ */
|
||||
a.popup_link {
|
||||
}
|
||||
|
||||
a.popup_link:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.popup_window {
|
||||
display: none;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
/*border: solid #627173 1px; */
|
||||
padding: 10px;
|
||||
background-color: #E6E6D6;
|
||||
font-family: "Lucida Console", "Courier New", Courier, monospace;
|
||||
text-align: left;
|
||||
font-size: 8pt;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
}
|
||||
/* -- report ------------------------------------------------------------------------ */
|
||||
#show_detail_line {
|
||||
margin-top: 3ex;
|
||||
margin-bottom: 1ex;
|
||||
}
|
||||
#result_table {
|
||||
width: 80%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #777;
|
||||
}
|
||||
#header_row {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
background-color: #777;
|
||||
}
|
||||
#result_table td {
|
||||
border: 1px solid #777;
|
||||
padding: 2px;
|
||||
}
|
||||
#total_row { font-weight: bold; }
|
||||
.passClass { background-color: #6c6; }
|
||||
.failClass { background-color: #c60; }
|
||||
.errorClass { background-color: #c00; }
|
||||
.passCase { color: #6c6; }
|
||||
.failCase { color: #c60; font-weight: bold; }
|
||||
.errorCase { color: #c00; font-weight: bold; }
|
||||
.hiddenRow { display: none; }
|
||||
.testcase { margin-left: 2em; }
|
||||
|
||||
|
||||
/* -- ending ---------------------------------------------------------------------- */
|
||||
#ending {
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<script language="javascript" type="text/javascript"><!--
|
||||
output_list = Array();
|
||||
|
||||
/* level - 0:Summary; 1:Failed; 2:All */
|
||||
function showCase(level) {
|
||||
trs = document.getElementsByTagName("tr");
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
tr = trs[i];
|
||||
id = tr.id;
|
||||
if (id.substr(0,2) == 'ft') {
|
||||
if (level < 1) {
|
||||
tr.className = 'hiddenRow';
|
||||
}
|
||||
else {
|
||||
tr.className = '';
|
||||
}
|
||||
}
|
||||
if (id.substr(0,2) == 'pt') {
|
||||
if (level > 1) {
|
||||
tr.className = '';
|
||||
}
|
||||
else {
|
||||
tr.className = 'hiddenRow';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showClassDetail(cid, count) {
|
||||
var id_list = Array(count);
|
||||
var toHide = 1;
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid0 = 't' + cid.substr(1) + '.' + (i+1);
|
||||
tid = 'f' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
if (!tr) {
|
||||
tid = 'p' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
}
|
||||
id_list[i] = tid;
|
||||
if (tr.className) {
|
||||
toHide = 0;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid = id_list[i];
|
||||
if (toHide) {
|
||||
document.getElementById('div_'+tid).style.display = 'none'
|
||||
document.getElementById(tid).className = 'hiddenRow';
|
||||
}
|
||||
else {
|
||||
document.getElementById(tid).className = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showTestDetail(div_id){
|
||||
var details_div = document.getElementById(div_id)
|
||||
var displayState = details_div.style.display
|
||||
// alert(displayState)
|
||||
if (displayState != 'block' ) {
|
||||
displayState = 'block'
|
||||
details_div.style.display = 'block'
|
||||
}
|
||||
else {
|
||||
details_div.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function html_escape(s) {
|
||||
s = s.replace(/&/g,'&');
|
||||
s = s.replace(/</g,'<');
|
||||
s = s.replace(/>/g,'>');
|
||||
return s;
|
||||
}
|
||||
|
||||
/* obsoleted by detail in <div>
|
||||
function showOutput(id, name) {
|
||||
var w = window.open("", //url
|
||||
name,
|
||||
"resizable,scrollbars,status,width=800,height=450");
|
||||
d = w.document;
|
||||
d.write("<pre>");
|
||||
d.write(html_escape(output_list[id]));
|
||||
d.write("\n");
|
||||
d.write("<a href='javascript:window.close()'>close</a>\n");
|
||||
d.write("</pre>\n");
|
||||
d.close();
|
||||
}
|
||||
*/
|
||||
--></script>
|
||||
|
||||
<div class='heading'>
|
||||
<h1>Test Report</h1>
|
||||
<p class='attribute'><strong>Start Time:</strong> 2013-11-05 15:24:44</p>
|
||||
<p class='attribute'><strong>Duration:</strong> 0:00:00.007500</p>
|
||||
<p class='attribute'><strong>Status:</strong> Pass 22</p>
|
||||
|
||||
<p class='description'>This demonstrates the report output by Prasanna.Yelsangikar.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<p id='show_detail_line'>Show
|
||||
<a href='javascript:showCase(0)'>Summary</a>
|
||||
<a href='javascript:showCase(1)'>Failed</a>
|
||||
<a href='javascript:showCase(2)'>All</a>
|
||||
</p>
|
||||
<table id='result_table'>
|
||||
<colgroup>
|
||||
<col align='left' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
</colgroup>
|
||||
<tr id='header_row'>
|
||||
<td>Test Group/Test case</td>
|
||||
<td>Count</td>
|
||||
<td>Pass</td>
|
||||
<td>Fail</td>
|
||||
<td>Error</td>
|
||||
<td>View</td>
|
||||
</tr>
|
||||
|
||||
<tr class='passClass'>
|
||||
<td>test_basemesh.TestBaseMesh</td>
|
||||
<td>11</td>
|
||||
<td>11</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td><a href="javascript:showClassDetail('c1',11)">Detail</a></td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.1' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_meshDimensions</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.2' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_nc</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.3' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_nc_xyz</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.4' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_ne</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.5' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_nf</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.6' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_numbers</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.7' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_CC_M</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.8' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_E_M</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.9' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_E_V</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.10' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_F_M</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.11' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_F_V</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr class='passClass'>
|
||||
<td>test_basemesh.TestMeshNumbers2D</td>
|
||||
<td>11</td>
|
||||
<td>11</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td><a href="javascript:showClassDetail('c2',11)">Detail</a></td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.1' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_meshDimensions</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.2' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_nc</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.3' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_nc_xyz</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.4' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_ne</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.5' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_nf</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.6' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_numbers</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.7' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_CC_M</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.8' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_E_M</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.9' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_E_V</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.10' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_F_M</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt2.11' class='hiddenRow'>
|
||||
<td class='none'><div class='testcase'>test_mesh_r_F_V</div></td>
|
||||
<td colspan='5' align='center'>pass</td>
|
||||
</tr>
|
||||
|
||||
<tr id='total_row'>
|
||||
<td>Total</td>
|
||||
<td>22</td>
|
||||
<td>22</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
+43
-36
@@ -4,47 +4,54 @@ import unittest
|
||||
import HTMLTestRunner
|
||||
|
||||
# This code will run all tests in directory named test_*.py
|
||||
def main(html=False):
|
||||
TITLE = 'Test Results'
|
||||
test_file_strings = glob.glob('test_*.py')
|
||||
module_strings = [str[0:len(str)-3] for str in test_file_strings]
|
||||
suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str
|
||||
in module_strings]
|
||||
testSuite = unittest.TestSuite(suites)
|
||||
|
||||
TITLE = 'Test Results'
|
||||
test_file_strings = glob.glob('test_*.py')
|
||||
module_strings = [str[0:len(str)-3] for str in test_file_strings]
|
||||
suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str
|
||||
in module_strings]
|
||||
testSuite = unittest.TestSuite(suites)
|
||||
unittest.TextTestRunner(verbosity=2).run(testSuite)
|
||||
if not html:
|
||||
unittest.TextTestRunner(verbosity=2).run(testSuite)
|
||||
return
|
||||
|
||||
|
||||
outfile = open("report.html", "w")
|
||||
runner = HTMLTestRunner.HTMLTestRunner(
|
||||
stream=outfile,
|
||||
title=TITLE,
|
||||
description='SimPEG Test Report was automatically generated.'
|
||||
)
|
||||
outfile = open("report.html", "w")
|
||||
runner = HTMLTestRunner.HTMLTestRunner(
|
||||
stream=outfile,
|
||||
title=TITLE,
|
||||
description='SimPEG Test Report was automatically generated.',
|
||||
verbosity=2
|
||||
)
|
||||
|
||||
runner.run(testSuite)
|
||||
outfile.close()
|
||||
runner.run(testSuite)
|
||||
outfile.close()
|
||||
|
||||
reader = open("report.html", "r")
|
||||
writer = open("../../docs/api_TestResults.rst", "w")
|
||||
reader = open("report.html", "r")
|
||||
writer = open("../../docs/api_TestResults.rst", "w")
|
||||
|
||||
writer.write('.. _api_TestResults:\n\nTest Results\n============\n\n.. raw:: html\n\n')
|
||||
writer.write('.. _api_TestResults:\n\nTest Results\n============\n\n.. raw:: html\n\n')
|
||||
|
||||
go = False
|
||||
for line in reader:
|
||||
skip = False
|
||||
if line == '<style type="text/css" media="screen">\n':
|
||||
go = True
|
||||
elif line == "<div id='ending'> </div>\n":
|
||||
go = False
|
||||
elif line == '</head>\n':
|
||||
skip = True
|
||||
elif line == '<h1>'+TITLE+'</h1>\n':
|
||||
skip = True
|
||||
elif line == '<body>\n':
|
||||
skip = True
|
||||
if go and not skip:
|
||||
writer.write(' '+line)
|
||||
go = False
|
||||
for line in reader:
|
||||
skip = False
|
||||
if line == '<style type="text/css" media="screen">\n':
|
||||
go = True
|
||||
elif line == "<div id='ending'> </div>\n":
|
||||
go = False
|
||||
elif line == '</head>\n':
|
||||
skip = True
|
||||
elif line == '<h1>'+TITLE+'</h1>\n':
|
||||
skip = True
|
||||
elif line == '<body>\n':
|
||||
skip = True
|
||||
if go and not skip:
|
||||
writer.write(' '+line)
|
||||
|
||||
writer.close()
|
||||
reader.close()
|
||||
os.remove("report.html")
|
||||
writer.close()
|
||||
reader.close()
|
||||
os.remove("report.html")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(True)
|
||||
@@ -44,50 +44,54 @@ class BasicLOMTests(unittest.TestCase):
|
||||
|
||||
def test_tangents(self):
|
||||
T = self.LOM2.tangents
|
||||
self.assertTrue(np.all(self.LOM2.r(T, 'E', 'Ex', 'V')[0] == np.ones(self.LOM2.nE[0])))
|
||||
self.assertTrue(np.all(self.LOM2.r(T, 'E', 'Ex', 'V')[1] == np.zeros(self.LOM2.nE[0])))
|
||||
self.assertTrue(np.all(self.LOM2.r(T, 'E', 'Ey', 'V')[0] == np.zeros(self.LOM2.nE[1])))
|
||||
self.assertTrue(np.all(self.LOM2.r(T, 'E', 'Ey', 'V')[1] == np.ones(self.LOM2.nE[1])))
|
||||
self.assertTrue(np.all(self.LOM2.r(T, 'E', 'Ex', 'V')[0] == np.ones(self.LOM2.nEv[0])))
|
||||
self.assertTrue(np.all(self.LOM2.r(T, 'E', 'Ex', 'V')[1] == np.zeros(self.LOM2.nEv[0])))
|
||||
self.assertTrue(np.all(self.LOM2.r(T, 'E', 'Ey', 'V')[0] == np.zeros(self.LOM2.nEv[1])))
|
||||
self.assertTrue(np.all(self.LOM2.r(T, 'E', 'Ey', 'V')[1] == np.ones(self.LOM2.nEv[1])))
|
||||
|
||||
T = self.LOM3.tangents
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ex', 'V')[0] == np.ones(self.LOM3.nE[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ex', 'V')[1] == np.zeros(self.LOM3.nE[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ex', 'V')[2] == np.zeros(self.LOM3.nE[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ex', 'V')[0] == np.ones(self.LOM3.nEv[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ex', 'V')[1] == np.zeros(self.LOM3.nEv[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ex', 'V')[2] == np.zeros(self.LOM3.nEv[0])))
|
||||
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ey', 'V')[0] == np.zeros(self.LOM3.nE[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ey', 'V')[1] == np.ones(self.LOM3.nE[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ey', 'V')[2] == np.zeros(self.LOM3.nE[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ey', 'V')[0] == np.zeros(self.LOM3.nEv[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ey', 'V')[1] == np.ones(self.LOM3.nEv[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ey', 'V')[2] == np.zeros(self.LOM3.nEv[1])))
|
||||
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ez', 'V')[0] == np.zeros(self.LOM3.nE[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ez', 'V')[1] == np.zeros(self.LOM3.nE[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ez', 'V')[2] == np.ones(self.LOM3.nE[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ez', 'V')[0] == np.zeros(self.LOM3.nEv[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ez', 'V')[1] == np.zeros(self.LOM3.nEv[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(T, 'E', 'Ez', 'V')[2] == np.ones(self.LOM3.nEv[2])))
|
||||
|
||||
def test_normals(self):
|
||||
N = self.LOM2.normals
|
||||
self.assertTrue(np.all(self.LOM2.r(N, 'F', 'Fx', 'V')[0] == np.ones(self.LOM2.nF[0])))
|
||||
self.assertTrue(np.all(self.LOM2.r(N, 'F', 'Fx', 'V')[1] == np.zeros(self.LOM2.nF[0])))
|
||||
self.assertTrue(np.all(self.LOM2.r(N, 'F', 'Fy', 'V')[0] == np.zeros(self.LOM2.nF[1])))
|
||||
self.assertTrue(np.all(self.LOM2.r(N, 'F', 'Fy', 'V')[1] == np.ones(self.LOM2.nF[1])))
|
||||
self.assertTrue(np.all(self.LOM2.r(N, 'F', 'Fx', 'V')[0] == np.ones(self.LOM2.nFv[0])))
|
||||
self.assertTrue(np.all(self.LOM2.r(N, 'F', 'Fx', 'V')[1] == np.zeros(self.LOM2.nFv[0])))
|
||||
self.assertTrue(np.all(self.LOM2.r(N, 'F', 'Fy', 'V')[0] == np.zeros(self.LOM2.nFv[1])))
|
||||
self.assertTrue(np.all(self.LOM2.r(N, 'F', 'Fy', 'V')[1] == np.ones(self.LOM2.nFv[1])))
|
||||
|
||||
N = self.LOM3.normals
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fx', 'V')[0] == np.ones(self.LOM3.nF[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fx', 'V')[1] == np.zeros(self.LOM3.nF[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fx', 'V')[2] == np.zeros(self.LOM3.nF[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fx', 'V')[0] == np.ones(self.LOM3.nFv[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fx', 'V')[1] == np.zeros(self.LOM3.nFv[0])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fx', 'V')[2] == np.zeros(self.LOM3.nFv[0])))
|
||||
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fy', 'V')[0] == np.zeros(self.LOM3.nF[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fy', 'V')[1] == np.ones(self.LOM3.nF[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fy', 'V')[2] == np.zeros(self.LOM3.nF[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fy', 'V')[0] == np.zeros(self.LOM3.nFv[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fy', 'V')[1] == np.ones(self.LOM3.nFv[1])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fy', 'V')[2] == np.zeros(self.LOM3.nFv[1])))
|
||||
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fz', 'V')[0] == np.zeros(self.LOM3.nF[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fz', 'V')[1] == np.zeros(self.LOM3.nF[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fz', 'V')[2] == np.ones(self.LOM3.nF[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fz', 'V')[0] == np.zeros(self.LOM3.nFv[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fz', 'V')[1] == np.zeros(self.LOM3.nFv[2])))
|
||||
self.assertTrue(np.all(self.LOM3.r(N, 'F', 'Fz', 'V')[2] == np.ones(self.LOM3.nFv[2])))
|
||||
|
||||
def test_grid(self):
|
||||
self.assertTrue(np.all(self.LOM2.gridCC == self.TM2.gridCC))
|
||||
self.assertTrue(np.all(self.LOM2.gridN == self.TM2.gridN))
|
||||
self.assertTrue(np.all(self.LOM2.gridFx == self.TM2.gridFx))
|
||||
self.assertTrue(np.all(self.LOM2.gridFy == self.TM2.gridFy))
|
||||
self.assertTrue(np.all(self.LOM2.gridEx == self.TM2.gridEx))
|
||||
self.assertTrue(np.all(self.LOM2.gridEy == self.TM2.gridEy))
|
||||
|
||||
self.assertTrue(np.all(self.LOM3.gridCC == self.TM3.gridCC))
|
||||
self.assertTrue(np.all(self.LOM3.gridN == self.TM3.gridN))
|
||||
self.assertTrue(np.all(self.LOM3.gridFx == self.TM3.gridFx))
|
||||
self.assertTrue(np.all(self.LOM3.gridFy == self.TM3.gridFy))
|
||||
self.assertTrue(np.all(self.LOM3.gridFz == self.TM3.gridFz))
|
||||
|
||||
@@ -58,23 +58,39 @@ class TestSolver(unittest.TestCase):
|
||||
x = solve.solve(rhs)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
|
||||
def test_directLower_1(self):
|
||||
def test_directLower_1_python(self):
|
||||
AL = sparse.tril(self.A)
|
||||
solve = Solver(AL, doDirect=True, flag='L', options={})
|
||||
solve = Solver(AL, doDirect=True, flag='L', options={'backend':'python'})
|
||||
e = np.ones(self.M.nC)
|
||||
rhs = AL.dot(e)
|
||||
x = solve.solve(rhs)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
|
||||
def test_directLower_M(self):
|
||||
def test_directLower_M_python(self):
|
||||
AL = sparse.tril(self.A)
|
||||
solve = Solver(AL, doDirect=True, flag='L', options={})
|
||||
solve = Solver(AL, doDirect=True, flag='L', options={'backend':'python'})
|
||||
e = np.ones((self.M.nC,numRHS))
|
||||
rhs = AL.dot(e)
|
||||
x = solve.solve(rhs)
|
||||
|
||||
def test_directLower_1_fortran(self):
|
||||
AL = sparse.tril(self.A)
|
||||
solve = Solver(AL, doDirect=True, flag='L', options={'backend':'fortran'})
|
||||
e = np.ones(self.M.nC)
|
||||
rhs = AL.dot(e)
|
||||
x = solve.solve(rhs)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
|
||||
def test_directUpper_1(self):
|
||||
def test_directLower_M_fortran(self):
|
||||
AL = sparse.tril(self.A)
|
||||
solve = Solver(AL, doDirect=True, flag='L', options={'backend':'fortran'})
|
||||
e = np.ones((self.M.nC,numRHS))
|
||||
rhs = AL.dot(e)
|
||||
x = solve.solve(rhs)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
|
||||
def test_directUpper_1_python(self):
|
||||
AU = sparse.triu(self.A)
|
||||
solve = Solver(AU, doDirect=True, flag='U', options={})
|
||||
e = np.ones(self.M.nC)
|
||||
@@ -82,7 +98,7 @@ class TestSolver(unittest.TestCase):
|
||||
x = solve.solve(rhs)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
|
||||
def test_directUpper_M(self):
|
||||
def test_directUpper_M_python(self):
|
||||
AU = sparse.triu(self.A)
|
||||
solve = Solver(AU, doDirect=True, flag='U', options={})
|
||||
e = np.ones((self.M.nC,numRHS))
|
||||
@@ -90,6 +106,23 @@ class TestSolver(unittest.TestCase):
|
||||
x = solve.solve(rhs)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
|
||||
|
||||
def test_directUpper_1_fortran(self):
|
||||
AU = sparse.triu(self.A)
|
||||
solve = Solver(AU, doDirect=True, flag='U', options={'backend':'fortran'})
|
||||
e = np.ones(self.M.nC)
|
||||
rhs = AU.dot(e)
|
||||
x = solve.solve(rhs)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
|
||||
def test_directUpper_M_fortran(self):
|
||||
AU = sparse.triu(self.A)
|
||||
solve = Solver(AU, doDirect=True, flag='U', options={'backend':'fortran'})
|
||||
e = np.ones((self.M.nC,numRHS))
|
||||
rhs = AU.dot(e)
|
||||
x = solve.solve(rhs)
|
||||
self.assertTrue(np.linalg.norm(e-x,np.inf) < TOL, True)
|
||||
|
||||
def test_directDiagonal_1(self):
|
||||
AD = sdiag(self.A.diagonal())
|
||||
solve = Solver(AD, doDirect=True, flag='D', options={})
|
||||
|
||||
@@ -38,15 +38,17 @@ class TestBaseMesh(unittest.TestCase):
|
||||
|
||||
def test_mesh_numbers(self):
|
||||
c = self.mesh.nC == 36
|
||||
f = np.all(self.mesh.nF == [42, 54, 48])
|
||||
e = np.all(self.mesh.nE == [72, 56, 63])
|
||||
fv = np.all(self.mesh.nFv == [42, 54, 48])
|
||||
ev = np.all(self.mesh.nEv == [72, 56, 63])
|
||||
f = np.all(self.mesh.nF == np.sum([42, 54, 48]))
|
||||
e = np.all(self.mesh.nE == np.sum([72, 56, 63]))
|
||||
|
||||
self.assertTrue(np.all([c, f, e]))
|
||||
self.assertTrue(np.all([c, fv, ev, f, e]))
|
||||
|
||||
def test_mesh_r_E_V(self):
|
||||
ex = np.ones(self.mesh.nE[0])
|
||||
ey = np.ones(self.mesh.nE[1])*2
|
||||
ez = np.ones(self.mesh.nE[2])*3
|
||||
ex = np.ones(self.mesh.nEv[0])
|
||||
ey = np.ones(self.mesh.nEv[1])*2
|
||||
ez = np.ones(self.mesh.nEv[2])*3
|
||||
e = np.r_[ex, ey, ez]
|
||||
tex = self.mesh.r(e, 'E', 'Ex', 'V')
|
||||
tey = self.mesh.r(e, 'E', 'Ey', 'V')
|
||||
@@ -60,9 +62,9 @@ class TestBaseMesh(unittest.TestCase):
|
||||
self.assertTrue(np.all(tez == ez))
|
||||
|
||||
def test_mesh_r_F_V(self):
|
||||
fx = np.ones(self.mesh.nF[0])
|
||||
fy = np.ones(self.mesh.nF[1])*2
|
||||
fz = np.ones(self.mesh.nF[2])*3
|
||||
fx = np.ones(self.mesh.nFv[0])
|
||||
fy = np.ones(self.mesh.nFv[1])*2
|
||||
fz = np.ones(self.mesh.nFv[2])*3
|
||||
f = np.r_[fx, fy, fz]
|
||||
tfx = self.mesh.r(f, 'F', 'Fx', 'V')
|
||||
tfy = self.mesh.r(f, 'F', 'Fy', 'V')
|
||||
@@ -146,14 +148,16 @@ class TestMeshNumbers2D(unittest.TestCase):
|
||||
|
||||
def test_mesh_numbers(self):
|
||||
c = self.mesh.nC == 12
|
||||
f = np.all(self.mesh.nF == [14, 18])
|
||||
e = np.all(self.mesh.nE == [18, 14])
|
||||
fv = np.all(self.mesh.nFv == [14, 18])
|
||||
ev = np.all(self.mesh.nEv == [18, 14])
|
||||
f = np.all(self.mesh.nF == np.sum([14, 18]))
|
||||
e = np.all(self.mesh.nE == np.sum([18, 14]))
|
||||
|
||||
self.assertTrue(np.all([c, f, e]))
|
||||
self.assertTrue(np.all([c, fv, ev, f, e]))
|
||||
|
||||
def test_mesh_r_E_V(self):
|
||||
ex = np.ones(self.mesh.nE[0])
|
||||
ey = np.ones(self.mesh.nE[1])*2
|
||||
ex = np.ones(self.mesh.nEv[0])
|
||||
ey = np.ones(self.mesh.nEv[1])*2
|
||||
e = np.r_[ex, ey]
|
||||
tex = self.mesh.r(e, 'E', 'Ex', 'V')
|
||||
tey = self.mesh.r(e, 'E', 'Ey', 'V')
|
||||
@@ -165,8 +169,8 @@ class TestMeshNumbers2D(unittest.TestCase):
|
||||
self.assertRaises(AssertionError, self.mesh.r, e, 'E', 'Ez', 'V')
|
||||
|
||||
def test_mesh_r_F_V(self):
|
||||
fx = np.ones(self.mesh.nF[0])
|
||||
fy = np.ones(self.mesh.nF[1])*2
|
||||
fx = np.ones(self.mesh.nFv[0])
|
||||
fy = np.ones(self.mesh.nFv[1])*2
|
||||
f = np.r_[fx, fy]
|
||||
tfx = self.mesh.r(f, 'F', 'Fx', 'V')
|
||||
tfy = self.mesh.r(f, 'F', 'Fy', 'V')
|
||||
|
||||
@@ -155,6 +155,109 @@ class TestNodalGrad2D(OrderTest):
|
||||
def test_order(self):
|
||||
self.orderTest()
|
||||
|
||||
class TestAveraging2D(OrderTest):
|
||||
name = "Averaging 2D"
|
||||
meshTypes = MESHTYPES
|
||||
meshDimension = 2
|
||||
|
||||
def getError(self):
|
||||
num = self.getAve(self.M) * self.getHere(self.M)
|
||||
err = np.linalg.norm((self.getThere(self.M)-num), np.inf)
|
||||
return err
|
||||
|
||||
def test_orderN2CC(self):
|
||||
self.name = "Averaging 2D: N2CC"
|
||||
fun = lambda x, y: (np.cos(x)+np.sin(y))
|
||||
self.getHere = lambda M: call2(fun, M.gridN)
|
||||
self.getThere = lambda M: call2(fun, M.gridCC)
|
||||
self.getAve = lambda M: M.aveN2CC
|
||||
self.orderTest()
|
||||
|
||||
def test_orderN2F(self):
|
||||
self.name = "Averaging 2D: N2F"
|
||||
fun = lambda x, y: (np.cos(x)+np.sin(y))
|
||||
self.getHere = lambda M: call2(fun, M.gridN)
|
||||
self.getThere = lambda M: np.r_[call2(fun, M.gridFx), call2(fun, M.gridFy)]
|
||||
self.getAve = lambda M: M.aveN2F
|
||||
self.orderTest()
|
||||
|
||||
def test_orderN2E(self):
|
||||
self.name = "Averaging 2D: N2E"
|
||||
fun = lambda x, y: (np.cos(x)+np.sin(y))
|
||||
self.getHere = lambda M: call2(fun, M.gridN)
|
||||
self.getThere = lambda M: np.r_[call2(fun, M.gridEx), call2(fun, M.gridEy)]
|
||||
self.getAve = lambda M: M.aveN2E
|
||||
self.orderTest()
|
||||
|
||||
def test_orderF2CC(self):
|
||||
self.name = "Averaging 2D: F2CC"
|
||||
fun = lambda x, y: (np.cos(x)+np.sin(y))
|
||||
self.getHere = lambda M: np.r_[call2(fun, M.gridFx), call2(fun, M.gridFy)]
|
||||
self.getThere = lambda M: call2(fun, M.gridCC)
|
||||
self.getAve = lambda M: M.aveF2CC
|
||||
self.orderTest()
|
||||
|
||||
|
||||
def test_orderE2CC(self):
|
||||
self.name = "Averaging 2D: E2CC"
|
||||
fun = lambda x, y: (np.cos(x)+np.sin(y))
|
||||
self.getHere = lambda M: np.r_[call2(fun, M.gridEx), call2(fun, M.gridEy)]
|
||||
self.getThere = lambda M: call2(fun, M.gridCC)
|
||||
self.getAve = lambda M: M.aveE2CC
|
||||
self.orderTest()
|
||||
|
||||
|
||||
class TestAveraging3D(OrderTest):
|
||||
name = "Averaging 3D"
|
||||
meshTypes = MESHTYPES
|
||||
meshDimension = 3
|
||||
|
||||
def getError(self):
|
||||
num = self.getAve(self.M) * self.getHere(self.M)
|
||||
err = np.linalg.norm((self.getThere(self.M)-num), np.inf)
|
||||
return err
|
||||
|
||||
def test_orderN2CC(self):
|
||||
self.name = "Averaging 3D: N2CC"
|
||||
fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z))
|
||||
self.getHere = lambda M: call3(fun, M.gridN)
|
||||
self.getThere = lambda M: call3(fun, M.gridCC)
|
||||
self.getAve = lambda M: M.aveN2CC
|
||||
self.orderTest()
|
||||
|
||||
def test_orderN2F(self):
|
||||
self.name = "Averaging 3D: N2F"
|
||||
fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z))
|
||||
self.getHere = lambda M: call3(fun, M.gridN)
|
||||
self.getThere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)]
|
||||
self.getAve = lambda M: M.aveN2F
|
||||
self.orderTest()
|
||||
|
||||
def test_orderN2E(self):
|
||||
self.name = "Averaging 3D: N2E"
|
||||
fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z))
|
||||
self.getHere = lambda M: call3(fun, M.gridN)
|
||||
self.getThere = lambda M: np.r_[call3(fun, M.gridEx), call3(fun, M.gridEy), call3(fun, M.gridEz)]
|
||||
self.getAve = lambda M: M.aveN2E
|
||||
self.orderTest()
|
||||
|
||||
def test_orderF2CC(self):
|
||||
self.name = "Averaging 3D: F2CC"
|
||||
fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z))
|
||||
self.getHere = lambda M: np.r_[call3(fun, M.gridFx), call3(fun, M.gridFy), call3(fun, M.gridFz)]
|
||||
self.getThere = lambda M: call3(fun, M.gridCC)
|
||||
self.getAve = lambda M: M.aveF2CC
|
||||
self.orderTest()
|
||||
|
||||
|
||||
def test_orderE2CC(self):
|
||||
self.name = "Averaging 3D: E2CC"
|
||||
fun = lambda x, y, z: (np.cos(x)+np.sin(y)+np.exp(z))
|
||||
self.getHere = lambda M: np.r_[call3(fun, M.gridEx), call3(fun, M.gridEy), call3(fun, M.gridEz)]
|
||||
self.getThere = lambda M: call3(fun, M.gridCC)
|
||||
self.getAve = lambda M: M.aveE2CC
|
||||
self.orderTest()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,54 @@
|
||||
import unittest
|
||||
from SimPEG import Solver
|
||||
from SimPEG.mesh import TensorMesh
|
||||
from SimPEG.utils import sdiag
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
from SimPEG import inverse
|
||||
from SimPEG.tests import getQuadratic, Rosenbrock
|
||||
|
||||
TOL = 1e-2
|
||||
|
||||
class TestOptimizers(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.A = sp.identity(2).tocsr()
|
||||
self.b = np.array([-5,-5])
|
||||
|
||||
def test_GN_Rosenbrock(self):
|
||||
GN = inverse.GaussNewton()
|
||||
xopt = GN.minimize(Rosenbrock,np.array([0,0]))
|
||||
x_true = np.array([1.,1.])
|
||||
print 'xopt: ', xopt
|
||||
print 'x_true: ', x_true
|
||||
self.assertTrue(np.linalg.norm(xopt-x_true,2) < TOL, True)
|
||||
|
||||
def test_GN_quadratic(self):
|
||||
GN = inverse.GaussNewton()
|
||||
xopt = GN.minimize(getQuadratic(self.A,self.b),np.array([0,0]))
|
||||
x_true = np.array([5.,5.])
|
||||
print 'xopt: ', xopt
|
||||
print 'x_true: ', x_true
|
||||
self.assertTrue(np.linalg.norm(xopt-x_true,2) < TOL, True)
|
||||
|
||||
def test_ProjGradient_quadraticBounded(self):
|
||||
PG = inverse.ProjectedGradient()
|
||||
PG.lower, PG.upper = -2, 2
|
||||
xopt = PG.minimize(getQuadratic(self.A,self.b),np.array([0,0]))
|
||||
x_true = np.array([2.,2.])
|
||||
print 'xopt: ', xopt
|
||||
print 'x_true: ', x_true
|
||||
self.assertTrue(np.linalg.norm(xopt-x_true,2) < TOL, True)
|
||||
|
||||
def test_ProjGradient_quadratic1Bound(self):
|
||||
myB = np.array([-5,1])
|
||||
PG = inverse.ProjectedGradient()
|
||||
PG.lower, PG.upper = -2, 2
|
||||
xopt = PG.minimize(getQuadratic(self.A,myB),np.array([0,0]))
|
||||
x_true = np.array([2.,-1.])
|
||||
print 'xopt: ', xopt
|
||||
print 'x_true: ', x_true
|
||||
self.assertTrue(np.linalg.norm(xopt-x_true,2) < TOL, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1 @@
|
||||
import emSources
|
||||
@@ -0,0 +1 @@
|
||||
from emSources import MagneticDipoleVectorPotential
|
||||
@@ -0,0 +1,39 @@
|
||||
import numpy as np
|
||||
from scipy.constants import mu_0, pi
|
||||
|
||||
def MagneticDipoleVectorPotential(txLoc, obsLoc, component, dipoleMoment=(0., 0., 1.)):
|
||||
"""
|
||||
Calculate the vector potential of a set of magnetic dipoles
|
||||
at given locations 'ref. <http://en.wikipedia.org/wiki/Dipole#Magnetic_vector_potential>'
|
||||
|
||||
:param numpy.ndarray txLoc: Location of the transmitter(s) (x, y, z)
|
||||
:param numpy.ndarray obsLoc: Where the potentials will be calculated (x, y, z)
|
||||
:param str component: The component to calculate - 'x', 'y', or 'z'
|
||||
:param numpy.ndarray dipoleMoment: The vector dipole moment
|
||||
:rtype: numpy.ndarray
|
||||
:return: The vector potential each dipole at each observation location
|
||||
"""
|
||||
|
||||
if component=='x':
|
||||
dimInd = 0
|
||||
elif component=='y':
|
||||
dimInd = 1
|
||||
elif component=='z':
|
||||
dimInd = 2
|
||||
else:
|
||||
raise ValueError('Invalid component')
|
||||
|
||||
txLoc = np.atleast_2d(txLoc)
|
||||
obsLoc = np.atleast_2d(obsLoc)
|
||||
|
||||
nEdges = obsLoc.shape[0]
|
||||
nTx = txLoc.shape[0]
|
||||
|
||||
m = np.array(dipoleMoment).repeat(nEdges, axis=0)
|
||||
A = np.empty((nEdges, nTx))
|
||||
for i in range(nTx):
|
||||
dR = obsLoc - txLoc[i, np.newaxis].repeat(nEdges, axis=0)
|
||||
mCr = np.cross(m, dR)
|
||||
r = np.sqrt((dR**2).sum(axis=1))
|
||||
A[:, i] = -(mu_0/(4*pi)) * mCr[:,dimInd]/(r**3)
|
||||
return A
|
||||
+71
-19
@@ -1,7 +1,22 @@
|
||||
import numpy as np
|
||||
import scipy.sparse as sparse
|
||||
import scipy.sparse.linalg as linalg
|
||||
from SimPEG.utils import mkvc
|
||||
|
||||
DEFAULTS = {'direct':'scipy', 'forward':'fortran', 'backward':'fortran', 'diagonal':'python'}
|
||||
|
||||
try:
|
||||
import TriSolve
|
||||
except Exception, e:
|
||||
try:
|
||||
import os
|
||||
# Note: this may not work from SublimeText, if that is the case, just run the command in your shell.
|
||||
os.system('f2py -c TriSolve.f -m TriSolve')
|
||||
import TriSolve
|
||||
except Exception, e:
|
||||
print 'Warning: Python backend is being used for solver. Run setup.py from the command line.'
|
||||
DEFAULTS['forward'] = 'python'
|
||||
DEFAULTS['backward'] = 'python'
|
||||
|
||||
class Solver(object):
|
||||
"""
|
||||
@@ -55,11 +70,11 @@ class Solver(object):
|
||||
elif self.flag is None and not self.doDirect:
|
||||
return self.solveIter(b, **self.options)
|
||||
elif self.flag == 'U':
|
||||
return self.solveBackward(b)
|
||||
return self.solveBackward(b, **self.options)
|
||||
elif self.flag == 'L':
|
||||
return self.solveForward(b)
|
||||
return self.solveForward(b, **self.options)
|
||||
elif self.flag == 'D':
|
||||
return self.solveDiagonal(b)
|
||||
return self.solveDiagonal(b, **self.options)
|
||||
else:
|
||||
raise Exception('Unknown flag.')
|
||||
pass
|
||||
@@ -69,7 +84,7 @@ class Solver(object):
|
||||
del self.dsolve
|
||||
self.dsolve = None
|
||||
|
||||
def solveDirect(self, b, factorize=False, backend='scipy'):
|
||||
def solveDirect(self, b, factorize=False, backend=None):
|
||||
"""
|
||||
Use solve instead of this interface.
|
||||
|
||||
@@ -78,6 +93,8 @@ class Solver(object):
|
||||
:rtype: numpy.ndarray
|
||||
:return: x
|
||||
"""
|
||||
if backend is None: backend = DEFAULTS['direct']
|
||||
|
||||
assert np.shape(self.A)[1] == np.shape(b)[0], 'Dimension mismatch'
|
||||
|
||||
if factorize and self.dsolve is None:
|
||||
@@ -104,7 +121,7 @@ class Solver(object):
|
||||
def solveIter(self, b, M=None, iterSolver='CG'):
|
||||
pass
|
||||
|
||||
def solveBackward(self, b, backend='python'):
|
||||
def solveBackward(self, b, backend=None):
|
||||
"""
|
||||
Use solve instead of this interface.
|
||||
|
||||
@@ -114,21 +131,29 @@ class Solver(object):
|
||||
:rtype: numpy.ndarray
|
||||
:return: x
|
||||
"""
|
||||
if backend is None: backend = DEFAULTS['backward']
|
||||
if type(self.A) is not sparse.csr.csr_matrix:
|
||||
from scipy.sparse import csr_matrix
|
||||
self.A = csr_matrix(self.A)
|
||||
vals = self.A.data
|
||||
rowptr = self.A.indptr
|
||||
colind = self.A.indices
|
||||
x = np.empty_like(b) # empty() is faster than zeros().
|
||||
for i in reversed(xrange(self.A.shape[0])):
|
||||
ith_row = vals[rowptr[i] : rowptr[i+1]]
|
||||
cols = colind[rowptr[i] : rowptr[i+1]]
|
||||
x_vals = x[cols]
|
||||
x[i] = (b[i] - np.dot(ith_row[1:], x_vals[1:])) / ith_row[0]
|
||||
if backend == 'fortran':
|
||||
if len(b.shape) == 1 or b.shape[1] == 1:
|
||||
x = TriSolve.backward(vals, rowptr, colind, b, self.A.data.size, b.size, 1)
|
||||
x = mkvc(x)
|
||||
else:
|
||||
x = TriSolve.backward(vals, rowptr, colind, b, self.A.data.size, b.shape[0], b.shape[1])
|
||||
elif backend == 'python':
|
||||
x = np.empty_like(b) # empty() is faster than zeros().
|
||||
for i in reversed(xrange(self.A.shape[0])):
|
||||
ith_row = vals[rowptr[i] : rowptr[i+1]]
|
||||
cols = colind[rowptr[i] : rowptr[i+1]]
|
||||
x_vals = x[cols]
|
||||
x[i] = (b[i] - np.dot(ith_row[1:], x_vals[1:])) / ith_row[0]
|
||||
return x
|
||||
|
||||
def solveForward(self, b, backend='python'):
|
||||
def solveForward(self, b, backend=None):
|
||||
"""
|
||||
Use solve instead of this interface.
|
||||
|
||||
@@ -138,21 +163,29 @@ class Solver(object):
|
||||
:rtype: numpy.ndarray
|
||||
:return: x
|
||||
"""
|
||||
if backend is None: backend = DEFAULTS['forward']
|
||||
if type(self.A) is not sparse.csr.csr_matrix:
|
||||
from scipy.sparse import csr_matrix
|
||||
self.A = csr_matrix(self.A)
|
||||
vals = self.A.data
|
||||
rowptr = self.A.indptr
|
||||
colind = self.A.indices
|
||||
x = np.empty_like(b) # empty() is faster than zeros().
|
||||
for i in xrange(self.A.shape[0]):
|
||||
ith_row = vals[rowptr[i] : rowptr[i+1]]
|
||||
cols = colind[rowptr[i] : rowptr[i+1]]
|
||||
x_vals = x[cols]
|
||||
x[i] = (b[i] - np.dot(ith_row[:-1], x_vals[:-1])) / ith_row[-1]
|
||||
if backend == 'fortran':
|
||||
if len(b.shape) == 1 or b.shape[1] == 1:
|
||||
x = TriSolve.forward(vals, rowptr, colind, b, self.A.data.size, b.size, 1)
|
||||
x = mkvc(x)
|
||||
else:
|
||||
x = TriSolve.forward(vals, rowptr, colind, b, self.A.data.size, b.shape[0], b.shape[1])
|
||||
elif backend == 'python':
|
||||
x = np.empty_like(b) # empty() is faster than zeros().
|
||||
for i in xrange(self.A.shape[0]):
|
||||
ith_row = vals[rowptr[i] : rowptr[i+1]]
|
||||
cols = colind[rowptr[i] : rowptr[i+1]]
|
||||
x_vals = x[cols]
|
||||
x[i] = (b[i] - np.dot(ith_row[:-1], x_vals[:-1])) / ith_row[-1]
|
||||
return x
|
||||
|
||||
def solveDiagonal(self, b, backend='python'):
|
||||
def solveDiagonal(self, b, backend=None):
|
||||
"""
|
||||
Use solve instead of this interface.
|
||||
|
||||
@@ -162,6 +195,8 @@ class Solver(object):
|
||||
:rtype: numpy.ndarray
|
||||
:return: x
|
||||
"""
|
||||
if backend is None: backend = DEFAULTS['diagonal']
|
||||
|
||||
diagA = self.A.diagonal()
|
||||
if len(b.shape) == 1 or b.shape[1] == 1:
|
||||
# Just one RHS
|
||||
@@ -205,3 +240,20 @@ if __name__ == '__main__':
|
||||
print np.linalg.norm(e-x,np.inf)
|
||||
|
||||
|
||||
n = 6000
|
||||
A_dense = np.random.random((n,n))
|
||||
L = np.tril(np.dot(A_dense, A_dense)) # Positive definite is better conditioned.
|
||||
e = np.ones(n)
|
||||
b = np.dot(L, e)
|
||||
|
||||
A = sparse.csr_matrix(L)
|
||||
pSolve = Solver(A,flag='L',options={'backend':'python'});
|
||||
fSolve = Solver(A,flag='L',options={'backend':'fortran'})
|
||||
tic = time()
|
||||
x = pSolve.solve(b)
|
||||
toc = time() - tic
|
||||
print 'Error Forward Python = ', np.linalg.norm(x-e, np.inf), 'Time: ', toc
|
||||
tic = time()
|
||||
x = fSolve.solve(b)
|
||||
toc = time() - tic
|
||||
print 'Error Forward Fortran = ', np.linalg.norm(x-e, np.inf), 'Time: ', toc
|
||||
@@ -0,0 +1,64 @@
|
||||
c File TriSolve.f
|
||||
subroutine forward(al, ial, jal, b, nv, n, nRHS, x)
|
||||
double precision al(nv)
|
||||
integer ial(n+1)
|
||||
integer jal(nv)
|
||||
double precision b(n,nRHS)
|
||||
double precision x(n,nRHS)
|
||||
integer nv
|
||||
integer n
|
||||
integer nRHS
|
||||
integer rhs
|
||||
cf2py intent(in) :: al
|
||||
cf2py intent(in) :: ial
|
||||
cf2py intent(in) :: jal
|
||||
cf2py intent(in) :: b
|
||||
cf2py intent(in) :: nv
|
||||
cf2py intent(in) :: n
|
||||
cf2py intent(in) :: nRHS
|
||||
cf2py intent(out) :: x
|
||||
real ( kind = 8 ) t
|
||||
|
||||
do rhs = 1, nRHS
|
||||
do k = 1, n
|
||||
t = b(k,rhs)
|
||||
do j = ial(k)+1, ial(k+1)
|
||||
t = t - al(j) * x(jal(j)+1,rhs)
|
||||
end do
|
||||
x(k,rhs) = t/al(ial(k+1))
|
||||
end do
|
||||
end do
|
||||
end subroutine forward
|
||||
|
||||
|
||||
subroutine backward(au,iau, jau, b, nv, n, nRHS, x)
|
||||
double precision au(nv)
|
||||
integer iau(n+1)
|
||||
integer jau(nv)
|
||||
double precision b(n,nRHS)
|
||||
double precision x(n,nRHS)
|
||||
integer nv
|
||||
integer n
|
||||
integer nRHS
|
||||
integer rhs
|
||||
cf2py intent(in) :: au
|
||||
cf2py intent(in) :: iau
|
||||
cf2py intent(in) :: jau
|
||||
cf2py intent(in) :: b
|
||||
cf2py intent(in) :: nv
|
||||
cf2py intent(in) :: n
|
||||
cf2py intent(in) :: nRHS
|
||||
cf2py intent(out) :: x
|
||||
real ( kind = 8 ) t
|
||||
|
||||
do rhs = 1, nRHS
|
||||
do k = n, 1, -1
|
||||
t = b(k,rhs)
|
||||
do j = iau(k)+1, iau(k+1)
|
||||
t = t - au(j) * x(jau(j)+1,rhs)
|
||||
end do
|
||||
x(k,rhs) = t/au(iau(k)+1)
|
||||
end do
|
||||
end do
|
||||
|
||||
end subroutine backward
|
||||
@@ -3,9 +3,60 @@ import sputils
|
||||
import lomutils
|
||||
import interputils
|
||||
import ModelBuilder
|
||||
import Solver
|
||||
from Solver import Solver
|
||||
from matutils import getSubArray, mkvc, ndgrid, ind2sub, sub2ind
|
||||
from sputils import spzeros, kron3, speye, sdiag
|
||||
from sputils import spzeros, kron3, speye, sdiag, ddx, av
|
||||
from lomutils import volTetra, faceInfo, inv2X2BlockDiagonal, inv3X3BlockDiagonal, indexCube, exampleLomGird
|
||||
from interputils import interpmat
|
||||
from ipythonUtils import easyAnimate as animate
|
||||
import Solver
|
||||
from Solver import Solver
|
||||
import Geophysics
|
||||
|
||||
def setKwargs(obj, **kwargs):
|
||||
"""Sets key word arguments (kwargs) that are present in the object, throw an error if they don't exist."""
|
||||
for attr in kwargs:
|
||||
if hasattr(obj, attr):
|
||||
setattr(obj, attr, kwargs[attr])
|
||||
else:
|
||||
raise Exception('%s attr is not recognized' % attr)
|
||||
|
||||
def printTitles(obj, printers, name='Print Titles', pad=''):
|
||||
titles = ''
|
||||
widths = 0
|
||||
for printer in printers:
|
||||
titles += ('{:^%i}'%printer['width']).format(printer['title']) + ''
|
||||
widths += printer['width']
|
||||
print pad + "{0} {1} {0}".format('='*((widths-1-len(name))/2), name)
|
||||
print pad + titles
|
||||
print pad + "%s" % '-'*widths
|
||||
|
||||
def printLine(obj, printers, pad=''):
|
||||
values = ''
|
||||
for printer in printers:
|
||||
values += ('{:^%i}'%printer['width']).format(printer['format'] % printer['value'](obj))
|
||||
print pad + values
|
||||
|
||||
def checkStoppers(obj, stoppers):
|
||||
# check stopping rules
|
||||
optimal = []
|
||||
critical = []
|
||||
for stopper in stoppers:
|
||||
l = stopper['left'](obj)
|
||||
r = stopper['right'](obj)
|
||||
if stopper['stopType'] == 'optimal':
|
||||
optimal.append(l <= r)
|
||||
if stopper['stopType'] == 'critical':
|
||||
critical.append(l <= r)
|
||||
|
||||
if obj.debug: print 'checkStoppers.optimal: ', optimal
|
||||
if obj.debug: print 'checkStoppers.critical: ', critical
|
||||
|
||||
return (len(optimal)>0 and all(optimal)) | (len(critical)>0 and any(critical))
|
||||
|
||||
def printStoppers(obj, stoppers, pad='', stop='STOP!', done='DONE!'):
|
||||
print pad + "%s%s%s" % ('-'*25,stop,'-'*25)
|
||||
for stopper in stoppers:
|
||||
l = stopper['left'](obj)
|
||||
r = stopper['right'](obj)
|
||||
print pad + stopper['str'] % (l<=r,l,r)
|
||||
print pad + "%s%s%s" % ('-'*25,done,'-'*25)
|
||||
@@ -0,0 +1,28 @@
|
||||
from tempfile import NamedTemporaryFile
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import animation
|
||||
|
||||
# http://jakevdp.github.io/blog/2013/05/12/embedding-matplotlib-animations/
|
||||
# http://www.renevolution.com/how-to-install-ffmpeg-on-mac-os-x/
|
||||
|
||||
VIDEO_TAG = """<video controls loop>
|
||||
<source src="data:video/x-m4v;base64,{0}" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>"""
|
||||
|
||||
def anim_to_html(anim):
|
||||
if not hasattr(anim, '_encoded_video'):
|
||||
with NamedTemporaryFile(suffix='.mp4') as f:
|
||||
anim.save(f.name, fps=20, extra_args=['-vcodec', 'libx264', '-pix_fmt', 'yuv420p'])
|
||||
video = open(f.name, "rb").read()
|
||||
anim._encoded_video = video.encode("base64")
|
||||
|
||||
return VIDEO_TAG.format(anim._encoded_video)
|
||||
|
||||
def display_animation(anim):
|
||||
plt.close(anim._fig)
|
||||
return anim_to_html(anim)
|
||||
|
||||
animation.Animation._repr_html_ = display_animation
|
||||
|
||||
easyAnimate = animation.FuncAnimation
|
||||
@@ -1,5 +1,6 @@
|
||||
from scipy import sparse as sp
|
||||
from matutils import mkvc
|
||||
import numpy as np
|
||||
|
||||
|
||||
def sdiag(h):
|
||||
@@ -20,3 +21,13 @@ def kron3(A, B, C):
|
||||
def spzeros(n1, n2):
|
||||
"""spzeros"""
|
||||
return sp.coo_matrix((n1, n2)).tocsr()
|
||||
|
||||
|
||||
def ddx(n):
|
||||
"""Define 1D derivatives, inner, this means we go from n+1 to n"""
|
||||
return sp.spdiags((np.ones((n+1, 1))*[-1, 1]).T, [0, 1], n, n+1, format="csr")
|
||||
|
||||
|
||||
def av(n):
|
||||
"""Define 1D averaging operator from cell-centres to nodes."""
|
||||
return sp.spdiags((0.5*np.ones((n+1, 1))*[1, 1]).T, [0, 1], n, n+1, format="csr")
|
||||
+1361
-550
File diff suppressed because it is too large.
Load diff
@@ -1,2 +1,3 @@
|
||||
numpy
|
||||
pypubsub
|
||||
ipython
|
||||
@@ -0,0 +1,620 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": ""
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import SimPEG\n",
|
||||
"from SimPEG.mesh import TensorMesh\n",
|
||||
"from SimPEG.regularization import Regularization\n",
|
||||
"import SimPEG.inverse as inverse\n",
|
||||
"from SimPEG.inverse import Minimize\n",
|
||||
"import numpy as np\n",
|
||||
"import scipy.sparse as sp"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 1
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"from SimPEG.forward.LinearProblem import example as LinExample\n",
|
||||
"\n",
|
||||
"prob, m_true = LinExample(1000)\n",
|
||||
"M = prob.mesh\n",
|
||||
"\n",
|
||||
"reg = Regularization(M)\n",
|
||||
"opt = inverse.InexactGaussNewton(maxIter=100,maxStep=0.2,debug=False,LSreduction=0.3,maxIterLS=50)\n",
|
||||
"opt.remember('f', ('norm_g', lambda M:np.linalg.norm(M.g)))\n",
|
||||
"inv = inverse.Inversion(prob,reg,opt,beta0=1e-4,maxIter=2,debug=False)\n",
|
||||
"m0 = np.zeros_like(m_true)\n",
|
||||
"\n",
|
||||
"mrec = inv.run(m0)\n",
|
||||
"\n",
|
||||
"plt.plot(M.vectorCCx, m_true, 'b-')\n",
|
||||
"plt.plot(M.vectorCCx, mrec, 'r-')\n",
|
||||
"\n",
|
||||
"figure()\n",
|
||||
"plot(opt.recall('f'))\n"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"====================== Inexact Gauss Newton ======================\n",
|
||||
" # beta phi_d phi_m f |proj(x-g)-x| LS \n",
|
||||
"-----------------------------------------------------------------\n",
|
||||
" 0 1.00e-04 9.62e+02 0.00e+00 9.62e+02 1.02e+04 0 \n",
|
||||
" 1 1.00e-04 6.63e+02 7.73e+02 6.63e+02 8.47e+03 0 \n",
|
||||
" 2 1.00e-04 4.15e+02 4.39e+03 4.15e+02 6.63e+03 0 \n",
|
||||
" 3 1.00e-04 2.26e+02 6.85e+03 2.27e+02 4.80e+03 0 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 4 1.00e-04 9.74e+01 1.07e+04 9.84e+01 3.02e+03 0 \n",
|
||||
" 5 1.00e-04 2.42e+01 1.64e+04 2.58e+01 1.35e+03 0 \n",
|
||||
" 6 1.00e-04 1.06e+00 2.34e+04 3.39e+00 9.21e+00 0 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"1 : |fc-fOld| = 2.2421e+01 <= tolF*(1+|f0|) = 9.6325e+01\n",
|
||||
"0 : |xc-x_last| = 2.1351e+00 <= tolX*(1+|x0|) = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 9.2073e+00 <= tolG = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 9.2073e+00 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 100 <= iter = 6\n",
|
||||
"1 : phi_d = 1.0595e+00 <= phi_d_target = 2.0000e+01 \n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"-------------------------STOP!-------------------------\n",
|
||||
"0 : maxIter = 2 <= iter = 1\n",
|
||||
"1 : phi_d = 1.0595e+00 <= phi_d_target = 2.0000e+01 \n",
|
||||
"-------------------------DONE!-------------------------\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 3,
|
||||
"text": [
|
||||
"[<matplotlib.lines.Line2D at 0x10ebf9f10>]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10ecafa10>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10ecbec90>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"FUN = SimPEG.tests.getQuadratic(sp.identity(2),np.array([-5,-5]))\n",
|
||||
"# FUN = SimPEG.tests.Rosenbrock\n",
|
||||
"\n",
|
||||
"f = FUN(np.array([1,2]))\n",
|
||||
"print f\n",
|
||||
"n,l,u = 50,-10,10\n",
|
||||
"I = np.zeros((n,n))\n",
|
||||
"X = np.linspace(l,u,n)\n",
|
||||
"for i, x in enumerate(X):\n",
|
||||
" for j, y in enumerate(X):\n",
|
||||
" f, g, H = FUN(np.array([x,y]))\n",
|
||||
" I[i,j] = f\n",
|
||||
"\n",
|
||||
"colorbar(contourf(X,X, I.T))\n",
|
||||
"\n",
|
||||
"GN = inverse.GaussNewton()\n",
|
||||
"xopt = GN.minimize(FUN,np.array([0,0]))\n",
|
||||
"print xopt"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"(-12.5, array([-4., -3.]), <2x2 sparse matrix of type '<type 'numpy.float64'>'\n",
|
||||
"\twith 2 stored elements (1 diagonals) in DIAgonal format>)\n",
|
||||
"=========== Gauss Newton ==========="
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" # f |proj(x-g)-x| LS \n",
|
||||
"-----------------------------------\n",
|
||||
" 0 0.00e+00 7.07e+00 0 \n",
|
||||
" 1 -2.50e+01 0.00e+00 0 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"0 : |fc-fOld| = 2.5000e+01 <= tolF*(1+|f0|) = 1.0000e-01\n",
|
||||
"0 : |xc-x_last| = 7.0711e+00 <= tolX*(1+|x0|) = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 0.0000e+00 <= tolG = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 0.0000e+00 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 20 <= iter = 1\n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"[ 5. 5.]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10ebd9750>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 5
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"opt = inverse.ProjectedGradient(maxIter=50,maxStep=np.inf, maxIterLS=20, debug=False)\n",
|
||||
"opt.remember('f')\n",
|
||||
"opt.lower = -2\n",
|
||||
"opt.upper = 2\n",
|
||||
"opt.minimize(FUN,np.array([0,0]))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"======================= Projected Gradient =======================\n",
|
||||
" # f |proj(x-g)-x| LS itType aSet bSet Comment\n",
|
||||
"------------------------------------------------------------------\n",
|
||||
" 0 0.00e+00 2.83e+00 0 SD 0 0 \n",
|
||||
" 1 -1.60e+01 0.00e+00 0 SD 2 2 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"0 : |fc-fOld| = 1.6000e+01 <= tolF*(1+|f0|) = 1.0000e-01\n",
|
||||
"0 : |xc-x_last| = 2.8284e+00 <= tolX*(1+|x0|) = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 0.0000e+00 <= tolG = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 0.0000e+00 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 50 <= iter = 1\n",
|
||||
"1 : probSize = 2 <= bindingSet = 2\n",
|
||||
"------------------------- DONE! -------------------------\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 7,
|
||||
"text": [
|
||||
"array([ 2., 2.])"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 7
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"opt = inverse.ProjectedGradient(maxIter=50, maxStep=0.3,debug=False, maxIterLS=20, tolCG=1e-5, maxIterCG=1000)\n",
|
||||
"opt.lower, opt.upper = -0.4, 0.9\n",
|
||||
"opt.remember('f', 'xc', ('norm_g', lambda M: np.linalg.norm(M.g)), 'phi_d', 'phi_m')\n",
|
||||
"inv = inverse.Inversion(prob,reg,opt,beta0=1e-3,debug=False)\n",
|
||||
"inv.remember(('phi_d',lambda I:I.opt.recall('phi_d')),('phi_m',lambda I:I.opt.recall('phi_m')))\n",
|
||||
"m0 = np.zeros_like(m_true)\n",
|
||||
"mrecB = inv.run(m0)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"====================================== Projected Gradient ======================================\n",
|
||||
" # beta phi_d phi_m f |proj(x-g)-x| LS itType aSet bSet Comment\n",
|
||||
"------------------------------------------------------------------------------------------------\n",
|
||||
" 0 1.00e-03 9.62e+02 0.00e+00 9.62e+02 2.14e+01 0 SD 0 0 \n",
|
||||
" 1 1.00e-03 9.53e+02 8.49e-03 9.53e+02 2.18e+01 9 SD 0 0 \n",
|
||||
" 2 1.00e-03 5.32e+02 1.42e+03 5.33e+02 2.20e+01 0 .CG. 0 0 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 3 1.00e-03 2.32e+02 5.66e+03 2.38e+02 2.26e+01 0 .CG. 0 0 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 4 1.00e-03 1.29e+02 8.85e+03 1.38e+02 2.30e+01 1 .CG. 0 0 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 5 1.00e-03 1.10e+02 9.74e+03 1.20e+02 2.15e+01 3 .CG. 22 22 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 6 1.00e-03 1.09e+02 9.74e+03 1.19e+02 2.36e+01 10 SD 22 0 Stop SD\n",
|
||||
" 7 1.00e-03 7.65e+01 1.33e+04 8.98e+01 2.21e+01 1 .CG. 85 75 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 8 1.00e-03 5.11e+01 1.33e+04 6.44e+01 2.38e+01 9 SD 75 3 \n",
|
||||
" 9 1.00e-03 5.07e+01 1.33e+04 6.41e+01 2.11e+01 12 SD 4 4 \n",
|
||||
" 10 1.00e-03 5.06e+01 1.33e+04 6.40e+01 2.20e+01 12 SD 17 9 Stop SD\n",
|
||||
" 11 1.00e-03 5.04e+01 1.34e+04 6.37e+01 2.05e+01 8 .CG. 85 81 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 12 1.00e-03 5.03e+01 1.34e+04 6.37e+01 1.65e+01 13 SD 81 26 \n",
|
||||
" 13 1.00e-03 5.03e+01 1.34e+04 6.37e+01 1.67e+01 15 SD 30 30 \n",
|
||||
" 14 1.00e-03 5.03e+01 1.34e+04 6.36e+01 1.42e+01 15 SD 84 84 Stop SD\n",
|
||||
" 15 1.00e-03 2.65e+01 2.26e+04 4.91e+01 2.52e+01 0 .CG. 190 50 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 16 1.00e-03 1.51e+01 2.26e+04 3.77e+01 2.24e+01 10 SD 50 1 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"1 : |fc-fOld| = 1.1392e+01 <= tolF*(1+|f0|) = 9.6325e+01\n",
|
||||
"1 : |xc-x_last| = 3.4809e-03 <= tolX*(1+|x0|) = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 2.2369e+01 <= tolG = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 2.2369e+01 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 50 <= iter = 16\n",
|
||||
"0 : probSize = 1000 <= bindingSet = 1\n",
|
||||
"1 : phi_d = 1.5077e+01 <= phi_d_target = 2.0000e+01 \n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"-------------------------STOP!-------------------------\n",
|
||||
"0 : maxIter = 10 <= iter = 1\n",
|
||||
"1 : phi_d = 1.5077e+01 <= phi_d_target = 2.0000e+01 \n",
|
||||
"-------------------------DONE!-------------------------\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 8
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"# First set up the figure, the axis, and the plot element we want to animate\n",
|
||||
"fig = plt.figure()\n",
|
||||
"ax = plt.axes()\n",
|
||||
"ax.plot(M.vectorCCx, m_true, 'b-')\n",
|
||||
"txt = plt.text(0.8,0.9,'')\n",
|
||||
"line, = ax.plot([], [], 'r-', lw=1)\n",
|
||||
"\n",
|
||||
"def animate(i):\n",
|
||||
" txt.set_text('iteration %d'%i)\n",
|
||||
" line.set_data(M.vectorCCx, np.array(opt.recall('xc')[i]))\n",
|
||||
"\n",
|
||||
"SimPEG.utils.animate(fig, animate, frames=len(opt.recall('xc')))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"html": [
|
||||
"<video controls loop>\n",
|
||||
" <source src=\"data:video/x-m4v;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAALXFtZGF0AAACoQYF//+d\n",
|
||||
"3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDEyNSAtIEguMjY0L01QRUctNCBBVkMgY29kZWMg\n",
|
||||
"LSBDb3B5bGVmdCAyMDAzLTIwMTIgLSBodHRwOi8vd3d3LnZpZGVvbGFuLm9yZy94MjY0Lmh0bWwg\n",
|
||||
"LSBvcHRpb25zOiBjYWJhYz0xIHJlZj0zIGRlYmxvY2s9MTowOjAgYW5hbHlzZT0weDM6MHgxMTMg\n",
|
||||
"bWU9aGV4IHN1Ym1lPTcgcHN5PTEgcHN5X3JkPTEuMDA6MC4wMCBtaXhlZF9yZWY9MSBtZV9yYW5n\n",
|
||||
"ZT0xNiBjaHJvbWFfbWU9MSB0cmVsbGlzPTEgOHg4ZGN0PTEgY3FtPTAgZGVhZHpvbmU9MjEsMTEg\n",
|
||||
"ZmFzdF9wc2tpcD0xIGNocm9tYV9xcF9vZmZzZXQ9LTIgdGhyZWFkcz0xMiBsb29rYWhlYWRfdGhy\n",
|
||||
"ZWFkcz0yIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVy\n",
|
||||
"YXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9h\n",
|
||||
"ZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MiBr\n",
|
||||
"ZXlpbnQ9MjUwIGtleWludF9taW49MjAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xv\n",
|
||||
"b2thaGVhZD00MCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIzLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFw\n",
|
||||
"bWF4PTY5IHFwc3RlcD00IGlwX3JhdGlvPTEuNDAgYXE9MToxLjAwAIAAAAlFZYiEAFf9EwAD0rwK\n",
|
||||
"a/s12U1hg0FMgMmMOVNcwAAAAwANFchWCs4PnSPLHgxFeZ2MBPwOINxDCInVnrlTnaSkcTqCnVwZ\n",
|
||||
"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\n",
|
||||
"\" type=\"video/mp4\">\n",
|
||||
" Your browser does not support the video tag.\n",
|
||||
"</video>"
|
||||
],
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 9,
|
||||
"text": [
|
||||
"<matplotlib.animation.FuncAnimation at 0x10ee35450>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 9
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"plot(opt.recall('phi_d'))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 10,
|
||||
"text": [
|
||||
"[<matplotlib.lines.Line2D at 0x10eb01450>]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x11030ec90>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 10
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user