Files
simpeg/SimPEG/Inversion.py
T
rowanc1 67b067d938 Major Reorganization (Things are likely still broken...)
Added Parameter to Utils, which hints at where we are going with functions as parameters.
2014-01-17 14:03:08 -08:00

189 lines
5.5 KiB
Python

import SimPEG
from SimPEG import Utils, sp, np
from Optimization import Remember, IterationPrinters, StoppingCriteria
class BaseInversion(object):
"""BaseInversion(prob, reg, opt, data, **kwargs)
"""
__metaclass__ = Utils.Save.Savable
maxIter = 1 #: Maximum number of iterations
name = 'BaseInversion'
debug = False #: Print debugging information
comment = '' #: Used by some functions to indicate what is going on in the algorithm
counter = None #: Set this to a SimPEG.Utils.Counter() if you want to count things
def __init__(self, dataObj, opt, **kwargs):
Utils.setKwargs(self, **kwargs)
self.dataObj = dataObj
self.dataObj.parent = self
self.opt = opt
self.opt.parent = self
self.stoppers = [StoppingCriteria.iteration]
# Check if we have inserted printers into the optimization
if IterationPrinters.phi_d not in self.opt.printers:
self.opt.printers.insert(1,IterationPrinters.beta)
self.opt.printers.insert(2,IterationPrinters.phi_d)
self.opt.printers.insert(3,IterationPrinters.phi_m)
if not hasattr(opt, '_bfgsH0') and hasattr(opt, 'bfgsH0'): # Check if it has been set by the user and the default is not being used.
#TODO: I don't think that this if statement is working...
print 'Setting bfgsH0 to the inverse of the modelObj2Deriv. Done using direct methods.'
opt.bfgsH0 = SimPEG.Solver(reg.modelObj2Deriv())
@property
def phi_d_target(self):
"""
target for phi_d
By default this is the number of data.
Note that we do not set the target if it is None, but we return the default value.
"""
if getattr(self, '_phi_d_target', None) is None:
return self.data.dobs.size #
return self._phi_d_target
@phi_d_target.setter
def phi_d_target(self, value):
self._phi_d_target = value
@Utils.timeIt
def run(self, m0):
"""run(m0)
Runs the inversion!
"""
self.startup(m0)
while True:
self.doStartIteration()
self.m = self.opt.minimize(self.evalFunction, self.m)
self.doEndIteration()
if self.stoppingCriteria(): break
self.printDone()
self.finish()
return self.m
@Utils.callHooks('startup')
def startup(self, m0):
"""
**startup** is called at the start of any new run call.
:param numpy.ndarray x0: initial x
:rtype: None
:return: None
"""
if not hasattr(self.reg, '_mref'):
print 'Regularization has not set mref. SimPEG will set it to m0.'
self.reg.mref = m0
self.m = m0
self._iter = 0
self._beta = None
self.phi_d_last = np.nan
self.phi_m_last = np.nan
@Utils.callHooks('doStartIteration')
def doStartIteration(self):
"""
**doStartIteration** is called at the end of each run iteration.
:rtype: None
:return: None
"""
self._beta = self.getBeta()
@Utils.callHooks('doEndIteration')
def doEndIteration(self):
"""
**doEndIteration** is called at the end of each run iteration.
:rtype: None
:return: None
"""
# store old values
self.phi_d_last = self.phi_d
self.phi_m_last = self.phi_m
self._iter += 1
def stoppingCriteria(self):
if self.debug: print 'checking stoppingCriteria'
return Utils.checkStoppers(self, self.stoppers)
def printDone(self):
"""
**printDone** is called at the end of the inversion routine.
"""
Utils.printStoppers(self, self.stoppers)
@Utils.callHooks('finish')
def finish(self):
"""finish()
**finish** is called at the end of the optimization.
"""
pass
def save(self, group):
group.attrs['phi_d'] = self.phi_d
group.attrs['phi_m'] = self.phi_m
group.setArray('m', self.m)
group.setArray('dpred', self.dpred)
# class Inversion(Cooling, Remember, BaseInversion):
# maxIter = 10
# name = "SimPEG Inversion"
# def __init__(self, prob, reg, opt, data, **kwargs):
# BaseInversion.__init__(self, prob, reg, opt, data, **kwargs)
# self.stoppers.append(StoppingCriteria.phi_d_target_Inversion)
# if StoppingCriteria.phi_d_target_Minimize not in self.opt.stoppers:
# self.opt.stoppers.append(StoppingCriteria.phi_d_target_Minimize)
# class TimeSteppingInversion(Remember, BaseInversion):
# """
# A slightly different view on regularization parameters,
# let Beta be viewed as 1/dt, and timestep by updating the
# reference model every optimization iteration.
# """
# maxIter = 1
# name = "Time-Stepping SimPEG Inversion"
# def __init__(self, prob, reg, opt, data, **kwargs):
# BaseInversion.__init__(self, prob, reg, opt, data, **kwargs)
# self.stoppers.append(StoppingCriteria.phi_d_target_Inversion)
# if StoppingCriteria.phi_d_target_Minimize not in self.opt.stoppers:
# self.opt.stoppers.append(StoppingCriteria.phi_d_target_Minimize)
# def _startup_TimeSteppingInversion(self, m0):
# def _doEndIteration_updateMref(self, xt):
# if self.debug: 'Updating the reference model.'
# self.parent.reg.mref = self.xc
# self.opt.hook(_doEndIteration_updateMref, overwrite=True)