mirror of
https://github.com/wassname/simpeg.git
synced 2026-07-09 11:44:18 +08:00
updates to Inversion. Bug Fixes.
This commit is contained in:
@@ -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
@@ -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)
|
||||
|
||||
@@ -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) )
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user