1. Update for smoothmod and smoothmod_dif options in regularization

2. Update for ActiveCellsTopo: Mapping, which extends surface cell to air cell.
This commit is contained in:
SEOGI KANG
2014-12-07 23:49:33 -08:00
parent f5c58c5c20
commit bc7f330f29
2 changed files with 106 additions and 3 deletions
+58
View File
@@ -420,6 +420,64 @@ class ActiveCells(IdentityMap):
def deriv(self, m):
return self.P
class ActiveCellsTopo(IdentityMap):
"""
Active model parameters. Extend for cells on topography to air cell (only works for tensor mesh)
"""
indActive = None #: Active Cells
valInactive = None #: Values of inactive Cells
nC = None #: Number of cells in the full model
def __init__(self, mesh, indActive, nC=None):
self.mesh = mesh
self.nC = nC or mesh.nC
if indActive.dtype is not bool:
z = np.zeros(self.nC,dtype=bool)
z[indActive] = True
indActive = z
self.indActive = indActive
self.indInactive = np.logical_not(indActive)
inds = np.nonzero(self.indActive)[0]
self.P = sp.csr_matrix((np.ones(inds.size),(inds, range(inds.size))), shape=(self.nC, self.nP))
@property
def shape(self):
return (self.nC, self.nP)
@property
def nP(self):
"""Number of parameters in the model."""
return self.indActive.sum()
def _transform(self, m):
if self.mesh.dim == 3:
act_temp = self.indActive.reshape((self.mesh.nCx*self.mesh.nCy, self.mesh.nCz), order = 'F')
val_temp = np.zeros(self.mesh.nC)
val_temp[self.indActive] = m
val_temp = val_temp.reshape((self.mesh.nCx*self.mesh.nCy, self.mesh.nCz), order = 'F')
valInactive = np.zeros(self.mesh.nC)
z_temp = self.mesh.gridCC[:,2].reshape((self.mesh.nCx*self.mesh.nCy, self.mesh.nCz), order = 'F')
for i in range(self.mesh.nCx*self.mesh.nCy):
act_tempxy = act_temp[i,:] == 1
val_temp[i,~act_tempxy] = val_temp[i,np.argmax(z_temp[i,act_tempxy])]
valInactive[~self.indActive] = Utils.mkvc(val_temp)[~self.indActive]
else:
raise Exception("Not implemented for 1D and 2D")
self.valInactive = valInactive
return self.P*m + self.valInactive
def inverse(self, D):
return self.P.T*D
def deriv(self, m):
return self.P
class Weighting(IdentityMap):
"""
+48 -3
View File
@@ -81,7 +81,7 @@ class BaseRegularization(object):
"""
mD = self.mapping.deriv(m - self.mref)
r = self.W * ( self.mapping * (m - self.mref) )
return mD.T * ( self.W.T * r )
return mD.T * ( self.W.T * r )
@Utils.timeIt
def eval2Deriv(self, m, v=None):
@@ -196,7 +196,7 @@ class Tikhonov(BaseRegularization):
"""
smoothModel = True #: SMOOTH and SMOOTH_MOD_DIF options
alpha_s = Utils.dependentProperty('_alpha_s', 1e-6, ['_W', '_Ws'], "Smallness weight")
alpha_x = Utils.dependentProperty('_alpha_x', 1.0, ['_W', '_Wx'], "Weight for the first derivative in the x direction")
alpha_y = Utils.dependentProperty('_alpha_y', 1.0, ['_W', '_Wy'], "Weight for the first derivative in the y direction")
@@ -212,7 +212,10 @@ class Tikhonov(BaseRegularization):
def Ws(self):
"""Regularization matrix Ws"""
if getattr(self,'_Ws', None) is None:
self._Ws = Utils.sdiag((self.mesh.vol*self.alpha_s)**0.5)
if self.active == False:
self._Ws = Utils.sdiag((self.mesh.vol*self.alpha_s)**0.5)
elif self.active == True:
self._Ws = Utils.sdiag((self.mesh.vol[self.active_ind]*self.alpha_s)**0.5)
return self._Ws
@property
@@ -272,3 +275,45 @@ class Tikhonov(BaseRegularization):
self._W = sp.vstack(wlist)
return self._W
@Utils.timeIt
def eval(self, m):
if self.smoothModel == True:
r1 = self.W * ( self.mapping * (m) )
r2 = self.Ws * ( self.mapping * (self.mref) )
return 0.5*(r1.dot(r1)+r2.dot(r2))
elif self.smoothModel == False:
r = self.W * ( self.mapping * (m - self.mref) )
return 0.5*r.dot(r)
@Utils.timeIt
def evalDeriv(self, m):
"""
The regularization is:
.. math::
R(m) = \\frac{1}{2}\mathbf{(m-m_\\text{ref})^\\top W^\\top W(m-m_\\text{ref})}
So the derivative is straight forward:
.. math::
R(m) = \mathbf{W^\\top W (m-m_\\text{ref})}
"""
if self.smoothModel == True:
mD1 = self.mapping.deriv(m)
mD2 = self.mapping.deriv(self.mref)
r1 = self.W * ( self.mapping * (m) )
r2 = self.Ws * ( self.mapping * (self.mref) )
out1 = mD1.T * ( self.W.T * r1 )
out2 = mD2.T * ( self.Ws.T * r2 )
out = out1-out2
elif self.smoothModel == False:
mD = self.mapping.deriv(m - self.mref)
r = self.W * ( self.mapping * (m - self.mref) )
out = mD.T * ( self.W.T * r )
return out