mirror of
https://github.com/wassname/simpeg.git
synced 2026-09-30 11:42:17 +08:00
commit
b56e0a2e71
98 files changed
+2517
-10556
No files matched your search
@@ -3,4 +3,3 @@
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
docs/_build/
|
||||
myNotebooks/*
|
||||
@@ -0,0 +1,470 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
Input and output functions.
|
||||
"""
|
||||
|
||||
|
||||
import os as _os
|
||||
import errno as _errno
|
||||
import sys as _sys
|
||||
import numpy as _np
|
||||
|
||||
from petsc4py import PETSc as _PETSc
|
||||
import fileinput as _fl
|
||||
|
||||
def vecToArray(obj):
|
||||
""" Converts a PETSc vector to a numpy array, available on *all* MPI nodes.
|
||||
|
||||
Args:
|
||||
obj (petsc4py.PETSc.Vec): input vector.
|
||||
|
||||
Returns:
|
||||
numpy.array :
|
||||
"""
|
||||
# scatter vector 'obj' to all processes
|
||||
comm = obj.getComm()
|
||||
scatter, obj0 = _PETSc.Scatter.toAll(obj)
|
||||
scatter.scatter(obj, obj0, False, _PETSc.Scatter.Mode.FORWARD)
|
||||
|
||||
return _np.asarray(obj0)
|
||||
|
||||
# deallocate
|
||||
comm.barrier()
|
||||
scatter.destroy()
|
||||
obj0.destroy()
|
||||
|
||||
|
||||
def vecToArray0(obj):
|
||||
""" Converts a PETSc vector to a numpy array available on MPI node 0.
|
||||
|
||||
Args:
|
||||
obj (petsc4py.PETSc.Vec): input vector.
|
||||
|
||||
Returns:
|
||||
numpy.array :
|
||||
"""
|
||||
# scatter vector 'obj' to process 0
|
||||
comm = obj.getComm()
|
||||
rank = comm.getRank()
|
||||
scatter, obj0 = _PETSc.Scatter.toZero(obj)
|
||||
scatter.scatter(obj, obj0, False, _PETSc.Scatter.Mode.FORWARD)
|
||||
|
||||
if rank == 0: return _np.asarray(obj0)
|
||||
|
||||
# deallocate
|
||||
comm.barrier()
|
||||
scatter.destroy()
|
||||
obj0.destroy()
|
||||
|
||||
|
||||
def arrayToVec(vecArray):
|
||||
""" Converts a (global) array to a PETSc vector over :attr:`petsc4py.PETSc.COMM_WORLD`.
|
||||
|
||||
Args:
|
||||
vecArray (array or numpy.array): input vector.
|
||||
|
||||
Returns:
|
||||
petsc4py.PETSc.Vec() :
|
||||
"""
|
||||
vec = _PETSc.Vec().create(comm=_PETSc.COMM_WORLD)
|
||||
vec.setSizes(len(vecArray))
|
||||
vec.setUp()
|
||||
(Istart,Iend) = vec.getOwnershipRange()
|
||||
return vec.createWithArray(vecArray[Istart:Iend],
|
||||
comm=_PETSc.COMM_WORLD)
|
||||
vec.destroy()
|
||||
|
||||
|
||||
def arrayToMat(matArray):
|
||||
""" Converts a (global) 2D array to a PETSc matrix over :attr:`petsc4py.PETSc.COMM_WORLD`.
|
||||
|
||||
Args:
|
||||
matArray (array or numpy.array): input square array.
|
||||
|
||||
:rtype: petsc4py.PETSc.Mat()
|
||||
|
||||
.. important::
|
||||
Requires `SciPy <http://www.scipy.org>`_.
|
||||
|
||||
"""
|
||||
try:
|
||||
import scipy.sparse as sparse
|
||||
except:
|
||||
print '\nERROR: loading matrices from txt files requires Scipy!'
|
||||
return
|
||||
|
||||
matSparse =matArray
|
||||
|
||||
mat = _PETSc.Mat().createAIJ(size=matSparse.shape,comm=_PETSc.COMM_WORLD)
|
||||
(Istart,Iend) = mat.getOwnershipRange()
|
||||
|
||||
ai = matSparse.indptr[Istart:Iend+1] - matSparse.indptr[Istart]
|
||||
aj = matSparse.indices[matSparse.indptr[Istart]:matSparse.indptr[Iend]]
|
||||
av = matSparse.data[matSparse.indptr[Istart]:matSparse.indptr[Iend]]
|
||||
|
||||
mat.setValuesCSR(ai,aj,av)
|
||||
mat.assemble()
|
||||
|
||||
return mat
|
||||
mat.destroy()
|
||||
|
||||
def matToSparse(mat):
|
||||
""" Converts a PETSc matrix to a (global) sparse matrix.
|
||||
|
||||
Args:
|
||||
mat (petsc4py.PETSc.Mat): input PETSc matrix.
|
||||
|
||||
:rtype: scipy.sparse.csr_matrix
|
||||
|
||||
.. important::
|
||||
Requires `SciPy <http://www.scipy.org>`_.
|
||||
|
||||
"""
|
||||
import scipy.sparse as sparse
|
||||
|
||||
data = mat.getValuesCSR()
|
||||
|
||||
(Istart,Iend) = mat.getOwnershipRange()
|
||||
columns = mat.getSize()[0]
|
||||
sparseSubMat = sparse.csr_matrix(data[::-1],shape=(Iend-Istart,columns))
|
||||
|
||||
comm = _PETSc.COMM_WORLD
|
||||
|
||||
sparseSubMat = comm.tompi4py().allgather(sparseSubMat)
|
||||
|
||||
return sparse.vstack(sparseSubMat)
|
||||
|
||||
def adjToH(adj,d=[0],amp=[0.]):
|
||||
""" Creates a 1 particle PETSc-type Hamiltonian matrix from a PETSc adjacency matrix.
|
||||
|
||||
Args:
|
||||
adj (petsc4py.PETSc.Mat): input PETSc-type adjacency matrix.
|
||||
|
||||
d (array of ints): an array containing *integers* indicating the nodes
|
||||
where diagonal defects are to be placed (e.g. ``d=[0,1,4]``).
|
||||
|
||||
amp (array of floats): an array containing *floats* indicating the diagonal defect
|
||||
amplitudes corresponding to each element in ``d`` (e.g. ``amp=[0.5,-1,4.2]``).
|
||||
|
||||
Returns:
|
||||
: 1 particle Hamiltonian matrix
|
||||
:rtype: petsc4py.PETSc.Mat()
|
||||
|
||||
Warning:
|
||||
* The size of ``a`` and ``d`` must be identical
|
||||
|
||||
>>> amp = [0.5,-1.,4.2]
|
||||
>>> len(d) == len(amp)
|
||||
True
|
||||
|
||||
* Elements of ``d`` can range from :math:`[0,N-1]` where the adjacency matrix is :math:`N\\times N`.
|
||||
|
||||
"""
|
||||
(Istart,Iend) = adj.getOwnershipRange()
|
||||
diagSum = []
|
||||
for i in range(Istart,Iend):
|
||||
diagSum.append(_np.sum(adj.getRow(i)[-1]))
|
||||
for j,val in enumerate(d):
|
||||
if i==val: diagSum[i-Istart] += amp[j]
|
||||
|
||||
mat = _PETSc.Mat().create(comm=_PETSc.COMM_WORLD)
|
||||
mat.setSizes(adj.getSize())
|
||||
mat.setUp()
|
||||
|
||||
for i in range(Istart,Iend):
|
||||
mat.setValue(i,i,diagSum[i-Istart])
|
||||
|
||||
mat.assemble()
|
||||
mat.axpy(-1,adj)
|
||||
|
||||
return mat
|
||||
mat.destroy()
|
||||
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#---------------------- Vec I/O functions ---------------------------
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def exportVec(vec,filename,filetype):
|
||||
""" Export a PETSc vector to a file.
|
||||
|
||||
Args:
|
||||
vec (petsc4py.PETSc.Vec): input vector.
|
||||
filename (str): path to desired output file.
|
||||
filetype (str): the filetype of the exported vector.
|
||||
|
||||
* ``'txt'`` - a column vector in text format.
|
||||
* ``'bin'`` - a PETSc binary vector.
|
||||
"""
|
||||
if _os.path.isabs(filename):
|
||||
outDir = _os.path.dirname(filename)
|
||||
else:
|
||||
outDir = './'+_os.path.dirname(filename)
|
||||
|
||||
# create output directory if it doesn't exist
|
||||
try:
|
||||
_os.mkdir(outDir)
|
||||
except OSError as exception:
|
||||
if exception.errno != _errno.EEXIST:
|
||||
raise
|
||||
|
||||
if filetype == 'txt':
|
||||
# scatter prob to process 0
|
||||
comm = vec.getComm()
|
||||
rank = comm.getRank()
|
||||
scatter, vec0 = _PETSc.Scatter.toZero(vec)
|
||||
scatter.scatter(vec, vec0, False, _PETSc.Scatter.Mode.FORWARD)
|
||||
|
||||
# use process 0 to write to text file
|
||||
if rank == 0:
|
||||
array0 = _np.asarray(vec0)
|
||||
with open(filename,'w') as f:
|
||||
for i in range(len(array0)):
|
||||
f.write('{0: .12e}\n'.format(array0[i]))
|
||||
|
||||
# deallocate
|
||||
comm.barrier()
|
||||
scatter.destroy()
|
||||
vec0.destroy()
|
||||
|
||||
elif filetype == 'bin':
|
||||
binSave = _PETSc.Viewer().createBinary(filename, 'w')
|
||||
binSave(vec)
|
||||
binSave.destroy()
|
||||
|
||||
vec.comm.barrier()
|
||||
|
||||
def loadVec(filename,filetype):
|
||||
""" Import a PETSc vector from a file.
|
||||
|
||||
Args:
|
||||
filename (str): path to input file.
|
||||
filetype (str): the filetype.
|
||||
|
||||
* ``'txt'`` - a column vector in text format.
|
||||
* ``'bin'`` - a PETSc binary vector.
|
||||
"""
|
||||
if filetype == 'txt':
|
||||
try:
|
||||
vecArray = _np.loadtxt(filename,dtype=_PETSc.ScalarType)
|
||||
return arrayToVec(vecArray)
|
||||
except:
|
||||
print "\nERROR: input state space file " + filename\
|
||||
+ " does not exist or is in an incorrect format"
|
||||
_sys.exit()
|
||||
|
||||
elif filetype == 'bin':
|
||||
binLoad = _PETSc.Viewer().createBinary(filename, 'r')
|
||||
try:
|
||||
return _PETSc.Vec().load(binLoad)
|
||||
except:
|
||||
print "\nERROR: input state space file " + filename\
|
||||
+ " does not exist or is in an incorrect format"
|
||||
_sys.exit()
|
||||
binLoad.destroy()
|
||||
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#---------------------- Mat I/O functions ---------------------------
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def exportMat(mat,filename,filetype,mattype=None):
|
||||
""" Export a PETSc matrix to a file.
|
||||
|
||||
Args:
|
||||
mat (petsc4py.PETSc.Mat): input matrix.
|
||||
filename (str): path to desired output file.
|
||||
filetype (str): the filetype of the exported vector.
|
||||
|
||||
* ``'txt'`` - a 2D matrix array in text format.
|
||||
* ``'bin'`` - a PETSc binary matrix.
|
||||
mattype (str): (``None``,``'adj'``) - if set to ``adj``, only
|
||||
integers ``0`` and ``1`` are written. Note
|
||||
that this only applied in ``txt`` mode.
|
||||
"""
|
||||
rank = _PETSc.Comm.Get_rank(_PETSc.COMM_WORLD)
|
||||
|
||||
if _os.path.isabs(filename):
|
||||
outDir = _os.path.dirname(filename)
|
||||
else:
|
||||
outDir = './'+_os.path.dirname(filename)
|
||||
|
||||
# create output directory if it doesn't exist
|
||||
try:
|
||||
_os.mkdir(outDir)
|
||||
except OSError as exception:
|
||||
if exception.errno != _errno.EEXIST:
|
||||
raise
|
||||
|
||||
if filetype == 'txt':
|
||||
txtSave = _PETSc.Viewer().createASCII(filename, 'w',
|
||||
format=_PETSc.Viewer.Format.ASCII_DENSE, comm=_PETSc.COMM_WORLD)
|
||||
txtSave(mat)
|
||||
txtSave.destroy()
|
||||
|
||||
if rank == 0:
|
||||
for line in _fl.FileInput(filename,inplace=1):
|
||||
if line[2] != 't':
|
||||
if mattype == 'adj':
|
||||
line = line.replace(" i","j")
|
||||
line = line.replace(" -","-")
|
||||
line = line.replace("+-","-")
|
||||
line = line.replace("0000e+01+0.00000e+00j","")
|
||||
line = line.replace(".00000e+00+0.00000e+00j","")
|
||||
line = line.replace(".","")
|
||||
line = line.replace(" -","\t-")
|
||||
line = line.replace(" ","\t")
|
||||
line = line.replace(" ","")
|
||||
line = line.replace("\t"," ")
|
||||
print line,
|
||||
else:
|
||||
line = line.replace(" i","j")
|
||||
line = line.replace(" -","-")
|
||||
line = line.replace("+-","-")
|
||||
print line,
|
||||
|
||||
elif filetype == 'bin':
|
||||
binSave = _PETSc.Viewer().createBinary(filename, 'w', comm=_PETSc.COMM_WORLD)
|
||||
binSave(mat)
|
||||
binSave.destroy()
|
||||
|
||||
mat.comm.barrier()
|
||||
|
||||
def loadMat(filename,filetype,delimiter=None):
|
||||
""" Import a PETSc matrix from a file.
|
||||
|
||||
Args:
|
||||
filename (str): path to input file.
|
||||
filetype (str): the filetype.
|
||||
|
||||
* ``'txt'`` - a 2D matrix array in text format.
|
||||
* ``'bin'`` - a PETSc matrix vector.
|
||||
|
||||
delimiter (str): this is passed to `numpy.genfromtxt\
|
||||
<http://docs.scipy.org/doc/numpy/reference/generated/numpy.genfromtxt.html>`_
|
||||
in the case of strange delimiters in an imported ``txt`` file.
|
||||
"""
|
||||
if filetype == 'txt':
|
||||
try:
|
||||
try:
|
||||
if delimiter is None:
|
||||
matArray = _np.genfromtxt(filename,dtype=_PETSc.ScalarType)
|
||||
else:
|
||||
matArray = _np.genfromtxt(filename,dtype=_PETSc.ScalarType,delimiter=delimiter)
|
||||
except:
|
||||
filefix = []
|
||||
for line in _fl.FileInput(filename,inplace=0):
|
||||
if line[2] != 't':
|
||||
line = line.replace(" i","j")
|
||||
line = line.replace(" -","-")
|
||||
line = line.replace("+-","-")
|
||||
filefix.append(line)
|
||||
|
||||
matArray = _np.genfromtxt(filefix,dtype=_PETSc.ScalarType)
|
||||
|
||||
return arrayToMat(matArray)
|
||||
except:
|
||||
print "\nERROR: input state space file " + filename\
|
||||
+ " does not exist or is in an incorrect format"
|
||||
_sys.exit()
|
||||
|
||||
elif filetype == 'bin':
|
||||
binLoad = _PETSc.Viewer().createBinary(filename, 'r')
|
||||
try:
|
||||
return _PETSc.Mat().load(binLoad)
|
||||
except:
|
||||
print "\nERROR: input state space file " + filename\
|
||||
+ " does not exist or is in an incorrect format"
|
||||
_sys.exit()
|
||||
binLoad.destroy()
|
||||
|
||||
def exportVecToMat(vec,filename,filetype):
|
||||
""" Export a :math:`N^2` element PETSc vector as a :math:`N\\times N` matrix.
|
||||
|
||||
This is useful when wanting to view the full statespace of a 2 particle
|
||||
quantum walk.
|
||||
|
||||
Args:
|
||||
vec (petsc4py.PETSc.Vec): input :math:`N^2` element vector.
|
||||
filename (str): path to desired output file.
|
||||
filetype (str): the filetype of the exported vector.
|
||||
|
||||
* ``'txt'`` - an :math:`N\\times N` 2D matrix array in text format.
|
||||
* ``'bin'`` - an :math:`N\\times N` PETSc binary matrix.
|
||||
"""
|
||||
rank = _PETSc.Comm.Get_rank(_PETSc.COMM_WORLD)
|
||||
|
||||
if _os.path.isabs(filename):
|
||||
outDir = _os.path.dirname(filename)
|
||||
else:
|
||||
outDir = './'+_os.path.dirname(filename)
|
||||
|
||||
# create output directory if it doesn't exist
|
||||
try:
|
||||
_os.mkdir(outDir)
|
||||
except OSError as exception:
|
||||
if exception.errno != _errno.EEXIST:
|
||||
raise
|
||||
|
||||
vecArray = vecToArray(vec)
|
||||
matArray = vecArray.reshape([_np.sqrt(vecArray.size),_np.sqrt(vecArray.size)])
|
||||
|
||||
if filetype == 'txt':
|
||||
#if rank == 0: _np.savetxt(filename,matArray)
|
||||
txtSave = _PETSc.Viewer().createASCII(filename, 'w',
|
||||
format=_PETSc.Viewer.Format.ASCII_DENSE, comm=_PETSc.COMM_WORLD)
|
||||
txtSave(arrayToMat(matArray))
|
||||
txtSave.destroy()
|
||||
|
||||
if rank == 0:
|
||||
for line in _fl.FileInput(filename,inplace=1):
|
||||
if line[2] != 't':
|
||||
line = line.replace(" i","j")
|
||||
line = line.replace(" -","-")
|
||||
line = line.replace("+-","-")
|
||||
print line,
|
||||
|
||||
elif filetype == 'bin':
|
||||
binSave = _PETSc.Viewer().createBinary(filename, 'w', comm=_PETSc.COMM_WORLD)
|
||||
binSave(arrayToMat(matArray))
|
||||
binSave.destroy()
|
||||
vec.comm.barrier()
|
||||
|
||||
|
||||
def loadMatToVec(filename,filetype):
|
||||
""" Load a :math:`N\\times N` matrix as a :math:`N^2` element PETSc vector.
|
||||
|
||||
This is useful when wanting to import the full statespace of a 2 particle
|
||||
quantum walk to use for propagation.
|
||||
|
||||
Args:
|
||||
filename (str): path to the input file.
|
||||
filetype (str): the filetype
|
||||
|
||||
* ``'txt'`` - an :math:`N\\times N` 2D matrix array in text format.
|
||||
* ``'bin'`` - **Not yet implemented! Please use a txt \
|
||||
format for this type of import**.
|
||||
"""
|
||||
if filetype == 'txt':
|
||||
try:
|
||||
try:
|
||||
matArray = _np.loadtxt(filename,dtype=_PETSc.ScalarType)
|
||||
except:
|
||||
filefix = []
|
||||
for line in _fl.FileInput(filename,inplace=0):
|
||||
if line[2] != 't':
|
||||
line = line.replace(" i","j")
|
||||
line = line.replace(" -","-")
|
||||
line = line.replace("+-","-")
|
||||
filefix.append(line)
|
||||
|
||||
matArray = _np.loadtxt(filefix,dtype=_PETSc.ScalarType)
|
||||
|
||||
vecArray = matArray.reshape(matArray.shape[0]**2)
|
||||
return arrayToVec(vecArray)
|
||||
except:
|
||||
print "\nERROR: input state space file " + filename\
|
||||
+ " does not exist or is in an incorrect format"
|
||||
_sys.exit()
|
||||
|
||||
elif filetype == 'bin':
|
||||
print '\nERROR: only works for txt storage!'
|
||||
_sys.exit()
|
||||
@@ -0,0 +1,198 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": ""
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"from SimPEG import *\n",
|
||||
"%pylab inline"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"Populating the interactive namespace from numpy and matplotlib\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"M = mesh.TensorMesh([20,30]) \n",
|
||||
"A = M.faceDiv*M.faceDiv.T + sp.identity(M.nC)\n",
|
||||
"b = np.random.rand(M.nC)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 35
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"phi = Solver(A).solve(b)\n",
|
||||
"colorbar(M.plotImage(phi))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 37,
|
||||
"text": [
|
||||
"<matplotlib.colorbar.Colorbar instance at 0x6c411b8>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x67e6050>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 37
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"print np.linalg.norm(A*phi-b)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"1.5220841846e-13\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 38
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import petsc4py\n",
|
||||
"import sys\n",
|
||||
"petsc4py.init(sys.argv)\n",
|
||||
"from petsc4py import PETSc"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 39
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import PETScIO as IO\n",
|
||||
"Apetsc = PETSc.Mat().createAIJ(size=A.shape,csr=(A.indptr, A.indices, A.data))\n",
|
||||
"bpetsc = IO.arrayToVec(b)\n",
|
||||
"xpetsc = IO.arrayToVec(0*b)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 40
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"ksp = PETSc.KSP().create()\n",
|
||||
"pc = PETSc.PC().create()\n",
|
||||
"\n",
|
||||
"ksp.setOperators(Apetsc)\n",
|
||||
"\n",
|
||||
"ksp.setType(ksp.Type.CG)\n",
|
||||
"pc = ksp.getPC()\n",
|
||||
"pc.setType(pc.Type.HYPRE)\n",
|
||||
"ksp.view()\n",
|
||||
"\n",
|
||||
"ksp.solve(bpetsc, xpetsc)\n",
|
||||
"print ksp.its"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"3\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 76
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"X = IO.vecToArray(xpetsc)\n",
|
||||
"print np.linalg.norm(A*X-b)\n",
|
||||
"M.plotImage(X)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"0.000199616893249\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 77,
|
||||
"text": [
|
||||
"<matplotlib.collections.QuadMesh at 0x792ae50>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x77479d0>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 77
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
File renamed without changes.
Executable
+145
@@ -0,0 +1,145 @@
|
||||
#! /bin/bash
|
||||
|
||||
locale-gen en_US en_US.UTF-8 hu_HU hu_HU.UTF-8 > output.t
|
||||
dpkg-reconfigure locales >> output.t
|
||||
|
||||
sudo apt-get update >> output.t
|
||||
echo " "
|
||||
echo " "
|
||||
echo " ============================================"
|
||||
echo " | Installing packages form package manager |"
|
||||
echo " ============================================"
|
||||
echo " "
|
||||
echo " "
|
||||
|
||||
sudo apt-get -y install aptitude >> output.t
|
||||
|
||||
packages=(gcc gfortran git libopenmpi-dev python-pip python-dev git flex bison cmake vim cython ipython python-scipy python-numpy python-nose python-pip python-matplotlib python-vtk python-h5py libmumps-ptscotch-4.10.0 libmumps-ptscotch-dev libblas-dev liblapack-dev )
|
||||
|
||||
|
||||
for item in ${packages[*]}
|
||||
do
|
||||
printf " %-30s\n" $item
|
||||
|
||||
done
|
||||
|
||||
for item in ${packages[*]}
|
||||
do
|
||||
tput cuu1
|
||||
done
|
||||
|
||||
for item in ${packages[*]}
|
||||
do
|
||||
sudo aptitude -y install $item >> output.t
|
||||
printf " %-30s %-4s\n" $item done
|
||||
done
|
||||
|
||||
|
||||
echo " "
|
||||
echo " "
|
||||
echo " ====================================="
|
||||
echo " | Installing extra Python libraries |"
|
||||
echo " ====================================="
|
||||
echo " "
|
||||
echo " "
|
||||
|
||||
|
||||
pipPackages=(mpi4py pymumps)
|
||||
|
||||
for item in ${pipPackages[*]}
|
||||
do
|
||||
printf " %-30s\n" $item
|
||||
done
|
||||
|
||||
for item in ${pipPackages[*]}
|
||||
do
|
||||
tput cuu1
|
||||
done
|
||||
|
||||
for item in ${pipPackages[*]}
|
||||
do
|
||||
sudo pip install $item >> output.t
|
||||
printf " %-30s %-4s\n" $item done
|
||||
done
|
||||
|
||||
Upgrade=(scipy numpy ipython)
|
||||
|
||||
for item in ${Upgrade[*]}
|
||||
do
|
||||
printf " %-8s%-7s\n" $item upgrade
|
||||
|
||||
done
|
||||
|
||||
for item in ${Upgrade[*]}
|
||||
do
|
||||
tput cuu1
|
||||
done
|
||||
|
||||
for item in ${Upgrade[*]}
|
||||
do
|
||||
sudo pip install $item --upgrade >> output.t
|
||||
printf " %-8s%-7s %-4s\n" $item upgrade done
|
||||
done
|
||||
|
||||
|
||||
|
||||
echo " "
|
||||
echo " "
|
||||
echo " ====================="
|
||||
echo " | Installing SimPEG |"
|
||||
echo " ====================="
|
||||
echo " "
|
||||
echo " "
|
||||
cd ~
|
||||
|
||||
|
||||
git clone https://github.com/simpeg/simpeg.git >> output.t
|
||||
cd simpeg/SimPEG/
|
||||
python setup.py >> output.t
|
||||
cd ~
|
||||
|
||||
mkdir petsc
|
||||
cd petsc
|
||||
|
||||
echo " "
|
||||
echo " "
|
||||
echo " ===================="
|
||||
echo " | Installing PETSc |"
|
||||
echo " ===================="
|
||||
echo " "
|
||||
echo " "
|
||||
wget http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.4.3.tar.gz
|
||||
|
||||
tar -zxf petsc-3.4.3.tar.gz
|
||||
|
||||
cd petsc-3.4.3
|
||||
|
||||
./configure --with-debugging=no --dowload-mpich=yes --download-blacs=yes --download-f-blas-lapack=yes --download-scalapack=yes --download-mumps=yes --download-ml=yes --download-spooles=yes --download-hypre=yes --dowload-trilinos=yes --download-metis=yes --download-parmetis=yes --download-umfpack=yes --download-ptscotch=yes --download-superlu=yes --download-superlu_dist=yes --download-essl=yes --download-eucild=yes --download-spai=yes --download-mpi4py=yes --download-petsc4py=yes --download-scientificpython=yes
|
||||
|
||||
|
||||
echo "export PETSC_DIR=/home/${USER}/petsc/petsc-3.4.3" >> ~/.bashrc
|
||||
echo "export PETSC_ARCH=arch-linux2-c-opt" >> ~/.bashrc
|
||||
export PETSC_DIR=/home/${USER}/petsc/petsc-3.4.3
|
||||
export PETSC_ARCH=arch-linux2-c-opt
|
||||
. ~/.bashrc
|
||||
|
||||
make PETSC_DIR=/home/${USER}/petsc/petsc-3.4.3 PETSC_ARCH=arch-linux2-c-opt all
|
||||
make PETSC_DIR=/home/${USER}/petsc/petsc-3.4.3 PETSC_ARCH=arch-linux2-c-opt test
|
||||
|
||||
cd ~/petsc
|
||||
echo " "
|
||||
echo " "
|
||||
echo " ======================="
|
||||
echo " | Installing PETSc4PY |"
|
||||
echo " ======================="
|
||||
echo " "
|
||||
echo " "
|
||||
git clone https://bitbucket.org/petsc/petsc4py.git
|
||||
cd petsc4py/
|
||||
python setup.py build >> output.t
|
||||
python setup.py install --prefix=~/petsc >> output.t
|
||||
|
||||
echo "export PYTHONPATH=~/petsc/lib/python2.7/site-packages:/home/$USER/simpeg:${PYTHONPATH}" >> ~/.bashrc
|
||||
|
||||
cd ~
|
||||
source ~/.bashrc
|
||||
File renamed without changes.
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2014 SimPEG Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
Simulation and Parameter Estimation in Geoscience - A python package for simulation and gradient based parameter estimation in the context of geophysical applications.
|
||||
Simulation and Parameter Estimation in Geophysics - A python package for simulation and gradient based parameter estimation in the context of geophysical applications.
|
||||
|
||||
The vision is to create a package for finite volume simulation with applications to geophysical imaging and subsurface flow. To enable the understanding of the many different components, this package has the following features:
|
||||
|
||||
@@ -10,4 +10,20 @@ The vision is to create a package for finite volume simulation with applications
|
||||
* supports 1D, 2D and 3D problems
|
||||
* designed for large-scale inversions
|
||||
|
||||
Documentation:
|
||||
[http://simpeg.readthedocs.org/en/latest/](http://simpeg.readthedocs.org/en/latest/)
|
||||
|
||||
Code:
|
||||
[https://github.com/simpeg/simpeg](https://github.com/simpeg/simpeg)
|
||||
|
||||
Tests:
|
||||
[https://travis-ci.org/simpeg/simpeg](https://travis-ci.org/simpeg/simpeg)
|
||||
|
||||
Build Status:
|
||||
[](https://travis-ci.org/simpeg/simpeg)
|
||||
|
||||
Bugs & Issues:
|
||||
[https://github.com/simpeg/simpeg/issues](https://github.com/simpeg/simpeg/issues)
|
||||
|
||||
Code Snippets & Tutorials:
|
||||
[http://www.row1.ca/simpeg](http://www.row1.ca/simpeg)
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
import Utils, numpy as np
|
||||
|
||||
|
||||
class BaseData(object):
|
||||
"""Data holds the observed data, and the standard deviations."""
|
||||
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
std = None #: Estimated Standard Deviations
|
||||
dobs = None #: Observed data
|
||||
dtrue = None #: True data, if data is synthetic
|
||||
mtrue = None #: True model, if data is synthetic
|
||||
|
||||
counter = None #: A SimPEG.Utils.Counter object
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
@property
|
||||
def prob(self):
|
||||
"""
|
||||
The geophysical problem that explains this data, use::
|
||||
|
||||
data.pair(prob)
|
||||
"""
|
||||
return getattr(self, '_prob', None)
|
||||
|
||||
def pair(self, p):
|
||||
"""Bind a problem to this data instance using pointers"""
|
||||
assert hasattr(p, 'dataPair'), "Problem must have an attribute 'dataPair'."
|
||||
assert isinstance(self, p.dataPair), "Problem requires data object must be an instance of a %s class."%(p.dataPair.__name__)
|
||||
if p.ispaired:
|
||||
raise Exception("The problem object is already paired to a data. Use prob.unpair()")
|
||||
self._prob = p
|
||||
p._data = self
|
||||
|
||||
def unpair(self):
|
||||
"""Unbind a problem from this data instance"""
|
||||
if not self.ispaired: return
|
||||
self.prob._data = None
|
||||
self._prob = None
|
||||
|
||||
@property
|
||||
def ispaired(self): return self.prob is not None
|
||||
|
||||
@Utils.count
|
||||
@Utils.requires('prob')
|
||||
def dpred(self, m, u=None):
|
||||
"""
|
||||
Create the projected data from a model.
|
||||
The field, u, (if provided) will be used for the predicted data
|
||||
instead of recalculating the fields (which may be expensive!).
|
||||
|
||||
.. math::
|
||||
d_\\text{pred} = P(u(m))
|
||||
|
||||
Where P is a projection of the fields onto the data space.
|
||||
"""
|
||||
if u is None: u = self.prob.field(m)
|
||||
return Utils.mkvc(self.projectField(u))
|
||||
|
||||
|
||||
@Utils.count
|
||||
def projectField(self, u):
|
||||
"""
|
||||
This function projects the fields onto the data space.
|
||||
|
||||
|
||||
.. math::
|
||||
d_\\text{pred} = P(u(m))
|
||||
"""
|
||||
return u
|
||||
|
||||
#TODO: def projectFieldDeriv(self, u): Does this need to be made??!
|
||||
|
||||
@Utils.count
|
||||
def residual(self, m, u=None):
|
||||
"""
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array u: fields
|
||||
:rtype: float
|
||||
:return: data residual
|
||||
|
||||
The data residual:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data} = \mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs}
|
||||
|
||||
"""
|
||||
return Utils.mkvc(self.dpred(m, u=u) - self.dobs)
|
||||
|
||||
|
||||
@property
|
||||
def Wd(self):
|
||||
"""
|
||||
Data weighting matrix. This is a covariance matrix used in::
|
||||
|
||||
def data.residualWeighted(m,u=None):
|
||||
return self.Wd*self.residual(m, u=u)
|
||||
|
||||
By default, this is based on the norm of the data plus a noise floor.
|
||||
|
||||
"""
|
||||
if getattr(self,'_Wd',None) is None:
|
||||
eps = np.linalg.norm(Utils.mkvc(self.dobs),2)*1e-5
|
||||
self._Wd = 1/(abs(self.dobs)*self.std+eps)
|
||||
return self._Wd
|
||||
@Wd.setter
|
||||
def Wd(self, value):
|
||||
self._Wd = value
|
||||
|
||||
def residualWeighted(self, m, u=None):
|
||||
"""
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array u: fields
|
||||
:rtype: float
|
||||
:return: data residual
|
||||
|
||||
The weighted data residual:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data}^{\\text{weighted}} = \mathbf{W}_d(\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs})
|
||||
|
||||
Where W_d is a covariance matrix that weights the data residual.
|
||||
"""
|
||||
return Utils.mkvc(self.Wd*self.residual(m, u=u))
|
||||
|
||||
@property
|
||||
def RHS(self):
|
||||
"""
|
||||
Source matrix.
|
||||
"""
|
||||
return getattr(self, '_RHS', None)
|
||||
@RHS.setter
|
||||
def RHS(self, value):
|
||||
self._RHS = value
|
||||
|
||||
@property
|
||||
def isSynthetic(self):
|
||||
"Check if the data is synthetic."
|
||||
return (self.mtrue is not None)
|
||||
|
||||
if __name__ == '__main__':
|
||||
d = BaseData()
|
||||
d.dpred()
|
||||
@@ -1,27 +1,53 @@
|
||||
from SimPEG.mesh import TensorMesh
|
||||
from SimPEG.forward import Problem, ModelTransforms
|
||||
from SimPEG.tests import checkDerivative
|
||||
from SimPEG.utils import ModelBuilder, sdiag, mkvc
|
||||
from SimPEG import Solver
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
from SimPEG import *
|
||||
|
||||
|
||||
class DCProblem(ModelTransforms.LogModel, Problem):
|
||||
|
||||
class DCData(Data.BaseData):
|
||||
"""
|
||||
**DCData**
|
||||
|
||||
Geophysical DC resistivity data.
|
||||
|
||||
"""
|
||||
|
||||
P = None #: projection
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
Data.BaseData.__init__(self, **kwargs)
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
def reshapeFields(self, u):
|
||||
if len(u.shape) == 1:
|
||||
u = u.reshape([-1, self.RHS.shape[1]], order='F')
|
||||
return u
|
||||
|
||||
def projectField(self, u):
|
||||
"""
|
||||
Predicted data.
|
||||
|
||||
.. math::
|
||||
d_\\text{pred} = Pu(m)
|
||||
"""
|
||||
u = self.reshapeFields(u)
|
||||
return Utils.mkvc(self.P*u)
|
||||
|
||||
|
||||
|
||||
class DCProblem(Problem.BaseProblem):
|
||||
"""
|
||||
**DCProblem**
|
||||
|
||||
Geophysical DC resistivity problem.
|
||||
|
||||
"""
|
||||
def __init__(self, mesh):
|
||||
Problem.__init__(self, mesh)
|
||||
self.mesh.setCellGradBC('neumann')
|
||||
|
||||
def reshapeFields(self, u):
|
||||
if len(u.shape) == 1:
|
||||
u = u.reshape([-1, self.RHS.shape[1]], order='F')
|
||||
return u
|
||||
dataPair = DCData
|
||||
|
||||
def __init__(self, mesh, model, **kwargs):
|
||||
Problem.BaseProblem.__init__(self, mesh, model)
|
||||
self.mesh.setCellGradBC('neumann')
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
|
||||
def createMatrix(self, m):
|
||||
"""
|
||||
@@ -38,30 +64,16 @@ class DCProblem(ModelTransforms.LogModel, Problem):
|
||||
"""
|
||||
D = self.mesh.faceDiv
|
||||
G = self.mesh.cellGrad
|
||||
sigma = self.modelTransform(m)
|
||||
sigma = self.model.transform(m)
|
||||
Msig = self.mesh.getFaceMass(sigma)
|
||||
A = D*Msig*G
|
||||
return A.tocsc()
|
||||
|
||||
def dpred(self, m, u=None):
|
||||
"""
|
||||
Predicted data.
|
||||
|
||||
.. math::
|
||||
d_\\text{pred} = Pu(m)
|
||||
"""
|
||||
if u is None:
|
||||
u = self.field(m)
|
||||
|
||||
u = self.reshapeFields(u)
|
||||
|
||||
return mkvc(self.P*u)
|
||||
|
||||
def field(self, m):
|
||||
A = self.createMatrix(m)
|
||||
solve = Solver(A)
|
||||
phi = solve.solve(self.RHS)
|
||||
return mkvc(phi)
|
||||
phi = solve.solve(self.data.RHS)
|
||||
return Utils.mkvc(phi)
|
||||
|
||||
def J(self, m, v, u=None):
|
||||
"""
|
||||
@@ -88,24 +100,24 @@ class DCProblem(ModelTransforms.LogModel, Problem):
|
||||
if u is None:
|
||||
u = self.field(m)
|
||||
|
||||
u = self.reshapeFields(u)
|
||||
u = self.data.reshapeFields(u)
|
||||
|
||||
P = self.P
|
||||
P = self.data.P
|
||||
D = self.mesh.faceDiv
|
||||
G = self.mesh.cellGrad
|
||||
A = self.createMatrix(m)
|
||||
Av_dm = self.mesh.getFaceMassDeriv()
|
||||
mT_dm = self.modelTransformDeriv(m)
|
||||
mT_dm = self.model.transformDeriv(m)
|
||||
|
||||
dCdu = A
|
||||
|
||||
dCdm = np.empty_like(u)
|
||||
for i, ui in enumerate(u.T): # loop over each column
|
||||
dCdm[:, i] = D * ( sdiag( G * ui ) * ( Av_dm * ( mT_dm * v ) ) )
|
||||
dCdm[:, i] = D * ( Utils.sdiag( G * ui ) * ( Av_dm * ( mT_dm * v ) ) )
|
||||
|
||||
solve = Solver(dCdu)
|
||||
Jv = - P * solve.solve(dCdm)
|
||||
return mkvc(Jv)
|
||||
return Utils.mkvc(Jv)
|
||||
|
||||
def Jt(self, m, v, u=None):
|
||||
"""Takes data, turns it into a model..ish"""
|
||||
@@ -113,15 +125,15 @@ class DCProblem(ModelTransforms.LogModel, Problem):
|
||||
if u is None:
|
||||
u = self.field(m)
|
||||
|
||||
u = self.reshapeFields(u)
|
||||
v = self.reshapeFields(v)
|
||||
u = self.data.reshapeFields(u)
|
||||
v = self.data.reshapeFields(v)
|
||||
|
||||
P = self.P
|
||||
P = self.data.P
|
||||
D = self.mesh.faceDiv
|
||||
G = self.mesh.cellGrad
|
||||
A = self.createMatrix(m)
|
||||
Av_dm = self.mesh.getFaceMassDeriv()
|
||||
mT_dm = self.modelTransformDeriv(m)
|
||||
mT_dm = self.model.transformDeriv(m)
|
||||
|
||||
dCdu = A.T
|
||||
solve = Solver(dCdu)
|
||||
@@ -130,7 +142,7 @@ class DCProblem(ModelTransforms.LogModel, Problem):
|
||||
|
||||
Jtv = 0
|
||||
for i, ui in enumerate(u.T): # loop over each column
|
||||
Jtv += sdiag( G * ui ) * ( D.T * w[:,i] )
|
||||
Jtv += Utils.sdiag( G * ui ) * ( D.T * w[:,i] )
|
||||
|
||||
Jtv = - mT_dm.T * ( Av_dm.T * Jtv )
|
||||
return Jtv
|
||||
@@ -165,16 +177,13 @@ def genTxRxmat(nelec, spacelec, surfloc, elecini, mesh):
|
||||
return q, Q, rxmidLoc
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
from SimPEG import inverse
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Create the mesh
|
||||
h1 = np.ones(20)
|
||||
h2 = np.ones(100)
|
||||
mesh = TensorMesh([h1,h2])
|
||||
M = Mesh.TensorMesh([h1,h2])
|
||||
|
||||
# Create some parameters for the model
|
||||
sig1 = np.log(1)
|
||||
@@ -184,9 +193,9 @@ if __name__ == '__main__':
|
||||
p0 = [5, 10]
|
||||
p1 = [15, 50]
|
||||
condVals = [sig1, sig2]
|
||||
mSynth = ModelBuilder.defineBlockConductivity(p0,p1,mesh.gridCC,condVals)
|
||||
plt.colorbar(mesh.plotImage(mSynth))
|
||||
plt.show()
|
||||
mSynth = Utils.ModelBuilder.defineBlockConductivity(M.gridCC,p0,p1,condVals)
|
||||
plt.colorbar(M.plotImage(mSynth))
|
||||
# plt.show()
|
||||
|
||||
# Set up the projection
|
||||
nelec = 50
|
||||
@@ -196,41 +205,40 @@ if __name__ == '__main__':
|
||||
elecend = 0.5+spacelec*(nelec-1)
|
||||
elecLocR = np.linspace(elecini, elecend, nelec)
|
||||
rxmidLoc = (elecLocR[0:nelec-1]+elecLocR[1:nelec])*0.5
|
||||
q, Q, rxmidloc = genTxRxmat(nelec, spacelec, surfloc, elecini, mesh)
|
||||
q, Q, rxmidloc = genTxRxmat(nelec, spacelec, surfloc, elecini, M)
|
||||
P = Q.T
|
||||
|
||||
model = Model.LogModel(M)
|
||||
prob = DCProblem(M, model)
|
||||
|
||||
# Create some data
|
||||
problem = DCProblem(mesh)
|
||||
problem.P = P
|
||||
problem.RHS = q
|
||||
dobs, Wd = problem.createSyntheticData(mSynth, std=0.05)
|
||||
data = prob.createSyntheticData(mSynth, std=0.05, P=P, RHS=q)
|
||||
|
||||
u = problem.field(mSynth)
|
||||
u = problem.reshapeFields(u)
|
||||
mesh.plotImage(u[:,10])
|
||||
# plt.show()
|
||||
u = prob.field(mSynth)
|
||||
u = data.reshapeFields(u)
|
||||
M.plotImage(u[:,10])
|
||||
plt.show()
|
||||
|
||||
# Now set up the problem to do some minimization
|
||||
problem.dobs = dobs
|
||||
problem.std = dobs*0 + 0.05
|
||||
m0 = mesh.gridCC[:,0]*0+sig2
|
||||
# Now set up the prob to do some minimization
|
||||
# prob.dobs = dobs
|
||||
# prob.std = dobs*0 + 0.05
|
||||
m0 = M.gridCC[:,0]*0+sig2
|
||||
|
||||
opt = inverse.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6)
|
||||
reg = inverse.Regularization(mesh)
|
||||
inv = inverse.Inversion(problem, reg, opt, beta0=1e4)
|
||||
reg = Regularization.Tikhonov(model)
|
||||
objFunc = ObjFunction.BaseObjFunction(data, reg)
|
||||
opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=3, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6)
|
||||
inv = Inversion.BaseInversion(objFunc, opt)
|
||||
|
||||
# Check Derivative
|
||||
derChk = lambda m: [inv.dataObj(m), inv.dataObjDeriv(m)]
|
||||
checkDerivative(derChk, mSynth)
|
||||
derChk = lambda m: [objFunc.dataObj(m), objFunc.dataObjDeriv(m)]
|
||||
# Tests.checkDerivative(derChk, mSynth)
|
||||
|
||||
|
||||
|
||||
print inv.dataObj(m0)
|
||||
print inv.dataObj(mSynth)
|
||||
print objFunc.dataObj(m0)
|
||||
print objFunc.dataObj(mSynth)
|
||||
|
||||
m = inv.run(m0)
|
||||
|
||||
plt.colorbar(mesh.plotImage(m))
|
||||
plt.colorbar(M.plotImage(m))
|
||||
print m
|
||||
plt.show()
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
from SimPEG import mesh, forward, inverse, np
|
||||
from SimPEG import *
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
class LinearProblem(forward.Problem):
|
||||
class LinearProblem(Problem.BaseProblem):
|
||||
"""docstring for LinearProblem"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
forward.Problem.__init__(self, *args, **kwargs)
|
||||
def __init__(self, mesh, model, G, **kwargs):
|
||||
Problem.BaseProblem.__init__(self, mesh, model, **kwargs)
|
||||
self.G = G
|
||||
|
||||
def dpred(self, m, u=None):
|
||||
def field(self, m, u=None):
|
||||
return self.G.dot(m)
|
||||
|
||||
def J(self, m, v, u=None):
|
||||
@@ -20,7 +21,7 @@ class LinearProblem(forward.Problem):
|
||||
|
||||
def example(N):
|
||||
h = np.ones(N)/N
|
||||
M = mesh.TensorMesh([h])
|
||||
M = Mesh.TensorMesh([h])
|
||||
|
||||
nk = 20
|
||||
jk = np.linspace(1.,20.,nk)
|
||||
@@ -39,21 +40,24 @@ def example(N):
|
||||
mtrue[M.vectorCCx > 0.45] = -0.5
|
||||
mtrue[M.vectorCCx > 0.6] = 0
|
||||
|
||||
prob = LinearProblem(M)
|
||||
prob.G = G
|
||||
|
||||
|
||||
model = Model.BaseModel(M)
|
||||
prob = LinearProblem(M, model, G)
|
||||
data = prob.createSyntheticData(mtrue, std=0.01)
|
||||
|
||||
return prob, data
|
||||
return prob, data, model
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
prob, data = example(100)
|
||||
prob, data, model = example(100)
|
||||
M = prob.mesh
|
||||
|
||||
reg = inverse.Regularization(M)
|
||||
opt = inverse.InexactGaussNewton(maxIter=20)
|
||||
inv = inverse.Inversion(prob,reg,opt,data)
|
||||
reg = Regularization.Tikhonov(model)
|
||||
objFunc = ObjFunction.BaseObjFunction(data, reg)
|
||||
opt = Optimization.InexactGaussNewton(maxIter=20)
|
||||
inv = Inversion.BaseInversion(objFunc, opt)
|
||||
m0 = np.zeros_like(data.mtrue)
|
||||
|
||||
mrec = inv.run(m0)
|
||||
File renamed without changes.
@@ -0,0 +1,125 @@
|
||||
import SimPEG
|
||||
from SimPEG import Utils, sp, np
|
||||
from Optimization import Remember, IterationPrinters
|
||||
|
||||
|
||||
class BaseInversion(object):
|
||||
"""BaseInversion(objFunc, opt, **kwargs)
|
||||
"""
|
||||
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
name = 'BaseInversion'
|
||||
|
||||
debug = False #: Print debugging information
|
||||
|
||||
counter = None #: Set this to a SimPEG.Utils.Counter() if you want to count things
|
||||
|
||||
def __init__(self, objFunc, opt, **kwargs):
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
self.objFunc = objFunc
|
||||
self.objFunc.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(objFunc.reg.modelObj2Deriv())
|
||||
|
||||
|
||||
#TODO: Move this to the data class?
|
||||
@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.objFunc.startup(m0)
|
||||
self.m = self.opt.minimize(self.objFunc.evalFunction, m0)
|
||||
self.finish()
|
||||
|
||||
return self.m
|
||||
|
||||
@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)
|
||||
@@ -1,5 +1,5 @@
|
||||
import numpy as np
|
||||
from SimPEG import utils
|
||||
from SimPEG import Utils
|
||||
|
||||
|
||||
class BaseMesh(object):
|
||||
@@ -78,7 +78,7 @@ class BaseMesh(object):
|
||||
x_array = np.ones((x.size, len(x)))
|
||||
# Unwrap it and put it in a np array
|
||||
for i, xi in enumerate(x):
|
||||
x_array[:, i] = utils.mkvc(xi)
|
||||
x_array[:, i] = Utils.mkvc(xi)
|
||||
x = x_array
|
||||
|
||||
assert type(x) == np.ndarray, "x must be a numpy array"
|
||||
@@ -91,17 +91,17 @@ class BaseMesh(object):
|
||||
if format == 'M':
|
||||
return xx.reshape(nn, order='F')
|
||||
elif format == 'V':
|
||||
return utils.mkvc(xx)
|
||||
return Utils.mkvc(xx)
|
||||
|
||||
def switchKernal(xx):
|
||||
"""Switches over the different options."""
|
||||
if xType in ['CC', 'N']:
|
||||
nn = (self.n) if xType == 'CC' else (self.n+1)
|
||||
nn = (self._n) if xType == 'CC' else (self._n+1)
|
||||
assert xx.size == np.prod(nn), "Number of elements must not change."
|
||||
return outKernal(xx, nn)
|
||||
elif xType in ['F', 'E']:
|
||||
# This will only deal with components of fields, not full 'F' or 'E'
|
||||
xx = utils.mkvc(xx) # unwrap it in case it is a matrix
|
||||
xx = Utils.mkvc(xx) # unwrap it in case it is a matrix
|
||||
nn = self.nFv if xType == 'F' else self.nEv
|
||||
nn = np.r_[0, nn]
|
||||
|
||||
@@ -147,16 +147,6 @@ class BaseMesh(object):
|
||||
else:
|
||||
return switchKernal(x)
|
||||
|
||||
def n():
|
||||
doc = """
|
||||
Number of Cells in each dimension (array of integers)
|
||||
|
||||
:rtype: numpy.array
|
||||
:return: n
|
||||
"""
|
||||
fget = lambda self: self._n
|
||||
return locals()
|
||||
n = property(**n())
|
||||
|
||||
def dim():
|
||||
doc = """
|
||||
@@ -176,7 +166,7 @@ class BaseMesh(object):
|
||||
:rtype: int
|
||||
:return: nCx
|
||||
"""
|
||||
fget = lambda self: self.n[0]
|
||||
fget = lambda self: self._n[0]
|
||||
return locals()
|
||||
nCx = property(**nCx())
|
||||
|
||||
@@ -190,7 +180,7 @@ class BaseMesh(object):
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 1:
|
||||
return self.n[1]
|
||||
return self._n[1]
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
@@ -205,7 +195,7 @@ class BaseMesh(object):
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 2:
|
||||
return self.n[2]
|
||||
return self._n[2]
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
@@ -219,12 +209,12 @@ class BaseMesh(object):
|
||||
:return: nC
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG.mesh import TensorMesh
|
||||
import numpy as np
|
||||
TensorMesh([np.ones(n) for n in [2,3]]).plotGrid(centers=True,showIt=True)
|
||||
from SimPEG import Mesh, np
|
||||
Mesh.TensorMesh([np.ones(n) for n in [2,3]]).plotGrid(centers=True,showIt=True)
|
||||
"""
|
||||
fget = lambda self: np.prod(self.n)
|
||||
fget = lambda self: np.prod(self._n)
|
||||
return locals()
|
||||
nC = property(**nC())
|
||||
|
||||
@@ -260,7 +250,7 @@ class BaseMesh(object):
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 1:
|
||||
return self.n[1] + 1
|
||||
return self._n[1] + 1
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
@@ -276,7 +266,7 @@ class BaseMesh(object):
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 2:
|
||||
return self.n[2] + 1
|
||||
return self._n[2] + 1
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
@@ -290,12 +280,12 @@ class BaseMesh(object):
|
||||
:return: nN
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG.mesh import TensorMesh
|
||||
import numpy as np
|
||||
TensorMesh([np.ones(n) for n in [2,3]]).plotGrid(nodes=True,showIt=True)
|
||||
from SimPEG import Mesh, np
|
||||
Mesh.TensorMesh([np.ones(n) for n in [2,3]]).plotGrid(nodes=True,showIt=True)
|
||||
"""
|
||||
fget = lambda self: np.prod(self.n + 1)
|
||||
fget = lambda self: np.prod(self.nCv + 1)
|
||||
return locals()
|
||||
nN = property(**nN())
|
||||
|
||||
@@ -361,10 +351,10 @@ class BaseMesh(object):
|
||||
:return: [prod(nEx), prod(nEy), prod(nEz)]
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG.mesh import TensorMesh
|
||||
import numpy as np
|
||||
TensorMesh([np.ones(n) for n in [2,3]]).plotGrid(edges=True,showIt=True)
|
||||
from SimPEG import Mesh, np
|
||||
Mesh.TensorMesh([np.ones(n) for n in [2,3]]).plotGrid(edges=True,showIt=True)
|
||||
"""
|
||||
fget = lambda self: np.array([np.prod(x) for x in [self.nEx, self.nEy, self.nEz] if not x is None])
|
||||
return locals()
|
||||
@@ -433,10 +423,10 @@ class BaseMesh(object):
|
||||
:return: [prod(nFx), prod(nFy), prod(nFz)]
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG.mesh import TensorMesh
|
||||
import numpy as np
|
||||
TensorMesh([np.ones(n) for n in [2,3]]).plotGrid(faces=True,showIt=True)
|
||||
from SimPEG import Mesh, np
|
||||
Mesh.TensorMesh([np.ones(n) for n in [2,3]]).plotGrid(faces=True,showIt=True)
|
||||
"""
|
||||
fget = lambda self: np.array([np.prod(x) for x in [self.nFx, self.nFy, self.nFz] if not x is None])
|
||||
return locals()
|
||||
@@ -1,7 +1,7 @@
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
from scipy.constants import pi
|
||||
from SimPEG.utils import mkvc, ndgrid, sdiag
|
||||
from SimPEG.Utils import mkvc, ndgrid, sdiag
|
||||
|
||||
class Cyl1DMesh(object):
|
||||
"""
|
||||
@@ -84,7 +84,7 @@ class Cyl1DMesh(object):
|
||||
doc = "Total number of cells in each direction"
|
||||
fget = lambda self: np.array([self.nCx, self.nCz])
|
||||
return locals()
|
||||
nCv = property(**nCv())
|
||||
nCv = property(**nCv())
|
||||
|
||||
def nNr():
|
||||
doc = "Number of nodes in the radial direction"
|
||||
@@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
from scipy import sparse as sp
|
||||
from SimPEG.utils import mkvc, sdiag, speye, kron3, spzeros, ddx, av, avExtrap
|
||||
from SimPEG.Utils import mkvc, sdiag, speye, kron3, spzeros, ddx, av, avExtrap
|
||||
|
||||
|
||||
def checkBC(bc):
|
||||
@@ -129,7 +129,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._faceDiv is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
# Compute faceDivergence operator on faces
|
||||
if(self.dim == 1):
|
||||
D = ddx(n[0])
|
||||
@@ -158,7 +158,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._faceDivx is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
# Compute faceDivergence operator on faces
|
||||
if(self.dim == 1):
|
||||
D1 = ddx(n[0])
|
||||
@@ -183,7 +183,7 @@ class DiffOperators(object):
|
||||
if(self.dim < 2): return None
|
||||
if(self._faceDivy is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
# Compute faceDivergence operator on faces
|
||||
if(self.dim == 2):
|
||||
D2 = sp.kron(ddx(n[1]), speye(n[0]))
|
||||
@@ -225,7 +225,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._nodalGrad is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
# Compute divergence operator on faces
|
||||
if(self.dim == 1):
|
||||
G = ddx(n[0])
|
||||
@@ -253,7 +253,7 @@ class DiffOperators(object):
|
||||
if(self._nodalLaplacian is None):
|
||||
print 'Warning: Laplacian has not been tested rigorously.'
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
# Compute divergence operator on faces
|
||||
if(self.dim == 1):
|
||||
D1 = sdiag(1./self.hx) * ddx(mesh.nCx)
|
||||
@@ -291,7 +291,7 @@ class DiffOperators(object):
|
||||
|
||||
"""
|
||||
if(type(BC) is str):
|
||||
BC = [BC for _ in self.n] # Repeat the str self.dim times
|
||||
BC = [BC for _ in self.nCv] # Repeat the str self.dim times
|
||||
elif(type(BC) is list):
|
||||
assert len(BC) == self.dim, 'BC list must be the size of your mesh'
|
||||
else:
|
||||
@@ -313,7 +313,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._cellGrad is None):
|
||||
BC = self.setCellGradBC(self._cellGradBC_list)
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
G = ddxCellGrad(n[0], BC[0])
|
||||
elif(self.dim == 2):
|
||||
@@ -340,7 +340,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._cellGradBC is None):
|
||||
BC = self.setCellGradBC(self._cellGradBC_list)
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
G = ddxCellGradBC(n[0], BC[0])
|
||||
elif(self.dim == 2):
|
||||
@@ -367,7 +367,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if getattr(self, '_cellGradx', None) is None:
|
||||
BC = ['neumann', 'neumann']
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
G1 = ddxCellGrad(n[0], BC)
|
||||
elif(self.dim == 2):
|
||||
@@ -388,7 +388,7 @@ class DiffOperators(object):
|
||||
if self.dim < 2: return None
|
||||
if getattr(self, '_cellGrady', None) is None:
|
||||
BC = ['neumann', 'neumann']
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 2):
|
||||
G2 = sp.kron(ddxCellGrad(n[1], BC), speye(n[0]))
|
||||
elif(self.dim == 3):
|
||||
@@ -422,6 +422,7 @@ class DiffOperators(object):
|
||||
|
||||
def fget(self):
|
||||
if(self._edgeCurl is None):
|
||||
assert self.dim > 2, "Edge Curl only programed for 3D."
|
||||
# The number of cell centers in each direction
|
||||
n1 = self.nCx
|
||||
n2 = self.nCy
|
||||
@@ -466,7 +467,7 @@ class DiffOperators(object):
|
||||
|
||||
def fget(self):
|
||||
if(self._aveF2CC is None):
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
self._aveF2CC = av(n[0])
|
||||
elif(self.dim == 2):
|
||||
@@ -486,7 +487,7 @@ class DiffOperators(object):
|
||||
|
||||
def fget(self):
|
||||
if(self._aveCC2F is None):
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
self._aveCC2F = avExtrap(n[0])
|
||||
elif(self.dim == 2):
|
||||
@@ -507,7 +508,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._aveE2CC is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
raise Exception('Edge Averaging does not make sense in 1D: Use Identity?')
|
||||
elif(self.dim == 2):
|
||||
@@ -528,7 +529,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._aveN2CC is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
self._aveN2CC = av(n[0])
|
||||
elif(self.dim == 2):
|
||||
@@ -546,7 +547,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._aveN2E is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
self._aveN2E = av(n[0])
|
||||
elif(self.dim == 2):
|
||||
@@ -567,7 +568,7 @@ class DiffOperators(object):
|
||||
def fget(self):
|
||||
if(self._aveN2F is None):
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
if(self.dim == 1):
|
||||
self._aveN2F = av(n[0])
|
||||
elif(self.dim == 2):
|
||||
@@ -1,5 +1,5 @@
|
||||
from scipy import sparse as sp
|
||||
from SimPEG.utils import sub2ind, ndgrid, mkvc, getSubArray, sdiag, inv3X3BlockDiagonal, inv2X2BlockDiagonal
|
||||
from SimPEG.Utils import sub2ind, ndgrid, mkvc, getSubArray, sdiag, inv3X3BlockDiagonal, inv2X2BlockDiagonal
|
||||
import numpy as np
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from SimPEG import utils, np
|
||||
from SimPEG import Utils, np
|
||||
from BaseMesh import BaseMesh
|
||||
from DiffOperators import DiffOperators
|
||||
from InnerProducts import InnerProducts
|
||||
@@ -7,8 +7,8 @@ from LomView import LomView
|
||||
# Some helper functions.
|
||||
length2D = lambda x: (x[:, 0]**2 + x[:, 1]**2)**0.5
|
||||
length3D = lambda x: (x[:, 0]**2 + x[:, 1]**2 + x[:, 2]**2)**0.5
|
||||
normalize2D = lambda x: x/np.kron(np.ones((1, 2)), utils.mkvc(length2D(x), 2))
|
||||
normalize3D = lambda x: x/np.kron(np.ones((1, 3)), utils.mkvc(length3D(x), 2))
|
||||
normalize2D = lambda x: x/np.kron(np.ones((1, 2)), Utils.mkvc(length2D(x), 2))
|
||||
normalize3D = lambda x: x/np.kron(np.ones((1, 3)), Utils.mkvc(length3D(x), 2))
|
||||
|
||||
|
||||
class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
@@ -17,11 +17,16 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
|
||||
Example of a logically orthogonal mesh:
|
||||
|
||||
.. plot:: examples/mesh/plot_LogicallyOrthogonalMesh.py
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, Utils
|
||||
X, Y = Utils.exampleLomGird([3,3],'rotate')
|
||||
M = Mesh.LogicallyOrthogonalMesh([X, Y])
|
||||
M.plotGrid(showIt=True)
|
||||
"""
|
||||
|
||||
__metaclass__ = utils.Save.Savable
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
_meshType = 'LOM'
|
||||
|
||||
@@ -40,7 +45,7 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
# Save nodes to private variable _gridN as vectors
|
||||
self._gridN = np.ones((nodes[0].size, self.dim))
|
||||
for i, node_i in enumerate(nodes):
|
||||
self._gridN[:, i] = utils.mkvc(node_i.astype(float))
|
||||
self._gridN[:, i] = Utils.mkvc(node_i.astype(float))
|
||||
|
||||
def gridCC():
|
||||
doc = "Cell-centered grid."
|
||||
@@ -71,10 +76,10 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
if self._gridFx is None:
|
||||
N = self.r(self.gridN, 'N', 'N', 'M')
|
||||
if self.dim == 2:
|
||||
XY = [utils.mkvc(0.5 * (n[:, :-1] + n[:, 1:])) for n in N]
|
||||
XY = [Utils.mkvc(0.5 * (n[:, :-1] + n[:, 1:])) for n in N]
|
||||
self._gridFx = np.c_[XY[0], XY[1]]
|
||||
elif self.dim == 3:
|
||||
XYZ = [utils.mkvc(0.25 * (n[:, :-1, :-1] + n[:, :-1, 1:] + n[:, 1:, :-1] + n[:, 1:, 1:])) for n in N]
|
||||
XYZ = [Utils.mkvc(0.25 * (n[:, :-1, :-1] + n[:, :-1, 1:] + n[:, 1:, :-1] + n[:, 1:, 1:])) for n in N]
|
||||
self._gridFx = np.c_[XYZ[0], XYZ[1], XYZ[2]]
|
||||
return self._gridFx
|
||||
return locals()
|
||||
@@ -88,10 +93,10 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
if self._gridFy is None:
|
||||
N = self.r(self.gridN, 'N', 'N', 'M')
|
||||
if self.dim == 2:
|
||||
XY = [utils.mkvc(0.5 * (n[:-1, :] + n[1:, :])) for n in N]
|
||||
XY = [Utils.mkvc(0.5 * (n[:-1, :] + n[1:, :])) for n in N]
|
||||
self._gridFy = np.c_[XY[0], XY[1]]
|
||||
elif self.dim == 3:
|
||||
XYZ = [utils.mkvc(0.25 * (n[:-1, :, :-1] + n[:-1, :, 1:] + n[1:, :, :-1] + n[1:, :, 1:])) for n in N]
|
||||
XYZ = [Utils.mkvc(0.25 * (n[:-1, :, :-1] + n[:-1, :, 1:] + n[1:, :, :-1] + n[1:, :, 1:])) for n in N]
|
||||
self._gridFy = np.c_[XYZ[0], XYZ[1], XYZ[2]]
|
||||
return self._gridFy
|
||||
return locals()
|
||||
@@ -104,7 +109,7 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
def fget(self):
|
||||
if self._gridFz is None and self.dim == 3:
|
||||
N = self.r(self.gridN, 'N', 'N', 'M')
|
||||
XYZ = [utils.mkvc(0.25 * (n[:-1, :-1, :] + n[:-1, 1:, :] + n[1:, :-1, :] + n[1:, 1:, :])) for n in N]
|
||||
XYZ = [Utils.mkvc(0.25 * (n[:-1, :-1, :] + n[:-1, 1:, :] + n[1:, :-1, :] + n[1:, 1:, :])) for n in N]
|
||||
self._gridFz = np.c_[XYZ[0], XYZ[1], XYZ[2]]
|
||||
return self._gridFz
|
||||
return locals()
|
||||
@@ -118,10 +123,10 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
if self._gridEx is None:
|
||||
N = self.r(self.gridN, 'N', 'N', 'M')
|
||||
if self.dim == 2:
|
||||
XY = [utils.mkvc(0.5 * (n[:-1, :] + n[1:, :])) for n in N]
|
||||
XY = [Utils.mkvc(0.5 * (n[:-1, :] + n[1:, :])) for n in N]
|
||||
self._gridEx = np.c_[XY[0], XY[1]]
|
||||
elif self.dim == 3:
|
||||
XYZ = [utils.mkvc(0.5 * (n[:-1, :, :] + n[1:, :, :])) for n in N]
|
||||
XYZ = [Utils.mkvc(0.5 * (n[:-1, :, :] + n[1:, :, :])) for n in N]
|
||||
self._gridEx = np.c_[XYZ[0], XYZ[1], XYZ[2]]
|
||||
return self._gridEx
|
||||
return locals()
|
||||
@@ -135,10 +140,10 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
if self._gridEy is None:
|
||||
N = self.r(self.gridN, 'N', 'N', 'M')
|
||||
if self.dim == 2:
|
||||
XY = [utils.mkvc(0.5 * (n[:, :-1] + n[:, 1:])) for n in N]
|
||||
XY = [Utils.mkvc(0.5 * (n[:, :-1] + n[:, 1:])) for n in N]
|
||||
self._gridEy = np.c_[XY[0], XY[1]]
|
||||
elif self.dim == 3:
|
||||
XYZ = [utils.mkvc(0.5 * (n[:, :-1, :] + n[:, 1:, :])) for n in N]
|
||||
XYZ = [Utils.mkvc(0.5 * (n[:, :-1, :] + n[:, 1:, :])) for n in N]
|
||||
self._gridEy = np.c_[XYZ[0], XYZ[1], XYZ[2]]
|
||||
return self._gridEy
|
||||
return locals()
|
||||
@@ -151,7 +156,7 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
def fget(self):
|
||||
if self._gridEz is None and self.dim == 3:
|
||||
N = self.r(self.gridN, 'N', 'N', 'M')
|
||||
XYZ = [utils.mkvc(0.5 * (n[:, :, :-1] + n[:, :, 1:])) for n in N]
|
||||
XYZ = [Utils.mkvc(0.5 * (n[:, :, :-1] + n[:, :, 1:])) for n in N]
|
||||
self._gridEz = np.c_[XYZ[0], XYZ[1], XYZ[2]]
|
||||
return self._gridEz
|
||||
return locals()
|
||||
@@ -194,25 +199,25 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
def fget(self):
|
||||
if(self._vol is None):
|
||||
if self.dim == 2:
|
||||
A, B, C, D = utils.indexCube('ABCD', self.n+1)
|
||||
normal, area = utils.faceInfo(np.c_[self.gridN, np.zeros((self.nN, 1))], A, B, C, D)
|
||||
A, B, C, D = Utils.indexCube('ABCD', self.nCv+1)
|
||||
normal, area = Utils.faceInfo(np.c_[self.gridN, np.zeros((self.nN, 1))], A, B, C, D)
|
||||
self._vol = area
|
||||
elif self.dim == 3:
|
||||
# Each polyhedron can be decomposed into 5 tetrahedrons
|
||||
# However, this presents a choice so we may as well divide in two ways and average.
|
||||
A, B, C, D, E, F, G, H = utils.indexCube('ABCDEFGH', self.n+1)
|
||||
A, B, C, D, E, F, G, H = Utils.indexCube('ABCDEFGH', self.nCv+1)
|
||||
|
||||
vol1 = (utils.volTetra(self.gridN, A, B, D, E) + # cutted edge top
|
||||
utils.volTetra(self.gridN, B, E, F, G) + # cutted edge top
|
||||
utils.volTetra(self.gridN, B, D, E, G) + # middle
|
||||
utils.volTetra(self.gridN, B, C, D, G) + # cutted edge bottom
|
||||
utils.volTetra(self.gridN, D, E, G, H)) # cutted edge bottom
|
||||
vol1 = (Utils.volTetra(self.gridN, A, B, D, E) + # cutted edge top
|
||||
Utils.volTetra(self.gridN, B, E, F, G) + # cutted edge top
|
||||
Utils.volTetra(self.gridN, B, D, E, G) + # middle
|
||||
Utils.volTetra(self.gridN, B, C, D, G) + # cutted edge bottom
|
||||
Utils.volTetra(self.gridN, D, E, G, H)) # cutted edge bottom
|
||||
|
||||
vol2 = (utils.volTetra(self.gridN, A, F, B, C) + # cutted edge top
|
||||
utils.volTetra(self.gridN, A, E, F, H) + # cutted edge top
|
||||
utils.volTetra(self.gridN, A, H, F, C) + # middle
|
||||
utils.volTetra(self.gridN, C, H, D, A) + # cutted edge bottom
|
||||
utils.volTetra(self.gridN, C, G, H, F)) # cutted edge bottom
|
||||
vol2 = (Utils.volTetra(self.gridN, A, F, B, C) + # cutted edge top
|
||||
Utils.volTetra(self.gridN, A, E, F, H) + # cutted edge top
|
||||
Utils.volTetra(self.gridN, A, H, F, C) + # middle
|
||||
Utils.volTetra(self.gridN, C, H, D, A) + # cutted edge bottom
|
||||
Utils.volTetra(self.gridN, C, G, H, F)) # cutted edge bottom
|
||||
|
||||
self._vol = (vol1 + vol2)/2
|
||||
return self._vol
|
||||
@@ -228,30 +233,30 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
# Compute areas of cell faces
|
||||
if(self.dim == 2):
|
||||
xy = self.gridN
|
||||
A, B = utils.indexCube('AB', self.n+1, np.array([self.nNx, self.nCy]))
|
||||
A, B = Utils.indexCube('AB', self.nCv+1, np.array([self.nNx, self.nCy]))
|
||||
edge1 = xy[B, :] - xy[A, :]
|
||||
normal1 = np.c_[edge1[:, 1], -edge1[:, 0]]
|
||||
area1 = length2D(edge1)
|
||||
A, D = utils.indexCube('AD', self.n+1, np.array([self.nCx, self.nNy]))
|
||||
A, D = Utils.indexCube('AD', self.nCv+1, np.array([self.nCx, self.nNy]))
|
||||
# Note that we are doing A-D to make sure the normal points the right way.
|
||||
# Think about it. Look at the picture. Normal points towards C iff you do this.
|
||||
edge2 = xy[A, :] - xy[D, :]
|
||||
normal2 = np.c_[edge2[:, 1], -edge2[:, 0]]
|
||||
area2 = length2D(edge2)
|
||||
self._area = np.r_[utils.mkvc(area1), utils.mkvc(area2)]
|
||||
self._area = np.r_[Utils.mkvc(area1), Utils.mkvc(area2)]
|
||||
self._normals = [normalize2D(normal1), normalize2D(normal2)]
|
||||
elif(self.dim == 3):
|
||||
|
||||
A, E, F, B = utils.indexCube('AEFB', self.n+1, np.array([self.nNx, self.nCy, self.nCz]))
|
||||
normal1, area1 = utils.faceInfo(self.gridN, A, E, F, B, average=False, normalizeNormals=False)
|
||||
A, E, F, B = Utils.indexCube('AEFB', self.nCv+1, np.array([self.nNx, self.nCy, self.nCz]))
|
||||
normal1, area1 = Utils.faceInfo(self.gridN, A, E, F, B, average=False, normalizeNormals=False)
|
||||
|
||||
A, D, H, E = utils.indexCube('ADHE', self.n+1, np.array([self.nCx, self.nNy, self.nCz]))
|
||||
normal2, area2 = utils.faceInfo(self.gridN, A, D, H, E, average=False, normalizeNormals=False)
|
||||
A, D, H, E = Utils.indexCube('ADHE', self.nCv+1, np.array([self.nCx, self.nNy, self.nCz]))
|
||||
normal2, area2 = Utils.faceInfo(self.gridN, A, D, H, E, average=False, normalizeNormals=False)
|
||||
|
||||
A, B, C, D = utils.indexCube('ABCD', self.n+1, np.array([self.nCx, self.nCy, self.nNz]))
|
||||
normal3, area3 = utils.faceInfo(self.gridN, A, B, C, D, average=False, normalizeNormals=False)
|
||||
A, B, C, D = Utils.indexCube('ABCD', self.nCv+1, np.array([self.nCx, self.nCy, self.nNz]))
|
||||
normal3, area3 = Utils.faceInfo(self.gridN, A, B, C, D, average=False, normalizeNormals=False)
|
||||
|
||||
self._area = np.r_[utils.mkvc(area1), utils.mkvc(area2), utils.mkvc(area3)]
|
||||
self._area = np.r_[Utils.mkvc(area1), Utils.mkvc(area2), Utils.mkvc(area3)]
|
||||
self._normals = [normal1, normal2, normal3]
|
||||
return self._area
|
||||
return locals()
|
||||
@@ -291,21 +296,21 @@ class LogicallyOrthogonalMesh(BaseMesh, DiffOperators, InnerProducts, LomView):
|
||||
if(self._edge is None or self._tangents is None):
|
||||
if(self.dim == 2):
|
||||
xy = self.gridN
|
||||
A, D = utils.indexCube('AD', self.n+1, np.array([self.nCx, self.nNy]))
|
||||
A, D = Utils.indexCube('AD', self.nCv+1, np.array([self.nCx, self.nNy]))
|
||||
edge1 = xy[D, :] - xy[A, :]
|
||||
A, B = utils.indexCube('AB', self.n+1, np.array([self.nNx, self.nCy]))
|
||||
A, B = Utils.indexCube('AB', self.nCv+1, np.array([self.nNx, self.nCy]))
|
||||
edge2 = xy[B, :] - xy[A, :]
|
||||
self._edge = np.r_[utils.mkvc(length2D(edge1)), utils.mkvc(length2D(edge2))]
|
||||
self._edge = np.r_[Utils.mkvc(length2D(edge1)), Utils.mkvc(length2D(edge2))]
|
||||
self._tangents = np.r_[edge1, edge2]/np.c_[self._edge, self._edge]
|
||||
elif(self.dim == 3):
|
||||
xyz = self.gridN
|
||||
A, D = utils.indexCube('AD', self.n+1, np.array([self.nCx, self.nNy, self.nNz]))
|
||||
A, D = Utils.indexCube('AD', self.nCv+1, np.array([self.nCx, self.nNy, self.nNz]))
|
||||
edge1 = xyz[D, :] - xyz[A, :]
|
||||
A, B = utils.indexCube('AB', self.n+1, np.array([self.nNx, self.nCy, self.nNz]))
|
||||
A, B = Utils.indexCube('AB', self.nCv+1, np.array([self.nNx, self.nCy, self.nNz]))
|
||||
edge2 = xyz[B, :] - xyz[A, :]
|
||||
A, E = utils.indexCube('AE', self.n+1, np.array([self.nNx, self.nNy, self.nCz]))
|
||||
A, E = Utils.indexCube('AE', self.nCv+1, np.array([self.nNx, self.nNy, self.nCz]))
|
||||
edge3 = xyz[E, :] - xyz[A, :]
|
||||
self._edge = np.r_[utils.mkvc(length3D(edge1)), utils.mkvc(length3D(edge2)), utils.mkvc(length3D(edge3))]
|
||||
self._edge = np.r_[Utils.mkvc(length3D(edge1)), Utils.mkvc(length3D(edge2)), Utils.mkvc(length3D(edge3))]
|
||||
self._tangents = np.r_[edge1, edge2, edge3]/np.c_[self._edge, self._edge, self._edge]
|
||||
return self._edge
|
||||
return locals()
|
||||
@@ -331,10 +336,10 @@ if __name__ == '__main__':
|
||||
h3 = np.cumsum(np.r_[0, np.ones(nc)/(nc)])
|
||||
dee3 = True
|
||||
if dee3:
|
||||
X, Y, Z = utils.ndgrid(h1, h2, h3, vector=False)
|
||||
X, Y, Z = Utils.ndgrid(h1, h2, h3, vector=False)
|
||||
M = LogicallyOrthogonalMesh([X, Y, Z])
|
||||
else:
|
||||
X, Y = utils.ndgrid(h1, h2, vector=False)
|
||||
X, Y = Utils.ndgrid(h1, h2, vector=False)
|
||||
M = LogicallyOrthogonalMesh([X, Y])
|
||||
|
||||
print M.r(M.normals, 'F', 'Fx', 'V')
|
||||
@@ -2,7 +2,7 @@ import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
from SimPEG.utils import mkvc
|
||||
from SimPEG.Utils import mkvc
|
||||
|
||||
|
||||
class LomView(object):
|
||||
@@ -15,10 +15,18 @@ class LomView(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def plotGrid(self, length=0.05):
|
||||
def plotGrid(self, length=0.05, showIt=False):
|
||||
"""Plot the nodal, cell-centered and staggered grids for 1,2 and 3 dimensions.
|
||||
|
||||
.. plot:: examples/mesh/plot_LogicallyOrthogonalMesh.py
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, Utils
|
||||
X, Y = Utils.exampleLomGird([3,3],'rotate')
|
||||
M = Mesh.LogicallyOrthogonalMesh([X, Y])
|
||||
M.plotGrid(showIt=True)
|
||||
|
||||
"""
|
||||
NN = self.r(self.gridN, 'N', 'N', 'M')
|
||||
if self.dim == 2:
|
||||
@@ -92,4 +100,5 @@ class LomView(object):
|
||||
ax.hold(False)
|
||||
ax.set_xlabel('x1')
|
||||
ax.set_ylabel('x2')
|
||||
fig.show()
|
||||
|
||||
if showIt: plt.show()
|
||||
@@ -1,4 +1,4 @@
|
||||
from SimPEG import utils, np, sp
|
||||
from SimPEG import Utils, np, sp
|
||||
from BaseMesh import BaseMesh
|
||||
from TensorView import TensorView
|
||||
from DiffOperators import DiffOperators
|
||||
@@ -17,23 +17,23 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
hy = np.array([1,2])
|
||||
hz = np.array([1,1,1,1])
|
||||
|
||||
mesh = TensorMesh([hx, hy, hz])
|
||||
mesh = Mesh.TensorMesh([hx, hy, hz])
|
||||
|
||||
Example of a padded tensor mesh:
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import mesh, utils
|
||||
M = mesh.TensorMesh(utils.meshTensors(((10,10),(40,10),(10,10)), ((10,10),(20,10),(0,0))))
|
||||
from SimPEG import Mesh, Utils
|
||||
M = Mesh.TensorMesh(Utils.meshTensors(((10,10),(40,10),(10,10)), ((10,10),(20,10),(0,0))))
|
||||
M.plotGrid()
|
||||
|
||||
For a quick tensor mesh on a (10x12x15) unit cube::
|
||||
|
||||
mesh = TensorMesh([10, 12, 15])
|
||||
mesh = Mesh.TensorMesh([10, 12, 15])
|
||||
|
||||
"""
|
||||
|
||||
__metaclass__ = utils.Save.Savable
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
_meshType = 'TENSOR'
|
||||
|
||||
@@ -52,7 +52,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
assert len(h) == len(self.x0), "Dimension mismatch. x0 != len(h)"
|
||||
|
||||
# Ensure h contains 1D vectors
|
||||
self._h = [utils.mkvc(x.astype(float)) for x in h]
|
||||
self._h = [Utils.mkvc(x.astype(float)) for x in h]
|
||||
|
||||
def __str__(self):
|
||||
outStr = ' ---- {0:d}-D TensorMesh ---- '.format(self.dim)
|
||||
@@ -170,7 +170,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
def fget(self):
|
||||
if self._gridCC is None:
|
||||
self._gridCC = utils.ndgrid(self.getTensor('CC'))
|
||||
self._gridCC = Utils.ndgrid(self.getTensor('CC'))
|
||||
return self._gridCC
|
||||
return locals()
|
||||
_gridCC = None # Store grid by default
|
||||
@@ -181,7 +181,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
def fget(self):
|
||||
if self._gridN is None:
|
||||
self._gridN = utils.ndgrid(self.getTensor('N'))
|
||||
self._gridN = Utils.ndgrid(self.getTensor('N'))
|
||||
return self._gridN
|
||||
return locals()
|
||||
_gridN = None # Store grid by default
|
||||
@@ -192,7 +192,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
def fget(self):
|
||||
if self._gridFx is None:
|
||||
self._gridFx = utils.ndgrid(self.getTensor('Fx'))
|
||||
self._gridFx = Utils.ndgrid(self.getTensor('Fx'))
|
||||
return self._gridFx
|
||||
return locals()
|
||||
_gridFx = None # Store grid by default
|
||||
@@ -203,7 +203,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
def fget(self):
|
||||
if self._gridFy is None and self.dim > 1:
|
||||
self._gridFy = utils.ndgrid(self.getTensor('Fy'))
|
||||
self._gridFy = Utils.ndgrid(self.getTensor('Fy'))
|
||||
return self._gridFy
|
||||
return locals()
|
||||
_gridFy = None # Store grid by default
|
||||
@@ -214,7 +214,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
def fget(self):
|
||||
if self._gridFz is None and self.dim > 2:
|
||||
self._gridFz = utils.ndgrid(self.getTensor('Fz'))
|
||||
self._gridFz = Utils.ndgrid(self.getTensor('Fz'))
|
||||
return self._gridFz
|
||||
return locals()
|
||||
_gridFz = None # Store grid by default
|
||||
@@ -225,7 +225,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
def fget(self):
|
||||
if self._gridEx is None:
|
||||
self._gridEx = utils.ndgrid(self.getTensor('Ex'))
|
||||
self._gridEx = Utils.ndgrid(self.getTensor('Ex'))
|
||||
return self._gridEx
|
||||
return locals()
|
||||
_gridEx = None # Store grid by default
|
||||
@@ -236,7 +236,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
def fget(self):
|
||||
if self._gridEy is None and self.dim > 1:
|
||||
self._gridEy = utils.ndgrid(self.getTensor('Ey'))
|
||||
self._gridEy = Utils.ndgrid(self.getTensor('Ey'))
|
||||
return self._gridEy
|
||||
return locals()
|
||||
_gridEy = None # Store grid by default
|
||||
@@ -247,7 +247,7 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
|
||||
def fget(self):
|
||||
if self._gridEz is None and self.dim > 2:
|
||||
self._gridEz = utils.ndgrid(self.getTensor('Ez'))
|
||||
self._gridEz = Utils.ndgrid(self.getTensor('Ez'))
|
||||
return self._gridEz
|
||||
return locals()
|
||||
_gridEz = None # Store grid by default
|
||||
@@ -262,13 +262,13 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
vh = self.h
|
||||
# Compute cell volumes
|
||||
if(self.dim == 1):
|
||||
self._vol = utils.mkvc(vh[0])
|
||||
self._vol = Utils.mkvc(vh[0])
|
||||
elif(self.dim == 2):
|
||||
# Cell sizes in each direction
|
||||
self._vol = utils.mkvc(np.outer(vh[0], vh[1]))
|
||||
self._vol = Utils.mkvc(np.outer(vh[0], vh[1]))
|
||||
elif(self.dim == 3):
|
||||
# Cell sizes in each direction
|
||||
self._vol = utils.mkvc(np.outer(utils.mkvc(np.outer(vh[0], vh[1])), vh[2]))
|
||||
self._vol = Utils.mkvc(np.outer(Utils.mkvc(np.outer(vh[0], vh[1])), vh[2]))
|
||||
return self._vol
|
||||
return locals()
|
||||
_vol = None
|
||||
@@ -282,19 +282,19 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
# Ensure that we are working with column vectors
|
||||
vh = self.h
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
# Compute areas of cell faces
|
||||
if(self.dim == 1):
|
||||
self._area = np.ones(n[0]+1)
|
||||
elif(self.dim == 2):
|
||||
area1 = np.outer(np.ones(n[0]+1), vh[1])
|
||||
area2 = np.outer(vh[0], np.ones(n[1]+1))
|
||||
self._area = np.r_[utils.mkvc(area1), utils.mkvc(area2)]
|
||||
self._area = np.r_[Utils.mkvc(area1), Utils.mkvc(area2)]
|
||||
elif(self.dim == 3):
|
||||
area1 = np.outer(np.ones(n[0]+1), utils.mkvc(np.outer(vh[1], vh[2])))
|
||||
area2 = np.outer(vh[0], utils.mkvc(np.outer(np.ones(n[1]+1), vh[2])))
|
||||
area3 = np.outer(vh[0], utils.mkvc(np.outer(vh[1], np.ones(n[2]+1))))
|
||||
self._area = np.r_[utils.mkvc(area1), utils.mkvc(area2), utils.mkvc(area3)]
|
||||
area1 = np.outer(np.ones(n[0]+1), Utils.mkvc(np.outer(vh[1], vh[2])))
|
||||
area2 = np.outer(vh[0], Utils.mkvc(np.outer(np.ones(n[1]+1), vh[2])))
|
||||
area3 = np.outer(vh[0], Utils.mkvc(np.outer(vh[1], np.ones(n[2]+1))))
|
||||
self._area = np.r_[Utils.mkvc(area1), Utils.mkvc(area2), Utils.mkvc(area3)]
|
||||
return self._area
|
||||
return locals()
|
||||
_area = None
|
||||
@@ -308,19 +308,19 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
# Ensure that we are working with column vectors
|
||||
vh = self.h
|
||||
# The number of cell centers in each direction
|
||||
n = self.n
|
||||
n = self.nCv
|
||||
# Compute edge lengths
|
||||
if(self.dim == 1):
|
||||
self._edge = utils.mkvc(vh[0])
|
||||
self._edge = Utils.mkvc(vh[0])
|
||||
elif(self.dim == 2):
|
||||
l1 = np.outer(vh[0], np.ones(n[1]+1))
|
||||
l2 = np.outer(np.ones(n[0]+1), vh[1])
|
||||
self._edge = np.r_[utils.mkvc(l1), utils.mkvc(l2)]
|
||||
self._edge = np.r_[Utils.mkvc(l1), Utils.mkvc(l2)]
|
||||
elif(self.dim == 3):
|
||||
l1 = np.outer(vh[0], utils.mkvc(np.outer(np.ones(n[1]+1), np.ones(n[2]+1))))
|
||||
l2 = np.outer(np.ones(n[0]+1), utils.mkvc(np.outer(vh[1], np.ones(n[2]+1))))
|
||||
l3 = np.outer(np.ones(n[0]+1), utils.mkvc(np.outer(np.ones(n[1]+1), vh[2])))
|
||||
self._edge = np.r_[utils.mkvc(l1), utils.mkvc(l2), utils.mkvc(l3)]
|
||||
l1 = np.outer(vh[0], Utils.mkvc(np.outer(np.ones(n[1]+1), np.ones(n[2]+1))))
|
||||
l2 = np.outer(np.ones(n[0]+1), Utils.mkvc(np.outer(vh[1], np.ones(n[2]+1))))
|
||||
l3 = np.outer(np.ones(n[0]+1), Utils.mkvc(np.outer(np.ones(n[1]+1), vh[2])))
|
||||
self._edge = np.r_[Utils.mkvc(l1), Utils.mkvc(l2), Utils.mkvc(l3)]
|
||||
return self._edge
|
||||
return locals()
|
||||
_edge = None
|
||||
@@ -410,11 +410,11 @@ class TensorMesh(BaseMesh, TensorView, DiffOperators, InnerProducts):
|
||||
ind = 0 if 'x' in locType else 1 if 'y' in locType else 2 if 'z' in locType else -1
|
||||
if locType in ['Fx','Fy','Fz','Ex','Ey','Ez'] and self.dim >= ind:
|
||||
nF_nE = self.nFv if 'F' in locType else self.nEv
|
||||
components = [utils.spzeros(loc.shape[0], n) for n in nF_nE]
|
||||
components[ind] = utils.interpmat(loc, *self.getTensor(locType))
|
||||
components = [Utils.spzeros(loc.shape[0], n) for n in nF_nE]
|
||||
components[ind] = Utils.interpmat(loc, *self.getTensor(locType))
|
||||
Q = sp.hstack(components)
|
||||
elif locType in ['CC', 'N']:
|
||||
Q = utils.interpmat(loc, *self.getTensor(locType))
|
||||
Q = Utils.interpmat(loc, *self.getTensor(locType))
|
||||
else:
|
||||
raise NotImplementedError('getInterpolationMat: locType=='+locType+' and mesh.dim=='+str(self.dim))
|
||||
return Q
|
||||
@@ -2,7 +2,7 @@ import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
from SimPEG.utils import mkvc, animate
|
||||
from SimPEG.Utils import mkvc, animate
|
||||
|
||||
|
||||
class TensorView(object):
|
||||
@@ -34,11 +34,22 @@ class TensorView(object):
|
||||
:param str annotationColor: color of annotation, e.g. 'w', 'k', 'b'
|
||||
:param bool showIt: call plt.show()
|
||||
|
||||
.. plot:: examples/mesh/plot_image_2D.py
|
||||
:include-source:
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, np
|
||||
M = Mesh.TensorMesh([20, 20])
|
||||
I = np.sin(M.gridCC[:,0]*2*np.pi)*np.sin(M.gridCC[:,1]*2*np.pi)
|
||||
M.plotImage(I, showIt=True)
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, np
|
||||
M = Mesh.TensorMesh([20,20,20])
|
||||
I = np.sin(M.gridCC[:,0]*2*np.pi)*np.sin(M.gridCC[:,1]*2*np.pi)*np.sin(M.gridCC[:,2]*2*np.pi)
|
||||
M.plotImage(I, annotationColor='k', showIt=True)
|
||||
|
||||
.. plot:: examples/mesh/plot_image_3D.py
|
||||
:include-source:
|
||||
"""
|
||||
assert type(I) == np.ndarray, "I must be a numpy array"
|
||||
assert type(numbering) == bool, "numbering must be a bool"
|
||||
@@ -124,9 +135,9 @@ class TensorView(object):
|
||||
ax.axis('tight')
|
||||
elif self.dim == 2:
|
||||
if imageType == 'CC':
|
||||
C = I[:].reshape(self.n, order='F')
|
||||
C = I[:].reshape(self.nCv, order='F')
|
||||
elif imageType == 'N':
|
||||
C = I[:].reshape(self.n+1, order='F')
|
||||
C = I[:].reshape(self.nNv, order='F')
|
||||
C = 0.25*(C[:-1, :-1] + C[1:, :-1] + C[:-1, 1:] + C[1:, 1:])
|
||||
elif imageType == 'Fx':
|
||||
C = I[:].reshape(self.nFx, order='F')
|
||||
@@ -153,9 +164,9 @@ class TensorView(object):
|
||||
|
||||
# get copy of image and average to cell-centres is necessary
|
||||
if imageType == 'CC':
|
||||
Ic = I[:].reshape(self.n, order='F')
|
||||
Ic = I[:].reshape(self.nCv, order='F')
|
||||
elif imageType == 'N':
|
||||
Ic = I[:].reshape(self.n+1, order='F')
|
||||
Ic = I[:].reshape(self.nNv, order='F')
|
||||
Ic = .125*(Ic[:-1,:-1,:-1]+Ic[1:,:-1,:-1] + Ic[:-1,1:,:-1]+ Ic[1:,1:,:-1]+ Ic[:-1,:-1,1:]+Ic[1:,:-1,1:] + Ic[:-1,1:,1:]+ Ic[1:,1:,1:] )
|
||||
elif imageType == 'Fx':
|
||||
Ic = I[:].reshape(self.nFx, order='F')
|
||||
@@ -237,11 +248,25 @@ class TensorView(object):
|
||||
:param bool lines: plot lines connecting nodes
|
||||
:param bool showIt: call plt.show()
|
||||
|
||||
.. plot:: examples/mesh/plot_grid_2D.py
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
.. plot:: examples/mesh/plot_grid_3D.py
|
||||
from SimPEG import Mesh, np
|
||||
h1 = np.linspace(.1,.5,3)
|
||||
h2 = np.linspace(.1,.5,5)
|
||||
mesh = Mesh.TensorMesh([h1, h2])
|
||||
mesh.plotGrid(nodes=True, faces=True, centers=True, lines=True, showIt=True)
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, np
|
||||
h1 = np.linspace(.1,.5,3)
|
||||
h2 = np.linspace(.1,.5,5)
|
||||
h3 = np.linspace(.1,.5,3)
|
||||
mesh = Mesh.TensorMesh([h1,h2,h3])
|
||||
mesh.plotGrid(nodes=True, faces=True, centers=True, lines=True, showIt=True)
|
||||
|
||||
"""
|
||||
if self.dim == 1:
|
||||
fig = plt.figure(1)
|
||||
File renamed without changes.
+129
@@ -0,0 +1,129 @@
|
||||
import Utils, Parameters, numpy as np, scipy.sparse as sp
|
||||
|
||||
|
||||
class BaseModel(object):
|
||||
"""
|
||||
SimPEG Model
|
||||
|
||||
"""
|
||||
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
counter = None #: A SimPEG.Utils.Counter object
|
||||
mesh = None #: A SimPEG Mesh
|
||||
|
||||
def __init__(self, mesh):
|
||||
self.mesh = mesh
|
||||
|
||||
def transform(self, m):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
:rtype: numpy.array
|
||||
:return: transformed model
|
||||
|
||||
The *transform* changes the model into the physical property.
|
||||
|
||||
"""
|
||||
return m
|
||||
|
||||
def transformInverse(self, D):
|
||||
"""
|
||||
:param numpy.array D: physical property
|
||||
:rtype: numpy.array
|
||||
:return: model
|
||||
|
||||
The *transformInverse* changes the physical property into the model.
|
||||
|
||||
.. note:: The *transformInverse* may not be easy to create in general.
|
||||
|
||||
"""
|
||||
raise NotImplementedError('The transformInverse is not implemented.')
|
||||
|
||||
def transformDeriv(self, m):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
:rtype: scipy.csr_matrix
|
||||
:return: derivative of transformed model
|
||||
|
||||
The *transform* changes the model into the physical property.
|
||||
The *transformDeriv* provides the derivative of the *transform*.
|
||||
"""
|
||||
return sp.identity(m.size)
|
||||
|
||||
@property
|
||||
def nP(self):
|
||||
"""Number of parameters in the model."""
|
||||
return self.mesh.nC
|
||||
|
||||
def example(self, modelType=None):
|
||||
return np.random.rand(self.mesh.nC)
|
||||
|
||||
|
||||
|
||||
class LogModel(BaseModel):
|
||||
"""SimPEG LogModel"""
|
||||
|
||||
def __init__(self, mesh, **kwargs):
|
||||
BaseModel.__init__(self, mesh, **kwargs)
|
||||
|
||||
def transform(self, m):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
:rtype: numpy.array
|
||||
:return: transformed model
|
||||
|
||||
The *transform* changes the model into the physical property.
|
||||
|
||||
A common example of this is to invert for electrical conductivity
|
||||
in log space. In this case, your model will be log(sigma) and to
|
||||
get back to sigma, you can take the exponential:
|
||||
|
||||
.. math::
|
||||
|
||||
m = \log{\sigma}
|
||||
|
||||
\exp{m} = \exp{\log{\sigma}} = \sigma
|
||||
"""
|
||||
return np.exp(Utils.mkvc(m))
|
||||
|
||||
|
||||
def transformInverse(self, D):
|
||||
"""
|
||||
:param numpy.array D: physical property
|
||||
:rtype: numpy.array
|
||||
:return: model
|
||||
|
||||
The *transformInverse* changes the physical property into the model.
|
||||
|
||||
.. math::
|
||||
|
||||
m = \log{\sigma}
|
||||
|
||||
"""
|
||||
return np.log(Utils.mkvc(D))
|
||||
|
||||
|
||||
def transformDeriv(self, m):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
:rtype: scipy.csr_matrix
|
||||
:return: derivative of transformed model
|
||||
|
||||
The *transform* changes the model into the physical property.
|
||||
The *transformDeriv* provides the derivative of the *transform*.
|
||||
|
||||
If the model *transform* is:
|
||||
|
||||
.. math::
|
||||
|
||||
m = \log{\sigma}
|
||||
|
||||
\exp{m} = \exp{\log{\sigma}} = \sigma
|
||||
|
||||
Then the derivative is:
|
||||
|
||||
.. math::
|
||||
|
||||
\\frac{\partial \exp{m}}{\partial m} = \\text{sdiag}(\exp{m})
|
||||
"""
|
||||
return Utils.sdiag(np.exp(Utils.mkvc(m)))
|
||||
@@ -0,0 +1,215 @@
|
||||
import Utils, Parameters, numpy as np, scipy.sparse as sp
|
||||
|
||||
class BaseObjFunction(object):
|
||||
"""BaseObjFunction(data, reg, **kwargs)"""
|
||||
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
beta = Parameters.ParameterProperty('beta', default=1, doc='Regularization trade-off parameter')
|
||||
|
||||
debug = False #: Print debugging information
|
||||
counter = None #: Set this to a SimPEG.Utils.Counter() if you want to count things
|
||||
|
||||
name = 'Base Objective Function' #: Name of the objective function
|
||||
|
||||
u_current = None #: The most current evaluated field
|
||||
m_current = None #: The most current model
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
"""This is the parent of the objective function."""
|
||||
return getattr(self,'_parent',None)
|
||||
@parent.setter
|
||||
def parent(self, p):
|
||||
if getattr(self,'_parent',None) is not None:
|
||||
print 'Objective function has switched to a new parent!'
|
||||
self._parent = p
|
||||
|
||||
@property
|
||||
def inv(self): return self.parent
|
||||
@property
|
||||
def objFunc(self): return self
|
||||
@property
|
||||
def opt(self): return getattr(self.parent,'opt',None)
|
||||
@property
|
||||
def prob(self): return self.data.prob
|
||||
@property
|
||||
def mesh(self): return self.data.prob.mesh
|
||||
@property
|
||||
def model(self): return self.data.prob.model
|
||||
|
||||
|
||||
def __init__(self, data, reg, **kwargs):
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
self.data = data
|
||||
|
||||
self.reg = reg
|
||||
self.reg.parent = self
|
||||
|
||||
|
||||
@Utils.callHooks('startup')
|
||||
def startup(self, m0):
|
||||
"""startup(m0)
|
||||
|
||||
Called when inversion is first starting.
|
||||
"""
|
||||
if self.debug: print 'Calling ObjFunction.startup'
|
||||
|
||||
if self.reg.mref is None:
|
||||
print 'Regularization has not set mref. SimPEG will set it to m0.'
|
||||
self.reg.mref = m0
|
||||
|
||||
self.phi_d = np.nan
|
||||
self.phi_m = np.nan
|
||||
|
||||
self.m_current = m0
|
||||
|
||||
@Utils.timeIt
|
||||
def evalFunction(self, m, return_g=True, return_H=True):
|
||||
"""evalFunction(m, return_g=True, return_H=True)
|
||||
"""
|
||||
|
||||
self.u_current = None
|
||||
self.m_current = m
|
||||
|
||||
u = self.data.prob.field(m)
|
||||
self.u_current = u
|
||||
|
||||
phi_d = self.dataObj(m, u=u)
|
||||
phi_m = self.reg.modelObj(m)
|
||||
|
||||
self.dpred = self.data.dpred(m, u=u) # This is a cheap matrix vector calculation.
|
||||
|
||||
self.phi_d, self.phi_d_last = phi_d, self.phi_d
|
||||
self.phi_m, self.phi_m_last = phi_m, self.phi_m
|
||||
|
||||
f = phi_d + self.beta * phi_m
|
||||
|
||||
out = (f,)
|
||||
if return_g:
|
||||
phi_dDeriv = self.dataObjDeriv(m, u=u)
|
||||
phi_mDeriv = self.reg.modelObjDeriv(m)
|
||||
|
||||
g = phi_dDeriv + self.beta * phi_mDeriv
|
||||
out += (g,)
|
||||
|
||||
if return_H:
|
||||
def H_fun(v):
|
||||
phi_d2Deriv = self.dataObj2Deriv(m, v, u=u)
|
||||
phi_m2Deriv = self.reg.modelObj2Deriv()*v
|
||||
|
||||
return phi_d2Deriv + self.beta * phi_m2Deriv
|
||||
|
||||
operator = sp.linalg.LinearOperator( (m.size, m.size), H_fun, dtype=m.dtype )
|
||||
out += (operator,)
|
||||
return out if len(out) > 1 else out[0]
|
||||
|
||||
@Utils.timeIt
|
||||
def dataObj(self, m, u=None):
|
||||
"""dataObj(m, u=None)
|
||||
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array u: fields
|
||||
:rtype: float
|
||||
:return: data misfit
|
||||
|
||||
The data misfit using an l_2 norm is:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data} = {1\over 2}\left| \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs}) \\right|_2^2
|
||||
|
||||
Where P is a projection matrix that brings the field on the full domain to the data measurement locations;
|
||||
u is the field of interest; d_obs is the observed data; and W is the weighting matrix.
|
||||
"""
|
||||
# TODO: ensure that this is a data is vector and Wd is a matrix.
|
||||
R = self.data.residualWeighted(m, u=u)
|
||||
return 0.5*np.vdot(R, R)
|
||||
|
||||
@Utils.timeIt
|
||||
def dataObjDeriv(self, m, u=None):
|
||||
"""dataObjDeriv(m, u=None)
|
||||
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array u: fields
|
||||
:rtype: numpy.array
|
||||
:return: data misfit derivative
|
||||
|
||||
The data misfit using an l_2 norm is:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data} = {1\over 2}\left| \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs}) \\right|_2^2
|
||||
|
||||
If the field, u, is provided, the calculation of the data is fast:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{d}_\\text{pred} = \mathbf{Pu(m)}
|
||||
|
||||
\mathbf{R} = \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs})
|
||||
|
||||
Where P is a projection matrix that brings the field on the full domain to the data measurement locations;
|
||||
u is the field of interest; d_obs is the observed data; and W is the weighting matrix.
|
||||
|
||||
The derivative of this, with respect to the model, is:
|
||||
|
||||
.. math::
|
||||
|
||||
\\frac{\partial \mu_\\text{data}}{\partial \mathbf{m}} = \mathbf{J}^\\top \mathbf{W \circ R}
|
||||
|
||||
"""
|
||||
if u is None: u = self.data.prob.field(m)
|
||||
|
||||
R = self.data.residualWeighted(m, u=u)
|
||||
|
||||
dmisfit = self.data.prob.Jt(m, self.data.Wd * R, u=u)
|
||||
|
||||
return dmisfit
|
||||
|
||||
@Utils.timeIt
|
||||
def dataObj2Deriv(self, m, v, u=None):
|
||||
"""dataObj2Deriv(m, v, u=None)
|
||||
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array v: vector to multiply
|
||||
:param numpy.array u: fields
|
||||
:rtype: numpy.array
|
||||
:return: data misfit derivative
|
||||
|
||||
The data misfit using an l_2 norm is:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data} = {1\over 2}\left| \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs}) \\right|_2^2
|
||||
|
||||
If the field, u, is provided, the calculation of the data is fast:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{d}_\\text{pred} = \mathbf{Pu(m)}
|
||||
|
||||
\mathbf{R} = \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs})
|
||||
|
||||
Where P is a projection matrix that brings the field on the full domain to the data measurement locations;
|
||||
u is the field of interest; d_obs is the observed data; and W is the weighting matrix.
|
||||
|
||||
The derivative of this, with respect to the model, is:
|
||||
|
||||
.. math::
|
||||
|
||||
\\frac{\partial \mu_\\text{data}}{\partial \mathbf{m}} = \mathbf{J}^\\top \mathbf{W \circ R}
|
||||
|
||||
\\frac{\partial^2 \mu_\\text{data}}{\partial^2 \mathbf{m}} = \mathbf{J}^\\top \mathbf{W \circ W J}
|
||||
|
||||
"""
|
||||
if u is None: u = self.data.prob.field(m)
|
||||
|
||||
R = self.data.residualWeighted(m, u=u)
|
||||
|
||||
# TODO: abstract to different norms a little cleaner.
|
||||
# \/ it goes here. in l2 it is the identity.
|
||||
dmisfit = self.data.prob.Jt_approx(m, self.data.Wd * self.data.Wd * self.data.prob.J_approx(m, v, u=u), u=u)
|
||||
|
||||
return dmisfit
|
||||
@@ -1,5 +1,5 @@
|
||||
from SimPEG import Solver, utils, sp, np
|
||||
import matplotlib.pyplot as plt
|
||||
import Utils, numpy as np, scipy.sparse as sp
|
||||
from Solver import Solver
|
||||
norm = np.linalg.norm
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ class StoppingCriteria(object):
|
||||
"""docstring for StoppingCriteria"""
|
||||
|
||||
iteration = { "str": "%d : maxIter = %3d <= iter = %3d",
|
||||
"left": lambda M: M.maxIter, "right": lambda M: M._iter,
|
||||
"left": lambda M: M.maxIter, "right": lambda M: M.iter,
|
||||
"stopType": "critical"}
|
||||
|
||||
iterationLS = { "str": "%d : maxIterLS = %3d <= iterLS = %3d",
|
||||
"left": lambda M: M.maxIterLS, "right": lambda M: M._iterLS,
|
||||
"left": lambda M: M.maxIterLS, "right": lambda M: M.iterLS,
|
||||
"stopType": "critical"}
|
||||
|
||||
armijoGoldstein = { "str": "%d : ft = %1.4e <= alp*descent = %1.4e",
|
||||
@@ -22,11 +22,11 @@ class StoppingCriteria(object):
|
||||
"stopType": "optimal"}
|
||||
|
||||
tolerance_f = { "str": "%d : |fc-fOld| = %1.4e <= tolF*(1+|f0|) = %1.4e",
|
||||
"left": lambda M: 1 if M._iter==0 else abs(M.f-M.f_last), "right": lambda M: 0 if M._iter==0 else M.tolF*(1+abs(M.f0)),
|
||||
"left": lambda M: 1 if M.iter==0 else abs(M.f-M.f_last), "right": lambda M: 0 if M.iter==0 else M.tolF*(1+abs(M.f0)),
|
||||
"stopType": "optimal"}
|
||||
|
||||
moving_x = { "str": "%d : |xc-x_last| = %1.4e <= tolX*(1+|x0|) = %1.4e",
|
||||
"left": lambda M: 1 if M._iter==0 else norm(M.xc-M.x_last), "right": lambda M: 0 if M._iter==0 else M.tolX*(1+norm(M.x0)),
|
||||
"left": lambda M: 1 if M.iter==0 else norm(M.xc-M.x_last), "right": lambda M: 0 if M.iter==0 else M.tolX*(1+norm(M.x0)),
|
||||
"stopType": "optimal"}
|
||||
|
||||
tolerance_g = { "str": "%d : |proj(x-g)-x| = %1.4e <= tolG = %1.4e",
|
||||
@@ -57,12 +57,12 @@ class StoppingCriteria(object):
|
||||
class IterationPrinters(object):
|
||||
"""docstring for IterationPrinters"""
|
||||
|
||||
iteration = {"title": "#", "value": lambda M: M._iter, "width": 5, "format": "%3d"}
|
||||
iteration = {"title": "#", "value": lambda M: M.iter, "width": 5, "format": "%3d"}
|
||||
f = {"title": "f", "value": lambda M: M.f, "width": 10, "format": "%1.2e"}
|
||||
norm_g = {"title": "|proj(x-g)-x|", "value": lambda M: norm(M.projection(M.xc - M.g) - M.xc), "width": 15, "format": "%1.2e"}
|
||||
totalLS = {"title": "LS", "value": lambda M: M._iterLS, "width": 5, "format": "%d"}
|
||||
totalLS = {"title": "LS", "value": lambda M: M.iterLS, "width": 5, "format": "%d"}
|
||||
|
||||
iterationLS = {"title": "#", "value": lambda M: (M._iter, M._iterLS), "width": 5, "format": "%3d.%d"}
|
||||
iterationLS = {"title": "#", "value": lambda M: (M.iter, M.iterLS), "width": 5, "format": "%3d.%d"}
|
||||
LS_ft = {"title": "ft", "value": lambda M: M._LS_ft, "width": 10, "format": "%1.2e"}
|
||||
LS_t = {"title": "t", "value": lambda M: M._LS_t, "width": 10, "format": "%0.5f"}
|
||||
LS_armijoGoldstein = {"title": "f + alp*g.T*p", "value": lambda M: M.f + M.LSreduction*M._LS_descent, "width": 16, "format": "%1.2e"}
|
||||
@@ -72,9 +72,9 @@ class IterationPrinters(object):
|
||||
bSet = {"title": "bSet", "value": lambda M: np.sum(M.bindingSet(M.xc)), "width": 8, "format": "%d"}
|
||||
comment = {"title": "Comment", "value": lambda M: M.comment, "width": 12, "format": "%s"}
|
||||
|
||||
beta = {"title": "beta", "value": lambda M: M.parent._beta, "width": 10, "format": "%1.2e"}
|
||||
phi_d = {"title": "phi_d", "value": lambda M: M.parent.phi_d, "width": 10, "format": "%1.2e"}
|
||||
phi_m = {"title": "phi_m", "value": lambda M: M.parent.phi_m, "width": 10, "format": "%1.2e"}
|
||||
beta = {"title": "beta", "value": lambda M: M.parent.objFunc.beta, "width": 10, "format": "%1.2e"}
|
||||
phi_d = {"title": "phi_d", "value": lambda M: M.parent.objFunc.phi_d, "width": 10, "format": "%1.2e"}
|
||||
phi_m = {"title": "phi_m", "value": lambda M: M.parent.objFunc.phi_m, "width": 10, "format": "%1.2e"}
|
||||
|
||||
|
||||
class Minimize(object):
|
||||
@@ -82,7 +82,7 @@ class Minimize(object):
|
||||
Minimize is a general class for derivative based optimization.
|
||||
"""
|
||||
|
||||
__metaclass__ = utils.Save.Savable
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
name = "General Optimization Algorithm" #: The name of the optimization algorithm
|
||||
|
||||
@@ -100,7 +100,8 @@ class Minimize(object):
|
||||
debugLS = False #: Print debugging information for the line-search
|
||||
|
||||
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
|
||||
counter = None #: Set this to a SimPEG.Utils.Counter() if you want to count things
|
||||
parent = None #: This is the parent of the optimization routine.
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.stoppers = [StoppingCriteria.tolerance_f, StoppingCriteria.moving_x, StoppingCriteria.tolerance_g, StoppingCriteria.norm_g, StoppingCriteria.iteration]
|
||||
@@ -109,9 +110,9 @@ class Minimize(object):
|
||||
self.printers = [IterationPrinters.iteration, IterationPrinters.f, IterationPrinters.norm_g, IterationPrinters.totalLS]
|
||||
self.printersLS = [IterationPrinters.iterationLS, IterationPrinters.LS_ft, IterationPrinters.LS_t, IterationPrinters.LS_armijoGoldstein]
|
||||
|
||||
utils.setKwargs(self, **kwargs)
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def minimize(self, evalFunction, x0):
|
||||
"""minimize(evalFunction, x0)
|
||||
|
||||
@@ -179,17 +180,7 @@ class Minimize(object):
|
||||
|
||||
return self.xc
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
"""
|
||||
This is the parent of the optimization routine.
|
||||
"""
|
||||
return getattr(self, '_parent', None)
|
||||
@parent.setter
|
||||
def parent(self, value):
|
||||
self._parent = value
|
||||
|
||||
@utils.callHooks('startup')
|
||||
@Utils.callHooks('startup')
|
||||
def startup(self, x0):
|
||||
"""
|
||||
**startup** is called at the start of any new minimize call.
|
||||
@@ -198,15 +189,15 @@ class Minimize(object):
|
||||
|
||||
x0 = x0
|
||||
xc = x0
|
||||
_iter = _iterLS = 0
|
||||
iter = iterLS = 0
|
||||
|
||||
:param numpy.ndarray x0: initial x
|
||||
:rtype: None
|
||||
:return: None
|
||||
"""
|
||||
|
||||
self._iter = 0
|
||||
self._iterLS = 0
|
||||
self.iter = 0
|
||||
self.iterLS = 0
|
||||
|
||||
x0 = self.projection(x0) # ensure that we start of feasible.
|
||||
self.x0 = x0
|
||||
@@ -214,8 +205,8 @@ class Minimize(object):
|
||||
self.f_last = np.nan
|
||||
self.x_last = x0
|
||||
|
||||
@utils.count
|
||||
@utils.callHooks('doStartIteration')
|
||||
@Utils.count
|
||||
@Utils.callHooks('doStartIteration')
|
||||
def doStartIteration(self):
|
||||
"""doStartIteration()
|
||||
|
||||
@@ -237,9 +228,9 @@ class Minimize(object):
|
||||
"""
|
||||
pad = ' '*10 if inLS else ''
|
||||
name = self.name if not inLS else self.nameLS
|
||||
utils.printTitles(self, self.printers if not inLS else self.printersLS, name, pad)
|
||||
Utils.printTitles(self, self.printers if not inLS else self.printersLS, name, pad)
|
||||
|
||||
@utils.callHooks('printIter')
|
||||
@Utils.callHooks('printIter')
|
||||
def printIter(self, inLS=False):
|
||||
"""
|
||||
**printIter** is called directly after function evaluations.
|
||||
@@ -249,7 +240,7 @@ class Minimize(object):
|
||||
|
||||
"""
|
||||
pad = ' '*10 if inLS else ''
|
||||
utils.printLine(self, self.printers if not inLS else self.printersLS, pad=pad)
|
||||
Utils.printLine(self, self.printers if not inLS else self.printersLS, pad=pad)
|
||||
|
||||
def printDone(self, inLS=False):
|
||||
"""
|
||||
@@ -262,10 +253,10 @@ class Minimize(object):
|
||||
pad = ' '*10 if inLS else ''
|
||||
stop, done = (' STOP! ', ' DONE! ') if not inLS else ('----------------', ' End Linesearch ')
|
||||
stoppers = self.stoppers if not inLS else self.stoppersLS
|
||||
utils.printStoppers(self, stoppers, pad='', stop=stop, done=done)
|
||||
Utils.printStoppers(self, stoppers, pad='', stop=stop, done=done)
|
||||
|
||||
|
||||
@utils.callHooks('finish')
|
||||
@Utils.callHooks('finish')
|
||||
def finish(self):
|
||||
"""finish()
|
||||
|
||||
@@ -278,13 +269,13 @@ class Minimize(object):
|
||||
pass
|
||||
|
||||
def stoppingCriteria(self, inLS=False):
|
||||
if self._iter == 0:
|
||||
if self.iter == 0:
|
||||
self.f0 = self.f
|
||||
self.g0 = self.g
|
||||
return utils.checkStoppers(self, self.stoppers if not inLS else self.stoppersLS)
|
||||
return Utils.checkStoppers(self, self.stoppers if not inLS else self.stoppersLS)
|
||||
|
||||
@utils.timeIt
|
||||
@utils.callHooks('projection')
|
||||
@Utils.timeIt
|
||||
@Utils.callHooks('projection')
|
||||
def projection(self, p):
|
||||
"""projection(p)
|
||||
|
||||
@@ -298,7 +289,7 @@ class Minimize(object):
|
||||
"""
|
||||
return p
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def findSearchDirection(self):
|
||||
"""findSearchDirection()
|
||||
|
||||
@@ -329,7 +320,7 @@ class Minimize(object):
|
||||
"""
|
||||
return -self.g
|
||||
|
||||
@utils.count
|
||||
@Utils.count
|
||||
def scaleSearchDirection(self, p):
|
||||
"""scaleSearchDirection(p)
|
||||
|
||||
@@ -348,7 +339,7 @@ class Minimize(object):
|
||||
|
||||
nameLS = "Armijo linesearch" #: The line-search name
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def modifySearchDirection(self, p):
|
||||
"""modifySearchDirection(p)
|
||||
|
||||
@@ -370,23 +361,23 @@ class Minimize(object):
|
||||
"""
|
||||
# Projected Armijo linesearch
|
||||
self._LS_t = 1
|
||||
self._iterLS = 0
|
||||
while self._iterLS < self.maxIterLS:
|
||||
self.iterLS = 0
|
||||
while self.iterLS < self.maxIterLS:
|
||||
self._LS_xt = self.projection(self.xc + self._LS_t*p)
|
||||
self._LS_ft = self.evalFunction(self._LS_xt, return_g=False, return_H=False)
|
||||
self._LS_descent = np.inner(self.g, self._LS_xt - self.xc) # this takes into account multiplying by t, but is important for projection.
|
||||
if self.stoppingCriteria(inLS=True): break
|
||||
self._iterLS += 1
|
||||
self.iterLS += 1
|
||||
self._LS_t = self.LSshorten*self._LS_t
|
||||
if self.debugLS:
|
||||
if self._iterLS == 1: self.printInit(inLS=True)
|
||||
if self.iterLS == 1: self.printInit(inLS=True)
|
||||
self.printIter(inLS=True)
|
||||
|
||||
if self.debugLS and self._iterLS > 0: self.printDone(inLS=True)
|
||||
if self.debugLS and self.iterLS > 0: self.printDone(inLS=True)
|
||||
|
||||
return self._LS_xt, self._iterLS < self.maxIterLS
|
||||
return self._LS_xt, self.iterLS < self.maxIterLS
|
||||
|
||||
@utils.count
|
||||
@Utils.count
|
||||
def modifySearchDirectionBreak(self, p):
|
||||
"""modifySearchDirectionBreak(p)
|
||||
|
||||
@@ -408,8 +399,8 @@ class Minimize(object):
|
||||
print 'The linesearch got broken. Boo.'
|
||||
return p, False
|
||||
|
||||
@utils.count
|
||||
@utils.callHooks('doEndIteration')
|
||||
@Utils.count
|
||||
@Utils.callHooks('doEndIteration')
|
||||
def doEndIteration(self, xt):
|
||||
"""doEndIteration(xt)
|
||||
|
||||
@@ -426,7 +417,7 @@ class Minimize(object):
|
||||
# store old values
|
||||
self.f_last = self.f
|
||||
self.x_last, self.xc = self.xc, xt
|
||||
self._iter += 1
|
||||
self.iter += 1
|
||||
if self.debug: self.printDone()
|
||||
|
||||
|
||||
@@ -527,7 +518,7 @@ class ProjectedGradient(Minimize, Remember):
|
||||
|
||||
self.aSet_prev = self.activeSet(x0)
|
||||
|
||||
@utils.count
|
||||
@Utils.count
|
||||
def projection(self, x):
|
||||
"""projection(x)
|
||||
|
||||
@@ -536,7 +527,7 @@ class ProjectedGradient(Minimize, Remember):
|
||||
"""
|
||||
return np.median(np.c_[self.lower,x,self.upper],axis=1)
|
||||
|
||||
@utils.count
|
||||
@Utils.count
|
||||
def activeSet(self, x):
|
||||
"""activeSet(x)
|
||||
|
||||
@@ -545,7 +536,7 @@ class ProjectedGradient(Minimize, Remember):
|
||||
"""
|
||||
return np.logical_or(x == self.lower, x == self.upper)
|
||||
|
||||
@utils.count
|
||||
@Utils.count
|
||||
def inactiveSet(self, x):
|
||||
"""inactiveSet(x)
|
||||
|
||||
@@ -554,7 +545,7 @@ class ProjectedGradient(Minimize, Remember):
|
||||
"""
|
||||
return np.logical_not(self.activeSet(x))
|
||||
|
||||
@utils.count
|
||||
@Utils.count
|
||||
def bindingSet(self, x):
|
||||
"""bindingSet(x)
|
||||
|
||||
@@ -567,7 +558,7 @@ class ProjectedGradient(Minimize, Remember):
|
||||
bind_low = np.logical_and(x == self.upper, self.g <= 0)
|
||||
return np.logical_or(bind_up, bind_low)
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def findSearchDirection(self):
|
||||
"""findSearchDirection()
|
||||
|
||||
@@ -612,7 +603,7 @@ class ProjectedGradient(Minimize, Remember):
|
||||
# aSet_after = self.activeSet(self.xc+p)
|
||||
return p
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def _doEndIteration_ProjectedGradient(self, xt):
|
||||
"""_doEndIteration_ProjectedGradient(xt)"""
|
||||
aSet = self.activeSet(xt)
|
||||
@@ -623,7 +614,7 @@ class ProjectedGradient(Minimize, Remember):
|
||||
|
||||
f_current_decrease = self.f_last - self.f
|
||||
self.comment = ''
|
||||
if self._iter < 1:
|
||||
if self.iter < 1:
|
||||
# Note that this is reset on every CG iteration.
|
||||
self.f_decrease_max = -np.inf
|
||||
else:
|
||||
@@ -694,7 +685,7 @@ class BFGS(Minimize, Remember):
|
||||
return self.bfgs(-self.g)
|
||||
|
||||
def _doEndIteration_BFGS(self, xt):
|
||||
if self._iter is 0:
|
||||
if self.iter is 0:
|
||||
self.g_last = self.g
|
||||
return
|
||||
|
||||
@@ -718,7 +709,7 @@ class GaussNewton(Minimize, Remember):
|
||||
def __init__(self, **kwargs):
|
||||
Minimize.__init__(self, **kwargs)
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def findSearchDirection(self):
|
||||
return Solver(self.H).solve(-self.g)
|
||||
|
||||
@@ -765,7 +756,7 @@ class InexactGaussNewton(BFGS, Minimize, Remember):
|
||||
def approxHinv(self, value):
|
||||
self._approxHinv = value
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def findSearchDirection(self):
|
||||
Hinv = Solver(self.H, doDirect=False, options={'iterSolver': 'CG', 'M': self.approxHinv, 'tol': self.tolCG, 'maxIter': self.maxIterCG})
|
||||
p = Hinv.solve(-self.g)
|
||||
@@ -778,7 +769,7 @@ class SteepestDescent(Minimize, Remember):
|
||||
def __init__(self, **kwargs):
|
||||
Minimize.__init__(self, **kwargs)
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def findSearchDirection(self):
|
||||
return -self.g
|
||||
|
||||
@@ -811,7 +802,7 @@ class NewtonRoot(object):
|
||||
doLS = True
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
utils.setKwargs(self, **kwargs)
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
def root(self, fun, x):
|
||||
"""root(fun, x)
|
||||
@@ -827,7 +818,7 @@ class NewtonRoot(object):
|
||||
"""
|
||||
if self.comments: print 'Newton Method:\n'
|
||||
|
||||
self._iter = 0
|
||||
self.iter = 0
|
||||
while True:
|
||||
|
||||
r, J = fun(x, return_g=True)
|
||||
@@ -861,10 +852,10 @@ class NewtonRoot(object):
|
||||
rt = fun(xt, return_g=False)
|
||||
|
||||
x = xt
|
||||
self._iter += 1
|
||||
self.iter += 1
|
||||
if norm(rt) < self.tol:
|
||||
break
|
||||
if self._iter > self.maxIter:
|
||||
if self.iter > self.maxIter:
|
||||
print 'NewtonRoot stopped by maxIters. norm: %4.4e' % norm(rt)
|
||||
break
|
||||
|
||||
@@ -873,7 +864,7 @@ class NewtonRoot(object):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from SimPEG.tests import Rosenbrock, checkDerivative
|
||||
from SimPEG.Tests import Rosenbrock, checkDerivative
|
||||
import matplotlib.pyplot as plt
|
||||
x0 = np.array([2.6, 3.7])
|
||||
checkDerivative(Rosenbrock, x0, plotIt=False)
|
||||
@@ -885,7 +876,7 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
print 'test the newtonRoot finding.'
|
||||
fun = lambda x, return_g=True: np.sin(x) if not return_g else ( np.sin(x), utils.sdiag( np.cos(x) ) )
|
||||
fun = lambda x, return_g=True: np.sin(x) if not return_g else ( np.sin(x), Utils.sdiag( np.cos(x) ) )
|
||||
x = np.array([np.pi-0.3, np.pi+0.1, 0])
|
||||
pnt = NewtonRoot(comments=True).root(fun,x)
|
||||
print pnt
|
||||
@@ -0,0 +1,164 @@
|
||||
import Utils, numpy as np
|
||||
|
||||
|
||||
class Parameter(object):
|
||||
"""Parameter"""
|
||||
|
||||
debug = False #: Print debugging information
|
||||
|
||||
current = None #: This hold
|
||||
currentIter = 0
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
"""This is the parent of the Parameter instance."""
|
||||
return getattr(self,'_parent',None)
|
||||
@parent.setter
|
||||
def parent(self, p):
|
||||
startupName = '_startup_paramProperty_'+self._propertyName
|
||||
if getattr(self,'_parent',None) is not None:
|
||||
delattr(self._parent,startupName)
|
||||
print 'Warning: Parameter %s has switched to a new parent.' % self._propertyName
|
||||
if self.debug: print '%s function has been deleted' % startupName
|
||||
self._parent = p
|
||||
|
||||
prop = self
|
||||
def _startup_paramProperty(self, *args):
|
||||
if prop.debug: print 'initializing %s' % prop._propertyName
|
||||
prop.initialize()
|
||||
|
||||
Utils.hook(self._parent, _startup_paramProperty, name=startupName, overwrite=True)
|
||||
|
||||
@property
|
||||
def inv(self): return self.parent.inv
|
||||
@property
|
||||
def objFunc(self): return self.parent.objFunc
|
||||
@property
|
||||
def opt(self): return self.parent.opt
|
||||
@property
|
||||
def reg(self): return self.parent.reg
|
||||
@property
|
||||
def data(self): return self.parent.data
|
||||
@property
|
||||
def prob(self): return self.parent.prob
|
||||
@property
|
||||
def model(self): return self.parent.model
|
||||
@property
|
||||
def mesh(self): return self.parent.mesh
|
||||
|
||||
def initialize(self):
|
||||
pass
|
||||
|
||||
def get(self):
|
||||
if (self.current is None or
|
||||
not self.opt.iter == self.currentIter):
|
||||
self.current = self.nextIter()
|
||||
self.currentIter = self.opt.iter
|
||||
return self.current
|
||||
|
||||
def nextIter(self):
|
||||
raise NotImplementedError('Getting the Parameter is not yet implemented.')
|
||||
|
||||
|
||||
def ParameterProperty(name, default=None, doc=""):
|
||||
def getter(self):
|
||||
out = getattr(self,'_'+name,default)
|
||||
if isinstance(out, Parameter):
|
||||
out = out.get()
|
||||
return out
|
||||
def setter(self, value):
|
||||
if isinstance(value, Parameter):
|
||||
value._propertyName = name
|
||||
value.parent = self
|
||||
setattr(self, '_'+name, value)
|
||||
|
||||
return property(fget=getter, fset=setter, doc=doc)
|
||||
|
||||
|
||||
class BetaEstimate(Parameter):
|
||||
"""BetaEstimate"""
|
||||
|
||||
beta0 = 'guess' #: The initial Beta (regularization parameter)
|
||||
beta0_ratio = 0.1 #: When beta0 is set to 'guess', estimateBeta0 is used with this ratio
|
||||
|
||||
beta = None #: Beta parameter
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
Parameter.__init__(self, **kwargs)
|
||||
|
||||
def initialize(self):
|
||||
self.beta = self.beta0
|
||||
|
||||
@Utils.requires('parent')
|
||||
def nextIter(self):
|
||||
if self.beta is 'guess':
|
||||
if self.debug: print 'BetaSchedule is estimating Beta0.'
|
||||
self.beta = self.estimateBeta0()
|
||||
return self.beta
|
||||
|
||||
@Utils.requires('parent')
|
||||
def estimateBeta0(self):
|
||||
"""estimateBeta0(u=None)
|
||||
|
||||
The initial beta is calculated by comparing the estimated
|
||||
eigenvalues of JtJ and WtW.
|
||||
|
||||
To estimate the eigenvector of **A**, we will use one iteration
|
||||
of the *Power Method*:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{x_1 = A x_0}
|
||||
|
||||
Given this (very course) approximation of the eigenvector,
|
||||
we can use the *Rayleigh quotient* to approximate the largest eigenvalue.
|
||||
|
||||
.. math::
|
||||
|
||||
\lambda_0 = \\frac{\mathbf{x^\\top A x}}{\mathbf{x^\\top x}}
|
||||
|
||||
We will approximate the largest eigenvalue for both JtJ and WtW, and
|
||||
use some ratio of the quotient to estimate beta0.
|
||||
|
||||
.. math::
|
||||
|
||||
\\beta_0 = \gamma \\frac{\mathbf{x^\\top J^\\top J x}}{\mathbf{x^\\top W^\\top W x}}
|
||||
|
||||
:rtype: float
|
||||
:return: beta0
|
||||
"""
|
||||
objFunc = self.parent
|
||||
data = objFunc.data
|
||||
|
||||
m = objFunc.m_current
|
||||
u = objFunc.u_current
|
||||
|
||||
if u is None:
|
||||
u = data.prob.field(m)
|
||||
|
||||
x0 = np.random.rand(*m.shape)
|
||||
t = x0.dot(objFunc.dataObj2Deriv(m,x0,u=u))
|
||||
b = x0.dot(objFunc.reg.modelObj2Deriv()*x0)
|
||||
return self.beta0_ratio*(t/b)
|
||||
|
||||
|
||||
class BetaSchedule(BetaEstimate):
|
||||
"""BetaSchedule"""
|
||||
|
||||
coolingFactor = 2.
|
||||
coolingRate = 3
|
||||
|
||||
@Utils.requires('parent')
|
||||
def nextIter(self):
|
||||
if self.beta is 'guess':
|
||||
if self.debug: print 'BetaSchedule is estimating Beta0.'
|
||||
self.beta = self.estimateBeta0()
|
||||
|
||||
if self.opt.iter > 0 and self.opt.iter % self.coolingRate == 0:
|
||||
if self.debug: print 'BetaSchedule is cooling Beta. Iteration: %d' % self.opt.iter
|
||||
self.beta /= self.coolingFactor
|
||||
|
||||
return self.beta
|
||||
@@ -1,8 +1,7 @@
|
||||
from SimPEG import utils, data, np, sp
|
||||
norm = np.linalg.norm
|
||||
import Utils, Data, numpy as np, scipy.sparse as sp
|
||||
|
||||
|
||||
class Problem(object):
|
||||
class BaseProblem(object):
|
||||
"""
|
||||
Problem is the base class for all geophysical forward problems in SimPEG.
|
||||
|
||||
@@ -35,71 +34,42 @@ class Problem(object):
|
||||
to (locally) find how model parameters change the data, and optimize!
|
||||
"""
|
||||
|
||||
__metaclass__ = utils.Save.Savable
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
counter = None #: A SimPEG.utils.Counter object
|
||||
counter = None #: A SimPEG.Utils.Counter object
|
||||
|
||||
dataPair = Data.BaseData
|
||||
|
||||
def __init__(self, mesh, *args, **kwargs):
|
||||
utils.setKwargs(self, **kwargs)
|
||||
def __init__(self, mesh, model, *args, **kwargs):
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
self.mesh = mesh
|
||||
self.model = model
|
||||
|
||||
@property
|
||||
def RHS(self):
|
||||
def data(self):
|
||||
"""
|
||||
Source matrix.
|
||||
The data object for this problem.
|
||||
"""
|
||||
return self._RHS
|
||||
@RHS.setter
|
||||
def RHS(self, value):
|
||||
self._RHS = value
|
||||
return getattr(self, '_data', None)
|
||||
|
||||
def pair(self, d):
|
||||
"""Bind a data to this problem instance using pointers."""
|
||||
assert isinstance(d, self.dataPair), "Data object must be an instance of a %s class."%(self.dataPair.__name__)
|
||||
if d.ispaired:
|
||||
raise Exception("The data object is already paired to a problem. Use data.unpair()")
|
||||
self._data = d
|
||||
d._prob = self
|
||||
|
||||
def unpair(self):
|
||||
"""Unbind a data from this problem instance."""
|
||||
if not self.ispaired: return
|
||||
self.data._prob = None
|
||||
self._data = None
|
||||
|
||||
@property
|
||||
def P(self):
|
||||
"""
|
||||
Projection matrix.
|
||||
def ispaired(self): return self.data is not None
|
||||
|
||||
.. math::
|
||||
d_\\text{pred} = Pu(m)
|
||||
"""
|
||||
return self._P
|
||||
@P.setter
|
||||
def P(self, value):
|
||||
self._P = value
|
||||
|
||||
@utils.count
|
||||
def dpred(self, m, u=None):
|
||||
"""
|
||||
Predicted data.
|
||||
|
||||
.. math::
|
||||
d_\\text{pred} = Pu(m)
|
||||
"""
|
||||
if u is None:
|
||||
u = self.field(m)
|
||||
return self.P*u
|
||||
|
||||
@utils.count
|
||||
def dataResidual(self, m, data, u=None):
|
||||
"""
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array u: fields
|
||||
:rtype: float
|
||||
:return: data misfit
|
||||
|
||||
The data misfit:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data} = \mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs}
|
||||
|
||||
Where P is a projection matrix that brings the field on the full domain to the data measurement locations;
|
||||
u is the field of interest; d_obs is the observed data.
|
||||
"""
|
||||
|
||||
return self.dpred(m, u=u) - data.dobs
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def J(self, m, v, u=None):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
@@ -129,7 +99,7 @@ class Problem(object):
|
||||
"""
|
||||
raise NotImplementedError('J is not yet implemented.')
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def Jt(self, m, v, u=None):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
@@ -143,7 +113,7 @@ class Problem(object):
|
||||
raise NotImplementedError('Jt is not yet implemented.')
|
||||
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def J_approx(self, m, v, u=None):
|
||||
"""
|
||||
|
||||
@@ -158,7 +128,7 @@ class Problem(object):
|
||||
"""
|
||||
return self.J(m, v, u)
|
||||
|
||||
@utils.timeIt
|
||||
@Utils.timeIt
|
||||
def Jt_approx(self, m, v, u=None):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
@@ -182,33 +152,7 @@ class Problem(object):
|
||||
"""
|
||||
pass
|
||||
|
||||
def modelTransform(self, m):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
:rtype: numpy.array
|
||||
:return: transformed model
|
||||
|
||||
The modelTransform changes the model into the physical property.
|
||||
|
||||
A common example of this is to invert for electrical conductivity
|
||||
in log space. In this case, your model will be log(sigma) and to
|
||||
get back to sigma, you can take the exponential:
|
||||
|
||||
"""
|
||||
return m
|
||||
|
||||
def modelTransformDeriv(self, m):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
:rtype: scipy.csr_matrix
|
||||
:return: derivative of transformed model
|
||||
|
||||
The modelTransform changes the model into the physical property.
|
||||
The modelTransformDeriv provides the derivative of the modelTransform.
|
||||
"""
|
||||
return sp.identity(m.size)
|
||||
|
||||
def createSyntheticData(self, m, std=0.05, u=None):
|
||||
def createSyntheticData(self, m, std=0.05, u=None, **geometry_kwargs):
|
||||
"""
|
||||
Create synthetic data given a model, and a standard deviation.
|
||||
|
||||
@@ -220,11 +164,13 @@ class Problem(object):
|
||||
Returns the observed data with random Gaussian noise
|
||||
and Wd which is the same size as data, and can be used to weight the inversion.
|
||||
"""
|
||||
dtrue = self.dpred(m,u=u)
|
||||
noise = std*abs(dtrue)*np.random.randn(*dtrue.shape)
|
||||
dobs = dtrue+noise
|
||||
stdev = dobs*0 + std
|
||||
return data.SimPEGData(self, dobs=dobs, std=stdev, dtrue=dtrue, mtrue=m)
|
||||
data = self.dataPair(mtrue=m, **geometry_kwargs)
|
||||
data.pair(self)
|
||||
data.dtrue = data.dpred(m, u=u)
|
||||
noise = std*abs(data.dtrue)*np.random.randn(*data.dtrue.shape)
|
||||
data.dobs = data.dtrue+noise
|
||||
data.std = data.dobs*0 + std
|
||||
return data
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,109 @@
|
||||
from SimPEG import utils, np, sp
|
||||
import Utils, Model, Parameters, numpy as np, scipy.sparse as sp
|
||||
|
||||
class Regularization(object):
|
||||
"""**Regularization**
|
||||
class BaseRegularization(object):
|
||||
"""
|
||||
**Base Regularization Class**
|
||||
|
||||
This is used to regularize the model space::
|
||||
|
||||
reg = Regularization(mesh, model)
|
||||
|
||||
"""
|
||||
|
||||
__metaclass__ = Utils.Save.Savable
|
||||
|
||||
modelPair = Model.BaseModel #: Some regularizations only work on specific models
|
||||
|
||||
model = None #: A SimPEG.Model instance.
|
||||
|
||||
counter = None
|
||||
|
||||
def __init__(self, model, **kwargs):
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
assert isinstance(model, self.modelPair), "Incorrect model for this regularization"
|
||||
self.model = model
|
||||
|
||||
mref = Parameters.ParameterProperty('mref', default=None, doc='Reference model.')
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
"""This is the parent of the regularization."""
|
||||
return getattr(self,'_parent',None)
|
||||
@parent.setter
|
||||
def parent(self, p):
|
||||
if getattr(self,'_parent',None) is not None:
|
||||
print 'Regularization has switched to a new parent!'
|
||||
self._parent = p
|
||||
|
||||
@property
|
||||
def inv(self): return self.parent.inv
|
||||
@property
|
||||
def objFunc(self): return self.parent
|
||||
@property
|
||||
def reg(self): return self
|
||||
@property
|
||||
def opt(self): return self.parent.opt
|
||||
@property
|
||||
def prob(self): return self.parent.prob
|
||||
@property
|
||||
def data(self): return self.parent.data
|
||||
@property
|
||||
def mesh(self): return self.model.mesh
|
||||
|
||||
|
||||
@property
|
||||
def W(self):
|
||||
"""Full regularization weighting matrix W."""
|
||||
return sp.identity(self.model.nP)
|
||||
|
||||
|
||||
@Utils.timeIt
|
||||
def modelObj(self, m):
|
||||
r = self.W * (m - self.mref)
|
||||
return 0.5*r.dot(r)
|
||||
|
||||
@Utils.timeIt
|
||||
def modelObjDeriv(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})}
|
||||
|
||||
"""
|
||||
return self.W.T * ( self.W * (m - self.mref) )
|
||||
|
||||
@Utils.timeIt
|
||||
def modelObj2Deriv(self):
|
||||
"""
|
||||
|
||||
The regularization is:
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) = \\frac{1}{2}\mathbf{(m-m_\\text{ref})^\\top W^\\top W(m-m_\\text{ref})}
|
||||
|
||||
So the second derivative is straight forward:
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) = \mathbf{W^\\top W}
|
||||
|
||||
"""
|
||||
return self.W.T * self.W
|
||||
|
||||
|
||||
|
||||
class Tikhonov(BaseRegularization):
|
||||
"""**Tikhonov Regularization**
|
||||
|
||||
Here we will define regularization of a model, m, in general however, this should be thought of as (m-m_ref) but otherwise it is exactly the same:
|
||||
|
||||
@@ -83,36 +185,22 @@ class Regularization(object):
|
||||
|
||||
"""
|
||||
|
||||
__metaclass__ = utils.Save.Savable
|
||||
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")
|
||||
alpha_z = Utils.dependentProperty('_alpha_z', 1.0, ['_W', '_Wz'], "Weight for the first derivative in the z direction")
|
||||
alpha_xx = Utils.dependentProperty('_alpha_xx', 0.0, ['_W', '_Wxx'], "Weight for the second derivative in the x direction")
|
||||
alpha_yy = Utils.dependentProperty('_alpha_yy', 0.0, ['_W', '_Wyy'], "Weight for the second derivative in the y direction")
|
||||
alpha_zz = Utils.dependentProperty('_alpha_zz', 0.0, ['_W', '_Wzz'], "Weight for the second derivative in the z direction")
|
||||
|
||||
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")
|
||||
alpha_z = utils.dependentProperty('_alpha_z', 1.0, ['_W', '_Wz'], "Weight for the first derivative in the z direction")
|
||||
alpha_xx = utils.dependentProperty('_alpha_xx', 0.0, ['_W', '_Wxx'], "Weight for the second derivative in the x direction")
|
||||
alpha_yy = utils.dependentProperty('_alpha_yy', 0.0, ['_W', '_Wyy'], "Weight for the second derivative in the y direction")
|
||||
alpha_zz = utils.dependentProperty('_alpha_zz', 0.0, ['_W', '_Wzz'], "Weight for the second derivative in the z direction")
|
||||
|
||||
counter = None
|
||||
|
||||
def __init__(self, mesh, **kwargs):
|
||||
utils.setKwargs(self, **kwargs)
|
||||
self.mesh = mesh
|
||||
|
||||
@property
|
||||
def mref(self):
|
||||
if getattr(self, '_mref', None) is None:
|
||||
return np.zeros(self.mesh.nC);
|
||||
return self._mref
|
||||
@mref.setter
|
||||
def mref(self, value):
|
||||
self._mref = value
|
||||
def __init__(self, model, **kwargs):
|
||||
BaseRegularization.__init__(self, model, **kwargs)
|
||||
|
||||
@property
|
||||
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)
|
||||
self._Ws = Utils.sdiag((self.mesh.vol*self.alpha_s)**0.5)
|
||||
return self._Ws
|
||||
|
||||
@property
|
||||
@@ -120,7 +208,7 @@ class Regularization(object):
|
||||
"""Regularization matrix Wx"""
|
||||
if getattr(self, '_Wx', None) is None:
|
||||
Ave_x_vol = self.mesh.aveF2CC[:,:self.mesh.nFv[0]].T*self.mesh.vol
|
||||
self._Wx = utils.sdiag((Ave_x_vol*self.alpha_x)**0.5)*self.mesh.cellGradx
|
||||
self._Wx = Utils.sdiag((Ave_x_vol*self.alpha_x)**0.5)*self.mesh.cellGradx
|
||||
return self._Wx
|
||||
|
||||
@property
|
||||
@@ -128,7 +216,7 @@ class Regularization(object):
|
||||
"""Regularization matrix Wy"""
|
||||
if getattr(self, '_Wy', None) is None:
|
||||
Ave_y_vol = self.mesh.aveF2CC[:,self.mesh.nFv[0]:np.sum(self.mesh.nFv[:2])].T*self.mesh.vol
|
||||
self._Wy = utils.sdiag((Ave_y_vol*self.alpha_y)**0.5)*self.mesh.cellGrady
|
||||
self._Wy = Utils.sdiag((Ave_y_vol*self.alpha_y)**0.5)*self.mesh.cellGrady
|
||||
return self._Wy
|
||||
|
||||
@property
|
||||
@@ -136,31 +224,30 @@ class Regularization(object):
|
||||
"""Regularization matrix Wz"""
|
||||
if getattr(self, '_Wz', None) is None:
|
||||
Ave_z_vol = self.mesh.aveF2CC[:,np.sum(self.mesh.nFv[:2]):].T*self.mesh.vol
|
||||
self._Wz = utils.sdiag((Ave_z_vol*self.alpha_z)**0.5)*self.mesh.cellGradz
|
||||
self._Wz = Utils.sdiag((Ave_z_vol*self.alpha_z)**0.5)*self.mesh.cellGradz
|
||||
return self._Wz
|
||||
|
||||
@property
|
||||
def Wxx(self):
|
||||
"""Regularization matrix Wxx"""
|
||||
if getattr(self, '_Wxx', None) is None:
|
||||
self._Wxx = utils.sdiag((self.mesh.vol*self.alpha_xx)**0.5)*self.mesh.faceDivx*self.mesh.cellGradx
|
||||
self._Wxx = Utils.sdiag((self.mesh.vol*self.alpha_xx)**0.5)*self.mesh.faceDivx*self.mesh.cellGradx
|
||||
return self._Wxx
|
||||
|
||||
@property
|
||||
def Wyy(self):
|
||||
"""Regularization matrix Wyy"""
|
||||
if getattr(self, '_Wyy', None) is None:
|
||||
self._Wyy = utils.sdiag((self.mesh.vol*self.alpha_yy)**0.5)*self.mesh.faceDivy*self.mesh.cellGrady
|
||||
self._Wyy = Utils.sdiag((self.mesh.vol*self.alpha_yy)**0.5)*self.mesh.faceDivy*self.mesh.cellGrady
|
||||
return self._Wyy
|
||||
|
||||
@property
|
||||
def Wzz(self):
|
||||
"""Regularization matrix Wzz"""
|
||||
if getattr(self, '_Wzz', None) is None:
|
||||
self._Wzz = utils.sdiag((self.mesh.vol*self.alpha_zz)**0.5)*self.mesh.faceDivz*self.mesh.cellGradz
|
||||
self._Wzz = Utils.sdiag((self.mesh.vol*self.alpha_zz)**0.5)*self.mesh.faceDivz*self.mesh.cellGradz
|
||||
return self._Wzz
|
||||
|
||||
|
||||
@property
|
||||
def W(self):
|
||||
"""Full regularization matrix W"""
|
||||
@@ -173,47 +260,3 @@ class Regularization(object):
|
||||
self._W = sp.vstack(wlist)
|
||||
return self._W
|
||||
|
||||
|
||||
@utils.timeIt
|
||||
def modelObj(self, m):
|
||||
r = self.W * (m - self.mref)
|
||||
return 0.5*r.dot(r)
|
||||
|
||||
@utils.timeIt
|
||||
def modelObjDeriv(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})}
|
||||
|
||||
"""
|
||||
return self.W.T * ( self.W * (m - self.mref) )
|
||||
|
||||
@utils.timeIt
|
||||
def modelObj2Deriv(self):
|
||||
"""
|
||||
|
||||
The regularization is:
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) = \\frac{1}{2}\mathbf{(m-m_\\text{ref})^\\top W^\\top W(m-m_\\text{ref})}
|
||||
|
||||
So the second derivative is straight forward:
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) = \mathbf{W^\\top W}
|
||||
|
||||
"""
|
||||
return self.W.T * self.W
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
import scipy.sparse.linalg as linalg
|
||||
from SimPEG.utils import mkvc, sdiag
|
||||
from Utils.matutils import mkvc
|
||||
from Utils.sputils import sdiag
|
||||
import warnings
|
||||
|
||||
DEFAULTS = {'direct':'scipy', 'iter':'scipy', 'triangular':'fortran', 'diagonal':'python'}
|
||||
OPTIONS = {'direct':['scipy'], 'iter':['scipy'], 'triangular':['python'], 'diagonal':['python']}
|
||||
|
||||
try:
|
||||
import TriSolve
|
||||
import Utils.TriSolve as TriSolve
|
||||
OPTIONS['triangular'].append('fortran')
|
||||
except Exception, e:
|
||||
print 'Warning: Python backend is being used for solver. Run setup.py from the command line.'
|
||||
@@ -319,7 +320,7 @@ class Solver(object):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from SimPEG.mesh import TensorMesh
|
||||
from SimPEG.Mesh import TensorMesh
|
||||
from time import time
|
||||
h1 = np.ones(20)*100.
|
||||
h2 = np.ones(20)*100.
|
||||
@@ -1,9 +1,9 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from pylab import norm
|
||||
from SimPEG.utils import mkvc, sdiag
|
||||
from SimPEG import utils
|
||||
from SimPEG.mesh import TensorMesh, LogicallyOrthogonalMesh
|
||||
from numpy.linalg import norm
|
||||
from SimPEG.Utils import mkvc, sdiag
|
||||
from SimPEG import Utils
|
||||
from SimPEG.Mesh import TensorMesh, LogicallyOrthogonalMesh
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
import unittest
|
||||
@@ -112,10 +112,10 @@ class OrderTest(unittest.TestCase):
|
||||
else:
|
||||
raise Exception('Unexpected meshType')
|
||||
if self.meshDimension == 2:
|
||||
X, Y = utils.exampleLomGird([nc, nc], kwrd)
|
||||
X, Y = Utils.exampleLomGird([nc, nc], kwrd)
|
||||
self.M = LogicallyOrthogonalMesh([X, Y])
|
||||
if self.meshDimension == 3:
|
||||
X, Y, Z = utils.exampleLomGird([nc, nc, nc], kwrd)
|
||||
X, Y, Z = Utils.exampleLomGird([nc, nc, nc], kwrd)
|
||||
self.M = LogicallyOrthogonalMesh([X, Y, Z])
|
||||
return 1./nc
|
||||
|
||||
@@ -211,12 +211,10 @@ def checkDerivative(fctn, x0, num=7, plotIt=True, dx=None, expectedOrder=2, tole
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG.tests import checkDerivative
|
||||
from SimPEG.utils import sdiag
|
||||
import numpy as np
|
||||
from SimPEG import Tests, Utils, np
|
||||
def simplePass(x):
|
||||
return np.sin(x), sdiag(np.cos(x))
|
||||
checkDerivative(simplePass, np.random.randn(5))
|
||||
return np.sin(x), Utils.sdiag(np.cos(x))
|
||||
Tests.checkDerivative(simplePass, np.random.randn(5))
|
||||
"""
|
||||
|
||||
print "%s checkDerivative %s" % ('='*20, '='*20)
|
||||
@@ -0,0 +1,14 @@
|
||||
from TestUtils import checkDerivative, Rosenbrock, OrderTest, getQuadratic
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os
|
||||
import glob
|
||||
import unittest
|
||||
test_file_strings = glob.glob('test_*.py')
|
||||
module_strings = [str[0:len(str)-3] for str in test_file_strings]
|
||||
suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str
|
||||
in module_strings]
|
||||
testSuite = unittest.TestSuite(suites)
|
||||
|
||||
unittest.TextTestRunner(verbosity=2).run(testSuite)
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG.mesh import TensorMesh, LogicallyOrthogonalMesh
|
||||
from SimPEG.utils import ndgrid
|
||||
from SimPEG.Mesh import TensorMesh, LogicallyOrthogonalMesh
|
||||
from SimPEG.Utils import ndgrid
|
||||
|
||||
|
||||
class BasicLOMTests(unittest.TestCase):
|
||||
@@ -1,7 +1,7 @@
|
||||
import unittest
|
||||
from SimPEG import Solver
|
||||
from SimPEG.mesh import TensorMesh
|
||||
from SimPEG.utils import sdiag
|
||||
from SimPEG.Mesh import TensorMesh
|
||||
from SimPEG.Utils import sdiag
|
||||
import numpy as np
|
||||
import scipy.sparse as sparse
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import unittest
|
||||
import sys
|
||||
from SimPEG.mesh import BaseMesh
|
||||
from SimPEG.Mesh import BaseMesh
|
||||
import numpy as np
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class TestBaseMesh(unittest.TestCase):
|
||||
self.assertTrue(self.mesh.dim, 3)
|
||||
|
||||
def test_mesh_nc(self):
|
||||
self.assertTrue(np.all(self.mesh.n == [6, 2, 3]))
|
||||
self.assertTrue(np.all(self.mesh.nCv == [6, 2, 3]))
|
||||
|
||||
def test_mesh_nc_xyz(self):
|
||||
x = np.all(self.mesh.nCx == 6)
|
||||
@@ -106,9 +106,9 @@ class TestBaseMesh(unittest.TestCase):
|
||||
g[:, 1] = 2
|
||||
g[:, 2] = 3
|
||||
Xc, Yc, Zc = self.mesh.r(g, 'CC', 'CC', 'M')
|
||||
self.assertTrue(np.all(Xc.shape == self.mesh.n))
|
||||
self.assertTrue(np.all(Yc.shape == self.mesh.n))
|
||||
self.assertTrue(np.all(Zc.shape == self.mesh.n))
|
||||
self.assertTrue(np.all(Xc.shape == self.mesh.nCv))
|
||||
self.assertTrue(np.all(Yc.shape == self.mesh.nCv))
|
||||
self.assertTrue(np.all(Zc.shape == self.mesh.nCv))
|
||||
self.assertTrue(np.all(Xc == 1))
|
||||
self.assertTrue(np.all(Yc == 2))
|
||||
self.assertTrue(np.all(Zc == 3))
|
||||
@@ -123,7 +123,7 @@ class TestMeshNumbers2D(unittest.TestCase):
|
||||
self.assertTrue(self.mesh.dim, 2)
|
||||
|
||||
def test_mesh_nc(self):
|
||||
self.assertTrue(np.all(self.mesh.n == [6, 2]))
|
||||
self.assertTrue(np.all(self.mesh.nCv == [6, 2]))
|
||||
|
||||
def test_mesh_nc_xyz(self):
|
||||
x = np.all(self.mesh.nCx == 6)
|
||||
@@ -203,8 +203,8 @@ class TestMeshNumbers2D(unittest.TestCase):
|
||||
g = np.ones((self.mesh.nC, 2))
|
||||
g[:, 1] = 2
|
||||
Xc, Yc = self.mesh.r(g, 'CC', 'CC', 'M')
|
||||
self.assertTrue(np.all(Xc.shape == self.mesh.n))
|
||||
self.assertTrue(np.all(Yc.shape == self.mesh.n))
|
||||
self.assertTrue(np.all(Xc.shape == self.mesh.nCv))
|
||||
self.assertTrue(np.all(Yc.shape == self.mesh.nCv))
|
||||
self.assertTrue(np.all(Xc == 1))
|
||||
self.assertTrue(np.all(Yc == 2))
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
# import numpy as np
|
||||
# import unittest
|
||||
# from SimPEG.mesh import TensorMesh
|
||||
# from SimPEG.Utils import ModelBuilder, sdiag
|
||||
# from SimPEG.forward import Problem
|
||||
# from SimPEG.examples.DC import *
|
||||
# from TestUtils import checkDerivative
|
||||
# from scipy.sparse.linalg import dsolve
|
||||
# from SimPEG import inverse
|
||||
|
||||
|
||||
# class DCProblemTests(unittest.TestCase):
|
||||
|
||||
# def setUp(self):
|
||||
# # Create the mesh
|
||||
# h1 = np.ones(20)
|
||||
# h2 = np.ones(20)
|
||||
# mesh = TensorMesh([h1,h2])
|
||||
|
||||
# # Create some parameters for the model
|
||||
# sig1 = 1
|
||||
# sig2 = 0.01
|
||||
|
||||
# # Create a synthetic model from a block in a half-space
|
||||
# p0 = [2, 2]
|
||||
# p1 = [5, 5]
|
||||
# condVals = [sig1, sig2]
|
||||
# mSynth = ModelBuilder.defineBlockConductivity(p0,p1,mesh.gridCC,condVals)
|
||||
|
||||
# # Set up the projection
|
||||
# nelec = 10
|
||||
# spacelec = 2
|
||||
# surfloc = 0.5
|
||||
# elecini = 0.5
|
||||
# elecend = 0.5+spacelec*(nelec-1)
|
||||
# elecLocR = np.linspace(elecini, elecend, nelec)
|
||||
# rxmidLoc = (elecLocR[0:nelec-1]+elecLocR[1:nelec])*0.5
|
||||
# q, Q, rxmidloc = genTxRxmat(nelec, spacelec, surfloc, elecini, mesh)
|
||||
# P = Q.T
|
||||
|
||||
# # Create some data
|
||||
|
||||
# problem = DCProblem(mesh)
|
||||
# problem.P = P
|
||||
# problem.RHS = q
|
||||
# data = problem.createSyntheticData(mSynth, std=0.05)
|
||||
|
||||
# # Now set up the problem to do some minimization
|
||||
# opt = inverse.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6)
|
||||
# reg = inverse.Regularization(mesh)
|
||||
# inv = inverse.Inversion(problem, reg, opt, data, beta0=1e4)
|
||||
|
||||
# self.inv = inv
|
||||
# self.reg = reg
|
||||
# self.p = problem
|
||||
# self.mesh = mesh
|
||||
# self.m0 = mSynth
|
||||
# self.data = data
|
||||
|
||||
# def test_misfit(self):
|
||||
# derChk = lambda m: [self.p.dpred(m), lambda mx: self.p.J(self.m0, mx)]
|
||||
# passed = checkDerivative(derChk, self.m0, plotIt=False)
|
||||
# self.assertTrue(passed)
|
||||
|
||||
# def test_adjoint(self):
|
||||
# # Adjoint Test
|
||||
# u = np.random.rand(self.mesh.nC*self.p.RHS.shape[1])
|
||||
# v = np.random.rand(self.mesh.nC)
|
||||
# w = np.random.rand(self.data.dobs.shape[0])
|
||||
# wtJv = w.dot(self.p.J(self.m0, v, u=u))
|
||||
# vtJtw = v.dot(self.p.Jt(self.m0, w, u=u))
|
||||
# passed = (wtJv - vtJtw) < 1e-10
|
||||
# self.assertTrue(passed)
|
||||
|
||||
# def test_dataObj(self):
|
||||
# derChk = lambda m: [self.inv.dataObj(m), self.inv.dataObjDeriv(m)]
|
||||
# checkDerivative(derChk, self.m0, plotIt=False)
|
||||
|
||||
# def test_modelObj(self):
|
||||
# derChk = lambda m: [self.reg.modelObj(m), self.reg.modelObjDeriv(m)]
|
||||
# checkDerivative(derChk, self.m0, plotIt=False)
|
||||
|
||||
|
||||
# if __name__ == '__main__':
|
||||
# unittest.main()
|
||||
@@ -1,7 +1,7 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from TestUtils import OrderTest
|
||||
from SimPEG.utils import mkvc
|
||||
from SimPEG.Utils import mkvc
|
||||
|
||||
MESHTYPES = ['uniformTensorMesh', 'randomTensorMesh']
|
||||
TOLERANCES = [0.9, 0.55]
|
||||
File renamed without changes.
@@ -0,0 +1,27 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG import *
|
||||
from TestUtils import checkDerivative
|
||||
from scipy.sparse.linalg import dsolve
|
||||
|
||||
|
||||
class ModelTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
a = np.array([1, 1, 1])
|
||||
b = np.array([1, 2])
|
||||
c = np.array([1, 4])
|
||||
self.mesh2 = Mesh.TensorMesh([a, b], np.array([3, 5]))
|
||||
|
||||
def test_modelTransforms(self):
|
||||
print 'SimPEG.Model.BaseModel: Testing Model Transform'
|
||||
for M in dir(Model):
|
||||
if 'Model' not in M: continue
|
||||
model = getattr(Model, M)(self.mesh2)
|
||||
m = model.example()
|
||||
passed = checkDerivative(lambda m : [model.transform(m), model.transformDeriv(m)], m, plotIt=False)
|
||||
self.assertTrue(passed)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
File renamed without changes.
@@ -1,11 +1,11 @@
|
||||
import unittest
|
||||
from SimPEG import Solver
|
||||
from SimPEG.mesh import TensorMesh
|
||||
from SimPEG.utils import sdiag
|
||||
from SimPEG.Mesh import TensorMesh
|
||||
from SimPEG.Utils import sdiag
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
from SimPEG import inverse
|
||||
from SimPEG.tests import getQuadratic, Rosenbrock
|
||||
from SimPEG import Optimization
|
||||
from SimPEG.Tests import getQuadratic, Rosenbrock
|
||||
|
||||
TOL = 1e-2
|
||||
|
||||
@@ -16,7 +16,7 @@ class TestOptimizers(unittest.TestCase):
|
||||
self.b = np.array([-5,-5])
|
||||
|
||||
def test_GN_Rosenbrock(self):
|
||||
GN = inverse.GaussNewton()
|
||||
GN = Optimization.GaussNewton()
|
||||
xopt = GN.minimize(Rosenbrock,np.array([0,0]))
|
||||
x_true = np.array([1.,1.])
|
||||
print 'xopt: ', xopt
|
||||
@@ -24,7 +24,7 @@ class TestOptimizers(unittest.TestCase):
|
||||
self.assertTrue(np.linalg.norm(xopt-x_true,2) < TOL, True)
|
||||
|
||||
def test_GN_quadratic(self):
|
||||
GN = inverse.GaussNewton()
|
||||
GN = Optimization.GaussNewton()
|
||||
xopt = GN.minimize(getQuadratic(self.A,self.b),np.array([0,0]))
|
||||
x_true = np.array([5.,5.])
|
||||
print 'xopt: ', xopt
|
||||
@@ -32,7 +32,7 @@ class TestOptimizers(unittest.TestCase):
|
||||
self.assertTrue(np.linalg.norm(xopt-x_true,2) < TOL, True)
|
||||
|
||||
def test_ProjGradient_quadraticBounded(self):
|
||||
PG = inverse.ProjectedGradient(debug=True)
|
||||
PG = Optimization.ProjectedGradient(debug=True)
|
||||
PG.lower, PG.upper = -2, 2
|
||||
xopt = PG.minimize(getQuadratic(self.A,self.b),np.array([0,0]))
|
||||
x_true = np.array([2.,2.])
|
||||
@@ -42,7 +42,7 @@ class TestOptimizers(unittest.TestCase):
|
||||
|
||||
def test_ProjGradient_quadratic1Bound(self):
|
||||
myB = np.array([-5,1])
|
||||
PG = inverse.ProjectedGradient()
|
||||
PG = Optimization.ProjectedGradient()
|
||||
PG.lower, PG.upper = -2, 2
|
||||
xopt = PG.minimize(getQuadratic(self.A,myB),np.array([0,0]))
|
||||
x_true = np.array([2.,-1.])
|
||||
@@ -53,7 +53,7 @@ class TestOptimizers(unittest.TestCase):
|
||||
def test_NewtonRoot(self):
|
||||
fun = lambda x, return_g=True: np.sin(x) if not return_g else ( np.sin(x), sdiag( np.cos(x) ) )
|
||||
x = np.array([np.pi-0.3, np.pi+0.1, 0])
|
||||
xopt = inverse.NewtonRoot(comments=False).root(fun,x)
|
||||
xopt = Optimization.NewtonRoot(comments=False).root(fun,x)
|
||||
x_true = np.array([np.pi,np.pi,0])
|
||||
print 'Newton Root Finding'
|
||||
print 'xopt: ', xopt
|
||||
@@ -0,0 +1,31 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG import *
|
||||
from TestUtils import checkDerivative
|
||||
from scipy.sparse.linalg import dsolve
|
||||
import inspect
|
||||
|
||||
|
||||
class RegularizationTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mesh2 = Mesh.TensorMesh([3, 2])
|
||||
|
||||
def test_regularization(self):
|
||||
for R in dir(Regularization):
|
||||
r = getattr(Regularization, R)
|
||||
if not inspect.isclass(r): continue
|
||||
if not issubclass(r, Regularization.BaseRegularization):
|
||||
continue
|
||||
# if 'Regularization' not in R: continue
|
||||
print 'Check:', R
|
||||
model = r.modelPair(self.mesh2)
|
||||
reg = r(model)
|
||||
m = model.example()
|
||||
reg.mref = model.example()*0
|
||||
passed = checkDerivative(lambda m : [reg.modelObj(m), reg.modelObjDeriv(m)], m, plotIt=False)
|
||||
self.assertTrue(passed)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG.mesh import TensorMesh
|
||||
from SimPEG.Mesh import TensorMesh
|
||||
from TestUtils import OrderTest
|
||||
from scipy.sparse.linalg import dsolve
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG.utils import mkvc, ndgrid, indexCube, sdiag, inv3X3BlockDiagonal, inv2X2BlockDiagonal
|
||||
from SimPEG.tests import checkDerivative
|
||||
from SimPEG.Utils import mkvc, ndgrid, indexCube, sdiag, inv3X3BlockDiagonal, inv2X2BlockDiagonal
|
||||
from SimPEG.Tests import checkDerivative
|
||||
|
||||
|
||||
class TestCheckDerivative(unittest.TestCase):
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -27,6 +27,9 @@ def getIndecesBlock(p0,p1,ccMesh):
|
||||
dimMesh = np.size(ccMesh[0,:])
|
||||
assert len(p0) == dimMesh, "Dimension mismatch. len(p0) != dimMesh"
|
||||
|
||||
for ii in range(len(p0)):
|
||||
p0[ii], p1[ii] = np.min([p0[ii], p1[ii]]), np.max([p0[ii], p1[ii]])
|
||||
|
||||
if dimMesh == 1:
|
||||
# Define the reference points
|
||||
x1 = p0[0]
|
||||
@@ -67,7 +70,7 @@ def getIndecesBlock(p0,p1,ccMesh):
|
||||
# Return a tuple
|
||||
return ind
|
||||
|
||||
def defineBlockConductivity(p0,p1,ccMesh,condVals):
|
||||
def defineBlockConductivity(ccMesh,p0,p1,condVals):
|
||||
"""
|
||||
Build a block with the conductivity specified by condVal. Returns an array.
|
||||
condVals[0] conductivity of the block
|
||||
@@ -80,7 +83,7 @@ def defineBlockConductivity(p0,p1,ccMesh,condVals):
|
||||
|
||||
return sigma
|
||||
|
||||
def defineTwoLayeredConductivity(depth,ccMesh,condVals):
|
||||
def defineTwoLayeredConductivity(ccMesh,depth,condVals):
|
||||
"""
|
||||
Define a two layered model. Depth of the first layer must be specified.
|
||||
CondVals vector with the conductivity values of the layers. Eg:
|
||||
@@ -151,7 +154,7 @@ def randomModel(shape, seed=None, anisotropy=None, its=100, bounds=[0,1]):
|
||||
.. plot::
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import SimPEG.utils.ModelBuilder as MB
|
||||
import SimPEG.Utils.ModelBuilder as MB
|
||||
plt.colorbar(plt.imshow(MB.randomModel((50,50),bounds=[-4,0])))
|
||||
plt.title('A very cool, yet completely random model.')
|
||||
plt.show()
|
||||
@@ -196,7 +199,7 @@ def randomModel(shape, seed=None, anisotropy=None, its=100, bounds=[0,1]):
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
from SimPEG.mesh import TensorMesh
|
||||
from SimPEG.Mesh import TensorMesh
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
# Define the mesh
|
||||
@@ -229,7 +232,7 @@ if __name__ == '__main__':
|
||||
p1 = np.array([1.0,1.0,1.0])[:testDim]
|
||||
condVals = np.array([100,1e-6])
|
||||
|
||||
sigma = defineBlockConductivity(p0,p1,ccMesh,condVals)
|
||||
sigma = defineBlockConductivity(ccMesh,p0,p1,condVals)
|
||||
|
||||
# Plot sigma model
|
||||
print sigma.shape
|
||||
@@ -242,7 +245,7 @@ if __name__ == '__main__':
|
||||
condVals = np.array([100,1e-5]);
|
||||
depth = 1.0;
|
||||
|
||||
sigma = defineTwoLayeredConductivity(depth,ccMesh,condVals)
|
||||
sigma = defineTwoLayeredConductivity(ccMesh,depth,condVals)
|
||||
|
||||
M.plotImage(sigma)
|
||||
print sigma
|
||||
@@ -5,7 +5,7 @@ import re
|
||||
try:
|
||||
import h5py
|
||||
except Exception, e:
|
||||
print 'Warning: SimPEG.utils.Save needs h5py to be installed.'
|
||||
print 'Warning: SimPEG.Utils.Save needs h5py to be installed.'
|
||||
|
||||
|
||||
SAVEABLES = {}
|
||||
@@ -57,7 +57,7 @@ class SimPEGTable:
|
||||
|
||||
# At the start of every iteration we will create a inversion iteration node.
|
||||
def _doStartIteration_hdf5_inv(invObj):
|
||||
invObj._invNodeIt = invObj._invNode.addGroup('%d'%(invObj._iter+1))
|
||||
invObj._invNodeIt = invObj._invNode.addGroup('%d'%(invObj.iter+1))
|
||||
preIteration(invObj._invNodeIt)
|
||||
invObj.hook(_doStartIteration_hdf5_inv, overwrite=True)
|
||||
|
||||
@@ -78,7 +78,7 @@ class SimPEGTable:
|
||||
invObj.hook(_finish_hdf5_inv, overwrite=True)
|
||||
|
||||
def _doStartIteration_hdf5_opt(optObj):
|
||||
optObj._optNodeIt = optObj.parent._invNode.addGroup('%d.%d'%(optObj.parent._iter, optObj._iter))
|
||||
optObj._optNodeIt = optObj.parent._invNode.addGroup('%d.%d'%(optObj.parent.iter, optObj.iter))
|
||||
preIteration(optObj._optNodeIt)
|
||||
invObj.opt.hook(_doStartIteration_hdf5_opt, overwrite=True)
|
||||
|
||||
@@ -208,6 +208,10 @@ class hdf5Inversion(hdf5Group):
|
||||
def rebuild(self):
|
||||
return loadSavable(self['rebuild'])
|
||||
|
||||
@property
|
||||
def results(self): return self['results']
|
||||
|
||||
|
||||
class hdf5InversionResults(hdf5Group):
|
||||
def __init__(self, T, groupNode):
|
||||
hdf5Group.__init__(self, T, groupNode)
|
||||
@@ -343,6 +347,6 @@ def loadSavable(node, pointers=None):
|
||||
print 'KWARGS: ', KWARGS
|
||||
return (cls, ARGS, KWARGS, node)
|
||||
else:
|
||||
print 'Warning: %s Class not found in SimPEG.utils.Save.SAVABLES' % cls
|
||||
print 'Warning: %s Class not found in SimPEG.Utils.Save.SAVABLES' % cls
|
||||
return (cls, ARGS, KWARGS, node)
|
||||
|
||||
File renamed without changes.
@@ -1,19 +1,12 @@
|
||||
import matutils
|
||||
import sputils
|
||||
import lomutils
|
||||
import interputils
|
||||
import ModelBuilder
|
||||
import meshutils
|
||||
from matutils import getSubArray, mkvc, ndgrid, ind2sub, sub2ind
|
||||
from sputils import spzeros, kron3, speye, sdiag, ddx, av, avExtrap
|
||||
from meshutils import exampleLomGird, meshTensors
|
||||
from lomutils import volTetra, faceInfo, inv2X2BlockDiagonal, inv3X3BlockDiagonal, indexCube
|
||||
from interputils import interpmat
|
||||
from ipythonUtils import easyAnimate as animate
|
||||
import Solver
|
||||
from Solver import Solver
|
||||
from ipythonutils import easyAnimate as animate
|
||||
import Save
|
||||
import Geophysics
|
||||
import ModelBuilder
|
||||
|
||||
import types
|
||||
import time
|
||||
@@ -90,7 +83,7 @@ def printStoppers(obj, stoppers, pad='', stop='STOP!', done='DONE!'):
|
||||
print pad + stopper['str'] % (l<=r,l,r)
|
||||
print pad + "%s%s%s" % ('-'*25,done,'-'*25)
|
||||
|
||||
def callHooks(match):
|
||||
def callHooks(match, mainFirst=False):
|
||||
"""
|
||||
Use this to wrap a funciton::
|
||||
|
||||
@@ -99,16 +92,28 @@ def callHooks(match):
|
||||
pass
|
||||
|
||||
This will call everything named _doEndIteration* at the beginning of the function call.
|
||||
By default the master method (doEndIteration) is run after all of the sub methods (_doEndIteration*).
|
||||
This can be reversed by adding the mainFirst=True kwarg.
|
||||
"""
|
||||
def callHooksWrap(f):
|
||||
@wraps(f)
|
||||
def wrapper(self,*args,**kwargs):
|
||||
|
||||
for method in [posible for posible in dir(self) if ('_'+match) in posible]:
|
||||
if getattr(self,'debug',False): print (match+' is calling self.'+method)
|
||||
getattr(self,method)(*args, **kwargs)
|
||||
if not mainFirst:
|
||||
for method in [posible for posible in dir(self) if ('_'+match) in posible]:
|
||||
if getattr(self,'debug',False): print (match+' is calling self.'+method)
|
||||
getattr(self,method)(*args, **kwargs)
|
||||
|
||||
return f(self,*args,**kwargs)
|
||||
else:
|
||||
out = f(self,*args,**kwargs)
|
||||
|
||||
for method in [posible for posible in dir(self) if ('_'+match) in posible]:
|
||||
if getattr(self,'debug',False): print (match+' is calling self.'+method)
|
||||
getattr(self,method)(*args, **kwargs)
|
||||
|
||||
return out
|
||||
|
||||
return f(self,*args,**kwargs)
|
||||
|
||||
extra = """
|
||||
If you have things that also need to run in the method %s, you can create a method::
|
||||
@@ -119,8 +124,8 @@ def callHooks(match):
|
||||
Where the * can be any string. If present, _%s* will be called at the start of the default %s call.
|
||||
You may also completely overwrite this function.
|
||||
""" % (match, match, match, match)
|
||||
|
||||
wrapper.__doc__ += extra
|
||||
doc = wrapper.__doc__
|
||||
wrapper.__doc__ = ('' if doc is None else doc) + extra
|
||||
return wrapper
|
||||
return callHooksWrap
|
||||
|
||||
@@ -133,6 +138,45 @@ def dependentProperty(name, value, children, doc):
|
||||
setattr(self, name, val)
|
||||
return property(fget=fget, fset=fset, doc=doc)
|
||||
|
||||
def requires(var):
|
||||
"""
|
||||
Use this to wrap a funciton::
|
||||
|
||||
@requires('prob')
|
||||
def dpred(self):
|
||||
pass
|
||||
|
||||
This wrapper will ensure that a problem has been bound to the data.
|
||||
If a problem is not bound an Exception will be raised, and an nice error message printed.
|
||||
"""
|
||||
def requiresVar(f):
|
||||
if var is 'prob':
|
||||
extra = """
|
||||
|
||||
.. note::
|
||||
|
||||
To use data.%s(), SimPEG requires that a problem be bound to the data.
|
||||
If a problem has not been bound, an Exception will be raised.
|
||||
To bind a problem to the Data object::
|
||||
|
||||
data.pair(myProblem)
|
||||
|
||||
""" % f.__name__
|
||||
else:
|
||||
extra = """
|
||||
To use *%s* method, SimPEG requires that the %s be specified.
|
||||
""" % (f.__name__, var)
|
||||
@wraps(f)
|
||||
def requiresVarWrapper(self,*args,**kwargs):
|
||||
if getattr(self, var, None) is None:
|
||||
raise Exception(extra)
|
||||
return f(self,*args,**kwargs)
|
||||
|
||||
doc = requiresVarWrapper.__doc__
|
||||
requiresVarWrapper.__doc__ = ('' if doc is None else doc) + extra
|
||||
|
||||
return requiresVarWrapper
|
||||
return requiresVar
|
||||
|
||||
class Counter(object):
|
||||
"""
|
||||
@@ -14,10 +14,10 @@ def _interp_point_1D(x, xr_i):
|
||||
"""
|
||||
# TODO: This fails if the point is on the outside of the mesh. We may want to replace this by extrapolation?
|
||||
im = np.argmin(abs(x-xr_i))
|
||||
if xr_i - x[im] >= 0: # Point on the left
|
||||
if xr_i - x[im] >= 0: # Point on the left
|
||||
ind_x1 = im
|
||||
ind_x2 = im+1
|
||||
elif xr_i - x[im] < 0: # Point on the right
|
||||
elif xr_i - x[im] < 0: # Point on the right
|
||||
ind_x1 = im-1
|
||||
ind_x2 = im
|
||||
dx1 = xr_i - x[ind_x1]
|
||||
@@ -45,7 +45,7 @@ def interpmat(locs, x, y=None, z=None):
|
||||
x = np.linspace(0,1,7)
|
||||
dense = np.linspace(0,1,200)
|
||||
fun = lambda x: np.cos(2*np.pi*x)
|
||||
Q = SimPEG.utils.interpmat(locs, x)
|
||||
Q = SimPEG.Utils.interpmat(locs, x)
|
||||
plt.plot(x, fun(x), 'bs-')
|
||||
plt.plot(dense, fun(dense), 'y:')
|
||||
plt.plot(locs, Q*fun(x), 'mo')
|
||||
@@ -173,7 +173,7 @@ if __name__ == '__main__':
|
||||
x = np.linspace(0,1,7)
|
||||
dense = np.linspace(0,1,200)
|
||||
fun = lambda x: np.cos(2*np.pi*x)
|
||||
Q = SimPEG.utils.interpmat(locs, x)
|
||||
Q = SimPEG.Utils.interpmat(locs, x)
|
||||
plt.plot(x, fun(x), 'bs-')
|
||||
plt.plot(dense, fun(dense), 'y:')
|
||||
plt.plot(locs, Q*fun(x), 'mo')
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -30,12 +30,12 @@ def meshTensors(*args):
|
||||
"""
|
||||
**meshTensors** takes any number of tuples that have the form::
|
||||
|
||||
h1 = ( (numPad, sizeStart [, increaseFactor]), (numCore, sizeCode), (numPad, sizeStart [, increaseFactor]) )
|
||||
h1 = ( (numPad, sizeStart [, increaseFactor]), (numCore, sizeCore), (numPad, sizeStart [, increaseFactor]) )
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import mesh, utils
|
||||
M = mesh.TensorMesh(utils.meshTensors(((10,10),(40,10),(10,10)), ((10,10),(20,10),(0,0))))
|
||||
from SimPEG import Mesh, Utils
|
||||
M = Mesh.TensorMesh(Utils.meshTensors(((10,10),(40,10),(10,10)), ((10,10),(20,10),(0,0))))
|
||||
M.plotGrid()
|
||||
|
||||
"""
|
||||
File renamed without changes.
+14
-8
@@ -1,13 +1,19 @@
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
import utils
|
||||
from utils import Solver
|
||||
import mesh
|
||||
import data
|
||||
import forward
|
||||
import inverse
|
||||
import visualize
|
||||
import examples
|
||||
import Utils
|
||||
from Solver import Solver
|
||||
import Mesh
|
||||
import Model
|
||||
import Problem
|
||||
import Data
|
||||
import Regularization
|
||||
import ObjFunction
|
||||
import Optimization
|
||||
import Inversion
|
||||
import Parameters
|
||||
import Examples
|
||||
import Tests
|
||||
|
||||
|
||||
import scipy.version as _v
|
||||
if _v.version < '0.13.0':
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
from SimPEG import utils
|
||||
|
||||
|
||||
class SimPEGData(object):
|
||||
"""Data holds the observed data, and the standard deviations."""
|
||||
|
||||
__metaclass__ = utils.Save.Savable
|
||||
|
||||
std = None #: Estimated Standard Deviations
|
||||
dobs = None #: Observed data
|
||||
dtrue = None #: True data, if data is synthetic
|
||||
mtrue = None #: True model, if data is synthetic
|
||||
|
||||
def __init__(self, prob, **kwargs):
|
||||
utils.setKwargs(self, **kwargs)
|
||||
self.prob = prob
|
||||
|
||||
def isSynthetic(self):
|
||||
"Check if the data is synthetic."
|
||||
return self.mtrue is not None
|
||||
@@ -1,49 +0,0 @@
|
||||
import numpy as np
|
||||
from SimPEG.utils import mkvc, sdiag
|
||||
|
||||
class LogModel(object):
|
||||
"""docstring for LogModel"""
|
||||
def modelTransform(self, m):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
:rtype: numpy.array
|
||||
:return: transformed model
|
||||
|
||||
The modelTransform changes the model into the physical property.
|
||||
|
||||
A common example of this is to invert for electrical conductivity
|
||||
in log space. In this case, your model will be log(sigma) and to
|
||||
get back to sigma, you can take the exponential:
|
||||
|
||||
.. math::
|
||||
|
||||
m = \log{\sigma}
|
||||
|
||||
\exp{m} = \exp{\log{\sigma}} = \sigma
|
||||
"""
|
||||
return np.exp(mkvc(m))
|
||||
|
||||
def modelTransformDeriv(self, m):
|
||||
"""
|
||||
:param numpy.array m: model
|
||||
:rtype: scipy.csr_matrix
|
||||
:return: derivative of transformed model
|
||||
|
||||
The modelTransform changes the model into the physical property.
|
||||
The modelTransformDeriv provides the derivative of the modelTransform.
|
||||
|
||||
If the model transform is:
|
||||
|
||||
.. math::
|
||||
|
||||
m = \log{\sigma}
|
||||
|
||||
\exp{m} = \exp{\log{\sigma}} = \sigma
|
||||
|
||||
Then the derivative is:
|
||||
|
||||
.. math::
|
||||
|
||||
\\frac{\partial \exp{m}}{\partial m} = \\text{sdiag}(\exp{m})
|
||||
"""
|
||||
return sdiag(np.exp(mkvc(m)))
|
||||
@@ -1,2 +0,0 @@
|
||||
from Problem import *
|
||||
import ModelTransforms
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
class Cooling(object):
|
||||
"""Simple Beta Schedule"""
|
||||
|
||||
beta0 = None #: The initial beta value, set to none means that it will be approximated in the first iteration.
|
||||
beta_coolingFactor = 2.
|
||||
|
||||
def getBeta(self):
|
||||
if self._beta is None:
|
||||
return self.beta0
|
||||
return self._beta / self.beta_coolingFactor
|
||||
@@ -1,396 +0,0 @@
|
||||
import SimPEG
|
||||
from SimPEG import utils, sp, np
|
||||
from Optimize import Remember
|
||||
from BetaSchedule import Cooling
|
||||
from SimPEG.inverse import 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
|
||||
|
||||
beta0 = None #: The initial Beta (regularization parameter)
|
||||
beta0_ratio = 0.1 #: When beta0 is set to None, estimateBeta0 is used with this ratio
|
||||
|
||||
def __init__(self, prob, reg, opt, data, **kwargs):
|
||||
utils.setKwargs(self, **kwargs)
|
||||
self.prob = prob
|
||||
self.reg = reg
|
||||
self.opt = opt
|
||||
self.data = data
|
||||
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.
|
||||
print 'Setting bfgsH0 to the inverse of the modelObj2Deriv. Done using direct methods.'
|
||||
opt.bfgsH0 = SimPEG.Solver(reg.modelObj2Deriv())
|
||||
|
||||
|
||||
@property
|
||||
def Wd(self):
|
||||
"""
|
||||
Standard deviation weighting matrix.
|
||||
"""
|
||||
if getattr(self,'_Wd',None) is None:
|
||||
eps = np.linalg.norm(utils.mkvc(self.data.dobs),2)*1e-5
|
||||
self._Wd = 1/(abs(self.data.dobs)*self.data.std+eps)
|
||||
return self._Wd
|
||||
@Wd.setter
|
||||
def Wd(self, value):
|
||||
self._Wd = value
|
||||
|
||||
@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 getBeta(self):
|
||||
return self.beta0
|
||||
|
||||
def estimateBeta0(self, u=None, ratio=0.1):
|
||||
"""estimateBeta0(u=None, ratio=0.1)
|
||||
|
||||
The initial beta is calculated by comparing the estimated
|
||||
eigenvalues of JtJ and WtW.
|
||||
|
||||
To estimate the eigenvector of **A**, we will use one iteration
|
||||
of the *Power Method*:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{x_1 = A x_0}
|
||||
|
||||
Given this (very course) approximation of the eigenvector,
|
||||
we can use the *Rayleigh quotient* to approximate the largest eigenvalue.
|
||||
|
||||
.. math::
|
||||
|
||||
\lambda_0 = \\frac{\mathbf{x^\\top A x}}{\mathbf{x^\\top x}}
|
||||
|
||||
We will approximate the largest eigenvalue for both JtJ and WtW, and
|
||||
use some ratio of the quotient to estimate beta0.
|
||||
|
||||
.. math::
|
||||
|
||||
\\beta_0 = \gamma \\frac{\mathbf{x^\\top J^\\top J x}}{\mathbf{x^\\top W^\\top W x}}
|
||||
|
||||
|
||||
:param numpy.array u: fields
|
||||
:param float ratio: desired ratio of the eigenvalues, default is 0.1
|
||||
:rtype: float
|
||||
:return: beta0
|
||||
"""
|
||||
if u is None:
|
||||
u = self.prob.field(self.m)
|
||||
|
||||
x0 = np.random.rand(*self.m.shape)
|
||||
t = x0.dot(self.dataObj2Deriv(self.m,x0,u=u))
|
||||
b = x0.dot(self.reg.modelObj2Deriv()*x0)
|
||||
return ratio*(t/b)
|
||||
|
||||
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
|
||||
|
||||
@utils.timeIt
|
||||
def evalFunction(self, m, return_g=True, return_H=True):
|
||||
"""evalFunction(m, return_g=True, return_H=True)
|
||||
|
||||
|
||||
"""
|
||||
|
||||
u = self.prob.field(m)
|
||||
|
||||
if self._iter is 0 and self._beta is None:
|
||||
self._beta = self.beta0 = self.estimateBeta0(u=u,ratio=self.beta0_ratio)
|
||||
|
||||
phi_d = self.dataObj(m, u)
|
||||
phi_m = self.reg.modelObj(m)
|
||||
|
||||
self.dpred = self.prob.dpred(m, u=u) # This is a cheap matrix vector calculation.
|
||||
self.phi_d = phi_d
|
||||
self.phi_m = phi_m
|
||||
|
||||
f = phi_d + self._beta * phi_m
|
||||
|
||||
out = (f,)
|
||||
if return_g:
|
||||
phi_dDeriv = self.dataObjDeriv(m, u=u)
|
||||
phi_mDeriv = self.reg.modelObjDeriv(m)
|
||||
|
||||
g = phi_dDeriv + self._beta * phi_mDeriv
|
||||
out += (g,)
|
||||
|
||||
if return_H:
|
||||
def H_fun(v):
|
||||
phi_d2Deriv = self.dataObj2Deriv(m, v, u=u)
|
||||
phi_m2Deriv = self.reg.modelObj2Deriv()*v
|
||||
|
||||
return phi_d2Deriv + self._beta * phi_m2Deriv
|
||||
|
||||
operator = sp.linalg.LinearOperator( (m.size, m.size), H_fun, dtype=m.dtype )
|
||||
out += (operator,)
|
||||
return out if len(out) > 1 else out[0]
|
||||
|
||||
@utils.timeIt
|
||||
def dataObj(self, m, u=None):
|
||||
"""dataObj(m, u=None)
|
||||
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array u: fields
|
||||
:rtype: float
|
||||
:return: data misfit
|
||||
|
||||
The data misfit using an l_2 norm is:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data} = {1\over 2}\left| \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs}) \\right|_2^2
|
||||
|
||||
Where P is a projection matrix that brings the field on the full domain to the data measurement locations;
|
||||
u is the field of interest; d_obs is the observed data; and W is the weighting matrix.
|
||||
"""
|
||||
# TODO: ensure that this is a data is vector and Wd is a matrix.
|
||||
R = self.Wd*self.prob.dataResidual(m, self.data, u=u)
|
||||
R = utils.mkvc(R)
|
||||
return 0.5*np.vdot(R, R)
|
||||
|
||||
@utils.timeIt
|
||||
def dataObjDeriv(self, m, u=None):
|
||||
"""dataObjDeriv(m, u=None)
|
||||
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array u: fields
|
||||
:rtype: numpy.array
|
||||
:return: data misfit derivative
|
||||
|
||||
The data misfit using an l_2 norm is:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data} = {1\over 2}\left| \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs}) \\right|_2^2
|
||||
|
||||
If the field, u, is provided, the calculation of the data is fast:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{d}_\\text{pred} = \mathbf{Pu(m)}
|
||||
|
||||
\mathbf{R} = \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs})
|
||||
|
||||
Where P is a projection matrix that brings the field on the full domain to the data measurement locations;
|
||||
u is the field of interest; d_obs is the observed data; and W is the weighting matrix.
|
||||
|
||||
The derivative of this, with respect to the model, is:
|
||||
|
||||
.. math::
|
||||
|
||||
\\frac{\partial \mu_\\text{data}}{\partial \mathbf{m}} = \mathbf{J}^\\top \mathbf{W \circ R}
|
||||
|
||||
"""
|
||||
if u is None:
|
||||
u = self.prob.field(m)
|
||||
|
||||
R = self.Wd*self.prob.dataResidual(m, self.data, u=u)
|
||||
|
||||
dmisfit = self.prob.Jt(m, self.Wd * R, u=u)
|
||||
|
||||
return dmisfit
|
||||
|
||||
@utils.timeIt
|
||||
def dataObj2Deriv(self, m, v, u=None):
|
||||
"""dataObj2Deriv(m, v, u=None)
|
||||
|
||||
:param numpy.array m: geophysical model
|
||||
:param numpy.array v: vector to multiply
|
||||
:param numpy.array u: fields
|
||||
:rtype: numpy.array
|
||||
:return: data misfit derivative
|
||||
|
||||
The data misfit using an l_2 norm is:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\\text{data} = {1\over 2}\left| \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs}) \\right|_2^2
|
||||
|
||||
If the field, u, is provided, the calculation of the data is fast:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{d}_\\text{pred} = \mathbf{Pu(m)}
|
||||
|
||||
\mathbf{R} = \mathbf{W} \circ (\mathbf{d}_\\text{pred} - \mathbf{d}_\\text{obs})
|
||||
|
||||
Where P is a projection matrix that brings the field on the full domain to the data measurement locations;
|
||||
u is the field of interest; d_obs is the observed data; and W is the weighting matrix.
|
||||
|
||||
The derivative of this, with respect to the model, is:
|
||||
|
||||
.. math::
|
||||
|
||||
\\frac{\partial \mu_\\text{data}}{\partial \mathbf{m}} = \mathbf{J}^\\top \mathbf{W \circ R}
|
||||
|
||||
\\frac{\partial^2 \mu_\\text{data}}{\partial^2 \mathbf{m}} = \mathbf{J}^\\top \mathbf{W \circ W J}
|
||||
|
||||
"""
|
||||
if u is None:
|
||||
u = self.prob.field(m)
|
||||
|
||||
R = self.Wd*self.prob.dataResidual(m, self.data, u=u)
|
||||
|
||||
# TODO: abstract to different norms a little cleaner.
|
||||
# \/ it goes here. in l2 it is the identity.
|
||||
dmisfit = self.prob.Jt_approx(m, self.Wd * self.Wd * self.prob.J_approx(m, v, u=u), u=u)
|
||||
|
||||
return dmisfit
|
||||
|
||||
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)
|
||||
@@ -1,4 +0,0 @@
|
||||
from Optimize import *
|
||||
from Inversion import *
|
||||
from Regularization import Regularization
|
||||
import BetaSchedule
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 SimPEG Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import os
|
||||
print 'Compiling TriSolve.'
|
||||
os.system('f2py -c utils/TriSolve.f -m TriSolve')
|
||||
os.system('f2py -c Utils/TriSolve.f -m TriSolve')
|
||||
print 'TriSolve Compiled! yay.'
|
||||
print 'Moving TriSolve into Utils.'
|
||||
os.system('mv TriSolve.so utils/TriSolve.so')
|
||||
os.system('mv TriSolve.so Utils/TriSolve.so')
|
||||
print 'Thats it. Well Done Computer.'
|
||||
|
||||
@@ -1,825 +0,0 @@
|
||||
"""
|
||||
A TestRunner for use with the Python unit testing framework. It
|
||||
generates a HTML report to show the result at a glance.
|
||||
|
||||
The simplest way to use this is to invoke its main method. E.g.
|
||||
|
||||
import unittest
|
||||
import HTMLTestRunner
|
||||
|
||||
... define your tests ...
|
||||
|
||||
if __name__ == '__main__':
|
||||
HTMLTestRunner.main()
|
||||
|
||||
|
||||
For more customization options, instantiates a HTMLTestRunner object.
|
||||
HTMLTestRunner is a counterpart to unittest's TextTestRunner. E.g.
|
||||
|
||||
# output to a file
|
||||
fp = file('my_report.html', 'wb')
|
||||
runner = HTMLTestRunner.HTMLTestRunner(
|
||||
stream=fp,
|
||||
title='My unit test',
|
||||
description='This demonstrates the report output by HTMLTestRunner.'
|
||||
)
|
||||
|
||||
# Use an external stylesheet.
|
||||
# See the Template_mixin class for more customizable options
|
||||
runner.STYLESHEET_TMPL = '<link rel="stylesheet" href="my_stylesheet.css" type="text/css">'
|
||||
|
||||
# run the test
|
||||
runner.run(my_test_suite)
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Copyright (c) 2004-2007, Wai Yip Tung
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name Wai Yip Tung nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
# URL: http://tungwaiyip.info/software/HTMLTestRunner.html
|
||||
|
||||
__author__ = "Wai Yip Tung"
|
||||
__version__ = "0.8.2"
|
||||
|
||||
|
||||
"""
|
||||
Change History
|
||||
|
||||
Version 0.8.2
|
||||
* Show output inline instead of popup window (Viorel Lupu).
|
||||
|
||||
Version in 0.8.1
|
||||
* Validated XHTML (Wolfgang Borgert).
|
||||
* Added description of test classes and test cases.
|
||||
|
||||
Version in 0.8.0
|
||||
* Define Template_mixin class for customization.
|
||||
* Workaround a IE 6 bug that it does not treat <script> block as CDATA.
|
||||
|
||||
Version in 0.7.1
|
||||
* Back port to Python 2.3 (Frank Horowitz).
|
||||
* Fix missing scroll bars in detail log (Podi).
|
||||
"""
|
||||
|
||||
# TODO: color stderr
|
||||
# TODO: simplify javascript using ,ore than 1 class in the class attribute?
|
||||
|
||||
import datetime
|
||||
import StringIO
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
from xml.sax import saxutils
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# The redirectors below are used to capture output during testing. Output
|
||||
# sent to sys.stdout and sys.stderr are automatically captured. However
|
||||
# in some cases sys.stdout is already cached before HTMLTestRunner is
|
||||
# invoked (e.g. calling logging.basicConfig). In order to capture those
|
||||
# output, use the redirectors for the cached stream.
|
||||
#
|
||||
# e.g.
|
||||
# >>> logging.basicConfig(stream=HTMLTestRunner.stdout_redirector)
|
||||
# >>>
|
||||
|
||||
class OutputRedirector(object):
|
||||
""" Wrapper to redirect stdout or stderr """
|
||||
def __init__(self, fp):
|
||||
self.fp = fp
|
||||
|
||||
def write(self, s):
|
||||
self.fp.write(s)
|
||||
|
||||
def writelines(self, lines):
|
||||
self.fp.writelines(lines)
|
||||
|
||||
def flush(self):
|
||||
self.fp.flush()
|
||||
|
||||
stdout_redirector = OutputRedirector(sys.stdout)
|
||||
stderr_redirector = OutputRedirector(sys.stderr)
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Template
|
||||
|
||||
class Template_mixin(object):
|
||||
"""
|
||||
Define a HTML template for report customerization and generation.
|
||||
|
||||
Overall structure of an HTML report
|
||||
|
||||
HTML
|
||||
+------------------------+
|
||||
|<html> |
|
||||
| <head> |
|
||||
| |
|
||||
| STYLESHEET |
|
||||
| +----------------+ |
|
||||
| | | |
|
||||
| +----------------+ |
|
||||
| |
|
||||
| </head> |
|
||||
| |
|
||||
| <body> |
|
||||
| |
|
||||
| HEADING |
|
||||
| +----------------+ |
|
||||
| | | |
|
||||
| +----------------+ |
|
||||
| |
|
||||
| REPORT |
|
||||
| +----------------+ |
|
||||
| | | |
|
||||
| +----------------+ |
|
||||
| |
|
||||
| ENDING |
|
||||
| +----------------+ |
|
||||
| | | |
|
||||
| +----------------+ |
|
||||
| |
|
||||
| </body> |
|
||||
|</html> |
|
||||
+------------------------+
|
||||
"""
|
||||
|
||||
STATUS = {
|
||||
0: 'pass',
|
||||
1: 'fail',
|
||||
2: 'error',
|
||||
}
|
||||
|
||||
DEFAULT_TITLE = 'Unit Test Report'
|
||||
DEFAULT_DESCRIPTION = ''
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# HTML Template
|
||||
|
||||
HTML_TMPL = r"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>%(title)s</title>
|
||||
<meta name="generator" content="%(generator)s"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
%(stylesheet)s
|
||||
</head>
|
||||
<body>
|
||||
<script language="javascript" type="text/javascript"><!--
|
||||
output_list = Array();
|
||||
|
||||
/* level - 0:Summary; 1:Failed; 2:All */
|
||||
function showCase(level) {
|
||||
trs = document.getElementsByTagName("tr");
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
tr = trs[i];
|
||||
id = tr.id;
|
||||
if (id.substr(0,2) == 'ft') {
|
||||
if (level < 1) {
|
||||
tr.className = 'hiddenRow';
|
||||
}
|
||||
else {
|
||||
tr.className = '';
|
||||
}
|
||||
}
|
||||
if (id.substr(0,2) == 'pt') {
|
||||
if (level > 1) {
|
||||
tr.className = '';
|
||||
}
|
||||
else {
|
||||
tr.className = 'hiddenRow';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showClassDetail(cid, count) {
|
||||
var id_list = Array(count);
|
||||
var toHide = 1;
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid0 = 't' + cid.substr(1) + '.' + (i+1);
|
||||
tid = 'f' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
if (!tr) {
|
||||
tid = 'p' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
}
|
||||
id_list[i] = tid;
|
||||
if (tr.className) {
|
||||
toHide = 0;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid = id_list[i];
|
||||
if (toHide) {
|
||||
var divTid = document.getElementById('div_'+tid);
|
||||
if(divTid !== null){divTid.style.display = 'none';}
|
||||
document.getElementById(tid).className = 'hiddenRow';
|
||||
}
|
||||
else {
|
||||
document.getElementById(tid).className = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showTestDetail(div_id){
|
||||
var details_div = document.getElementById(div_id)
|
||||
var displayState = details_div.style.display
|
||||
// alert(displayState)
|
||||
if (displayState != 'block' ) {
|
||||
displayState = 'block'
|
||||
details_div.style.display = 'block'
|
||||
}
|
||||
else {
|
||||
details_div.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function html_escape(s) {
|
||||
s = s.replace(/&/g,'&');
|
||||
s = s.replace(/</g,'<');
|
||||
s = s.replace(/>/g,'>');
|
||||
return s;
|
||||
}
|
||||
|
||||
/* obsoleted by detail in <div>
|
||||
function showOutput(id, name) {
|
||||
var w = window.open("", //url
|
||||
name,
|
||||
"resizable,scrollbars,status,width=800,height=450");
|
||||
d = w.document;
|
||||
d.write("<pre>");
|
||||
d.write(html_escape(output_list[id]));
|
||||
d.write("\n");
|
||||
d.write("<a href='javascript:window.close()'>close</a>\n");
|
||||
d.write("</pre>\n");
|
||||
d.close();
|
||||
}
|
||||
*/
|
||||
--></script>
|
||||
|
||||
%(heading)s
|
||||
%(report)s
|
||||
%(ending)s
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
# variables: (title, generator, stylesheet, heading, report, ending)
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Stylesheet
|
||||
#
|
||||
# alternatively use a <link> for external style sheet, e.g.
|
||||
# <link rel="stylesheet" href="$url" type="text/css">
|
||||
|
||||
STYLESHEET_TMPL = """
|
||||
<style type="text/css" media="screen">
|
||||
body { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }
|
||||
table { font-size: 100%; }
|
||||
pre { }
|
||||
|
||||
/* -- heading ---------------------------------------------------------------------- */
|
||||
h1 {
|
||||
font-size: 16pt;
|
||||
color: gray;
|
||||
}
|
||||
.heading {
|
||||
margin-top: 0ex;
|
||||
margin-bottom: 1ex;
|
||||
}
|
||||
|
||||
.heading .attribute {
|
||||
margin-top: 1ex;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.heading .description {
|
||||
margin-top: 4ex;
|
||||
margin-bottom: 6ex;
|
||||
}
|
||||
|
||||
/* -- css div popup ------------------------------------------------------------------------ */
|
||||
a.popup_link {
|
||||
}
|
||||
|
||||
a.popup_link:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.popup_window {
|
||||
display: none;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
/*border: solid #627173 1px; */
|
||||
padding: 10px;
|
||||
background-color: #E6E6D6;
|
||||
font-family: "Lucida Console", "Courier New", Courier, monospace;
|
||||
text-align: left;
|
||||
font-size: 8pt;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
}
|
||||
/* -- report ------------------------------------------------------------------------ */
|
||||
#show_detail_line {
|
||||
margin-top: 3ex;
|
||||
margin-bottom: 1ex;
|
||||
}
|
||||
#result_table {
|
||||
width: 80%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #777;
|
||||
}
|
||||
#header_row {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
background-color: #777;
|
||||
}
|
||||
#result_table td {
|
||||
border: 1px solid #777;
|
||||
padding: 2px;
|
||||
}
|
||||
#total_row { font-weight: bold; }
|
||||
.passClass { background-color: #6c6; }
|
||||
.failClass { background-color: #c60; }
|
||||
.errorClass { background-color: #c00; }
|
||||
.passCase { color: #6c6; }
|
||||
.failCase { color: #c60; font-weight: bold; }
|
||||
.errorCase { color: #c00; font-weight: bold; }
|
||||
.hiddenRow { display: none; }
|
||||
.testcase { margin-left: 2em; }
|
||||
|
||||
|
||||
/* -- ending ---------------------------------------------------------------------- */
|
||||
#ending {
|
||||
}
|
||||
|
||||
</style>
|
||||
"""
|
||||
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Heading
|
||||
#
|
||||
|
||||
HEADING_TMPL = """<div class='heading'>
|
||||
<h1>%(title)s</h1>
|
||||
%(parameters)s
|
||||
<p class='description'>%(description)s</p>
|
||||
</div>
|
||||
|
||||
""" # variables: (title, parameters, description)
|
||||
|
||||
HEADING_ATTRIBUTE_TMPL = """<p class='attribute'><strong>%(name)s:</strong> %(value)s</p>
|
||||
""" # variables: (name, value)
|
||||
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Report
|
||||
#
|
||||
|
||||
REPORT_TMPL = """
|
||||
<p id='show_detail_line'>Show
|
||||
<a href='javascript:showCase(0)'>Summary</a>
|
||||
<a href='javascript:showCase(1)'>Failed</a>
|
||||
<a href='javascript:showCase(2)'>All</a>
|
||||
</p>
|
||||
<table id='result_table'>
|
||||
<colgroup>
|
||||
<col align='left' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
</colgroup>
|
||||
<tr id='header_row'>
|
||||
<td>Test Group/Test case</td>
|
||||
<td>Count</td>
|
||||
<td>Pass</td>
|
||||
<td>Fail</td>
|
||||
<td>Error</td>
|
||||
<td>View</td>
|
||||
</tr>
|
||||
%(test_list)s
|
||||
<tr id='total_row'>
|
||||
<td>Total</td>
|
||||
<td>%(count)s</td>
|
||||
<td>%(Pass)s</td>
|
||||
<td>%(fail)s</td>
|
||||
<td>%(error)s</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
""" # variables: (test_list, count, Pass, fail, error)
|
||||
|
||||
REPORT_CLASS_TMPL = r"""
|
||||
<tr class='%(style)s'>
|
||||
<td>%(desc)s</td>
|
||||
<td>%(count)s</td>
|
||||
<td>%(Pass)s</td>
|
||||
<td>%(fail)s</td>
|
||||
<td>%(error)s</td>
|
||||
<td><a href="javascript:showClassDetail('%(cid)s',%(count)s)">Detail</a></td>
|
||||
</tr>
|
||||
""" # variables: (style, desc, count, Pass, fail, error, cid)
|
||||
|
||||
|
||||
REPORT_TEST_WITH_OUTPUT_TMPL = r"""
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link" onfocus='this.blur();' href="javascript:showTestDetail('div_%(tid)s')" >
|
||||
%(status)s</a>
|
||||
|
||||
<div id='div_%(tid)s' class="popup_window">
|
||||
<div style='text-align: right; color:red;cursor:pointer'>
|
||||
<a onfocus='this.blur();' onclick="document.getElementById('div_%(tid)s').style.display = 'none' " >
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
%(script)s
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
|
||||
|
||||
REPORT_TEST_NO_OUTPUT_TMPL = r"""
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
|
||||
<td colspan='5' align='center'>%(status)s</td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
|
||||
|
||||
REPORT_TEST_OUTPUT_TMPL = r"""
|
||||
%(id)s: %(output)s
|
||||
""" # variables: (id, output)
|
||||
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# ENDING
|
||||
#
|
||||
|
||||
ENDING_TMPL = """<div id='ending'> </div>"""
|
||||
|
||||
# -------------------- The end of the Template class -------------------
|
||||
|
||||
|
||||
TestResult = unittest.TestResult
|
||||
|
||||
class _TestResult(TestResult):
|
||||
# note: _TestResult is a pure representation of results.
|
||||
# It lacks the output and reporting ability compares to unittest._TextTestResult.
|
||||
|
||||
def __init__(self, verbosity=1):
|
||||
TestResult.__init__(self)
|
||||
self.stdout0 = None
|
||||
self.stderr0 = None
|
||||
self.success_count = 0
|
||||
self.failure_count = 0
|
||||
self.error_count = 0
|
||||
self.verbosity = verbosity
|
||||
|
||||
# result is a list of result in 4 tuple
|
||||
# (
|
||||
# result code (0: success; 1: fail; 2: error),
|
||||
# TestCase object,
|
||||
# Test output (byte string),
|
||||
# stack trace,
|
||||
# )
|
||||
self.result = []
|
||||
|
||||
|
||||
def startTest(self, test):
|
||||
TestResult.startTest(self, test)
|
||||
# just one buffer for both stdout and stderr
|
||||
self.outputBuffer = StringIO.StringIO()
|
||||
stdout_redirector.fp = self.outputBuffer
|
||||
stderr_redirector.fp = self.outputBuffer
|
||||
self.stdout0 = sys.stdout
|
||||
self.stderr0 = sys.stderr
|
||||
sys.stdout = stdout_redirector
|
||||
sys.stderr = stderr_redirector
|
||||
|
||||
|
||||
def complete_output(self):
|
||||
"""
|
||||
Disconnect output redirection and return buffer.
|
||||
Safe to call multiple times.
|
||||
"""
|
||||
if self.stdout0:
|
||||
sys.stdout = self.stdout0
|
||||
sys.stderr = self.stderr0
|
||||
self.stdout0 = None
|
||||
self.stderr0 = None
|
||||
return self.outputBuffer.getvalue()
|
||||
|
||||
|
||||
def stopTest(self, test):
|
||||
# Usually one of addSuccess, addError or addFailure would have been called.
|
||||
# But there are some path in unittest that would bypass this.
|
||||
# We must disconnect stdout in stopTest(), which is guaranteed to be called.
|
||||
self.complete_output()
|
||||
|
||||
|
||||
def addSuccess(self, test):
|
||||
self.success_count += 1
|
||||
TestResult.addSuccess(self, test)
|
||||
output = self.complete_output()
|
||||
self.result.append((0, test, output, ''))
|
||||
if self.verbosity > 1:
|
||||
sys.stderr.write('ok ')
|
||||
sys.stderr.write(str(test))
|
||||
sys.stderr.write('\n')
|
||||
else:
|
||||
sys.stderr.write('.')
|
||||
|
||||
def addError(self, test, err):
|
||||
self.error_count += 1
|
||||
TestResult.addError(self, test, err)
|
||||
_, _exc_str = self.errors[-1]
|
||||
output = self.complete_output()
|
||||
self.result.append((2, test, output, _exc_str))
|
||||
if self.verbosity > 1:
|
||||
sys.stderr.write('E ')
|
||||
sys.stderr.write(str(test))
|
||||
sys.stderr.write('\n')
|
||||
else:
|
||||
sys.stderr.write('E')
|
||||
|
||||
def addFailure(self, test, err):
|
||||
self.failure_count += 1
|
||||
TestResult.addFailure(self, test, err)
|
||||
_, _exc_str = self.failures[-1]
|
||||
output = self.complete_output()
|
||||
self.result.append((1, test, output, _exc_str))
|
||||
if self.verbosity > 1:
|
||||
sys.stderr.write('F ')
|
||||
sys.stderr.write(str(test))
|
||||
sys.stderr.write('\n')
|
||||
else:
|
||||
sys.stderr.write('F')
|
||||
|
||||
|
||||
class HTMLTestRunner(Template_mixin):
|
||||
"""
|
||||
"""
|
||||
def __init__(self, stream=sys.stdout, verbosity=1, title=None, description=None):
|
||||
self.stream = stream
|
||||
self.verbosity = verbosity
|
||||
if title is None:
|
||||
self.title = self.DEFAULT_TITLE
|
||||
else:
|
||||
self.title = title
|
||||
if description is None:
|
||||
self.description = self.DEFAULT_DESCRIPTION
|
||||
else:
|
||||
self.description = description
|
||||
|
||||
self.startTime = datetime.datetime.now()
|
||||
|
||||
|
||||
def run(self, test):
|
||||
"Run the given test case or test suite."
|
||||
result = _TestResult(self.verbosity)
|
||||
test(result)
|
||||
self.stopTime = datetime.datetime.now()
|
||||
self.generateReport(test, result)
|
||||
print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)
|
||||
return result
|
||||
|
||||
|
||||
def sortResult(self, result_list):
|
||||
# unittest does not seems to run in any particular order.
|
||||
# Here at least we want to group them together by class.
|
||||
rmap = {}
|
||||
classes = []
|
||||
for n,t,o,e in result_list:
|
||||
cls = t.__class__
|
||||
if not rmap.has_key(cls):
|
||||
rmap[cls] = []
|
||||
classes.append(cls)
|
||||
rmap[cls].append((n,t,o,e))
|
||||
r = [(cls, rmap[cls]) for cls in classes]
|
||||
return r
|
||||
|
||||
|
||||
def getReportAttributes(self, result):
|
||||
"""
|
||||
Return report attributes as a list of (name, value).
|
||||
Override this to add custom attributes.
|
||||
"""
|
||||
startTime = str(self.startTime)[:19]
|
||||
duration = str(self.stopTime - self.startTime)
|
||||
status = []
|
||||
if result.success_count: status.append('Pass %s' % result.success_count)
|
||||
if result.failure_count: status.append('Failure %s' % result.failure_count)
|
||||
if result.error_count: status.append('Error %s' % result.error_count )
|
||||
if status:
|
||||
status = ' '.join(status)
|
||||
else:
|
||||
status = 'none'
|
||||
return [
|
||||
('Start Time', startTime),
|
||||
('Duration', duration),
|
||||
('Status', status),
|
||||
]
|
||||
|
||||
|
||||
def generateReport(self, test, result):
|
||||
report_attrs = self.getReportAttributes(result)
|
||||
generator = 'HTMLTestRunner %s' % __version__
|
||||
stylesheet = self._generate_stylesheet()
|
||||
heading = self._generate_heading(report_attrs)
|
||||
report = self._generate_report(result)
|
||||
ending = self._generate_ending()
|
||||
output = self.HTML_TMPL % dict(
|
||||
title = saxutils.escape(self.title),
|
||||
generator = generator,
|
||||
stylesheet = stylesheet,
|
||||
heading = heading,
|
||||
report = report,
|
||||
ending = ending,
|
||||
)
|
||||
self.stream.write(output.encode('utf8'))
|
||||
|
||||
|
||||
def _generate_stylesheet(self):
|
||||
return self.STYLESHEET_TMPL
|
||||
|
||||
|
||||
def _generate_heading(self, report_attrs):
|
||||
a_lines = []
|
||||
for name, value in report_attrs:
|
||||
line = self.HEADING_ATTRIBUTE_TMPL % dict(
|
||||
name = saxutils.escape(name),
|
||||
value = saxutils.escape(value),
|
||||
)
|
||||
a_lines.append(line)
|
||||
heading = self.HEADING_TMPL % dict(
|
||||
title = saxutils.escape(self.title),
|
||||
parameters = ''.join(a_lines),
|
||||
description = saxutils.escape(self.description),
|
||||
)
|
||||
return heading
|
||||
|
||||
|
||||
def _generate_report(self, result):
|
||||
rows = []
|
||||
sortedResult = self.sortResult(result.result)
|
||||
for cid, (cls, cls_results) in enumerate(sortedResult):
|
||||
# subtotal for a class
|
||||
np = nf = ne = 0
|
||||
for n,t,o,e in cls_results:
|
||||
if n == 0: np += 1
|
||||
elif n == 1: nf += 1
|
||||
else: ne += 1
|
||||
|
||||
# format class description
|
||||
if cls.__module__ == "__main__":
|
||||
name = cls.__name__
|
||||
else:
|
||||
name = "%s.%s" % (cls.__module__, cls.__name__)
|
||||
doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""
|
||||
desc = doc and '%s: %s' % (name, doc) or name
|
||||
|
||||
row = self.REPORT_CLASS_TMPL % dict(
|
||||
style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass',
|
||||
desc = desc,
|
||||
count = np+nf+ne,
|
||||
Pass = np,
|
||||
fail = nf,
|
||||
error = ne,
|
||||
cid = 'c%s' % (cid+1),
|
||||
)
|
||||
rows.append(row)
|
||||
|
||||
for tid, (n,t,o,e) in enumerate(cls_results):
|
||||
self._generate_report_test(rows, cid, tid, n, t, o, e)
|
||||
|
||||
report = self.REPORT_TMPL % dict(
|
||||
test_list = ''.join(rows),
|
||||
count = str(result.success_count+result.failure_count+result.error_count),
|
||||
Pass = str(result.success_count),
|
||||
fail = str(result.failure_count),
|
||||
error = str(result.error_count),
|
||||
)
|
||||
return report
|
||||
|
||||
|
||||
def _generate_report_test(self, rows, cid, tid, n, t, o, e):
|
||||
# e.g. 'pt1.1', 'ft1.1', etc
|
||||
has_output = bool(o or e)
|
||||
tid = (n == 0 and 'p' or 'f') + 't%s.%s' % (cid+1,tid+1)
|
||||
name = t.id().split('.')[-1]
|
||||
doc = t.shortDescription() or ""
|
||||
desc = doc and ('%s: %s' % (name, doc)) or name
|
||||
tmpl = has_output and self.REPORT_TEST_WITH_OUTPUT_TMPL or self.REPORT_TEST_NO_OUTPUT_TMPL
|
||||
|
||||
# o and e should be byte string because they are collected from stdout and stderr?
|
||||
if isinstance(o,str):
|
||||
# TODO: some problem with 'string_escape': it escape \n and mess up formating
|
||||
# uo = unicode(o.encode('string_escape'))
|
||||
uo = o.decode('latin-1')
|
||||
else:
|
||||
uo = o
|
||||
if isinstance(e,str):
|
||||
# TODO: some problem with 'string_escape': it escape \n and mess up formating
|
||||
# ue = unicode(e.encode('string_escape'))
|
||||
ue = e.decode('latin-1')
|
||||
else:
|
||||
ue = e
|
||||
|
||||
script = self.REPORT_TEST_OUTPUT_TMPL % dict(
|
||||
id = tid,
|
||||
output = saxutils.escape(uo+ue),
|
||||
)
|
||||
|
||||
row = tmpl % dict(
|
||||
tid = tid,
|
||||
Class = (n == 0 and 'hiddenRow' or 'none'),
|
||||
style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'none'),
|
||||
desc = desc,
|
||||
script = script,
|
||||
status = self.STATUS[n],
|
||||
)
|
||||
rows.append(row)
|
||||
if not has_output:
|
||||
return
|
||||
|
||||
def _generate_ending(self):
|
||||
return self.ENDING_TMPL
|
||||
|
||||
|
||||
##############################################################################
|
||||
# Facilities for running tests from the command line
|
||||
##############################################################################
|
||||
|
||||
# Note: Reuse unittest.TestProgram to launch test. In the future we may
|
||||
# build our own launcher to support more specific command line
|
||||
# parameters like test title, CSS, etc.
|
||||
class TestProgram(unittest.TestProgram):
|
||||
"""
|
||||
A variation of the unittest.TestProgram. Please refer to the base
|
||||
class for command line parameters.
|
||||
"""
|
||||
def runTests(self):
|
||||
# Pick HTMLTestRunner as the default test runner.
|
||||
# base class's testRunner parameter is not useful because it means
|
||||
# we have to instantiate HTMLTestRunner before we know self.verbosity.
|
||||
if self.testRunner is None:
|
||||
self.testRunner = HTMLTestRunner(verbosity=self.verbosity)
|
||||
unittest.TestProgram.runTests(self)
|
||||
|
||||
main = TestProgram
|
||||
|
||||
##############################################################################
|
||||
# Executing this module from the command line
|
||||
##############################################################################
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(module=None)
|
||||
@@ -1,2 +0,0 @@
|
||||
import TestUtils
|
||||
from TestUtils import checkDerivative, Rosenbrock, OrderTest, getQuadratic
|
||||
@@ -1,57 +0,0 @@
|
||||
import os
|
||||
import glob
|
||||
import unittest
|
||||
import HTMLTestRunner
|
||||
|
||||
# This code will run all tests in directory named test_*.py
|
||||
def main(html=False):
|
||||
TITLE = 'Test Results'
|
||||
test_file_strings = glob.glob('test_*.py')
|
||||
module_strings = [str[0:len(str)-3] for str in test_file_strings]
|
||||
suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str
|
||||
in module_strings]
|
||||
testSuite = unittest.TestSuite(suites)
|
||||
|
||||
if not html:
|
||||
unittest.TextTestRunner(verbosity=2).run(testSuite)
|
||||
return
|
||||
|
||||
|
||||
outfile = open("report.html", "w")
|
||||
runner = HTMLTestRunner.HTMLTestRunner(
|
||||
stream=outfile,
|
||||
title=TITLE,
|
||||
description='SimPEG Test Report was automatically generated.',
|
||||
verbosity=2
|
||||
)
|
||||
|
||||
runner.run(testSuite)
|
||||
outfile.close()
|
||||
|
||||
reader = open("report.html", "r")
|
||||
writer = open("../../docs/api_TestResults.rst", "w")
|
||||
|
||||
writer.write('.. _api_TestResults:\n\nTest Results\n============\n\n.. raw:: html\n\n')
|
||||
|
||||
go = False
|
||||
for line in reader:
|
||||
skip = False
|
||||
if line == '<style type="text/css" media="screen">\n':
|
||||
go = True
|
||||
elif line == "<div id='ending'> </div>\n":
|
||||
go = False
|
||||
elif line == '</head>\n':
|
||||
skip = True
|
||||
elif line == '<h1>'+TITLE+'</h1>\n':
|
||||
skip = True
|
||||
elif line == '<body>\n':
|
||||
skip = True
|
||||
if go and not skip:
|
||||
writer.write(' '+line)
|
||||
|
||||
writer.close()
|
||||
reader.close()
|
||||
os.remove("report.html")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(True)
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
python -m unittest discover
|
||||
@@ -1,85 +0,0 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG.mesh import TensorMesh
|
||||
from SimPEG.utils import ModelBuilder, sdiag
|
||||
from SimPEG.forward import Problem
|
||||
from SimPEG.examples.DC import *
|
||||
from TestUtils import checkDerivative
|
||||
from scipy.sparse.linalg import dsolve
|
||||
from SimPEG import inverse
|
||||
|
||||
|
||||
class DCProblemTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
# Create the mesh
|
||||
h1 = np.ones(20)
|
||||
h2 = np.ones(20)
|
||||
mesh = TensorMesh([h1,h2])
|
||||
|
||||
# Create some parameters for the model
|
||||
sig1 = 1
|
||||
sig2 = 0.01
|
||||
|
||||
# Create a synthetic model from a block in a half-space
|
||||
p0 = [2, 2]
|
||||
p1 = [5, 5]
|
||||
condVals = [sig1, sig2]
|
||||
mSynth = ModelBuilder.defineBlockConductivity(p0,p1,mesh.gridCC,condVals)
|
||||
|
||||
# Set up the projection
|
||||
nelec = 10
|
||||
spacelec = 2
|
||||
surfloc = 0.5
|
||||
elecini = 0.5
|
||||
elecend = 0.5+spacelec*(nelec-1)
|
||||
elecLocR = np.linspace(elecini, elecend, nelec)
|
||||
rxmidLoc = (elecLocR[0:nelec-1]+elecLocR[1:nelec])*0.5
|
||||
q, Q, rxmidloc = genTxRxmat(nelec, spacelec, surfloc, elecini, mesh)
|
||||
P = Q.T
|
||||
|
||||
# Create some data
|
||||
|
||||
problem = DCProblem(mesh)
|
||||
problem.P = P
|
||||
problem.RHS = q
|
||||
data = problem.createSyntheticData(mSynth, std=0.05)
|
||||
|
||||
# Now set up the problem to do some minimization
|
||||
opt = inverse.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6)
|
||||
reg = inverse.Regularization(mesh)
|
||||
inv = inverse.Inversion(problem, reg, opt, data, beta0=1e4)
|
||||
|
||||
self.inv = inv
|
||||
self.reg = reg
|
||||
self.p = problem
|
||||
self.mesh = mesh
|
||||
self.m0 = mSynth
|
||||
self.data = data
|
||||
|
||||
def test_misfit(self):
|
||||
derChk = lambda m: [self.p.dpred(m), lambda mx: self.p.J(self.m0, mx)]
|
||||
passed = checkDerivative(derChk, self.m0, plotIt=False)
|
||||
self.assertTrue(passed)
|
||||
|
||||
def test_adjoint(self):
|
||||
# Adjoint Test
|
||||
u = np.random.rand(self.mesh.nC*self.p.RHS.shape[1])
|
||||
v = np.random.rand(self.mesh.nC)
|
||||
w = np.random.rand(self.data.dobs.shape[0])
|
||||
wtJv = w.dot(self.p.J(self.m0, v, u=u))
|
||||
vtJtw = v.dot(self.p.Jt(self.m0, w, u=u))
|
||||
passed = (wtJv - vtJtw) < 1e-10
|
||||
self.assertTrue(passed)
|
||||
|
||||
def test_dataObj(self):
|
||||
derChk = lambda m: [self.inv.dataObj(m), self.inv.dataObjDeriv(m)]
|
||||
checkDerivative(derChk, self.m0, plotIt=False)
|
||||
|
||||
def test_modelObj(self):
|
||||
derChk = lambda m: [self.reg.modelObj(m), self.reg.modelObjDeriv(m)]
|
||||
checkDerivative(derChk, self.m0, plotIt=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,34 +0,0 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG import mesh, forward, inverse
|
||||
from TestUtils import checkDerivative
|
||||
from scipy.sparse.linalg import dsolve
|
||||
|
||||
|
||||
class ProblemTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
a = np.array([1, 1, 1])
|
||||
b = np.array([1, 2])
|
||||
c = np.array([1, 4])
|
||||
self.mesh2 = mesh.TensorMesh([a, b], np.array([3, 5]))
|
||||
self.p2 = forward.Problem(self.mesh2)
|
||||
self.reg = inverse.Regularization(self.mesh2)
|
||||
|
||||
def test_modelTransform(self):
|
||||
print 'SimPEG.forward.Problem: Testing Model Transform'
|
||||
m = np.random.rand(self.mesh2.nC)
|
||||
passed = checkDerivative(lambda m : [self.p2.modelTransform(m), self.p2.modelTransformDeriv(m)], m, plotIt=False)
|
||||
self.assertTrue(passed)
|
||||
|
||||
def test_regularization(self):
|
||||
derChk = lambda m: [self.reg.modelObj(m), self.reg.modelObjDeriv(m)]
|
||||
mSynth = np.random.randn(self.mesh2.nC)
|
||||
checkDerivative(derChk, mSynth, plotIt=False)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -3,7 +3,7 @@ try:
|
||||
import vtk, vtk.util.numpy_support as npsup, pdb
|
||||
except Exception, e:
|
||||
print 'VTK import error. Please ensure you have VTK installed to use this visualization package.'
|
||||
from SimPEG.utils import mkvc
|
||||
from SimPEG.Utils import mkvc
|
||||
|
||||
|
||||
class vtkTools(object):
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
Base Mesh
|
||||
*********
|
||||
|
||||
.. automodule:: SimPEG.mesh.BaseMesh
|
||||
.. automodule:: SimPEG.Mesh.BaseMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -3,6 +3,6 @@
|
||||
Cylindrical 1D Mesh
|
||||
*******************
|
||||
|
||||
.. automodule:: SimPEG.mesh.Cyl1DMesh
|
||||
.. automodule:: SimPEG.Mesh.Cyl1DMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
:undoc-members:
|
||||
@@ -3,6 +3,6 @@
|
||||
Differential Operators
|
||||
**********************
|
||||
|
||||
.. automodule:: SimPEG.mesh.DiffOperators
|
||||
.. automodule:: SimPEG.Mesh.DiffOperators
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -1,32 +1,30 @@
|
||||
.. _api_Problem:
|
||||
.. _api_Forward:
|
||||
|
||||
|
||||
Model
|
||||
*****
|
||||
|
||||
.. automodule:: SimPEG.Model
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
Data
|
||||
****
|
||||
|
||||
.. automodule:: SimPEG.Data
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
Problem
|
||||
*******
|
||||
|
||||
.. automodule:: SimPEG.forward.Problem
|
||||
.. automodule:: SimPEG.Problem
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
DCProblem
|
||||
*********
|
||||
|
||||
.. automodule:: SimPEG.examples.DC
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
|
||||
Linear Problem
|
||||
**************
|
||||
|
||||
.. automodule:: SimPEG.examples.Linear
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
@@ -3,6 +3,6 @@
|
||||
Inner Products
|
||||
**************
|
||||
|
||||
.. automodule:: SimPEG.mesh.InnerProducts
|
||||
.. automodule:: SimPEG.Mesh.InnerProducts
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -1,35 +1,38 @@
|
||||
.. _api_Inverse:
|
||||
|
||||
Optimize
|
||||
********
|
||||
|
||||
.. automodule:: SimPEG.inverse.Optimize
|
||||
:show-inheritance:
|
||||
:private-members:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Inversion
|
||||
*********
|
||||
|
||||
.. automodule:: SimPEG.inverse.Inversion
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Beta Schedule
|
||||
*************
|
||||
|
||||
.. automodule:: SimPEG.inverse.BetaSchedule
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Regularization
|
||||
**************
|
||||
|
||||
.. automodule:: SimPEG.inverse.Regularization
|
||||
.. automodule:: SimPEG.Regularization
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Objective Function
|
||||
******************
|
||||
|
||||
.. automodule:: SimPEG.ObjFunction
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Optimize
|
||||
********
|
||||
|
||||
.. automodule:: SimPEG.Optimization
|
||||
:show-inheritance:
|
||||
:private-members:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Inversion
|
||||
*********
|
||||
|
||||
.. automodule:: SimPEG.Inversion
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
@@ -3,16 +3,8 @@
|
||||
Logically Orthogonal Mesh
|
||||
*************************
|
||||
|
||||
.. automodule:: SimPEG.mesh.LogicallyOrthogonalMesh
|
||||
.. automodule:: SimPEG.Mesh.LogicallyOrthogonalMesh
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
LOM View
|
||||
********
|
||||
|
||||
.. automodule:: SimPEG.mesh.LomView
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,11 @@
|
||||
.. _api_Parameters:
|
||||
|
||||
|
||||
Parameters
|
||||
**********
|
||||
|
||||
.. automodule:: SimPEG.Parameters
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
@@ -3,15 +3,8 @@
|
||||
Tensor Mesh
|
||||
***********
|
||||
|
||||
.. automodule:: SimPEG.mesh.TensorMesh
|
||||
.. automodule:: SimPEG.Mesh.TensorMesh
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
Tensor View
|
||||
***********
|
||||
|
||||
.. automodule:: SimPEG.mesh.TensorView
|
||||
:members:
|
||||
:undoc-members:
|
||||
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -3,6 +3,6 @@
|
||||
Testing SimPEG
|
||||
**************
|
||||
|
||||
.. automodule:: SimPEG.tests.TestUtils
|
||||
.. automodule:: SimPEG.Tests.TestUtils
|
||||
:members:
|
||||
:undoc-members:
|
||||
+8
-8
@@ -4,7 +4,7 @@
|
||||
Solver
|
||||
******
|
||||
|
||||
.. automodule:: SimPEG.utils.Solver
|
||||
.. automodule:: SimPEG.Solver
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
@@ -12,49 +12,49 @@ Solver
|
||||
Utilities
|
||||
*********
|
||||
|
||||
.. automodule:: SimPEG.utils
|
||||
.. automodule:: SimPEG.Utils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Matrix Utilities
|
||||
****************
|
||||
|
||||
.. automodule:: SimPEG.utils.matutils
|
||||
.. automodule:: SimPEG.Utils.matutils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Sparse Utilities
|
||||
****************
|
||||
|
||||
.. automodule:: SimPEG.utils.sputils
|
||||
.. automodule:: SimPEG.Utils.sputils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
LOM Utilities
|
||||
*************
|
||||
|
||||
.. automodule:: SimPEG.utils.lomutils
|
||||
.. automodule:: SimPEG.Utils.lomutils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Mesh Utilities
|
||||
**************
|
||||
|
||||
.. automodule:: SimPEG.utils.meshutils
|
||||
.. automodule:: SimPEG.Utils.meshutils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Model Builder Utilities
|
||||
***********************
|
||||
|
||||
.. automodule:: SimPEG.utils.ModelBuilder
|
||||
.. automodule:: SimPEG.Utils.ModelBuilder
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Interpolation Utilities
|
||||
***********************
|
||||
|
||||
.. automodule:: SimPEG.utils.interputils
|
||||
.. automodule:: SimPEG.Utils.interputils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
from SimPEG.mesh import LogicallyOrthogonalMesh
|
||||
from SimPEG import utils
|
||||
import matplotlib.pyplot as plt
|
||||
X, Y = utils.exampleLomGird([3,3],'rotate')
|
||||
M = LogicallyOrthogonalMesh([X, Y])
|
||||
M.plotGrid()
|
||||
plt.show()
|
||||
@@ -1,11 +0,0 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from SimPEG.mesh import TensorMesh
|
||||
|
||||
h1 = np.linspace(.1,.5,3)
|
||||
h2 = np.linspace(.1,.5,5)
|
||||
mesh = TensorMesh([h1, h2])
|
||||
mesh.plotGrid(nodes=True, faces=True, centers=True, lines=True)
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from SimPEG.mesh import TensorMesh
|
||||
|
||||
h1 = np.linspace(.1,.5,3)
|
||||
h2 = np.linspace(.1,.5,5)
|
||||
h3 = np.linspace(.1,.5,3)
|
||||
mesh = TensorMesh([h1,h2,h3])
|
||||
mesh.plotGrid(nodes=True, faces=True, centers=True, lines=True)
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from SimPEG.mesh import TensorMesh
|
||||
|
||||
n = 20
|
||||
h = np.ones(n)/n
|
||||
M = TensorMesh([h, h])
|
||||
I = np.sin(M.gridCC[:,0]*2*np.pi)*np.sin(M.gridCC[:,1]*2*np.pi)
|
||||
M.plotImage(I)
|
||||
|
||||
plt.show()
|
||||
@@ -1,12 +0,0 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from SimPEG.mesh import TensorMesh
|
||||
|
||||
n = 20
|
||||
h = np.ones(n)/n
|
||||
M = TensorMesh([h,h,h])
|
||||
|
||||
I = np.sin(M.gridCC[:,0]*2*np.pi)*np.sin(M.gridCC[:,1]*2*np.pi)*np.sin(M.gridCC[:,2]*2*np.pi)
|
||||
M.plotImage(I, annotationColor='k')
|
||||
|
||||
plt.show()
|
||||
@@ -1,13 +0,0 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from SimPEG.mesh import TensorMesh
|
||||
|
||||
x0 = np.zeros(2)
|
||||
h1 = np.linspace(.1,.5,3)
|
||||
h2 = np.linspace(.1,.5,5)
|
||||
M = TensorMesh([h1,h2],x0)
|
||||
M.plotGrid()
|
||||
plt.hold()
|
||||
plt.plot(M.gridN[:,0], M.gridN[:,1], 'ks', markersize=10)
|
||||
plt.show()
|
||||
|
||||
+16
-20
@@ -3,7 +3,7 @@
|
||||
:alt: SimPEG
|
||||
:align: center
|
||||
|
||||
SimPEG (Simulation and Parameter Estimation in Geoscience) is a python
|
||||
SimPEG (Simulation and Parameter Estimation in Geophysics) is a python
|
||||
package for simulation and gradient based parameter estimation in the
|
||||
context of geoscience applications.
|
||||
|
||||
@@ -16,11 +16,10 @@ these goals, this package has the following features:
|
||||
* provides a framework for geophysical and hydrogeologic problems
|
||||
* supports 1D, 2D and 3D problems
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<iframe src="http://row1.ca/labs/simpegvis" width="100%" height="500px" style="border:none;background:#eee;margin:50px 0;"></iframe>
|
||||
|
||||
.. image:: simpeg-framework.png
|
||||
:width: 400 px
|
||||
:alt: Framework
|
||||
:align: center
|
||||
|
||||
Meshing & Operators
|
||||
===================
|
||||
@@ -41,7 +40,7 @@ Forward Problems
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api_Problem
|
||||
api_Forward
|
||||
|
||||
Inversion
|
||||
=========
|
||||
@@ -49,7 +48,8 @@ Inversion
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api_Optimize
|
||||
api_Inverse
|
||||
api_Parameters
|
||||
|
||||
Testing SimPEG
|
||||
==============
|
||||
@@ -58,22 +58,18 @@ Testing SimPEG
|
||||
:maxdepth: 2
|
||||
|
||||
api_Tests
|
||||
api_TestResults
|
||||
|
||||
Build Results
|
||||
=============
|
||||
|
||||
* Master Branch
|
||||
.. image:: https://travis-ci.org/simpeg/simpeg.png?branch=master
|
||||
:target: https://travis-ci.org/simpeg/simpeg
|
||||
:alt: Master Branch
|
||||
:align: center
|
||||
.. image:: https://travis-ci.org/simpeg/simpeg.png?branch=master
|
||||
:target: https://travis-ci.org/simpeg/simpeg
|
||||
:alt: Master Branch
|
||||
:align: center
|
||||
|
||||
* Develop Branch
|
||||
.. image:: https://travis-ci.org/simpeg/simpeg.png?branch=develop
|
||||
:target: https://travis-ci.org/simpeg/simpeg
|
||||
:alt: Develop Branch
|
||||
:align: center
|
||||
.. image:: https://travis-ci.org/simpeg/simpeg.png?branch=develop
|
||||
:target: https://travis-ci.org/simpeg/simpeg
|
||||
:alt: Develop Branch
|
||||
:align: center
|
||||
|
||||
|
||||
Utility Codes
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -1,158 +0,0 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": ""
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import SimPEG\n",
|
||||
"from SimPEG import Solver\n",
|
||||
"from SimPEG.mesh import TensorMesh\n",
|
||||
"from SimPEG.regularization import Regularization\n",
|
||||
"import SimPEG.inverse as inverse\n",
|
||||
"from SimPEG.inverse import Minimize, Remember, IterationPrinters\n",
|
||||
"import numpy as np\n",
|
||||
"import scipy.sparse as sp"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"FUN = SimPEG.tests.Rosenbrock\n",
|
||||
"FUN = SimPEG.tests.getQuadratic(sp.csr_matrix(([100,1],([0,1],[0,1])),shape=(2,2)),np.array([-5,-5]),100)\n",
|
||||
"\n",
|
||||
"x0 = np.array([1,0])\n",
|
||||
"opt = inverse.BFGS()\n",
|
||||
"xopt = opt.minimize(FUN,x0)\n",
|
||||
"print xopt\n",
|
||||
"opt = inverse.GaussNewton()\n",
|
||||
"xopt = opt.minimize(FUN,x0)\n",
|
||||
"print xopt\n",
|
||||
"opt = inverse.SteepestDescent()\n",
|
||||
"xopt = opt.minimize(FUN,x0)\n",
|
||||
"print xopt"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"===================== BFGS =====================\n",
|
||||
" # f |proj(x-g)-x| LS Comment \n",
|
||||
"-----------------------------------------------\n",
|
||||
" 0 1.45e+02 9.51e+01 0 \n",
|
||||
" 1 1.14e+02 5.37e+01 6 \n",
|
||||
" 2 1.04e+02 3.04e+01 6 \n",
|
||||
" 3 8.83e+01 1.37e+01 0 \n",
|
||||
" 4 8.76e+01 5.97e+00 0 Skip BFGS \n",
|
||||
" 5 8.74e+01 2.61e+00 0 Skip BFGS \n",
|
||||
" 6 8.74e+01 1.14e+00 0 Skip BFGS \n",
|
||||
" 7 8.74e+01 5.01e-01 0 Skip BFGS \n",
|
||||
" 8 8.74e+01 2.19e-01 0 Skip BFGS \n",
|
||||
" 9 8.74e+01 9.60e-02 0 Skip BFGS \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"1 : |fc-fOld| = 1.9437e-04 <= tolF*(1+|f0|) = 1.4600e+01\n",
|
||||
"1 : |xc-x_last| = 1.2663e-03 <= tolX*(1+|x0|) = 2.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 9.5952e-02 <= tolG = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 9.5952e-02 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 20 <= iter = 9\n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"[ 0.05095952 4.99977449]\n",
|
||||
"=========== Gauss Newton ===========\n",
|
||||
" # f |proj(x-g)-x| LS \n",
|
||||
"-----------------------------------\n",
|
||||
" 0 1.45e+02 9.51e+01 0 \n",
|
||||
" 1 8.74e+01 4.44e-15 0 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"0 : |fc-fOld| = 5.7625e+01 <= tolF*(1+|f0|) = 1.4600e+01\n",
|
||||
"0 : |xc-x_last| = 5.0894e+00 <= tolX*(1+|x0|) = 2.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 4.4409e-15 <= tolG = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 4.4409e-15 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 20 <= iter = 1\n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"[ 0.05 5. ]\n",
|
||||
"========= Steepest Descent =========\n",
|
||||
" # f |proj(x-g)-x| LS \n",
|
||||
"-----------------------------------\n",
|
||||
" 0 1.45e+02 9.51e+01 0 \n",
|
||||
" 1 1.14e+02 5.37e+01 6 \n",
|
||||
" 2 1.04e+02 3.04e+01 6 \n",
|
||||
" 3 1.00e+02 1.76e+01 6 \n",
|
||||
" 4 9.88e+01 1.06e+01 6 \n",
|
||||
" 5 9.82e+01 7.07e+00 6 \n",
|
||||
" 6 9.80e+01 1.22e+01 5 \n",
|
||||
" 7 9.73e+01 7.77e+00 6 \n",
|
||||
" 8 9.68e+01 5.64e+00 6 \n",
|
||||
" 9 9.65e+01 8.72e+00 5 \n",
|
||||
" 10 9.60e+01 5.97e+00 6 \n",
|
||||
" 11 9.58e+01 9.98e+00 5 \n",
|
||||
" 12 9.53e+01 6.48e+00 6 \n",
|
||||
" 13 9.53e+01 1.16e+01 5 \n",
|
||||
" 14 9.46e+01 7.20e+00 6 \n",
|
||||
" 15 9.43e+01 5.07e+00 6 \n",
|
||||
" 16 9.41e+01 8.17e+00 5 \n",
|
||||
" 17 9.37e+01 5.43e+00 6 \n",
|
||||
" 18 9.36e+01 9.42e+00 5 \n",
|
||||
" 19 9.32e+01 5.98e+00 6 \n",
|
||||
" 20 9.29e+01 4.32e+00 6 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"1 : |fc-fOld| = 2.5913e-01 <= tolF*(1+|f0|) = 1.4600e+01\n",
|
||||
"1 : |xc-x_last| = 9.3379e-02 <= tolX*(1+|x0|) = 2.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 4.3246e+00 <= tolG = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 4.3246e+00 <= 1e3*eps = 1.0000e-02\n",
|
||||
"1 : maxIter = 20 <= iter = 20\n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"[ 0.07777107 1.6849632 ]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stderr",
|
||||
"text": [
|
||||
"/Users/rowan/git/simpeg/SimPEG/inverse/Optimize.py:664: RuntimeWarning: divide by zero encountered in remainder\n",
|
||||
" khat = np.mod(n-nn+k,nn)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"A = sp.identity(2)\n",
|
||||
"S = Solver(A)\n",
|
||||
"\n",
|
||||
"assert type(S) is Solver"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 6
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,620 +0,0 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": ""
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import SimPEG\n",
|
||||
"from SimPEG.mesh import TensorMesh\n",
|
||||
"from SimPEG.regularization import Regularization\n",
|
||||
"import SimPEG.inverse as inverse\n",
|
||||
"from SimPEG.inverse import Minimize\n",
|
||||
"import numpy as np\n",
|
||||
"import scipy.sparse as sp"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 1
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"from SimPEG.forward.LinearProblem import example as LinExample\n",
|
||||
"\n",
|
||||
"prob, m_true = LinExample(1000)\n",
|
||||
"M = prob.mesh\n",
|
||||
"\n",
|
||||
"reg = Regularization(M)\n",
|
||||
"opt = inverse.InexactGaussNewton(maxIter=100,maxStep=0.2,debug=False,LSreduction=0.3,maxIterLS=50)\n",
|
||||
"opt.remember('f', ('norm_g', lambda M:np.linalg.norm(M.g)))\n",
|
||||
"inv = inverse.Inversion(prob,reg,opt,beta0=1e-4,maxIter=2,debug=False)\n",
|
||||
"m0 = np.zeros_like(m_true)\n",
|
||||
"\n",
|
||||
"mrec = inv.run(m0)\n",
|
||||
"\n",
|
||||
"plt.plot(M.vectorCCx, m_true, 'b-')\n",
|
||||
"plt.plot(M.vectorCCx, mrec, 'r-')\n",
|
||||
"\n",
|
||||
"figure()\n",
|
||||
"plot(opt.recall('f'))\n"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"====================== Inexact Gauss Newton ======================\n",
|
||||
" # beta phi_d phi_m f |proj(x-g)-x| LS \n",
|
||||
"-----------------------------------------------------------------\n",
|
||||
" 0 1.00e-04 9.62e+02 0.00e+00 9.62e+02 1.02e+04 0 \n",
|
||||
" 1 1.00e-04 6.63e+02 7.73e+02 6.63e+02 8.47e+03 0 \n",
|
||||
" 2 1.00e-04 4.15e+02 4.39e+03 4.15e+02 6.63e+03 0 \n",
|
||||
" 3 1.00e-04 2.26e+02 6.85e+03 2.27e+02 4.80e+03 0 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 4 1.00e-04 9.74e+01 1.07e+04 9.84e+01 3.02e+03 0 \n",
|
||||
" 5 1.00e-04 2.42e+01 1.64e+04 2.58e+01 1.35e+03 0 \n",
|
||||
" 6 1.00e-04 1.06e+00 2.34e+04 3.39e+00 9.21e+00 0 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"1 : |fc-fOld| = 2.2421e+01 <= tolF*(1+|f0|) = 9.6325e+01\n",
|
||||
"0 : |xc-x_last| = 2.1351e+00 <= tolX*(1+|x0|) = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 9.2073e+00 <= tolG = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 9.2073e+00 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 100 <= iter = 6\n",
|
||||
"1 : phi_d = 1.0595e+00 <= phi_d_target = 2.0000e+01 \n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"-------------------------STOP!-------------------------\n",
|
||||
"0 : maxIter = 2 <= iter = 1\n",
|
||||
"1 : phi_d = 1.0595e+00 <= phi_d_target = 2.0000e+01 \n",
|
||||
"-------------------------DONE!-------------------------\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 3,
|
||||
"text": [
|
||||
"[<matplotlib.lines.Line2D at 0x10ebf9f10>]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEACAYAAAC08h1NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlcVPX+P/DXYcncwgVzSUXBBVAQBEGvgriAGmndopLW\nq9VXLZUyy6/lfRhere79ZWXWVatrt+916RZa7imYgEkC7hum4oJaLkjiigLz+f3xkVGcGWZfz+v5\neMxDmDlzzpvjzGs+8zmf8zmKEEKAiIhUw8vZBRARkWMx+ImIVIbBT0SkMgx+IiKVYfATEakMg5+I\nSGWsDv7Ro0ejZcuWCAsL0/t4dnY2/Pz8EBkZicjISMycOdPaTRIRkRV8rF3BqFGjMGHCBDz33HMG\nl+nfvz9Wrlxp7aaIiMgGrG7xx8XFoWnTpnUuw3PEiIhch937+BVFQV5eHiIiIjBp0iQUFxfbe5NE\nRFQHuwd/z549cfLkSRQWFiI0NBRpaWn23iQREdVF2MCxY8dE9+7djS6n0WjE/fffLyoqKnQeCwoK\nEgB444033ngz4xYUFGR2Ztu9xX/27FltH/+qVasQHh6OevXq6SxXXFwMIQRvQmD69OlOr8FVbtwX\n3BfcF3XfLOk+t3pUT2pqKnJyclBaWop27dohPT0dlZWVAIAxY8YgIyMD8+bNg4+PD8LDwzF79mxr\nN0lERFawOviXLl1a5+OvvPIKXnnlFWs3Q0RENsIzd11QQkKCs0twGdwXt3Ff3MZ9YR1FCCGcXQQg\nh326SClERG7Dkuxki5+ISGUY/EREKsPgJyJSGQY/EZHKMPiJiFSGwU9EpDIMfiIilWHwExGpDIOf\niEhlGPxERCrD4CciUhkGPxGRyjD4iYhUhsFPRKQyDH4iIpVh8BMRqQyDn4hIZRj8REQqw+AnIlIZ\nBj8Rkcow+ImIVMbH2QWQyly5AmRmAhcuAD17ApGRgKI4uyoiVWGLnxxn0SIgKAiYPx/YsgV4/HEg\nKQk4dcrZlRGpClv85BjvvQf861/A+vVARIS8r6pK3t+vH7BpE9Cxo3NrJFIJBj/Z37ffAp9/Dvzy\nC9Cq1e37fXyAv/4VaNwYGDFCPt6okfPqJFIJRQghnF0EACiKAhcphWzpyBGgTx9gwwbZn6+PEMDz\nzwP33Qd8+qlj6yNyc5ZkJ4Of7EcIYMgQ2Y8/eXLdy/7xB9C9O5CRIT8oiMgklmQnD+6S/Xz3HXD2\nLJCWZnzZpk2BWbOAKVPkBwYR2Q2Dn+yjqgqYNg2YPRvw9TXtOc8+C5SWAj/+aN/aiFSOwU/2sXgx\n0KYNMGiQ6c/x9gZmzJA3IrIb9vGT7Wk0QHAw8MUXQP/+5j23uhro1An45hsgNtY+9RF5EPbxk2tY\nt06O0ImPN/+53t7AxInAnDm2r4uIALDFT/YwZAjw9NPAc89Z9vzyciAgAPj1V6BlS9vWRuRh2OIn\n5ysqAnbvBp580vJ1+PkBDz8MLFliu7qISMvq4B89ejRatmyJsLAwg8tMnToVgYGBiIqKwsGDB63d\nJLmyBQuAF18E6tWzbj2jRgFffcWhnUR2YHXwjxo1Cj/WMfyuoKAAmzdvxrZt2zB58mRMNnYiD7mv\nmzdlK33UKOvXFR8vZ/LcudP6dRFRLVYHf1xcHJo2bWrw8fz8fKSkpKBZs2ZITU1FUVGRtZskV7Vu\nnRzNExRk/bq8vIDUVDnPDxHZlN0naSsoKMCzzz6r/b1FixYoLi5GkC3CgexCowF+/hmorDTveWEf\nfI3S2Ofx+0bb1NGoXQrC/vY4fhn8nsVz9gcFAR062KYeIk9h9+AXQugccVYMvInfeecd7c8JCQlI\nSEiwY2VkSFER8OCD5g2jv6/yAv6z9SdM8fo3rtmqd0ZE4D9lAv99azeKG0eY/fTSUjk4aOVKG9VD\n5AKys7ORnZ1t1TpsMpzz+PHjGD58OPbu3avz2Ny5c1FVVYXXXnsNABAUFITi4mLdQjic02Xs3i1H\nYu7ebcaTvvxSzsBp666ZKVPklA8zZ5r91LVr5WSfa9fatiQiV+KSwzljY2OxbNkyXLhwAUuWLEFI\nSIi9N0lWEsKCnpWMDHlFLVtLSZHrJiKbsbqrJzU1FTk5OSgtLUW7du2Qnp6Oyludw2PGjEFMTAz6\n9euH6OhoNGvWDIsWLbK6aLIvs4O/rExeRGXZMtsXEx0NXL4MHD4MdO5s1lMVhaNBifSxOviXLl1q\ndJn3338f77//vrWbIgcxO/h/+AFITAQaNrR9MYoiDzisXWva9M53PZXBT6SLZ+6SDrODPyNDdsnY\ny7BhcqgoEdkEg590mBX8Fy8CW7YAycn2K2jwYLmNq1fNehpb/ET6MfhJh1lhuW6dPMu2cWO71YP7\n7gN69QI2bTL7qQx+Il0MftJhVot/9Wpg+HC71gNAdveYOS7TwnO+iDweg590mBz8VVXyMon27Oap\nkZQEZGWZ9RR29RDpx+AnHSYH/y+/yFNjH3jA7jUhLEwOGz150v7bIvJwDH7SYXLwO6qbB5CTtg0Y\nYFY/P1v8RPox+EmHycG/ahXw0EN2r0dr0CDgp59MXpzBT6Qfg590mBT8xcWy6yUqyiE1AQAGDpTB\nzzQnsgqDn3SYFPxr1sgzar0c+BLq3FnOGa1nkj992OIn0o/BTzpMCv7MTGDoUIfUo6Uot1v9Ji7O\n4CfSxeAnHUaDv7ISyM2VIexoZgQ/EenH4CcdRoM/Px/o1Anw93dYTVpxccDmzSY15dniJ9KPwU86\njAZ/VpacjdMZAgNlP/+JEyYtzuAn0sXgJx1Ggz8zU06c5gyKAvTrJy8KbMKiRKSLwU866gz+S5eA\nPXuAvn0dWlMtZgQ/W/xEuhj8pKPO4M/OBnr3BurXd2RJtZkY/ACDn0gfBj/pqDP4s7Kc181To0cP\noKQE+OOPOhdjVw+Rfgx+0mE0+J11YLeGjw8QEwPk5dW5GLt6iPRj8JNeeoP/1Cng3DkgIsLh9egw\no7uHiGpj8JMOgy3+jRvlCVSOnKbBEBOCny1+Iv1c4B1MrsZg8GdmOr+bp0bv3sCOHcCNGwYXYfAT\n6cfgJx16g18I1ziwW6NRI3n28O7dzq6EyO0w+EmH3uDfv1+GbceOTqlJr9hYOX2EAWzxE+nH4Ccd\neoPfmWfrGsLgJ7IIg5906A1+V+rmqWEk+IlIPwY/6dBpJd+8KWfEdMY0zHUJCQHOngUuXND7MFv8\nRPox+EmHTot/61aga1egWTOn1aSXtzcQHQ0UFBhchMFPpIvBTzp0gt+VhnHerY7uHk7ZQKQfg590\n6AS/K/bv1zAS/GzxE+li8JOOWsFfXg7s2wf86U9Orcmg2FjZ1WMg4Rn8RLoY/KSjVvBv2iRD/957\nnVqTQa1bAw0bAkeO6DzErh4i/Rj8pKNW8LtyN08NA9097Ooh0o/BTzpqBb8rH9itwfH8RGZh8JMO\nbfCXlABlZUB4uLNLqltMDFv8RGawOvhzc3MREhKCzp07Y+7cuTqPZ2dnw8/PD5GRkYiMjMTMmTOt\n3STZmTb4N24EBg1yjWmY6xIVJQ9A3zVTJ4OfSD8fa1eQlpaGBQsWICAgAEOGDEFqair8/f1rLdO/\nf3+sXLnS2k2Rg2iD3x26eQB5cLdTJ2DvXnlCFxHVyaqmXHl5OQAgPj4eAQEBSEpKQr6er9yCzS63\nIgTgBY1s8bv6gd0a0dHAtm217mKLn0g/q4K/sLAQwcHB2t9DQ0OxdevWWssoioK8vDxERERg0qRJ\nKC4utmaT5ABCAAGX9gL33QcEBDi7HNNERwPbt+vczeAn0mX3ztuePXvi5MmTKCwsRGhoKNLS0uy9\nSbKSEED4WTfp5qkRFaW3xU9Euqzq4+/VqxfeeOMN7e/79+/H0KFDay3TuHFj7c8vvPAC3n77bdy4\ncQP16tXTWd8777yj/TkhIQEJCQnWlEcWEgIIO5sJJI1zdimmCw8Hfv0VqKjQnmzGrh7yRNnZ2cjO\nzrZqHVYFv5+fHwA5sqd9+/bIzMzE9OnTay1z9uxZ3H///VAUBatWrUJ4eLje0AdqBz85j3KjAl1K\n84AB3zq7FNPVry9nEN2zRw7vvIXBT57m7kZxenq62euwelTPxx9/jDFjxqCyshITJ06Ev78/FixY\nAAAYM2YMMjIyMG/ePPj4+CA8PByzZ8+2dpNkZy1+/Rknm4Shy60PdrdR091zK/jZ1UOknyJcZMiN\noigc/eMi9j00BYdK7sWje8xvSTjV/PlywraFCwHIof0jR8p/iTyVJdnp4mfmkDO03peJ/a3d6MBu\nDT0je9iWINLF4Kfazp1D43NHcbRFrLMrMV9YGHD4MHDtGgB29RAZwuCn2jZuxJmu/aHx9nV2Jear\nV09eh3f3bgAc1UNkCIOfasvMxG/dEt23tXzXGbwMfiJdDH66TQhgwwacCnXz4L/Vz++2fwORnTH4\n6baDBwEvL5Tf38XZlVjurjN42eIn0sXgp9tuzcYpoLhva7l7d+DoUeDqVff9G4jsjMFPt61bB9ya\ncsNtQ/Oee2T479rFg7tEBjD4Sbp2Dfj5ZyApqfalF93RHd09DH4iXQx+kn76SQamn5/7B/+tkT1u\n/TcQ2RGDn6S1a4HkZADwjODfvp1dPUQGMPhJpuOaNcCDD2p/devgDw0FTpyAcuUyg59IDwY/AQcO\nyKQPDQXgAcHv6wuEheHeop3OroTIJTH46XY3z620d/vgB4DoaNy7fztb/ER6MPipVjcP4DnBX29v\nIYOfSA8Gv9qVlwM7dgADBmjv8pjg36d78XUiYvDT2rVAfDzQoIH2Lo8I/uBg+Jw9jUbV5c6uhMjl\nMPjVbvly4NFHa93lEcHv44ObIRHoVsFWP9HdGPxqdv06sGEDMGJErbs9IvgB3AyPRvjNbcLine truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10ecafa10>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "iVBORw0KGgoAAAANSUhEUgAAAXsAAAEACAYAAABS29YJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHo1JREFUeJzt3Xt01OWdx/H3BCQUuRRFgrswgpDmAkoC5oIYElAhoiEB\nRMoKWBOtRm1A4NSzqy3Y3SMFbSGgCdjdWC3HWo/dKiIKJDZAUJJwKSiEkggt4HIRRJ0IKMLsH49M\nQLkkk8k8c/m8zpkzYTK/zHfmcD558v09v+dxuN1uNyIiEtIibBcgIiItT2EvIhIGFPYiImFAYS8i\nEgYU9iIiYUBhLyISBi4a9rm5uURFRXHdddd5HnO5XGRnZ+N0OsnJyaG+vt7zvQULFhAdHU18fDwV\nFRWex2tqahgwYADXXnstjz/+eAu8DRERuZiLhv29997LO++8c85jxcXFOJ1Oamtr6d69O4sWLQLg\n0KFDFBUVUVZWRnFxMQUFBZ5jpk+fzmOPPUZ1dTWrV69mw4YNLfBWRETkQi4a9mlpaXTu3Pmcx6qq\nqsjLyyMyMpLc3FwqKysBqKysJDMzE6fTSXp6Om632zPq//vf/8748eO58sorGTNmjOcYERHxjyb3\n7Kurq4mNjQUgNjaWqqoqwIR9XFyc53kxMTFUVlZSV1dH165dPY/Hx8ezfv365tYtIiJN0OSwb8rq\nCg6Ho1nHi4iIb7Ru6gFJSUnU1NSQmJhITU0NSUlJAKSkpFBaWup53o4dO0hKSqJDhw4cPHjQ8/j2\n7dtJTU0978/u06cPH330UVNLEhEJa71796auru6iz2nyyD4lJYWSkhKOHz9OSUmJJ7iTk5NZsWIF\ne/bsoby8nIiICDp06ACYds8rr7zC4cOH+ctf/kJKSsp5f/ZHH32E2+3Wze1m5syZ1msIlJs+C30W\n+iwufmvMIPmiYT9hwgRuvPFGdu7cSY8ePXjhhRfIz89nz549xMTE8PHHH/Pggw8CEBUVRX5+PsOG\nDeOhhx6isLDQ83OeeeYZ5s6dS1JSEmlpadxwww2N+80iIiI+cdE2zh//+MfzPv7GG2+c9/EpU6Yw\nZcqU7z0eHx/Ppk2bvChPRER8QVfQBqiMjAzbJQQMfRYN9Fk00GfRNA632x0w02McDgcBVI6ISFBo\nTHZqZC8iEgYU9iIiYSDgwn7XLtsViIiEnoAL+2HDFPgiIr4WcGH/2GMwdKgCX0TEl5q8XEJLy88H\nh8ME/rvvQu/etisSEQl+ARf2AN9elMuwYQp8ERFfCMiwBxP4DocCX0TEFwI27AEeeODclk6fPrYr\nEhEJTgEd9gA//am5PzPCV+CLiDRdwIc9KPBFRJorKMIeTOCf6eGXlUF0tO2KRESCR9CEPcD99597\n0laBLyLSOEEV9gD33WfuFfgiIo0XdGEPJvDPbun86Ee2KxIRCWxBGfYAeXkm8G++WYEvInIpQRv2\nALm55l6BLyJycUEd9mAC/+yWTkyM7YpERAJP0Ic9wL33mvszI3wFvojIuUIi7MEE/tk9fAW+iEiD\nkAl7gJ/8pCHwS0shNtZ2RSIigSGkwh7gnnvM/ZkRvgJfRCQEwx4U+CIi3xWSYQ8m8M9u6cTF2a5I\nRMSekA17gMmTTeDfcgusWgXx8bYrEhGxI6TDHmDSJBP4t96qwBeR8BXyYQ8wcaK5v+UW09JR4ItI\nuAmLsAcT+Ge3dPr2tV2RiIj/hE3YA9x9t7k/09JR4ItIuAirsAcT+Gf38BX4IhIOwi7sAf7t38z9\nrbfCypXQr5/dekREWlpYhj2YwD97hK/AF5FQFrZhDzBhgrlX4ItIqAvrsAcT+GdG+CtXwnXX2a5I\nRMT3Irw98He/+x033ngjAwcOZOrUqQC4XC6ys7NxOp3k5ORQX1/vef6CBQuIjo4mPj6eioqK5lfu\nQz/+McyfD8OHw9attqsREfE9r8L+008/5amnnmLVqlVUV1ezc+dOVqxYQXFxMU6nk9raWrp3786i\nRYsAOHToEEVFRZSVlVFcXExBQYFP34QvjB9vAn/ECAW+iIQer8L+Bz/4AW63m88//5zjx49z7Ngx\nfvjDH1JVVUVeXh6RkZHk5uZSWVkJQGVlJZmZmTidTtLT03G73bhcLp++EV8YPx4KCxX4IhJ6vA77\n4uJievbsSbdu3Rg8eDApKSlUV1cT++16wrGxsVRVVQEm7OPOWnYyJibG871Ac9ddJvCHD4ctW2xX\nIyLiG16doP3kk0/Iz89n+/btdO7cmXHjxrFs2TLcbnejf4bD4Tjv47NmzfJ8nZGRQUZGhjclNstd\nd5mTtiNGwIoV0L+/30sQEbmg8vJyysvLm3SMV2FfVVVFamoqffr0AWDcuHGsXbuWpKQkampqSExM\npKamhqSkJABSUlIoLS31HL9jxw7P977r7LC3adw4c6/AF5FA892B8JNPPnnJY7xq46SlpbFhwwY+\n/fRTvvrqK95++22GDx9OSkoKJSUlHD9+nJKSElJTUwFITk5mxYoV7Nmzh/LyciIiIujQoYM3L+1X\n48bBs8+awP/b32xXIyLiPa9G9h07duSJJ55g9OjRHDt2jMzMTIYOHUpycjITJ04kJiaGAQMGMGfO\nHACioqLIz89n2LBhtGnThsWLF/v0TbSkO+8095mZ8M47kJBgtx4REW843E1ptLcwh8PRpL6/P/35\nz/Dww/D225CYaLsaEZEGjcnOsL+CtrHGjjX3t92mwBeR4KOwb4KxY80sHQW+iAQbhX0TjRnTEPjL\nl8OAAbYrEhG5NIW9F0aPNvdnRvgKfBEJdAp7LynwRSSYKOybYfToc1s6AwfarkhE5PwU9s2Uk2MC\nf+RIeOstuOEG2xWJiHyfwt4HsrPN/e23K/BFJDAp7H0kO9uM8BX4IhKIFPY+NGpUQ+AvWwYXWOtN\nRMTvvN6WUM4vKwv++79N4Afokv0iEoYU9i0gKwv+53/gjjsU+CISGBT2LSQrC0pKzL0CX0RsU9i3\noDvuaBjhf7sdr4iIFQr7FnbHHfDCC2aEr8AXEVsU9n5w++3w+9+bwF+/3nY1IhKOFPZ+MnKkCfxR\noxT4IuJ/Cns/UuCLiC0Kez8bORJefNEE/vvv265GRMKFwt6C226Dl14ySyy8957takQkHCjsLcnM\nNIGfk6PAF5GWp7C3KDMT/vAHBb6ItDyFvWUjRjQE/rp1tqsRkVClsA8AZwJ/9GioqLBdjYiEIoV9\ngBgxApYsgTFjFPgi4nsK+wAyfHhD4K9aZbsaEQklCvsAM3w4vPYaTJoECxeC2227IhEJBQ63O3Di\nxOFwEEDlWLVrl7nwavBgE/pt2tiuSEQCVWOyUyP7AHXttWY65v/9nxntHz5suyIRCWYK+wDWsSO8\n/jqkpkJyMnz4oe2KRCRYqY0TJJYsgUcfNZuhjBpluxoRCSSNyc7WfqpFmmniRIiONjN1amrg5z8H\nh8N2VSISLDSyDzL79pkF1OLj4Xe/g7ZtbVckIrbpBG0I6t4d1q6Fr7+GjAzYv992RSISDBT2Qahd\nO3jlFbPdYXIybNxouyIRCXReh/2XX37JPffcw49+9CPi4+OprKzE5XKRnZ2N0+kkJyeH+vp6z/MX\nLFhAdHQ08fHxVGg9gGZzOOAXv4D5883qmX/6k+2KRCSQeR32M2fOxOl0snXrVrZu3UpsbCzFxcU4\nnU5qa2vp3r07ixYtAuDQoUMUFRVRVlZGcXExBQUFPnsD4W7sWLO0ws9/Dr/8JZw+bbsiEQlEXod9\naWkp//Ef/0Hbtm1p3bo1nTp1oqqqiry8PCIjI8nNzaWyshKAyspKMjMzcTqdpKen43a7cblcPnsT\n4S4hAaqqoKwMxo2DL7+0XZGIBBqvwn7fvn2cOHGC/Px8UlJSmDNnDsePH6e6uprY2FgAYmNjqaqq\nAkzYx8XFeY6PiYnxfE98IyoK3n3XXIg1eDD885+2KxKRQOJV2J84cYKdO3cyduxYysvL2bZtG6++\n+mqTpk06NEnc5yIjoaTELKI2aJA2QxGRBl5dVNWnTx9iYmLIysoCYMKECbz00kskJSVRU1NDYmIi\nNTU1JCUlAZCSkkJpaann+B07dni+912zZs3yfJ2RkUFGRoY3JYYthwOmTzfz8EePhrlz4Sc/sV2V\niPhSeXk55eXlTTrG64uqRo0axeOPP05SUhIFBQUkJiZy5MgR9u7dy9y5c5kxYwa9evVixowZHDx4\nkPT0dFauXMmuXbuYNm0amzZt+n4xuqjKp2pqICvLbHk4Zw60amW7IhFpCY3JTq/DfufOnUyePJkT\nJ05wyy238OSTT3L69GkmTpzI5s2bGTBgAEuWLKF9+/YAFBYWsnDhQtq0acPixYtJS0vzqmBpmiNH\n4K67TIvnj3+ETp1sVyQivtaiYd8SFPYt4+RJs4haWRksXWrW2BGR0KHlEgSAyy6DZ5+FKVPgpptM\n6ItIeFHYh5EHHzTLLNx9Nzz3nO1qRMSf1MYJQx99ZNbEHzIEFiwwI38RCV5q48h59e4N778Pe/ea\nLQ+PHLFdkYi0NIV9mOrYEd54A5KSzMqZ27bZrkhEWpLCPoy1amUuupo506yNv2yZ7YpEpKWoZy+A\naevceSdMnQozZmjLQ5Fgonn20iR795otD/v1g+ef15aHIsFCJ2ilSXr0MFseHj8OQ4fCgQO2KxIR\nX1HYyzkuv9zsepWZaU7cnmcJIxEJQmrjyAW99hrk50NRkdkURUQCk3r20mybN5s+fm6u2fYwQn8L\nigQchb34xIEDZm38f/1XePFF0+oRkcChE7TiE926wV//akL+pptgzx7bFYlIUynspVHatoXf/94s\nopaaaubli0jwUBtHmuytt+Dee+Hpp+Gee2xXIyLq2UuL2b7dbHk4Zgz8+tfa8lDEJoW9tKLine truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10ecbec90>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"FUN = SimPEG.tests.getQuadratic(sp.identity(2),np.array([-5,-5]))\n",
|
||||
"# FUN = SimPEG.tests.Rosenbrock\n",
|
||||
"\n",
|
||||
"f = FUN(np.array([1,2]))\n",
|
||||
"print f\n",
|
||||
"n,l,u = 50,-10,10\n",
|
||||
"I = np.zeros((n,n))\n",
|
||||
"X = np.linspace(l,u,n)\n",
|
||||
"for i, x in enumerate(X):\n",
|
||||
" for j, y in enumerate(X):\n",
|
||||
" f, g, H = FUN(np.array([x,y]))\n",
|
||||
" I[i,j] = f\n",
|
||||
"\n",
|
||||
"colorbar(contourf(X,X, I.T))\n",
|
||||
"\n",
|
||||
"GN = inverse.GaussNewton()\n",
|
||||
"xopt = GN.minimize(FUN,np.array([0,0]))\n",
|
||||
"print xopt"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"(-12.5, array([-4., -3.]), <2x2 sparse matrix of type '<type 'numpy.float64'>'\n",
|
||||
"\twith 2 stored elements (1 diagonals) in DIAgonal format>)\n",
|
||||
"=========== Gauss Newton ==========="
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" # f |proj(x-g)-x| LS \n",
|
||||
"-----------------------------------\n",
|
||||
" 0 0.00e+00 7.07e+00 0 \n",
|
||||
" 1 -2.50e+01 0.00e+00 0 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"0 : |fc-fOld| = 2.5000e+01 <= tolF*(1+|f0|) = 1.0000e-01\n",
|
||||
"0 : |xc-x_last| = 7.0711e+00 <= tolX*(1+|x0|) = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 0.0000e+00 <= tolG = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 0.0000e+00 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 20 <= iter = 1\n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"[ 5. 5.]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10ebd9750>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 5
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"opt = inverse.ProjectedGradient(maxIter=50,maxStep=np.inf, maxIterLS=20, debug=False)\n",
|
||||
"opt.remember('f')\n",
|
||||
"opt.lower = -2\n",
|
||||
"opt.upper = 2\n",
|
||||
"opt.minimize(FUN,np.array([0,0]))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"======================= Projected Gradient =======================\n",
|
||||
" # f |proj(x-g)-x| LS itType aSet bSet Comment\n",
|
||||
"------------------------------------------------------------------\n",
|
||||
" 0 0.00e+00 2.83e+00 0 SD 0 0 \n",
|
||||
" 1 -1.60e+01 0.00e+00 0 SD 2 2 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"0 : |fc-fOld| = 1.6000e+01 <= tolF*(1+|f0|) = 1.0000e-01\n",
|
||||
"0 : |xc-x_last| = 2.8284e+00 <= tolX*(1+|x0|) = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 0.0000e+00 <= tolG = 1.0000e-01\n",
|
||||
"1 : |proj(x-g)-x| = 0.0000e+00 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 50 <= iter = 1\n",
|
||||
"1 : probSize = 2 <= bindingSet = 2\n",
|
||||
"------------------------- DONE! -------------------------\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 7,
|
||||
"text": [
|
||||
"array([ 2., 2.])"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 7
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"opt = inverse.ProjectedGradient(maxIter=50, maxStep=0.3,debug=False, maxIterLS=20, tolCG=1e-5, maxIterCG=1000)\n",
|
||||
"opt.lower, opt.upper = -0.4, 0.9\n",
|
||||
"opt.remember('f', 'xc', ('norm_g', lambda M: np.linalg.norm(M.g)), 'phi_d', 'phi_m')\n",
|
||||
"inv = inverse.Inversion(prob,reg,opt,beta0=1e-3,debug=False)\n",
|
||||
"inv.remember(('phi_d',lambda I:I.opt.recall('phi_d')),('phi_m',lambda I:I.opt.recall('phi_m')))\n",
|
||||
"m0 = np.zeros_like(m_true)\n",
|
||||
"mrecB = inv.run(m0)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"====================================== Projected Gradient ======================================\n",
|
||||
" # beta phi_d phi_m f |proj(x-g)-x| LS itType aSet bSet Comment\n",
|
||||
"------------------------------------------------------------------------------------------------\n",
|
||||
" 0 1.00e-03 9.62e+02 0.00e+00 9.62e+02 2.14e+01 0 SD 0 0 \n",
|
||||
" 1 1.00e-03 9.53e+02 8.49e-03 9.53e+02 2.18e+01 9 SD 0 0 \n",
|
||||
" 2 1.00e-03 5.32e+02 1.42e+03 5.33e+02 2.20e+01 0 .CG. 0 0 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 3 1.00e-03 2.32e+02 5.66e+03 2.38e+02 2.26e+01 0 .CG. 0 0 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 4 1.00e-03 1.29e+02 8.85e+03 1.38e+02 2.30e+01 1 .CG. 0 0 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 5 1.00e-03 1.10e+02 9.74e+03 1.20e+02 2.15e+01 3 .CG. 22 22 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 6 1.00e-03 1.09e+02 9.74e+03 1.19e+02 2.36e+01 10 SD 22 0 Stop SD\n",
|
||||
" 7 1.00e-03 7.65e+01 1.33e+04 8.98e+01 2.21e+01 1 .CG. 85 75 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 8 1.00e-03 5.11e+01 1.33e+04 6.44e+01 2.38e+01 9 SD 75 3 \n",
|
||||
" 9 1.00e-03 5.07e+01 1.33e+04 6.41e+01 2.11e+01 12 SD 4 4 \n",
|
||||
" 10 1.00e-03 5.06e+01 1.33e+04 6.40e+01 2.20e+01 12 SD 17 9 Stop SD\n",
|
||||
" 11 1.00e-03 5.04e+01 1.34e+04 6.37e+01 2.05e+01 8 .CG. 85 81 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 12 1.00e-03 5.03e+01 1.34e+04 6.37e+01 1.65e+01 13 SD 81 26 \n",
|
||||
" 13 1.00e-03 5.03e+01 1.34e+04 6.37e+01 1.67e+01 15 SD 30 30 \n",
|
||||
" 14 1.00e-03 5.03e+01 1.34e+04 6.36e+01 1.42e+01 15 SD 84 84 Stop SD\n",
|
||||
" 15 1.00e-03 2.65e+01 2.26e+04 4.91e+01 2.52e+01 0 .CG. 190 50 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
" 16 1.00e-03 1.51e+01 2.26e+04 3.77e+01 2.24e+01 10 SD 50 1 \n",
|
||||
"------------------------- STOP! -------------------------\n",
|
||||
"1 : |fc-fOld| = 1.1392e+01 <= tolF*(1+|f0|) = 9.6325e+01\n",
|
||||
"1 : |xc-x_last| = 3.4809e-03 <= tolX*(1+|x0|) = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 2.2369e+01 <= tolG = 1.0000e-01\n",
|
||||
"0 : |proj(x-g)-x| = 2.2369e+01 <= 1e3*eps = 1.0000e-02\n",
|
||||
"0 : maxIter = 50 <= iter = 16\n",
|
||||
"0 : probSize = 1000 <= bindingSet = 1\n",
|
||||
"1 : phi_d = 1.5077e+01 <= phi_d_target = 2.0000e+01 \n",
|
||||
"------------------------- DONE! -------------------------\n",
|
||||
"-------------------------STOP!-------------------------\n",
|
||||
"0 : maxIter = 10 <= iter = 1\n",
|
||||
"1 : phi_d = 1.5077e+01 <= phi_d_target = 2.0000e+01 \n",
|
||||
"-------------------------DONE!-------------------------\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 8
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"# First set up the figure, the axis, and the plot element we want to animate\n",
|
||||
"fig = plt.figure()\n",
|
||||
"ax = plt.axes()\n",
|
||||
"ax.plot(M.vectorCCx, m_true, 'b-')\n",
|
||||
"txt = plt.text(0.8,0.9,'')\n",
|
||||
"line, = ax.plot([], [], 'r-', lw=1)\n",
|
||||
"\n",
|
||||
"def animate(i):\n",
|
||||
" txt.set_text('iteration %d'%i)\n",
|
||||
" line.set_data(M.vectorCCx, np.array(opt.recall('xc')[i]))\n",
|
||||
"\n",
|
||||
"SimPEG.utils.animate(fig, animate, frames=len(opt.recall('xc')))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"html": [
|
||||
"<video controls loop>\n",
|
||||
" <source src=\"data:video/x-m4v;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAALXFtZGF0AAACoQYF//+d\n",
|
||||
"3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDEyNSAtIEguMjY0L01QRUctNCBBVkMgY29kZWMg\n",
|
||||
"LSBDb3B5bGVmdCAyMDAzLTIwMTIgLSBodHRwOi8vd3d3LnZpZGVvbGFuLm9yZy94MjY0Lmh0bWwg\n",
|
||||
"LSBvcHRpb25zOiBjYWJhYz0xIHJlZj0zIGRlYmxvY2s9MTowOjAgYW5hbHlzZT0weDM6MHgxMTMg\n",
|
||||
"bWU9aGV4IHN1Ym1lPTcgcHN5PTEgcHN5X3JkPTEuMDA6MC4wMCBtaXhlZF9yZWY9MSBtZV9yYW5n\n",
|
||||
"ZT0xNiBjaHJvbWFfbWU9MSB0cmVsbGlzPTEgOHg4ZGN0PTEgY3FtPTAgZGVhZHpvbmU9MjEsMTEg\n",
|
||||
"ZmFzdF9wc2tpcD0xIGNocm9tYV9xcF9vZmZzZXQ9LTIgdGhyZWFkcz0xMiBsb29rYWhlYWRfdGhy\n",
|
||||
"ZWFkcz0yIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVy\n",
|
||||
"YXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9h\n",
|
||||
"ZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MiBr\n",
|
||||
"ZXlpbnQ9MjUwIGtleWludF9taW49MjAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xv\n",
|
||||
"b2thaGVhZD00MCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIzLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFw\n",
|
||||
"bWF4PTY5IHFwc3RlcD00IGlwX3JhdGlvPTEuNDAgYXE9MToxLjAwAIAAAAlFZYiEAFf9EwAD0rwK\n",
|
||||
"a/s12U1hg0FMgMmMOVNcwAAAAwANFchWCs4PnSPLHgxFeZ2MBPwOINxDCInVnrlTnaSkcTqCnVwZ\n",
|
||||
"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\n",
|
||||
"\" type=\"video/mp4\">\n",
|
||||
" Your browser does not support the video tag.\n",
|
||||
"</video>"
|
||||
],
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 9,
|
||||
"text": [
|
||||
"<matplotlib.animation.FuncAnimation at 0x10ee35450>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 9
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"plot(opt.recall('phi_d'))"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 10,
|
||||
"text": [
|
||||
"[<matplotlib.lines.Line2D at 0x10eb01450>]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEACAYAAAC08h1NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHg5JREFUeJzt3XtwVGWCxuFfIlcFlAIJOqEhQkgnoCRAp4MsJDBymXFj\ngiyFzHqpSdjSOEwEYcpdpUqc2nKKi8WANQSWmTjlWmKxO+OKyDXMNBgv3cEwKBDkbkCFAEHoQIIY\nzv5xTHMLkDSdnO4+71PVReju0/1Gi/d0f+f7zokxDMNARERsI9bqACIi0rpU/CIiNqPiFxGxGRW/\niIjNqPhFRGxGxS8iYjM3LP68vDzi4uK4//77A/f5/X5ycnJwOBzk5uZSU1MTeGzx4sUkJiaSkpJC\naWlp4P6KigoGDx7Mfffdx0svvdQCv4aIiDTVDYv/l7/8JevWrbvivqKiIhwOB3v37iU+Pp6lS5cC\nUFVVxZIlS9i0aRNFRUUUFhYGtpk5cyYvvPACZWVlbN68ma1bt7bAryIiIk1xw+IfMWIEXbt2veI+\nn89Hfn4+7du3Jy8vD6/XC4DX62X8+PE4HA4yMzMxDCPwbeDLL79k8uTJdOvWjUcffTSwjYiItL5m\nj/GXlZXhdDoBcDqd+Hw+wCz+5OTkwPOSkpLwer3s27ePHj16BO5PSUnh008/vdXcIiISpGYXf3PO\n8BATE3NL24uISOi1ae4GLpeLiooK0tLSqKiowOVyAeB2uykpKQk8b/fu3bhcLjp37syxY8cC9+/a\ntYuMjIxGX7tfv37s37+/uZFERGytb9++7Nu3r8nPb/YnfrfbTXFxMbW1tRQXFwdKPD09nfXr11NZ\nWYnH4yE2NpbOnTsD5pDQO++8w4kTJ3j33Xdxu92Nvvb+/fsxDCPsby+//LLlGaIlZyRkVE7lDPdb\ncz8w37D4p0yZwoMPPsiePXvo1asXb7zxBgUFBVRWVpKUlMTXX3/NM888A0BcXBwFBQWMHj2aZ599\nlkWLFgVeZ8GCBcybNw+Xy8WIESMYOnRos0KKiEjo3HCoZ8WKFY3e/9577zV6/3PPPcdzzz13zf0p\nKSmUl5cHEU9EREJNK3eDkJWVZXWEJomEnJGQEZQz1JTTWjGGYYTNNJuYmBjCKI6ISERobnfqE7+I\niM2o+EVEbEbFLyJiMyp+ERGbUfGLiNiMil9ExGZU/CIiNhN2xX/ihNUJRESiW9gVv07VLyLSssKu\n+D/5xOoEIiLRTcUvImIzYXeuns6dDaqroU2zLxEjImJPEX+unp/8BHbssDqFiEj0CrviHzZMwz0i\nIi1JxS8iYjMqfhERmwm74k9JgePHzZuIiIRe2BV/bCykp2shl4hISwm74gcN94iItCQVv4iIzYTd\nAi7DMDh1ChwOOHVKC7lERG4m4hdwAXTtCr16wRdfWJ1ERCT6hGXxg4Z7RERaiopfRMRmVPwiIjYT\ntsWfnGxejauqyuokIiLRJWyLPzYW3G4t5BIRCbWwLX7QcI+ISEtQ8YuI2ExYLuBq8N135nx+LeQS\nEbm+qFjA1eCuu8wVvJ9/bnUSEZHoEdbFDxruEREJNRW/iIjNqPhFRGwm6OJfvnw5Dz74IEOGDGH6\n9OkA+P1+cnJycDgc5ObmUlNTE3j+4sWLSUxMJCUlhdLS0ia/j9MJ1dVayCUiEipBFX91dTWvvvoq\nGzdupKysjD179rB+/XqKiopwOBzs3buX+Ph4li5dCkBVVRVLlixh06ZNFBUVUVhY2PSAPy7k0qd+\nEZHQCKr4O3bsiGEYnD59mtraWs6dO8ddd92Fz+cjPz+f9u3bk5eXh9frBcDr9TJ+/HgcDgeZmZkY\nhoHf72/y+2m4R0QkdIIu/qKiIvr06UPPnj0ZPnw4brebsrIynE4nAE6nE5/PB5jFn5ycHNg+KSkp\n8FhTqPhFREInqGVRx48fp6CggF27dtG1a1cmTZrE6tWrm7WAICYmptH758yZE/g5KyuLrKws3G74\n7DO4cAHatg0msYhI9PB4PHg8nqC3D6r4fT4fGRkZ9OvXD4BJkybx4Ycf4nK5qKioIC0tjYqKClwu\nFwBut5uSkpLA9rt37w48drXLi7/BnXdCnz7mQq4hQ4JJLCISPRo+FDd45ZVXmrV9UEM9I0aMYOvW\nrVRXV3P+/HnWrl3L2LFjcbvdFBcXU1tbS3FxMRkZGQCkp6ezfv16Kisr8Xg8xMbG0rlz52a9p4Z7\nRERCI6hP/F26dGH27NlMmDCBc+fOMX78eEaNGkV6ejqPP/44SUlJDB48mLlz5wIQFxdHQUEBo0eP\npl27dixbtqzZ7zlsGGzaBNOmBZNYREQahPVJ2i5XUQEPPwwHDrRyKBGRMBdVJ2m7XFKSebbOY8es\nTiIiEtkipvi1kEtEJDQipvhBB3hFREJBxS8iYjMRc3AX4MwZuPde84pcWsglImKK2oO7AF26QEIC\nbN9udRIRkcgVUcUPGu4REblVKn4REZtR8YuI2EzEFX///nD6NBw9anUSEZHIFHHFHxsLGRn61C8i\nEqyIK37QcI+IyK1Q8YuI2ExELeBq0LCQq7oa2rVrhWAiImEsqhdwNejSBe67Twu5RESCEZHFDxru\nEREJlopfRMRmVPwiIjYTscXfvz/4/fDtt1YnERGJLBFb/DExWsglIhKMiC1+0HCPiEgwVPwiIjYT\nkQu4Gvj9cM89WsglIvZmiwVcDTp3hr594R//sDqJiEjkiOjiBw33iIg0l4pfRMRmVPwiIjYT8cWf\nmAhnz8I331idREQkMkR88Wshl4hI80R88YOGe0REmkPFLyJiMxG9gKtBTQ3ExcGpU1rIJSL2Y6sF\nXA06dTIP8m7bZnUSEZHwFxXFDxruERFpKhW/iIjNBF38Z8+e5amnnqJ///6kpKTg9Xrx+/3k5OTg\ncDjIzc2lpqYm8PzFixeTmJhISkoKpaWlIQl/ORW/iEjTBF38L7/8Mg6Hg88//5zPP/8cp9NJUVER\nDoeDvXv3Eh8fz9KlSwGoqqpiyZIlbNq0iaKiIgoLC0P2CzTo1w9qa+Hrr0P+0iIiUSXo4i8pKeHF\nF1+kQ4cOtGnThjvvvBOfz0d+fj7t27cnLy8Pr9cLgNfrZfz48TgcDjIzMzEMA7/fH7JfArSQS0Sk\nqYIq/iNHjlBXV0dBQQFut5u5c+dSW1tLWVkZTqcTAKfTic/nA8ziT05ODmyflJQUeCyUNNwjInJz\nQRV/XV0de/bsYeLEiXg8Hnbu3MnKlSubNY80JiYmmLe+IRW/iMjNtQlmo379+pGUlER2djYAU6ZM\n4c0338TlclFRUUFaWhoVFRW4XC4A3G43JSUlge13794deOxqc+bMCfyclZVFVlZWk3O5XLB9O5w/\nD+3bN//3EhGJBB6PB4/HE/T2Qa/cfeSRR3jppZdwuVwUFhaSlpbGyZMnOXz4MPPmzWPWrFkkJCQw\na9Ysjh07RmZmJhs2bODAgQM8//zzlJeXXxsmyJW7l0tLg6Iic7xfRMQOmtudQX3iB1iwYAFPPvkk\ndXV1PPTQQzz22GNcvHiRxx9/nKSkJAYPHszcuXMBiIuLo6CggNGjR9OuXTuWLVsW7NveVMNwj4pf\nRKRxUXGunsv993/D++/DypUhCiUiEuZsea6ey+kAr4jIjUVd8fftC3V1cOSI1UlERMJT1BV/TIw+\n9YuI3EjUFT+o+EVEbkTFLyJiM1E3qwfg7Fno0QOqq7WQS0Sin+1n9QDccQckJUEja8RERGwvKosf\nNNwjInI9Kn4REZtR8YuI2EzUFv9998H338Phw1YnEREJL1Fb/DExkJkJGzdanUREJLxEbfED5OTA\ne+9ZnUJEJLxE5Tz+BqdOQe/e8O235hRPEZFopHn8l+naFdLTYf16q5OIiISPqC5+gAkT4P/+z+oU\nIiLhI6qHesCc1ZOaCkePQtu2IX1pEZGwoKGeq/TqZU7t3LLF6iQiIuEh6osfNNwjInK5qB/qAdi1\nC8aNg8pKc36/iEg00VBPI5KToWNHna1TRARsUvwxMZCbC+++a3USERHr2aL4QeP8IiINbFP8bjec\nOAF791qdRETEWrYp/thYnbtHRARsVPygcX4REbDJdM4G589DXBzs3g09e7bY24iItCpN57yB9u1h\n/Hh4/32rk4iIWMdWxQ/mcI9m94iIndlqqAfgzBmIj4cjR6BLlxZ9KxGRVqGhnpvo0gWGD4d166xO\nIiJiDdsVP2i4R0TszXZDPWBeijElBY4dg3btWvztRERalIZ6muCee8wTt/3971YnERFpfbYsftBw\nj4jYly2HegD27IGsLHN2T6xtd38iEg1adainvr6etLQ0srOzAfD7/eTk5OBwOMjNzaWmpibw3MWL\nF5OYmEhKSgqlpaW38rYh0b8/3HUX+HxWJxERaV23VPyLFi0iJSWFmB8va1VUVITD4WDv3r3Ex8ez\ndOlSAKqqqliyZAmbNm2iqKiIwsLCW08eAjpVs4jYUdDFf+TIEdasWcPUqVMDXzF8Ph/5+fm0b9+e\nvLw8vF4vAF6vl/Hjx+NwOMjMzMQwDPx+f2h+g1ugcX4RsaOgi3/GjBnMnz+f2MsGyMvKynA6nQA4\nnU58P46jeL1ekpOTA89LSkoKPGalIUOgpsY8aZuIiF0EVfyrV6+mR48epKWlXXFAoTkHF2LC4Krn\nsbE6VbOI2E+bYDb6+OOPWbVqFWvWrKGuro4zZ87wxBNP4HK5qKioIC0tjYqKClwuFwBut5uSkpLA\n9rt37w48drU5c+YEfs7KyiIrKyuYiE2WmwsvvQT/8R8t+jYiIiHj8XjweDxBb3/L0zk3b97MggUL\neP/995k3bx6HDx9m3rx5zJo1i4SEBGbNmsWxY8fIzMxkw4YNHDhwgOeff57y8vJrw7TidMLine truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x11030ec90>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 10
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,142 +0,0 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "VisualizeWithvtkView-updated"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import SimPEG as simpeg, matplotlib as mpl"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"The history saving thread hit an unexpected error (OperationalError('disk I/O error',)).History will not be written to the database.\n",
|
||||
"Warning: mumps solver not available."
|
||||
]
|
||||
},
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 1
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Simple notebook of how to use vtkView to visualize SimPEG models. It will pop-up external vtk windows."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"# Make a mesh and model\n",
|
||||
"x0 = np.zeros(3)\n",
|
||||
"h1 = np.ones(60)*50\n",
|
||||
"h2 = np.ones(60)*100\n",
|
||||
"h3 = np.ones(50)*200\n",
|
||||
"\n",
|
||||
"mesh = simpeg.mesh.TensorMesh([h1,h2,h3],x0)\n",
|
||||
"\n",
|
||||
"# Make a models that correspond to the cells, faces and edges.\n",
|
||||
"t = np.ones(mesh.nC)\n",
|
||||
"t[10000:50000] = 100\n",
|
||||
"t[100000:120000] = 100\n",
|
||||
"t[100000:120000] = 50\n",
|
||||
"# Make models called 'Test' for all with a range. \n",
|
||||
"models = {'C':{'Test':np.arange(0,mesh.nC),'Model':t},'F':{'Test':np.arange(0,mesh.nF)},'E':{'Test':np.arange(0,mesh.nE)}}\n"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"# Make the vtk viewer object.\n",
|
||||
"vtkViewer = simpeg.visualize.vtk.vtkView(mesh,models)\n",
|
||||
"# Set the .viewprop for which model to view\n",
|
||||
"vtkViewer.viewprop = {'F':'Test'}\n",
|
||||
"# Show the image\n",
|
||||
"vtkViewer.Show()\n",
|
||||
"\n"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"# Set subset of the mesh to view (remove padding)\n",
|
||||
"vtkViewer.extent = [4,14,0,7,0,3]\n",
|
||||
"vtkViewer.Show()\n",
|
||||
"\n",
|
||||
"# Change viewing property \n",
|
||||
"vtkViewer.viewprop = {'C':'Model'}\n",
|
||||
"# Set the color range\n",
|
||||
"# Reset extent. Error check will reset the limits correctly.\n",
|
||||
"vtkViewer.extent = [-1,1000,-1,1000,-1,1000]\n",
|
||||
"# Set the range\n",
|
||||
"vtkViewer.range = [0.,100.]\n",
|
||||
"# Show\n",
|
||||
"vtkViewer.Show()\n"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stderr",
|
||||
"text": [
|
||||
"/home/Gudni/Codes/python/simpeg/SimPEG/visualize/vtk/vtkView.py:116: UserWarning: Lower bounds smaller then 0\n",
|
||||
" warnings.warn('Lower bounds smaller then 0')\n",
|
||||
"/home/Gudni/Codes/python/simpeg/SimPEG/visualize/vtk/vtkView.py:128: UserWarning: Upper bounds greater then number of cells\n",
|
||||
" warnings.warn('Upper bounds greater then number of cells')\n",
|
||||
"/home/Gudni/Codes/python/simpeg/SimPEG/visualize/vtk/vtkView.py:137: UserWarning: Changed given extent from [-1, 1000, -1, 1000, -1, 1000] to [0, 59, 0, 59, 0, 49]\n",
|
||||
" warnings.warn('Changed given extent from {:s} to {:s}'.format(value,valnp.tolist()))\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"# Change color scale, has to be set to bytes=True.\n",
|
||||
"vtkViewer.cmap = mpl.cm.copper(np.arange(0.,1.,0.01),bytes=True)\n",
|
||||
"vtkViewer.Show()\n",
|
||||
"# Set limits of values to view \n",
|
||||
"vtkViewer.limits = [5.0,100.0]\n",
|
||||
"vtkViewer.Show()"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 5
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": ""
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import sys\n",
|
||||
"sys.path.append('../')\n",
|
||||
"\n",
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from SimPEG import LogicallyOrthogonalMesh, utils\n",
|
||||
"mkvc = utils.mkvc"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Test 2D Plots\n",
|
||||
"\n",
|
||||
"For 2D nodal or cell-centered plots are supported.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"X, Y = utils.exampleLomGird([3,3],'rotate')\n",
|
||||
"M = LogicallyOrthogonalMesh([X, Y])"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"M.plotGrid()"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10b6cc110>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 6
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Test 3D Plots\n",
|
||||
"\n",
|
||||
"Plot x, y, and z coordinates of cell-centred points"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"X, Y, Z = utils.exampleLomGird([3,3,3],'rotate')\n",
|
||||
"M = LogicallyOrthogonalMesh([X, Y, Z])"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 8
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"M.plotGrid()"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "iVBORw0KGgoAAAANSUhEUgAAAV0AAADtCAYAAAAcNaZ2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXeYVPX1/1+3TNvZAuzSOyzbaYJiwYao2BNFEzWaX2KM\n38fE3omICApYIipKULGXSFEQMYASBSO9CNvoxQbSt0675ffHZ++U3Znd2YaSzPt59gGWmTv3zr33\nfc/nfc55H8k0TZMEEkgggQSOC+SfewcSSCCBBP6XkCDdBBJIIIHjiATpJpBAAgkcRyRIN4EEEkjg\nOCJBugkkkEACxxEJ0k0ggQQSOI5IkG4CCSSQwHFEgnQTSCCBBI4jEqSbQAIJJHAckSDdBBJIIIHj\niATpJpBAAgkcRyRIN4EEEkjgOCJBugkkkEACxxEJ0k0ggQQSOI5IkG4CCSSQwHFEgnQTSCCBBI4j\nEqSbQAIJJHAckSDdBBJIIIHjiATpJpBAAgkcRyRIN4FmQ9d1NE0jMW4vgQQahvpz70ACJyZM08Q0\nTQKBAH6/H03TkCQJAEVRsNlsKIqCLMvIshz8vwQS+F9HgnQTaBTCybaqqgpZllFVFUmSkGUZn8+H\npmnouh7xPlmWURQl+JMg4wT+VyElRrAnEA/CydYwDACqq6sxDANd1zFNM0igkiRhs9mCxFp7G+FI\nkHEC/2tIkG4C9cI0TQzDQNM0DMNAkiQMw8Dn8+H1elEUBdN00aVLMoYhMX58BVlZGjk5Oh07aoAZ\njIItgq1NqoZhRJA2JMg4gf9eJOSFBKIiGtmaponH48Hv92O32/H7Hbz+uovp0x0YhiDD775T+fxz\nJ1u3Kvh8Ejk5Ojk5OtnZGllZGtnZAdLTfYAZJNJwQrVINVwvTpBxAv9NSES6CUTANM2IagRJktB1\nHZ/Ph9/vx+Fw4PM5+cc/bLz4osxZZ2k8+KDOmjUmK1famDq1DACHw8HhwxKlpXLwZ8sWmZISGdOU\nyM3Vyc7WycnRyM7W6NfPT7t2QqaoTcbhpGpJFLUjYyuattvtQWIOJ/EEEvilIBHpJgBEJ1vTNKmu\nriYQCOBwOND1NJ56ysbLLyuMGmXw6aeVZGbqOBwO1q8HTSP4PoD0dJPhw3WGD9fDPgcOHgwnYxsf\nfeRgy5ZUVNUkN9cIi4wDZGUFSEuLTsbhpKppGl6vN6KKAqgTFSfIOIGfGwnS/R9HQ2TrdDqpqkri\nmWdsvPaawuWXGyxf7qdvX/B4DKx1kqpCrYKFqJAk6NDBpEMHnbPPjiTj/fslSkoEGW/ebOODD5xs\n2SLjdpvk5Bg1UoUg4379AiQnh8g4nOzDSbV2os/6M5yMw3XmBBkn0NpIkO7/KKKRrWEYeDweNE3D\n6XRSUeFmyhSVN99UGD3aYOVKPz171t0OxE+6sSBJ0LmzSefOOuedF0nG338vBeWJNWvsvPmmk23b\nZNq0sSJjIU/06xcgJ0fD5YodGVvVFNGqLoAEGSfQ6kiQ7v8YrASVVUcbjWyPHUtmwgSV999XuO46\nnbVr/XTrVndbkWRlomktv7+SBN27m3TvrnPBBToQAMAw4NtvLZlC4euvHbz6qosdO1Q6dDBrJIpQ\nZJyZGcDhMBqUKSwyrg2LhFVVjfq+BBKIFwnS/R+BaZpomoamaZSXl5OcnIxpmni9XnRdx+l0cvhw\nMo88YmPOHJnf/15n40Y/nTrFt31FAU07fgQky9Crl0mvXjoXXSQi9kAggN3uYvduiS1bFEpLZZYu\ndfDiiy527pTp3NkkLy+ykqJPHz82m1GzTTmiIiJctrDI2O/31zpuJdggkoiME4gHCdL9L0c42Yaj\nqqoK0zRxOp0cOJDCk0+qLFggc9NNOps3+2nfvnGfEy4v/JwFMYoCmZkmmZkal14a+r2mwa5dclAz\nXrzYydSpSezZI9O9u0FOjkF2tkZOjoammQwd6qNLFy2ixjgWGXu9XgBsNhsQqqRIRMYJREOCdP9L\nEY1srQy/YRg4nU6++y6JKVNUFi+WueUWnaIiP+3axf8Z4ckrVQ1VL/wSoaqQlWWQlWXwq1+Ffu/3\nw44dgog3blT4059cwf+zaozDqyl69vQhy0YEGVvfQUORcYKME4AE6f7XIRbZejweAJxOJyUlMtOm\nJbNsmcqtt+o8+6yftLSmf6YkSaiq0axE2s8Fux0yMw2+/lph9myVyy4LsHevzE03BRgyRA+Wts2a\n5aK01M3+/RKZmUZQM87ODtCvn5/u3TV0vSquyDgWGYdLFAky/u9FgnT/S2DdzLHI1uVyUVxsZ8oU\nla+/lrjttgDTp/tJSWmZz5dlWiWR1prQNPjnP1UmT3aQlWXw/vseTjrJ4E9/cuJymQwYYDBggBHx\nnqoq2LrVavZQeOcdGyUlbo4ckcnMNMjNtZJ3QjPu0sUHGHGRsc/ni/is2qVt4e9L4MRFgnRPcFit\nuuEZ90AgENQZXS4X33xjZ/JklY0bZe66S2fq1KO0a+fAbrc367PrygsnRlRmGPDhhypPPOGgY0eD\nl1/2cvrpoe9P18VDJBrcbjjpJIOTTjIA8ZTx+XxUVkrs2uWs6bpT+eorO1u2yJSXS2RlhWqMLZmi\nUycfphmbjEP7otfR4y0yDpcorKaPBH75SJDuCYpYZOvxeJBlGZfLxdq1diZPtlFSInHvvRrvvqvh\nckFFRcvvT3PrdI8HTBM+/VRl4kQ7Tic8/bSXc8/Vqc1VpikSco1BSgqcfLLBySeHyBjg2DGClRSl\npSr//redkhIZr9fypRAJPPETICOjcWRslQBarm7hZBzNXCiBnx8J0j3BYBhGhL0igN/vx+v1Issy\nSUluVq60M2mSyu7dEvfdpzFnjoHDEdpGeITaUrBItzW23VyYJvz73woTJjjw+2HsWB8XXVSXbC0Y\nRuxIt7Fo0wZOPVXn1FMjn0iHD4fIuKRE5V//slNaKqPrUo1EoQfJuF8/P+np/mAjR3h0CwRL/qy/\n1+4uDCfjhEnQz48E6Z4AiOZlCyGyVRSFpCQ3L77o5KGHxCm94gqdTz7R6NvXbDECqQ+t1RzRXKxY\nofDYY3YOHJD52998/PrXWoPfR0uSbiykp8MZZ+iccUYkGR88GGqF3rLFxvz5DkpLQ74UInknomLL\nlwIIrnCimQRBXTIGgq9LkPHxRYJ0f8EIJ9vKykpsNhs2my3oZauqKm53Mp9/bmfSJIXSUnGz3Hab\nxtatMqNG2Sgvh7w8k7w8k4ICk/x8g969JTp2bH40Gh7ViuaIZm+yxbB+vczEiQ527JB58EEfv/mN\nhhrn1V6fptvaaN/e5Oyzo/tSWJUUhYU2Zs0S+nFSkklWVoD8fCJMgsJ9KeIh43Ak7DNbFwnS/QWi\ntpet9Tu/3091dXUN2abwr3/ZmTxZIRCABx/UGTXKoFs3O089pQPipj16FIqLJYqLJYqKZObOVSkq\naoPTCQUFUFBgBAk5N9fE7W7aPtts0i9C0y0ulnn8cTsbNijce6+fG28M0Nh8oWFIKEr8DyWL3FoL\n4b4UI0ZEkvG33xps3mywe7eLdevsvP22k61bhS+FMAnS+OEHiaoqiRkzymL6UtQmVavDLxwJMm4Z\nJEj3F4RYxuE+n49AIICiKLjdqXz8sY3JkxVsNnjoIZ1LLzWQZRGh+XziZrTug7ZtYfhwk+HDTUAQ\neGVlFfv3q+zc6aKoSGLZMpnp0yW2bZPo3FkQcX6+SX6+IOPMTLPBKPHnrl7YuVPmiSdS+c9/7Nx1\nl5+ZM724XA2/LxoMg5h67y8JkgRduxp06BDA5VKp7UuxaZPCnXc6OHxYPBAKCjLIyDCDXsaWTNG3\nbwCnM7ovRUNkbK3GHA5HgozjRIJ0fwGIZa/o9Xrx+XzYbDYkyca8eS7+/ncnaWkwYYKIbMOva0UR\nP4EA9UZ3sizRtatBZqbBhReGfq9psGOHFRVLzJol88gjMvv2QVZWSKIoKDDJyzPo1ClUYypJ+s8i\nL3z7rcSUKXY+/VTl5purmTYt0Oza4+Oh6bY2Vq8WicNTT9Xp1ElIK5Mn+9izR/hSlJTIfPGFg+nT\nhS9Fp051ybhPnwB2e/1kbJGwoiiJyDhOJEj3Z0RDZGu323G5Upk1y8bkyTIdOpg884zGeeeZMSMx\nh0NEu00pwVVVyMkxyckxueqq0O+rqqC0VBBxSYnE0qUKxcUqPp+drCwbOTkaaWkq334rs3+/jzZt\nRHQeK1pqCezfL/HUU3bmzLFx001+1q4tx+3242pqeBuGE5l0ly1TGDvWgaLAjBlezjhD59ln7Rw5\nIqEo0LevSd++GpdcEnqP5UthacaLFzuYOtXFnj0y3boJxzZByEIz7t07gKpGzrXTNC1mZJwYuRSJ\nBOn+DIhGtiCm61rzx1yuNN55R+Xpp1V69TJ57rlqTj89gNudVO+2nU7weqk32mtsWZfbDUOHmgwd\nKt5jGAF8Ph/ff+9j61Ybu3a5+fxzwVInn9yR1FSDvDyrM8tPTo6P7GyDpKTYlorx4vBhiWeftfPW\nWzZ+97sA69dXkZFhomkmtQKtJuNEIl3r+ikpkRk71sH27TKPPiqqNKyv1usFpzP2+Q73pbjiitDv\n/X4h21jVFB9/7KC01MV338n06iVMgrKyhI9xXp5Bz55+ZDnk2Bar++5/ff5dgnSPI2JFttawR4fD\ngcORxltvCbLNzTV57bUAp59u4vFoxMOTVqTbWvvv9Xrxer3YbDZ69HDRoYOXSy4xufJKL6eeqrB1\nazk7dgTYs8dNcbHC8uVuZsyQ2bXLcvPSyM0NkJ0tfnr3NrHZYjcBWCgrgxdesPPKK3auvDLAqlVV\ndOnSOvXAhtG45oifsy75xx8lJk9OZskSB/fc4+f99+smDr1eSE1t/LbtdsjNNcjNjWyF9nLine truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10d796110>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 9
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 42
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": ""
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"import sys\n",
|
||||
"sys.path.append('../')\n",
|
||||
"\n",
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from SimPEG import TensorMesh\n",
|
||||
"%pylab inline"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"Populating the interactive namespace from numpy and matplotlib\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 1
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Test 1D Plots\n",
|
||||
"\n",
|
||||
"For 1D nodal or cell-centered plots are supported.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"x0 = np.zeros(1)\n",
|
||||
"h = np.random.rand(32)\n",
|
||||
"mesh = TensorMesh([h],x0)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"ax1 = plt.subplot()\n",
|
||||
"ax1.set_title('sin(x) on CC grid')\n",
|
||||
"ph1 = mesh.plotImage(np.sin(mesh.gridCC),ax=ax1)\n",
|
||||
"ax2 = plt.subplot()\n",
|
||||
"ax2.set_title('sin(x) on N grid')\n",
|
||||
"ph2 = mesh.plotImage(np.sin(mesh.gridN), ax=ax2,imageType='N')"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10c1e9910>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10dd96ed0>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Test 2D Plots\n",
|
||||
"\n",
|
||||
"Plot x and y coordinates of cell-centred points"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"x0 = np.zeros(2)\n",
|
||||
"h1 = np.linspace(.1,.5,3)\n",
|
||||
"h2 = np.linspace(.1,.5,5)\n",
|
||||
"mesh = TensorMesh([h1,h2],x0)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"fig = plt.figure(1)\n",
|
||||
"ax1 = plt.subplot()\n",
|
||||
"ax1.set_title('mesh.gridCC[:,0]')\n",
|
||||
"mesh.plotImage(mesh.gridCC[:,0],ax = ax1)\n",
|
||||
"ax2 = plt.subplot()\n",
|
||||
"ax2.set_title('mesh.gridFx[:,1]')\n",
|
||||
"mesh.plotImage(mesh.gridFx[:,1],ax = ax2,imageType='Fx')"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10ddc1ad0>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10df9cf50>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 5,
|
||||
"text": [
|
||||
"<matplotlib.collections.QuadMesh at 0x10dfc4f50>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 5
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Test 3D Plots\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"x0 = np.zeros(3)\n",
|
||||
"h1 = np.linspace(.1,.5,3)\n",
|
||||
"h1 = np.r_[1,2,1]\n",
|
||||
"h2 = np.r_[1,3]\n",
|
||||
"h3 = np.linspace(.1,.5,10)\n",
|
||||
"\n",
|
||||
"mesh = TensorMesh([h1,h2,h3],x0)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 6
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"ax1 = plt.subplot()\n",
|
||||
"ax1.set_title('mesh.gridCC[:,0]')\n",
|
||||
"a1 = mesh.plotImage(mesh.gridCC[:,0],ax=ax1,annotationColor='w')\n",
|
||||
"ax2 = plt.subplot()\n",
|
||||
"ax2.set_title('mesh.gridFx[:,1]')\n",
|
||||
"a2 = mesh.plotImage(mesh.gridFx[:,1],ax=ax2,imageType='Fx')\n",
|
||||
"ax3 = plt.subplot()\n",
|
||||
"ax3.set_title('mesh.gridEz[:,2]')\n",
|
||||
"mesh.plotImage(mesh.gridEz[:,2],ax=ax3,imageType='Ez')"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10dfd5c50>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10dfa5990>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "display_data",
|
||||
"png": "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 truncated
|
||||
"text": [
|
||||
"<matplotlib.figure.Figure at 0x10f09be50>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 7,
|
||||
"text": [
|
||||
"<matplotlib.collections.QuadMesh at 0x10f2d2a90>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 7
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user