Compare commits

...
5 changed files with 447 additions and 238 deletions
+307 -163
View File
@@ -1,4 +1,6 @@
import Utils, numpy as np, scipy.sparse as sp
import Utils
import numpy as np
import scipy.sparse as sp
from scipy.sparse.linalg import LinearOperator
from Tests import checkDerivative
from PropMaps import PropMap, Property
@@ -6,6 +8,7 @@ from numpy.polynomial import polynomial
from scipy.interpolate import UnivariateSpline
import warnings
class IdentityMap(object):
"""
SimPEG Map
@@ -17,10 +20,11 @@ class IdentityMap(object):
Utils.setKwargs(self, **kwargs)
if nP is not None:
assert type(nP) in [int, long], ' Number of parameters must be an integer.'
assert type(nP) in [int, long], 'Number of parameters '
'must be an integer.'
self.mesh = mesh
self._nP = nP
self._nP = nP
@property
def nP(self):
@@ -50,14 +54,14 @@ class IdentityMap(object):
return ('*', self.nP)
return (self.mesh.nC, self.nP)
def _transform(self, m):
"""
Changes the model into the physical property.
.. note::
This can be called by the __mul__ property against a numpy.ndarray.
This can be called by the __mul__ property against a
:meth:numpy.ndarray.
:param numpy.array m: model
:rtype: numpy.array
@@ -81,7 +85,7 @@ class IdentityMap(object):
"""
raise NotImplementedError('The transformInverse is not implemented.')
def deriv(self, m):
def deriv(self, m, v=None):
"""
The derivative of the transformation.
@@ -90,13 +94,16 @@ class IdentityMap(object):
:return: derivative of transformed model
"""
if v is not None:
return v
return sp.identity(self.nP)
def test(self, m=None, **kwargs):
"""Test the derivative of the mapping.
:param numpy.array m: model
:param kwargs: key word arguments of :meth:`SimPEG.Tests.checkDerivative`
:param kwargs: key word arguments of
:meth:`SimPEG.Tests.checkDerivative`
:rtype: bool
:return: passed the test?
@@ -106,26 +113,52 @@ class IdentityMap(object):
m = abs(np.random.rand(self.nP))
if 'plotIt' not in kwargs:
kwargs['plotIt'] = False
return checkDerivative(lambda m : [self * m, self.deriv(m)], m, num=4, **kwargs)
return checkDerivative(lambda m : [self * m, self.deriv(m)], m, num=4,
**kwargs)
def testVec(self, m=None, **kwargs):
"""Test the derivative of the mapping times a vector.
:param numpy.array m: model
:param kwargs: key word arguments of
:meth:`SimPEG.Tests.checkDerivative`
:rtype: bool
:return: passed the test?
"""
print 'Testing %s' % str(self)
if m is None:
m = abs(np.random.rand(self.nP))
if 'plotIt' not in kwargs:
kwargs['plotIt'] = False
return checkDerivative(lambda m: [self*m, lambda x: self.deriv(m, x)],
m, num=4, **kwargs)
def _assertMatchesPair(self, pair):
assert (isinstance(self, pair) or
isinstance(self, ComboMap) and isinstance(self.maps[0], pair)
), "Mapping object must be an instance of a %s class."%(pair.__name__)
isinstance(self, ComboMap) and isinstance(self.maps[0], pair)
), ("Mapping object must be an instance of a %s"
" class."% (pair.__name__))
def __mul__(self, val):
if isinstance(val, IdentityMap):
if not (self.shape[1] == '*' or val.shape[0] == '*') and not self.shape[1] == val.shape[0]:
raise ValueError('Dimension mismatch in %s and %s.' % (str(self), str(val)))
if (not (self.shape[1] == '*' or val.shape[0] == '*') and not
self.shape[1] == val.shape[0]):
raise ValueError('Dimension mismatch in %s and %s.'
% (str(self), str(val)))
return ComboMap([self, val])
elif isinstance(val, np.ndarray):
if not self.shape[1] == '*' and not self.shape[1] == val.shape[0]:
raise ValueError('Dimension mismatch in %s and np.ndarray%s.' % (str(self), str(val.shape)))
raise ValueError('Dimension mismatch in %s and np.ndarray%s.'
% (str(self), str(val.shape)))
return self._transform(val)
raise Exception('Unrecognized data type to multiply. Try a map or a numpy.ndarray!')
raise Exception('Unrecognized data type to multiply. '
'Try a map or a numpy.ndarray!')
def __str__(self):
return "%s(%s,%s)" % (self.__class__.__name__, self.shape[0], self.shape[1])
return "%s(%s,%s)" % (self.__class__.__name__, self.shape[0],
self.shape[1])
class ComboMap(IdentityMap):
@@ -136,11 +169,17 @@ class ComboMap(IdentityMap):
self.maps = []
for ii, m in enumerate(maps):
assert isinstance(m, IdentityMap), 'Unrecognized data type, inherit from an IdentityMap or ComboMap!'
if ii > 0 and not (self.shape[1] == '*' or m.shape[0] == '*') and not self.shape[1] == m.shape[0]:
assert isinstance(m, IdentityMap), "Unrecognized data type, "
"inherit from an IdentityMap or ComboMap!"
if (ii > 0 and not (self.shape[1] == '*' or m.shape[0] == '*') and
not self.shape[1] == m.shape[0]):
prev = self.maps[-1]
errArgs = (prev.__class__.__name__, prev.shape[0], prev.shape[1], m.__class__.__name__, m.shape[0], m.shape[1])
raise ValueError('Dimension mismatch in map[%s] (%s, %s) and map[%s] (%s, %s).' % errArgs)
errArgs = (prev.__class__.__name__, prev.shape[0],
prev.shape[1], m.__class__.__name__, m.shape[0],
m.shape[1])
raise ValueError('Dimension mismatch in map[%s] (%s, %s) '
'and map[%s] (%s, %s).' % errArgs)
if isinstance(m, ComboMap):
self.maps += m.maps
@@ -164,8 +203,13 @@ class ComboMap(IdentityMap):
m = map_i * m
return m
def deriv(self, m):
deriv = 1
def deriv(self, m, v=None):
if v is not None:
deriv = v
else:
deriv = 1
mi = m
for map_i in reversed(self.maps):
deriv = map_i.deriv(mi) * deriv
@@ -212,8 +256,7 @@ class ExpMap(IdentityMap):
"""
return np.log(Utils.mkvc(D))
def deriv(self, m):
def deriv(self, m, v=None):
"""
:param numpy.array m: model
:rtype: scipy.sparse.csr_matrix
@@ -236,7 +279,11 @@ class ExpMap(IdentityMap):
\\frac{\partial \exp{m}}{\partial m} = \\text{sdiag}(\exp{m})
"""
return Utils.sdiag(np.exp(Utils.mkvc(m)))
deriv = Utils.sdiag(np.exp(Utils.mkvc(m)))
if v is not None:
return deriv * v
return deriv
class ReciprocalMap(IdentityMap):
"""
@@ -253,10 +300,12 @@ class ReciprocalMap(IdentityMap):
def inverse(self, D):
return 1.0 / Utils.mkvc(m)
def deriv(self, m):
def deriv(self, m, v=None):
# TODO: if this is a tensor, you might have a problem.
return Utils.sdiag( - Utils.mkvc(m)**(-2) )
deriv = Utils.sdiag( - Utils.mkvc(m)**(-2) )
if v is not None:
return deriv * v
return deriv
class LogMap(IdentityMap):
@@ -265,13 +314,13 @@ class LogMap(IdentityMap):
If \\(p\\) is the physical property and \\(m\\) is the model, then
..math::
.. math::
p = \\log(m)
and
..math::
.. math::
m = \\exp(p)
@@ -286,17 +335,20 @@ class LogMap(IdentityMap):
def _transform(self, m):
return np.log(Utils.mkvc(m))
def deriv(self, m):
def deriv(self, m, v=None):
mod = Utils.mkvc(m)
deriv = np.zeros(mod.shape)
tol = 1e-16 # zero
ind = np.greater_equal(np.abs(mod),tol)
ind = np.greater_equal(np.abs(mod), tol)
deriv[ind] = 1.0/mod[ind]
if v is not None:
return Utils.sdiag(deriv)*v
return Utils.sdiag(deriv)
def inverse(self, m):
return np.exp(Utils.mkvc(m))
class SurjectFull(IdentityMap):
"""
SurjectFull
@@ -305,8 +357,8 @@ class SurjectFull(IdentityMap):
full model space.
"""
def __init__(self,mesh,**kwargs):
IdentityMap.__init__(self, mesh,**kwargs)
def __init__(self, mesh, **kwargs):
IdentityMap.__init__(self, mesh, **kwargs)
@property
def nP(self):
@@ -318,22 +370,28 @@ class SurjectFull(IdentityMap):
:rtype: numpy.array
:return: transformed model
"""
return np.ones(self.mesh.nC)*m
return np.ones(self.mesh.nC) * m
def deriv(self, m):
def deriv(self, m, v=None):
"""
:param numpy.array m: model
:rtype: numpy.array
:return: derivative of transformed model
"""
return np.ones([self.mesh.nC,1])
deriv = np.ones([self.mesh.nC,1])
if v is not None:
return deriv * v
return deriv
class FullMap(SurjectFull):
def __init__(self,mesh,**kwargs):
"""FullMap is depreciated. Use SurjectVertical1DMap instead.
"""
def __init__(self, mesh, **kwargs):
warnings.warn(
"`FullMap` is deprecated and will be removed in future versions. Use `SurjectFull` instead",
FutureWarning)
SurjectFull.__init__(self,mesh,**kwargs)
SurjectFull.__init__(self, mesh, **kwargs)
class SurjectVertical1D(IdentityMap):
"""SurjectVertical1DMap
@@ -363,7 +421,7 @@ class SurjectVertical1D(IdentityMap):
repNum = self.mesh.vnC[:self.mesh.dim-1].prod()
return Utils.mkvc(m).repeat(repNum)
def deriv(self, m):
def deriv(self, m, v=None):
"""
:param numpy.array m: model
:rtype: scipy.sparse.csr_matrix
@@ -374,14 +432,22 @@ class SurjectVertical1D(IdentityMap):
(np.ones(repNum),
(range(repNum), np.zeros(repNum))
), shape=(repNum, 1))
return sp.kron(sp.identity(self.nP), repVec)
deriv = sp.kron(sp.identity(self.nP), repVec)
if v is not None:
return deriv * v
return deriv
class Vertical1DMap(SurjectVertical1D):
def __init__(self,mesh,**kwargs):
"""
Vertical1DMap is depreciated. Use SurjectVertical1D instead.
"""
def __init__(self, mesh, **kwargs):
warnings.warn(
"`Vertical1DMap` is deprecated and will be removed in future versions. Use `SurjectVertical1D` instead",
FutureWarning)
SurjectVertical1D.__init__(self,mesh,**kwargs)
SurjectVertical1D.__init__(self, mesh, **kwargs)
class Surject2Dto3D(IdentityMap):
"""Map2Dto3D
@@ -390,12 +456,12 @@ class Surject2Dto3D(IdentityMap):
3D model space.
"""
normal = 'Y' #: The normal
normal = 'Y' #: The normal
def __init__(self, mesh, **kwargs):
assert mesh.dim == 3, 'Only works for a 3D Mesh'
IdentityMap.__init__(self, mesh, **kwargs)
assert self.normal in ['X','Y','Z'], 'For now, only "Y" normal is supported'
assert self.normal in ['X', 'Y', 'Z'], 'For now, only "Y" normal is supported'
@property
def nP(self):
@@ -424,7 +490,7 @@ class Surject2Dto3D(IdentityMap):
elif self.normal == 'X':
return Utils.mkvc(m.reshape(self.mesh.vnC[[1,2]], order='F')[np.newaxis,:,:].repeat(self.mesh.nCx,axis=0))
def deriv(self, m):
def deriv(self, m, v=None):
"""
:param numpy.array m: model
:rtype: scipy.sparse.csr_matrix
@@ -436,19 +502,25 @@ class Surject2Dto3D(IdentityMap):
(np.ones(nC),
(range(nC), inds)
), shape=(nC, nP))
if v is not None:
return P * v
return P
class Map2Dto3D(Surject2Dto3D):
def __init__(self,mesh,**kwargs):
"""Map2Dto3D is depreciated. Use Surject2Dto3D instead
"""
def __init__(self, mesh, **kwargs):
warnings.warn(
"`Map2Dto3D` is deprecated and will be removed in future versions. Use `Surject2Dto3D` instead",
FutureWarning)
Surject2Dto3D.__init__(self,mesh,**kwargs)
Surject2Dto3D.__init__(self, mesh, **kwargs)
class Mesh2Mesh(IdentityMap):
"""
Takes a model on one mesh are translates it to another mesh.
"""
def __init__(self, meshes, **kwargs):
@@ -461,7 +533,7 @@ class Mesh2Mesh(IdentityMap):
self.mesh = meshes[0]
self.mesh2 = meshes[1]
self.P = self.mesh2.getInterpolationMat(self.mesh.gridCC,'CC',zerosOutside=True)
self.P = self.mesh2.getInterpolationMat(self.mesh.gridCC, 'CC', zerosOutside=True)
@property
def shape(self):
@@ -472,9 +544,13 @@ class Mesh2Mesh(IdentityMap):
def nP(self):
"""Number of parameters in the model."""
return self.mesh2.nC
def _transform(self, m):
return self.P*m
def deriv(self, m):
return self.P * m
def deriv(self, m, v=None):
if v is not None:
return self.P * v
return self.P
@@ -484,9 +560,9 @@ class InjectActiveCells(IdentityMap):
"""
indActive = None #: Active Cells
valInactive = None #: Values of inactive Cells
nC = None #: Number of cells in the full model
indActive = None #: Active Cells
valInactive = None #: Values of inactive Cells
nC = None #: Number of cells in the full model
def __init__(self, mesh, indActive, valInactive, nC=None):
self.mesh = mesh
@@ -494,7 +570,7 @@ class InjectActiveCells(IdentityMap):
self.nC = nC or mesh.nC
if indActive.dtype is not bool:
z = np.zeros(self.nC,dtype=bool)
z = np.zeros(self.nC, dtype=bool)
z[indActive] = True
indActive = z
self.indActive = indActive
@@ -504,11 +580,13 @@ class InjectActiveCells(IdentityMap):
else:
self.valInactive = np.ones(self.nC)
self.valInactive[self.indInactive] = valInactive.copy()
self.valInactive[self.indActive] = 0
inds = np.nonzero(self.indActive)[0]
self.P = sp.csr_matrix((np.ones(inds.size),(inds, range(inds.size))), shape=(self.nC, self.nP))
self.P = sp.csr_matrix((np.ones(inds.size), (inds, range(inds.size))),
shape=(self.nC, self.nP)
)
@property
def shape(self):
@@ -520,18 +598,25 @@ class InjectActiveCells(IdentityMap):
return self.indActive.sum()
def _transform(self, m):
return self.P*m + self.valInactive
return self.P * m + self.valInactive
def inverse(self, D):
return self.P.T*D
def deriv(self, m):
def deriv(self, m, v=None):
if v is not None:
return self.P * v
return self.P
class ActiveCells(InjectActiveCells):
"""ActiveCells is depreciated. Use InjectActiveCells instead.
"""
def __init__(self, mesh, indActive, valInactive, nC=None):
warnings.warn(
"`ActiveCells` is deprecated and will be removed in future versions. Use `InjectActiveCells` instead",
"`ActiveCells` is deprecated and will be removed in future "
"versions. Use `InjectActiveCells` instead",
FutureWarning)
InjectActiveCells.__init__(self, mesh, indActive, valInactive, nC)
@@ -539,11 +624,10 @@ class ActiveCells(InjectActiveCells):
class Weighting(IdentityMap):
"""
Model weight parameters.
"""
weights = None #: Active Cells
nC = None #: Number of cells in the full model
weights = None #: Active Cells
nC = None #: Number of cells in the full model
def __init__(self, mesh, weights=None, nC=None):
self.mesh = mesh
@@ -573,7 +657,9 @@ class Weighting(IdentityMap):
Pinv = Utils.sdiag(self.weights**(-1.))
return Pinv*D
def deriv(self, m):
def deriv(self, m, v=None):
if v is not None:
return self.P * v
return self.P
@@ -601,26 +687,32 @@ class ComplexMap(IdentityMap):
nC = self.mesh.nC
return m[:nC] + m[nC:]*1j
def deriv(self, m):
def deriv(self, m, v=None):
nC = self.nP/2
shp = (nC, nC*2)
def fwd(v):
return v[:nC] + v[nC:]*1j
def adj(v):
return np.r_[v.real,v.imag]
return LinearOperator(shp,matvec=fwd,rmatvec=adj)
return np.r_[v.real, v.imag]
if v is not None:
return LinearOperator(shp, matvec=fwd, rmatvec=adj) * v
return LinearOperator(shp, matvec=fwd, rmatvec=adj)
inverse = deriv
class CircleMap(IdentityMap):
"""CircleMap
class ParametricCircleMap(IdentityMap):
"""ParametricCircleMap
Parameterize the model space using a circle in a wholespace.
..math::
\sigma(m) = \sigma_1 + (\sigma_2 - \sigma_1)\left(\\arctan\left(100*\sqrt{(\\vec{x}-x_0)^2 + (\\vec{y}-y_0)}-r\\right) \pi^{-1} + 0.5\\right)
\sigma(m) = \sigma_1 + (\sigma_2 - \sigma_1)\left(
\\arctan\left(100*\sqrt{(\\vec{x}-x_0)^2 + (\\vec{y}-y_0)}-r
\\right) \pi^{-1} + 0.5\\right)
Define the model as:
@@ -629,46 +721,69 @@ class CircleMap(IdentityMap):
m = [\sigma_1, \sigma_2, x_0, y_0, r]
"""
def __init__(self, mesh, logSigma=True):
assert mesh.dim == 2, "Working for a 2D mesh only right now. But it isn't that hard to change.. :)"
IdentityMap.__init__(self, mesh)
self.logSigma = logSigma
slope = 1e-1
def __init__(self, mesh, logSigma=True):
assert mesh.dim == 2, "Working for a 2D mesh only right now. "
"But it isn't that hard to change.. :)"
IdentityMap.__init__(self, mesh)
# TODO: this should be done through a composition with and ExpMap
self.logSigma = logSigma
@property
def nP(self):
return 5
def _transform(self, m):
a = self.slope
sig1,sig2,x,y,r = m[0],m[1],m[2],m[3],m[4]
sig1, sig2, x, y, r = m[0], m[1], m[2], m[3], m[4]
if self.logSigma:
sig1, sig2 = np.exp(sig1), np.exp(sig2)
X = self.mesh.gridCC[:,0]
Y = self.mesh.gridCC[:,1]
return sig1 + (sig2 - sig1)*(np.arctan(a*(np.sqrt((X-x)**2 + (Y-y)**2) - r))/np.pi + 0.5)
X = self.mesh.gridCC[:, 0]
Y = self.mesh.gridCC[:, 1]
return sig1 + (sig2 - sig1)*(np.arctan(a*(np.sqrt((X-x)**2 +
(Y-y)**2) - r))/np.pi + 0.5)
def deriv(self, m):
def deriv(self, m, v=None):
a = self.slope
sig1,sig2,x,y,r = m[0],m[1],m[2],m[3],m[4]
sig1, sig2, x, y, r = m[0], m[1], m[2], m[3], m[4]
if self.logSigma:
sig1, sig2 = np.exp(sig1), np.exp(sig2)
X = self.mesh.gridCC[:,0]
Y = self.mesh.gridCC[:,1]
X = self.mesh.gridCC[:, 0]
Y = self.mesh.gridCC[:, 1]
if self.logSigma:
g1 = -(np.arctan(a*(-r + np.sqrt((X - x)**2 + (Y - y)**2)))/np.pi + 0.5)*sig1 + sig1
g2 = (np.arctan(a*(-r + np.sqrt((X - x)**2 + (Y - y)**2)))/np.pi + 0.5)*sig2
g1 = -(np.arctan(a*(-r + np.sqrt((X - x)**2 + (Y - y)**2)))/np.pi +
0.5)*sig1 + sig1
g2 = (np.arctan(a*(-r + np.sqrt((X - x)**2 + (Y - y)**2)))/np.pi +
0.5)*sig2
else:
g1 = -(np.arctan(a*(-r + np.sqrt((X - x)**2 + (Y - y)**2)))/np.pi + 0.5) + 1.0
g2 = (np.arctan(a*(-r + np.sqrt((X - x)**2 + (Y - y)**2)))/np.pi + 0.5)
g1 = -(np.arctan(a*(-r + np.sqrt((X - x)**2 + (Y - y)**2)))/np.pi +
0.5) + 1.0
g2 = (np.arctan(a*(-r + np.sqrt((X - x)**2 + (Y - y)**2)))/np.pi +
0.5)
g3 = a*(-X + x)*(-sig1 + sig2)/(np.pi*(a**2*(-r + np.sqrt((X - x)**2 + (Y - y)**2))**2 + 1)*np.sqrt((X - x)**2 + (Y - y)**2))
g4 = a*(-Y + y)*(-sig1 + sig2)/(np.pi*(a**2*(-r + np.sqrt((X - x)**2 + (Y - y)**2))**2 + 1)*np.sqrt((X - x)**2 + (Y - y)**2))
g5 = -a*(-sig1 + sig2)/(np.pi*(a**2*(-r + np.sqrt((X - x)**2 + (Y - y)**2))**2 + 1))
return sp.csr_matrix(np.c_[g1,g2,g3,g4,g5])
if v is not None:
return sp.csr_matrix(np.c_[g1, g2, g3, g4, g5]) * v
return sp.csr_matrix(np.c_[g1, g2, g3, g4, g5])
class PolyMap(IdentityMap):
class CircleMap(ParametricCircleMap):
"""CircleMap is depreciated. Use ParametricCircleMap instead.
"""
def __init__(self, mesh, logSigma=True):
warnings.warn(
"`CircleMap` is deprecated and will be removed in future "
"versions. Use `ParametricCircleMap` instead",
FutureWarning)
ParametricCircleMap.__init__(self, mesh, logSigma)
class ParametricPolyMap(IdentityMap):
"""PolyMap
@@ -687,7 +802,8 @@ class PolyMap(IdentityMap):
Can take in an actInd vector to account for topography.
"""
def __init__(self, mesh, order, logSigma=True, normal='X', actInd = None):
def __init__(self, mesh, order, logSigma=True, normal='X', actInd=None):
IdentityMap.__init__(self, mesh)
self.logSigma = logSigma
self.order = order
@@ -712,78 +828,88 @@ class PolyMap(IdentityMap):
if np.isscalar(self.order):
nP = self.order+3
else:
nP =(self.order[0]+1)*(self.order[1]+1)+2
nP = (self.order[0]+1)*(self.order[1]+1)+2
return nP
def _transform(self, m):
# Set model parameters
alpha = self.slope
sig1,sig2 = m[0],m[1]
sig1, sig2 = m[0], m[1]
c = m[2:]
if self.logSigma:
sig1, sig2 = np.exp(sig1), np.exp(sig2)
#2D
# 2D
if self.mesh.dim == 2:
X = self.mesh.gridCC[self.actInd,0]
Y = self.mesh.gridCC[self.actInd,1]
X = self.mesh.gridCC[self.actInd, 0]
Y = self.mesh.gridCC[self.actInd, 1]
if self.normal =='X':
f = polynomial.polyval(Y, c) - X
elif self.normal =='Y':
f = polynomial.polyval(X, c) - Y
else:
raise(Exception("Input for normal = X or Y or Z"))
#3D
# 3D
elif self.mesh.dim == 3:
X = self.mesh.gridCC[self.actInd,0]
Y = self.mesh.gridCC[self.actInd,1]
Z = self.mesh.gridCC[self.actInd,2]
if self.normal =='X':
f = polynomial.polyval2d(Y, Z, c.reshape((self.order[0]+1,self.order[1]+1))) - X
elif self.normal =='Y':
f = polynomial.polyval2d(X, Z, c.reshape((self.order[0]+1,self.order[1]+1))) - Y
elif self.normal =='Z':
f = polynomial.polyval2d(X, Y, c.reshape((self.order[0]+1,self.order[1]+1))) - Z
X = self.mesh.gridCC[self.actInd, 0]
Y = self.mesh.gridCC[self.actInd, 1]
Z = self.mesh.gridCC[self.actInd, 2]
if self.normal == 'X':
f = (polynomial.polyval2d(Y, Z, c.reshape((self.order[0]+1,
self.order[1]+1))) - X)
elif self.normal == 'Y':
f = (polynomial.polyval2d(X, Z, c.reshape((self.order[0]+1,
self.order[1]+1))) - Y)
elif self.normal == 'Z':
f = (polynomial.polyval2d(X, Y, c.reshape((self.order[0]+1,
self.order[1]+1))) - Z)
else:
raise(Exception("Input for normal = X or Y or Z"))
else:
raise(Exception("Only supports 2D"))
return sig1+(sig2-sig1)*(np.arctan(alpha*f)/np.pi+0.5)
def deriv(self, m):
def deriv(self, m, v=None):
alpha = self.slope
sig1,sig2, c = m[0],m[1],m[2:]
sig1, sig2, c = m[0], m[1], m[2:]
if self.logSigma:
sig1, sig2 = np.exp(sig1), np.exp(sig2)
#2D
if self.mesh.dim == 2:
X = self.mesh.gridCC[self.actInd,0]
Y = self.mesh.gridCC[self.actInd,1]
if self.normal =='X':
# 2D
if self.mesh.dim == 2:
X = self.mesh.gridCC[self.actInd, 0]
Y = self.mesh.gridCC[self.actInd, 1]
if self.normal == 'X':
f = polynomial.polyval(Y, c) - X
V = polynomial.polyvander(Y, len(c)-1)
elif self.normal =='Y':
elif self.normal == 'Y':
f = polynomial.polyval(X, c) - Y
V = polynomial.polyvander(X, len(c)-1)
else:
raise(Exception("Input for normal = X or Y or Z"))
#3D
elif self.mesh.dim == 3:
X = self.mesh.gridCC[self.actInd,0]
Y = self.mesh.gridCC[self.actInd,1]
Z = self.mesh.gridCC[self.actInd,2]
if self.normal =='X':
f = polynomial.polyval2d(Y, Z, c.reshape((self.order[0]+1,self.order[1]+1))) - X
# 3D
elif self.mesh.dim == 3:
X = self.mesh.gridCC[self.actInd, 0]
Y = self.mesh.gridCC[self.actInd, 1]
Z = self.mesh.gridCC[self.actInd, 2]
if self.normal == 'X':
f = (polynomial.polyval2d(Y, Z, c.reshape((self.order[0]+1,
self.order[1]+1))) - X)
V = polynomial.polyvander2d(Y, Z, self.order)
elif self.normal =='Y':
f = polynomial.polyval2d(X, Z, c.reshape((self.order[0]+1,self.order[1]+1))) - Y
elif self.normal == 'Y':
f = (polynomial.polyval2d(X, Z, c.reshape((self.order[0]+1,
self.order[1]+1))) - Y)
V = polynomial.polyvander2d(X, Z, self.order)
elif self.normal =='Z':
f = polynomial.polyval2d(X, Y, c.reshape((self.order[0]+1,self.order[1]+1))) - Z
elif self.normal == 'Z':
f = (polynomial.polyval2d(X, Y, c.reshape((self.order[0]+1,
self.order[1]+1))) - Z)
V = polynomial.polyvander2d(X, Y, self.order)
else:
raise(Exception("Input for normal = X or Y or Z"))
@@ -797,13 +923,17 @@ class PolyMap(IdentityMap):
g3 = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*V
return sp.csr_matrix(np.c_[g1,g2,g3])
if v is not None:
return sp.csr_matrix(np.c_[g1, g2, g3]) * v
return sp.csr_matrix(np.c_[g1, g2, g3])
class SplineMap(IdentityMap):
class ParametricSplineMap(IdentityMap):
"""SplineMap
Parameterize the boundary of two geological units using a spline interpolation
Parameterize the boundary of two geological units using
a spline interpolation
..math::
@@ -816,7 +946,10 @@ class SplineMap(IdentityMap):
m = [\sigma_1, \sigma_2, y]
"""
def __init__(self, mesh, pts, ptsv=None,order=3, logSigma=True, normal='X'):
slope = 1e4
def __init__(self, mesh, pts, ptsv=None, order=3, logSigma=True, normal='X'):
IdentityMap.__init__(self, mesh)
self.logSigma = logSigma
self.order = order
@@ -826,7 +959,6 @@ class SplineMap(IdentityMap):
self.ptsv = ptsv
self.spl = None
slope = 1e4
@property
def nP(self):
if self.mesh.dim == 2:
@@ -839,18 +971,18 @@ class SplineMap(IdentityMap):
def _transform(self, m):
# Set model parameters
alpha = self.slope
sig1,sig2 = m[0],m[1]
sig1, sig2 = m[0], m[1]
c = m[2:]
if self.logSigma:
sig1, sig2 = np.exp(sig1), np.exp(sig2)
#2D
# 2D
if self.mesh.dim == 2:
X = self.mesh.gridCC[:,0]
Y = self.mesh.gridCC[:,1]
X = self.mesh.gridCC[:, 0]
Y = self.mesh.gridCC[:, 1]
self.spl = UnivariateSpline(self.pts, c, k=self.order, s=0)
if self.normal =='X':
if self.normal == 'X':
f = self.spl(Y) - X
elif self.normal =='Y':
elif self.normal == 'Y':
f = self.spl(X) - Y
else:
raise(Exception("Input for normal = X or Y or Z"))
@@ -862,18 +994,18 @@ class SplineMap(IdentityMap):
# Using 2D interpolation is possible
elif self.mesh.dim == 3:
X = self.mesh.gridCC[:,0]
Y = self.mesh.gridCC[:,1]
Z = self.mesh.gridCC[:,2]
X = self.mesh.gridCC[:, 0]
Y = self.mesh.gridCC[:, 1]
Z = self.mesh.gridCC[:, 2]
npts = np.size(self.pts)
if np.mod(c.size, 2):
raise(Exception("Put even points!"))
self.spl = {"splb":UnivariateSpline(self.pts, c[:npts], k=self.order, s=0),
"splt":UnivariateSpline(self.pts, c[npts:], k=self.order, s=0)}
self.spl = {"splb": UnivariateSpline(self.pts, c[:npts], k=self.order, s=0),
"splt": UnivariateSpline(self.pts, c[npts:], k=self.order, s=0)}
if self.normal =='X':
if self.normal == 'X':
zb = self.ptsv[0]
zt = self.ptsv[1]
flines = (self.spl["splt"](Y)-self.spl["splb"](Y))*(Z-zb)/(zt-zb) + self.spl["splb"](Y)
@@ -885,30 +1017,29 @@ class SplineMap(IdentityMap):
else:
raise(Exception("Only supports 2D and 3D"))
return sig1+(sig2-sig1)*(np.arctan(alpha*f)/np.pi+0.5)
def deriv(self, m):
def deriv(self, m, v=None):
alpha = self.slope
sig1,sig2, c = m[0],m[1],m[2:]
sig1, sig2, c = m[0], m[1], m[2:]
if self.logSigma:
sig1, sig2 = np.exp(sig1), np.exp(sig2)
#2D
if self.mesh.dim == 2:
X = self.mesh.gridCC[:,0]
Y = self.mesh.gridCC[:,1]
X = self.mesh.gridCC[:, 0]
Y = self.mesh.gridCC[:, 1]
if self.normal =='X':
if self.normal == 'X':
f = self.spl(Y) - X
elif self.normal =='Y':
elif self.normal == 'Y':
f = self.spl(X) - Y
else:
raise(Exception("Input for normal = X or Y or Z"))
#3D
elif self.mesh.dim == 3:
X = self.mesh.gridCC[:,0]
Y = self.mesh.gridCC[:,1]
Z = self.mesh.gridCC[:,2]
X = self.mesh.gridCC[:, 0]
Y = self.mesh.gridCC[:, 1]
Z = self.mesh.gridCC[:, 2]
if self.normal =='X':
zb = self.ptsv[0]
zt = self.ptsv[1]
@@ -926,10 +1057,9 @@ class SplineMap(IdentityMap):
g1 = -(np.arctan(alpha*f)/np.pi + 0.5) + 1.0
g2 = (np.arctan(alpha*f)/np.pi + 0.5)
if self.mesh.dim ==2:
if self.mesh.dim == 2:
g3 = np.zeros((self.mesh.nC, self.npts))
if self.normal =='Y':
if self.normal == 'Y':
# Here we use perturbation to compute sensitivity
# TODO: bit more generalization of this ...
# Modfications for X and Z directions ...
@@ -944,11 +1074,11 @@ class SplineMap(IdentityMap):
spla = UnivariateSpline(self.pts, ca, k=self.order, s=0)
splb = UnivariateSpline(self.pts, cb, k=self.order, s=0)
fderiv = (spla(X)-splb(X))/(2*dy)
g3[:,i] = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*fderiv
g3[:, i] = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*fderiv
elif self.mesh.dim==3:
elif self.mesh.dim == 3:
g3 = np.zeros((self.mesh.nC, self.npts*2))
if self.normal =='X':
if self.normal == 'X':
# Here we use perturbation to compute sensitivity
for i in range(self.npts*2):
ctemp = c[i]
@@ -958,26 +1088,40 @@ class SplineMap(IdentityMap):
dy = self.mesh.hy[ind]*1.5
ca[i] = ctemp+dy
cb[i] = ctemp-dy
#treat bottom boundary
if i< self.npts:
# treat bottom boundary
if i < self.npts:
splba = UnivariateSpline(self.pts, ca[:self.npts], k=self.order, s=0)
splbb = UnivariateSpline(self.pts, cb[:self.npts], k=self.order, s=0)
flinesa = (self.spl["splt"](Y)-splba(Y))*(Z-zb)/(zt-zb) + splba(Y) - X
flinesb = (self.spl["splt"](Y)-splbb(Y))*(Z-zb)/(zt-zb) + splbb(Y) - X
#treat top boundary
# treat top boundary
else:
splta = UnivariateSpline(self.pts, ca[self.npts:], k=self.order, s=0)
spltb = UnivariateSpline(self.pts, ca[self.npts:], k=self.order, s=0)
flinesa = (self.spl["splt"](Y)-splta(Y))*(Z-zb)/(zt-zb) + splta(Y) - X
flinesb = (self.spl["splt"](Y)-spltb(Y))*(Z-zb)/(zt-zb) + spltb(Y) - X
fderiv = (flinesa-flinesb)/(2*dy)
g3[:,i] = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*fderiv
g3[:, i] = Utils.sdiag(alpha*(sig2-sig1)/(1.+(alpha*f)**2)/np.pi)*fderiv
else :
raise(Exception("Not Implemented for Y and Z, your turn :)"))
return sp.csr_matrix(np.c_[g1,g2,g3])
if v is not None:
return sp.csr_matrix(np.c_[g1, g2, g3]) * v
return sp.csr_matrix(np.c_[g1, g2, g3])
class SplineMap(ParametricSplineMap):
"""SplineMap is depreciated. Use ParametricSplineMap instead.
"""
def __init__(self, mesh, pts, ptsv=None, order=3, logSigma=True,
normal='X'):
warnings.warn(
"`SplineMap` is deprecated and will be removed in future "
"versions. Use `ParametricSplineMap` instead",
FutureWarning)
ParametricSplineMap.__init__(self, mesh, pts, ptsv, order, logSigma,
normal)
+122 -64
View File
@@ -2,39 +2,71 @@ import numpy as np
import unittest
from SimPEG import *
from scipy.sparse.linalg import dsolve
import inspect
TOL = 1e-14
MAPS_TO_TEST_2D = ["CircleMap", "ComplexMap", "ExpMap", "IdentityMap", "SurjectVertical1D", "Weighting", "SurjectFull","FullMap"]
MAPS_TO_TEST_3D = [ "ComplexMap", "ExpMap", "IdentityMap", "SurjectVertical1D", "Weighting", "SurjectFull","FullMap"]
MAPS_TO_EXCLUDE_2D = ["ComboMap", "ActiveCells", "InjectActiveCells"]
MAPS_TO_EXCLUDE_3D = ["ComboMap", "ActiveCells", "InjectActiveCells",
"CircleMap"]
MAPS_TO_TEST_INVERSE = ["ExpMap"]
class MapTests(unittest.TestCase):
def setUp(self):
maps2test2D = [M for M in dir(Maps) if M not in MAPS_TO_EXCLUDE_2D]
maps2test3D = [M for M in dir(Maps) if M not in MAPS_TO_EXCLUDE_3D]
self.maps2test2D = [getattr(Maps, m) for m in maps2test2D if
inspect.isclass(getattr(Maps, M)) and
issubclass(getattr(Maps, M), Maps.IdentityMap)]
self.maps2test3D = [getattr(Maps, m) for m in maps2test3D if
inspect.isclass(getattr(Maps, M)) and
issubclass(getattr(Maps, M), Maps.IdentityMap)]
a = np.array([1, 1, 1])
b = np.array([1, 2])
self.mesh2 = Mesh.TensorMesh([a, b], x0=np.array([3, 5]))
self.mesh3 = Mesh.TensorMesh([a, b, [3,4]], x0=np.array([3, 5, 2]))
self.mesh3 = Mesh.TensorMesh([a, b, [3, 4]], x0=np.array([3, 5, 2]))
self.mesh22 = Mesh.TensorMesh([b, a], x0=np.array([3, 5]))
def test_transforms2D(self):
for M in MAPS_TO_TEST_2D:
maps = getattr(Maps, M)(self.mesh2)
self.assertTrue(maps.test())
for M in self.maps2test2D:
self.assertTrue(M.test())
def test_transforms2Dvec(self):
for M in self.maps2test2D:
self.assertTrue(M.testVec())
def test_transforms3D(self):
for M in MAPS_TO_TEST_3D:
maps = getattr(Maps, M)(self.mesh3)
self.assertTrue(maps.test())
for M in self.maps2test3D:
self.assertTrue(M.test())
def test_transforms3Dvec(self):
for M in self.maps2test3D:
self.assertTrue(M.test())
def test_transforms_logMap_reciprocalMap(self):
# Note that log/reciprocal maps can be kinda finicky, so we are being explicit about the random seed.
v2 = np.r_[ 0.40077291, 0.14410044, 0.58452314, 0.96323738, 0.01198519, 0.79754415]
dv2 = np.r_[ 0.80653921, 0.13132446, 0.4901117, 0.03358737, 0.65473762, 0.44252488]
v3 = np.r_[ 0.96084865, 0.34385186, 0.39430044, 0.81671285, 0.65929109, 0.2235217, 0.87897526, 0.5784033, 0.96876393, 0.63535864, 0.84130763, 0.22123854]
dv3 = np.r_[ 0.96827838, 0.26072111, 0.45090749, 0.10573893, 0.65276365, 0.15646586, 0.51679682, 0.23071984, 0.95106218, 0.14201845, 0.25093564, 0.3732866 ]
# Note that log/reciprocal maps can be kinda finicky, so we are being
# explicit about the random seed.
v2 = np.r_[0.40077291, 0.14410044, 0.58452314, 0.96323738, 0.01198519,
0.79754415]
dv2 = np.r_[0.80653921, 0.13132446, 0.4901117, 0.03358737, 0.65473762,
0.44252488]
v3 = np.r_[0.96084865, 0.34385186, 0.39430044, 0.81671285, 0.65929109,
0.2235217, 0.87897526, 0.5784033, 0.96876393, 0.63535864,
0.84130763, 0.22123854]
dv3 = np.r_[0.96827838, 0.26072111, 0.45090749, 0.10573893,
0.65276365, 0.15646586, 0.51679682, 0.23071984,
0.95106218, 0.14201845, 0.25093564, 0.3732866 ]
maps = Maps.LogMap(self.mesh2)
self.assertTrue(maps.test(v2, dx=dv2))
maps = Maps.LogMap(self.mesh3)
@@ -49,100 +81,126 @@ class MapTests(unittest.TestCase):
maps = Maps.Mesh2Mesh([self.mesh22, self.mesh2])
self.assertTrue(maps.test())
def test_Mesh2MeshMapVec(self):
maps = Maps.Mesh2Mesh([self.mesh22, self.mesh2])
self.assertTrue(maps.testVec())
def test_mapMultiplication(self):
M = Mesh.TensorMesh([2,3])
M = Mesh.TensorMesh([2, 3])
expMap = Maps.ExpMap(M)
vertMap = Maps.SurjectVertical1D(M)
combo = expMap*vertMap
m = np.arange(3.0)
t_true = np.exp(np.r_[0,0,1,1,2,2.])
self.assertLess(np.linalg.norm((combo * m)-t_true,np.inf),TOL)
self.assertLess(np.linalg.norm((expMap * vertMap * m)-t_true,np.inf),TOL)
self.assertLess(np.linalg.norm(expMap * (vertMap * m)-t_true,np.inf),TOL)
self.assertLess(np.linalg.norm((expMap * vertMap) * m-t_true,np.inf),TOL)
#Try making a model
t_true = np.exp(np.r_[0, 0, 1, 1, 2, 2.])
self.assertLess(np.linalg.norm((combo * m) - t_true, np.inf), TOL)
self.assertLess(np.linalg.norm((expMap * vertMap * m)-t_true, np.inf),
TOL)
self.assertLess(np.linalg.norm(expMap * (vertMap * m)-t_true, np.inf),
TOL)
self.assertLess(np.linalg.norm((expMap * vertMap) * m-t_true, np.inf),
TOL)
# Try making a model
mod = Models.Model(m, mapping=combo)
# print mod.transform
# import matplotlib.pyplot as plt
# plt.colorbar(M.plotImage(mod.transform)[0])
# plt.show()
self.assertLess(np.linalg.norm(mod.transform-t_true,np.inf),TOL)
self.assertLess(np.linalg.norm(mod.transform - t_true, np.inf), TOL)
self.assertRaises(Exception,Models.Model,np.r_[1.0],mapping=combo)
self.assertRaises(Exception, Models.Model, np.r_[1.0], mapping=combo)
self.assertRaises(ValueError, lambda: combo * (vertMap * expMap))
self.assertRaises(ValueError, lambda: (combo * vertMap) * expMap)
self.assertRaises(ValueError, lambda: vertMap * expMap)
self.assertRaises(ValueError, lambda: expMap * np.ones(100))
self.assertRaises(ValueError, lambda: expMap * np.ones((100.0,1)))
self.assertRaises(ValueError, lambda: expMap * np.ones((100.0,5)))
self.assertRaises(ValueError, lambda: expMap * np.ones((100.0, 1)))
self.assertRaises(ValueError, lambda: expMap * np.ones((100.0, 5)))
self.assertRaises(ValueError, lambda: combo * np.ones(100))
self.assertRaises(ValueError, lambda: combo * np.ones((100.0,1)))
self.assertRaises(ValueError, lambda: combo * np.ones((100.0,5)))
self.assertRaises(ValueError, lambda: combo * np.ones((100.0, 1)))
self.assertRaises(ValueError, lambda: combo * np.ones((100.0, 5)))
def test_activeCells(self):
M = Mesh.TensorMesh([2,4],'0C')
M = Mesh.TensorMesh([2, 4], '0C')
expMap = Maps.ExpMap(M)
for actMap in [Maps.InjectActiveCells(M, M.vectorCCy <=0, 10, nC=M.nCy), Maps.ActiveCells(M, M.vectorCCy <=0, 10, nC=M.nCy)]:
# actMap = Maps.InjectActiveCells(M, M.vectorCCy <=0, 10, nC=M.nCy)
for actMap in [Maps.InjectActiveCells(M, M.vectorCCy <= 0, 10,
nC=M.nCy), Maps.ActiveCells(M, M.vectorCCy <= 0, 10,
nC=M.nCy)]:
vertMap = Maps.SurjectVertical1D(M)
combo = vertMap * actMap
m = np.r_[1,2.]
mod = Models.Model(m,combo)
# import matplotlib.pyplot as plt
# plt.colorbar(M.plotImage(mod.transform)[0])
# plt.show()
self.assertLess(np.linalg.norm(mod.transform - np.r_[1,1,2,2,10,10,10,10.]), TOL)
self.assertLess((mod.transformDeriv - combo.deriv(m)).toarray().sum(), TOL)
m = np.r_[1., 2.]
mod = Models.Model(m, combo)
self.assertLess(np.linalg.norm(mod.transform -
np.r_[1, 1, 2, 2, 10, 10, 10, 10.]), TOL)
self.assertLess((mod.transformDeriv -
combo.deriv(m)).toarray().sum(), TOL)
def test_tripleMultiply(self):
M = Mesh.TensorMesh([2,4],'0C')
M = Mesh.TensorMesh([2, 4], '0C')
expMap = Maps.ExpMap(M)
vertMap = Maps.SurjectVertical1D(M)
actMap = Maps.InjectActiveCells(M, M.vectorCCy <=0, 10, nC=M.nCy)
m = np.r_[1,2.]
t_true = np.exp(np.r_[1,1,2,2,10,10,10,10.])
self.assertLess(np.linalg.norm((expMap * vertMap * actMap * m)-t_true,np.inf),TOL)
self.assertLess(np.linalg.norm(((expMap * vertMap * actMap) * m)-t_true,np.inf),TOL)
self.assertLess(np.linalg.norm((expMap * vertMap * (actMap * m))-t_true,np.inf),TOL)
self.assertLess(np.linalg.norm((expMap * (vertMap * actMap) * m)-t_true,np.inf),TOL)
self.assertLess(np.linalg.norm(((expMap * vertMap) * actMap * m)-t_true,np.inf),TOL)
actMap = Maps.InjectActiveCells(M, M.vectorCCy <= 0, 10, nC=M.nCy)
m = np.r_[1., 2.]
t_true = np.exp(np.r_[1, 1, 2, 2, 10, 10, 10, 10.])
self.assertRaises(ValueError, lambda: expMap * actMap * vertMap )
self.assertRaises(ValueError, lambda: actMap * vertMap * expMap )
self.assertLess(np.linalg.norm((expMap * vertMap * actMap * m) -
t_true, np.inf), TOL)
self.assertLess(np.linalg.norm(((expMap * vertMap * actMap) * m) -
t_true, np.inf), TOL)
self.assertLess(np.linalg.norm((expMap * vertMap * (actMap * m)) -
t_true, np.inf), TOL)
self.assertLess(np.linalg.norm((expMap * (vertMap * actMap) * m) -
t_true, np.inf), TOL)
self.assertLess(np.linalg.norm(((expMap * vertMap) * actMap * m) -
t_true, np.inf), TOL)
self.assertRaises(ValueError, lambda: expMap * actMap * vertMap)
self.assertRaises(ValueError, lambda: actMap * vertMap * expMap)
def test_map2Dto3D_x(self):
M2 = Mesh.TensorMesh([2,4])
M3 = Mesh.TensorMesh([3,2,4])
M2 = Mesh.TensorMesh([2, 4])
M3 = Mesh.TensorMesh([3, 2, 4])
m = np.random.rand(M2.nC)
for m2to3 in [Maps.Surject2Dto3D(M3, normal='X'), Maps.Map2Dto3D(M3, normal='X')]:
# m2to3 = Maps.Surject2Dto3D(M3, normal='X')
for m2to3 in [Maps.Surject2Dto3D(M3, normal='X'),
Maps.Map2Dto3D(M3, normal='X')]:
# m2to3 = Maps.Surject2Dto3D(M3, normal='X')
m = np.arange(m2to3.nP)
self.assertTrue(m2to3.test())
self.assertTrue(np.all(Utils.mkvc( (m2to3 * m).reshape(M3.vnC,order='F')[0,:,:] ) == m))
self.assertTrue(m2to3.testVec())
self.assertTrue(np.all(Utils.mkvc((m2to3 * m).reshape(M3.vnC,
order='F')[0, :, :]) == m))
def test_map2Dto3D_y(self):
M2 = Mesh.TensorMesh([3,4])
M3 = Mesh.TensorMesh([3,2,4])
M2 = Mesh.TensorMesh([3, 4])
M3 = Mesh.TensorMesh([3, 2, 4])
m = np.random.rand(M2.nC)
for m2to3 in [Maps.Surject2Dto3D(M3, normal='Y'),Maps.Map2Dto3D(M3, normal='Y')]:
# m2to3 = Maps.Surject2Dto3D(M3, normal='Y')
for m2to3 in [Maps.Surject2Dto3D(M3, normal='Y'), Maps.Map2Dto3D(M3,
normal='Y')]:
# m2to3 = Maps.Surject2Dto3D(M3, normal='Y')
m = np.arange(m2to3.nP)
self.assertTrue(m2to3.test())
self.assertTrue(np.all(Utils.mkvc( (m2to3 * m).reshape(M3.vnC,order='F')[:,0,:] ) == m))
self.assertTrue(m2to3.testVec())
self.assertTrue(np.all(Utils.mkvc((m2to3 * m).reshape(M3.vnC,
order='F')[:, 0, :]) == m))
def test_map2Dto3D_z(self):
M2 = Mesh.TensorMesh([3,2])
M3 = Mesh.TensorMesh([3,2,4])
M2 = Mesh.TensorMesh([3, 2])
M3 = Mesh.TensorMesh([3, 2, 4])
m = np.random.rand(M2.nC)
for m2to3 in [Maps.Surject2Dto3D(M3, normal='Z'),Maps.Map2Dto3D(M3, normal='Z')]:
# m2to3 = Maps.Surject2Dto3D(M3, normal='Z')
for m2to3 in [Maps.Surject2Dto3D(M3, normal='Z'), Maps.Map2Dto3D(M3,
normal='Z')]:
# m2to3 = Maps.Surject2Dto3D(M3, normal='Z')
m = np.arange(m2to3.nP)
self.assertTrue(m2to3.test())
self.assertTrue(np.all(Utils.mkvc( (m2to3 * m).reshape(M3.vnC,order='F')[:,:,0] ) == m))
self.assertTrue(m2to3.testVec())
self.assertTrue(np.all(Utils.mkvc((m2to3 * m).reshape(M3.vnC,
order='F')[:, :, 0]) == m))
if __name__ == '__main__':
+3 -3
View File
@@ -5,12 +5,12 @@ from SimPEG import *
class TestTimeProblem(unittest.TestCase):
def setUp(self):
mesh = Mesh.TensorMesh([10,10])
mesh = Mesh.TensorMesh([10, 10])
self.prob = Problem.BaseTimeProblem(mesh)
def test_timeProblem_setTimeSteps(self):
self.prob.timeSteps = [(1e-6, 3), 1e-5, (1e-4, 2)]
trueTS = np.r_[1e-6,1e-6,1e-6,1e-5,1e-4,1e-4]
trueTS = np.r_[1e-6, 1e-6, 1e-6, 1e-5, 1e-4, 1e-4]
self.assertTrue(np.all(trueTS == self.prob.timeSteps))
self.prob.timeSteps = trueTS
@@ -18,7 +18,7 @@ class TestTimeProblem(unittest.TestCase):
self.assertTrue(self.prob.nT == 6)
self.assertTrue(np.all(self.prob.times == np.r_[0,trueTS].cumsum()))
self.assertTrue(np.all(self.prob.times == np.r_[0, trueTS].cumsum()))
if __name__ == '__main__':
+14 -7
View File
@@ -8,6 +8,7 @@ TOL = 1e-20
testReg = True
testRegMesh = True
class RegularizationTests(unittest.TestCase):
def setUp(self):
@@ -16,41 +17,47 @@ class RegularizationTests(unittest.TestCase):
mesh1 = Mesh.TensorMesh([hx])
mesh2 = Mesh.TensorMesh([hx, hy])
mesh3 = Mesh.TensorMesh([hx, hy, hz])
self.meshlist = [mesh1,mesh2, mesh3]
self.meshlist = [mesh1, mesh2, mesh3]
if testReg:
def test_regularization(self):
for R in dir(Regularization):
r = getattr(Regularization, R)
if not inspect.isclass(r): continue
if not inspect.isclass(r):
continue
if not issubclass(r, Regularization.BaseRegularization):
continue
for i, mesh in enumerate(self.meshlist):
print 'Testing %iD'%mesh.dim
print 'Testing %iD' % mesh.dim
mapping = r.mapPair(mesh)
reg = r(mesh, mapping=mapping)
m = np.random.rand(mapping.nP)
reg.mref = np.ones_like(m)*np.mean(m)
print 'Check: phi_m (mref) = %f' %reg.eval(reg.mref)
print 'Check: phi_m (mref) = %f' % reg.eval(reg.mref)
passed = reg.eval(reg.mref) < TOL
self.assertTrue(passed)
print 'Check:', R
passed = Tests.checkDerivative(lambda m : [reg.eval(m), reg.evalDeriv(m)], m, plotIt=False)
passed = Tests.checkDerivative(lambda m: [reg.eval(m),
reg.evalDeriv(m)], m,
plotIt=False)
self.assertTrue(passed)
print 'Check 2 Deriv:', R
passed = Tests.checkDerivative(lambda m : [reg.evalDeriv(m), reg.eval2Deriv(m)], m, plotIt=False)
passed = Tests.checkDerivative(lambda m: [reg.evalDeriv(m),
reg.eval2Deriv(m)], m,
plotIt=False)
self.assertTrue(passed)
def test_regularization_ActiveCells(self):
for R in dir(Regularization):
r = getattr(Regularization, R)
if not inspect.isclass(r): continue
if not inspect.isclass(r):
continue
if not issubclass(r, Regularization.BaseRegularization):
continue
+1 -1
View File
@@ -3,7 +3,7 @@ import unittest
from SimPEG.Tests import OrderTest
import matplotlib.pyplot as plt
#TODO: 'randomTensorMesh'
# TODO: 'randomTensorMesh'
MESHTYPES = ['uniformTensorMesh', 'uniformCurv', 'rotateCurv']
call2 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1])
call3 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1], xyz[:, 2])