class SimPEG.regularization.JointTotalVariation(mesh, wire_map, eps=1e-08, **kwargs)[source]#

Bases: BaseSimilarityMeasure

Joint total variation regularization for joint inversion.

JointTotalVariation regularization aims to ensure non-zero gradients in the recovered model to occur at the same locations for all physical property distributions. It assumes structures within each physical property distribution are sparse and correlated with one another.

meshSimPEG.regularization.RegularizationMesh, discretize.base.BaseMesh

Mesh on which the regularization is discretized. This is not necessarily the same as the mesh on which the simulation is defined.

active_cellsNone, (n_cells, ) numpy.ndarray of bool

Boolean array defining the set of RegularizationMesh cells that are active in the inversion. If None, all cells are active.


Wire map connecting physical properties defined on active cells of the RegularizationMesh` to the entire model.

reference_modelNone, (n_param, ) numpy.ndarray

Reference model. If None, the reference model in the inversion is set to the starting model.

unitsNone, str

Units for the model parameters. Some regularization classes behave differently depending on the units; e.g. ‘radian’.

weightsNone, dict

Weight multipliers to customize the least-squares function. Each key points to a (n_cells, ) numpy.ndarray that is defined on the RegularizationMesh.


Needs documentation!!!


Consider the case where the model is comprised of two physical properties \(m_1\) and \(m_2\). Here, we define the regularization function (objective function) for joint total variation as (Haber and Gazit, 2013):

\[\phi (m_1, m_2) = \int_\Omega \, w(r) \, \Big [ \, \big | \nabla m_1 \big |^2 \, + \, \big | \nabla m_2 \big |^2 \, \Big ]^{1/2} \, dv\]

where \(w(r)\) is a user-defined weighting function.

For implementation within SimPEG, the regularization function and its variables must be discretized onto a mesh. The discretized approximation for the regularization function (objective function) is given by:

\[\phi (m_1, m_2) \approx \sum_i \tilde{w}_i \, \bigg [ \, \Big | (\nabla m_1)_i \Big |^2 \, + \, \Big | (\nabla m_2)_i \Big |^2 \, \bigg ]^{1/2}\]

where \((\nabla m_1)_i\) are the gradients of property \(m_1\) defined on the mesh and \(\tilde{w}_i \in \mathbf{\tilde{w}}\) are amalgamated weighting constants that 1) account for cell dimensions in the discretization and 2) apply any user-defined weighting.

In practice, we define the model \(\mathbf{m}\) as a discrete vector of the form:

\[\begin{split}\mathbf{m} = \begin{bmatrix} \mathbf{m_1} \\ \mathbf{m_2} \end{bmatrix}\end{split}\]

where \(\mathbf{m_1}\) and \(\mathbf{m_2}\) are the discrete representations of the respective physical properties on the mesh. The discrete regularization function is therefore equivalent to an objective function of the form:

\[\phi (\mathbf{m}) = \mathbf{e}^T \Bigg ( \, \mathbf{W \, A} \bigg [ \sum_k (\mathbf{G \, m_k})^2 \bigg ] \; + \; \epsilon \mathbf{v}^2 \, \Bigg )^{1/2}\]

where exponents are computed elementwise,

  • \(\mathbf{e}\) is a vector of 1s,

  • \(\mathbf{W}\) is the weighting matrix for joint total variation regularization,

  • \(\mathbf{A}\) averages vectors from faces to cell centers,

  • \(\mathbf{G}\) is the cell gradient operator (cell centers to faces),

  • \(\mathbf{v}\) are the cell volumes, and

  • \(\epsilon\) is a constant added for continuous differentiability (set with the eps property),

Custom weights and the weighting matrix:

Let \(\mathbf{w_1, \; w_2, \; w_3, \; ...}\) each represent an optional set of custom cell weights. The weighting applied within the objective function is given by:

\[\mathbf{\tilde{w}} = \mathbf{v} \odot \prod_j \mathbf{w_j}\]

where \(\mathbf{v}\) are the cell volumes. The weighting matrix used to apply weights within the regularization is given by:

\[\boldsymbol{W} = \textrm{diag} \Big ( \, \mathbf{\tilde{w}}^2 \Big )\]

Each set of custom cell weights is stored within a dict as an (n_cells, ) numpy.ndarray. The weights can be set all at once during instantiation with the weights keyword argument as follows:

>>> reg = JointTotalVariation(
>>>     mesh, wire_map, weights={'weights_1': array_1, 'weights_2': array_2}
>>> )

or set after instantiation using the set_weights method:

>>> reg.set_weights(weights_1=array_1, weights_2=array_2})

The default weights that account for cell dimensions in the regularization are accessed via:

>>> reg.get_weights('volume')



Weighting matrix for joint total variation regularization.


Active cells defined on the regularization mesh.


Deprecated property for 'volume' and user defined weights.


active_cells.indActive has been deprecated.


Mapping from the inversion model parameters to the regularization mesh.


The model parameters.


reference_model.mref has been deprecated.


Number of model parameters.


The parent objective function


Reference model.


regularization_mesh.regmesh has been deprecated.


Regularization mesh.


Units for the model parameters.


Return the keys for the existing cell weights


Mapping from model to physical properties defined on the regularization mesh.



Evaluate the joint total variation regularization function for the model provided.


Gradient of the regularization function evaluated for the model provided.

deriv2(model[, v])

Hessian of the regularization function evaluated for the model provided.


Not implemented for BaseRegularization class.


Not implemented for BaseRegularization class.


Cell weights for a given key.


alias of IdentityMap


Removes the weights for the key provided.


Adds (or updates) the specified weights to the regularization.

test([x, num])

Run a convergence test on both the first and second derivatives.