updates to Inversion. Bug Fixes.

This commit is contained in:
Rowan Cockett
2013-11-07 17:42:24 -08:00
parent bc71b184aa
commit 19f79b3275
4 changed files with 94 additions and 22 deletions
+2 -2
View File
@@ -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
+82 -16
View File
@@ -1,13 +1,17 @@
import numpy as np
import scipy.sparse as sp
import SimPEG
from SimPEG.utils import sdiag, mkvc, setKwargs, checkStoppers
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)
@@ -47,32 +51,87 @@ 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._iter += 1
self.m = self.opt.minimize(self.evalFunction, self.m)
self.doEndIteration()
if self.stoppingCriteria(): break
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):
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):
u = self.prob.field(m)
@@ -209,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)
+5 -3
View File
@@ -468,7 +468,7 @@ class Remember(object):
self._rememberThese = args
def recall(self, param):
assert param in self._rememberThese, "You didn't tell me to remember "+param+", you gotta tell me what to remember!"
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):
@@ -479,15 +479,17 @@ class Remember(object):
elif type(param) is tuple:
self._rememberList[param[0]] = []
def _doEndIterationRemember(self, xt):
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 self.parent is not 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) )
+5 -1
View File
@@ -47,7 +47,11 @@ def checkStoppers(obj, stoppers):
optimal.append(l <= r)
if stopper['stopType'] == 'critical':
critical.append(l <= r)
return all(optimal) | any(critical)
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)