Petrophysically guided inversion: Joint linear example with nonlinear relationships#

We do a comparison between the classic least-squares inversion and our formulation of a petrophysically guided inversion. We explore it through coupling two linear problems whose respective physical properties are linked by polynomial relationships that change between rock units.

Problem 1, Problem 2, Petrophysical Distribution, Problem 1, Problem 2, Petrophysical Distribution, Problem 1, Problem 2, Petro Distribution
Running inversion with SimPEG v0.24.1.dev27+ge1af3e81a
simpeg.InvProblem will set Regularization.reference_model to m0.
simpeg.InvProblem will set Regularization.reference_model to m0.
simpeg.InvProblem will set Regularization.reference_model to m0.

                    simpeg.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.
                    ***Done using the default solver Pardiso and no solver_opts.***

Alpha scales: [np.float64(3.4732325724342), np.float64(0.0), np.float64(3.4873412732152422e-06), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09674557 0.90325443]
<class 'simpeg.regularization.pgi.PGIsmallness'>
Initial data misfit scales:  [0.09674557 0.90325443]
model has any nan: 0
=============================== Projected GNCG ===============================
  #     beta     phi_d     phi_m       f      |proj(x-g)-x|  LS    Comment
-----------------------------------------------------------------------------
x0 has any nan: 0
   0  2.51e+01  3.00e+05  0.00e+00  3.00e+05    1.41e+02      0
geophys. misfits: 1604.8 (target 30.0 [False]); 129.6 (target 30.0 [False]) | smallness misfit: 3102.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [1604.8  129.6]; minimum progress targets: [240000. 240000.]
   1  2.51e+01  2.72e+02  3.96e+01  1.27e+03    9.64e+01      0
geophys. misfits: 681.2 (target 30.0 [False]); 41.0 (target 30.0 [False]) | smallness misfit: 1471.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [681.2  41. ]; minimum progress targets: [1283.8  103.7]
   2  2.51e+01  1.03e+02  3.90e+01  1.08e+03    5.81e+01      0   Skip BFGS
geophys. misfits: 648.4 (target 30.0 [False]); 40.3 (target 30.0 [False]) | smallness misfit: 1437.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [648.4  40.3]; minimum progress targets: [545.   32.8]
Decreasing beta to counter data misfit decrase plateau.
   3  1.25e+01  9.91e+01  3.91e+01  5.90e+02    9.02e+01      0
geophys. misfits: 274.5 (target 30.0 [False]); 33.1 (target 30.0 [False]) | smallness misfit: 1501.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [274.5  33.1]; minimum progress targets: [518.7  32.2]
   4  1.25e+01  5.64e+01  4.15e+01  5.77e+02    5.52e+01      0
geophys. misfits: 272.5 (target 30.0 [False]); 32.9 (target 30.0 [False]) | smallness misfit: 1497.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [272.5  32.9]; minimum progress targets: [219.6  30. ]
Decreasing beta to counter data misfit decrase plateau.
   5  6.27e+00  5.61e+01  4.15e+01  3.16e+02    8.36e+01      0   Skip BFGS
geophys. misfits: 112.6 (target 30.0 [False]); 27.0 (target 30.0 [True]) | smallness misfit: 1774.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [112.6  27. ]; minimum progress targets: [218.  30.]
Updating scaling for data misfits by  1.1091383263554575
New scales: [0.10618307 0.89381693]
   6  6.27e+00  3.61e+01  4.38e+01  3.11e+02    7.50e+01      0
geophys. misfits: 103.7 (target 30.0 [False]); 27.2 (target 30.0 [True]) | smallness misfit: 1745.7 (target: 200.0 [False])
Beta cooling evaluation: progress: [103.7  27.2]; minimum progress targets: [90.1 30. ]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.1039453915914745
New scales: [0.11594065 0.88405935]
   7  3.14e+00  3.61e+01  4.39e+01  1.74e+02    7.69e+01      0   Skip BFGS
geophys. misfits: 58.3 (target 30.0 [False]); 22.2 (target 30.0 [True]) | smallness misfit: 2147.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [58.3 22.2]; minimum progress targets: [83. 30.]
Updating scaling for data misfits by  1.3528811144913078
New scales: [0.15068874 0.84931126]
   8  3.14e+00  2.76e+01  4.60e+01  1.72e+02    8.74e+01      0
geophys. misfits: 41.0 (target 30.0 [False]); 23.6 (target 30.0 [True]) | smallness misfit: 2071.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [41.  23.6]; minimum progress targets: [46.7 30. ]
Updating scaling for data misfits by  1.2700607693011543
New scales: [0.18390003 0.81609997]
   9  3.14e+00  2.68e+01  4.60e+01  1.71e+02    7.12e+01      0
geophys. misfits: 33.0 (target 30.0 [False]); 23.2 (target 30.0 [True]) | smallness misfit: 2126.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [33.  23.2]; minimum progress targets: [32.8 30. ]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.2912921516689961
New scales: [0.22539458 0.77460542]
  10  1.57e+00  2.54e+01  4.65e+01  9.84e+01    7.31e+01      0   Skip BFGS
geophys. misfits: 24.4 (target 30.0 [True]); 19.8 (target 30.0 [True]) | smallness misfit: 2583.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.4 19.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  1.3715168255447403
  11  1.57e+00  2.09e+01  5.01e+01  9.95e+01    5.93e+01      0
geophys. misfits: 24.4 (target 30.0 [True]); 19.9 (target 30.0 [True]) | smallness misfit: 1770.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.4 19.9]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  1.8790423790606863
  12  1.57e+00  2.09e+01  5.01e+01  9.95e+01    6.69e+01      0
geophys. misfits: 23.4 (target 30.0 [True]); 20.6 (target 30.0 [True]) | smallness misfit: 1579.7 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.4 20.6]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  2.574551292390448
  13  1.57e+00  2.12e+01  5.20e+01  1.03e+02    4.69e+01      0
geophys. misfits: 23.7 (target 30.0 [True]); 21.7 (target 30.0 [True]) | smallness misfit: 1334.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.7 21.7]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  3.4150979235328194
  14  1.57e+00  2.21e+01  5.36e+01  1.06e+02    6.15e+01      0
geophys. misfits: 23.9 (target 30.0 [True]); 22.8 (target 30.0 [True]) | smallness misfit: 1141.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.9 22.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  4.3878966767236545
  15  1.57e+00  2.31e+01  5.51e+01  1.09e+02    6.40e+01      0
geophys. misfits: 24.0 (target 30.0 [True]); 24.0 (target 30.0 [True]) | smallness misfit: 998.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [24. 24.]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  5.4819497322587125
  16  1.57e+00  2.40e+01  5.66e+01  1.13e+02    7.22e+01      0
geophys. misfits: 24.2 (target 30.0 [True]); 24.8 (target 30.0 [True]) | smallness misfit: 835.2 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.2 24.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  6.706018143679931
  17  1.57e+00  2.47e+01  5.76e+01  1.15e+02    8.87e+01      0
geophys. misfits: 24.5 (target 30.0 [True]); 25.9 (target 30.0 [True]) | smallness misfit: 708.7 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.5 25.9]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  7.993041105984709
  18  1.57e+00  2.56e+01  5.82e+01  1.17e+02    9.02e+01      0
geophys. misfits: 25.0 (target 30.0 [True]); 25.7 (target 30.0 [True]) | smallness misfit: 644.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [25.  25.7]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  9.465397841366356
  19  1.57e+00  2.55e+01  5.99e+01  1.19e+02    8.32e+01      0   Skip BFGS
geophys. misfits: 25.3 (target 30.0 [True]); 26.3 (target 30.0 [True]) | smallness misfit: 573.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [25.3 26.3]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  11.025262115573797
  20  1.57e+00  2.60e+01  6.12e+01  1.22e+02    9.13e+01      0
geophys. misfits: 24.8 (target 30.0 [True]); 25.5 (target 30.0 [True]) | smallness misfit: 492.2 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.8 25.5]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  13.148297439265052
  21  1.57e+00  2.54e+01  6.34e+01  1.25e+02    8.96e+01      0
geophys. misfits: 25.5 (target 30.0 [True]); 26.1 (target 30.0 [True]) | smallness misfit: 431.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [25.5 26.1]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  15.284762373267132
  22  1.57e+00  2.60e+01  6.46e+01  1.27e+02    8.76e+01      0
geophys. misfits: 26.8 (target 30.0 [True]); 26.3 (target 30.0 [True]) | smallness misfit: 389.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [26.8 26.3]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  17.287182280043
  23  1.57e+00  2.64e+01  6.59e+01  1.30e+02    8.07e+01      0   Skip BFGS
geophys. misfits: 27.0 (target 30.0 [True]); 26.8 (target 30.0 [True]) | smallness misfit: 359.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [27.  26.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  19.253922652703928
  24  1.57e+00  2.69e+01  6.70e+01  1.32e+02    9.49e+01      0
geophys. misfits: 27.3 (target 30.0 [True]); 27.2 (target 30.0 [True]) | smallness misfit: 337.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [27.3 27.2]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  21.198791736796903
  25  1.57e+00  2.72e+01  6.82e+01  1.34e+02    7.70e+01      0   Skip BFGS
geophys. misfits: 28.2 (target 30.0 [True]); 27.3 (target 30.0 [True]) | smallness misfit: 317.5 (target: 200.0 [False])
Beta cooling evaluation: progress: [28.2 27.3]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  22.9244372012882
  26  1.57e+00  2.75e+01  6.91e+01  1.36e+02    8.39e+01      0
geophys. misfits: 28.5 (target 30.0 [True]); 27.3 (target 30.0 [True]) | smallness misfit: 299.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [28.5 27.3]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  24.672049665599026
  27  1.57e+00  2.75e+01  7.02e+01  1.38e+02    9.20e+01      0
geophys. misfits: 29.3 (target 30.0 [True]); 27.5 (target 30.0 [True]) | smallness misfit: 277.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [29.3 27.5]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  26.104656606462232
  28  1.57e+00  2.79e+01  7.07e+01  1.39e+02    9.07e+01      0
geophys. misfits: 30.0 (target 30.0 [True]); 27.3 (target 30.0 [True]) | smallness misfit: 267.5 (target: 200.0 [False])
Beta cooling evaluation: progress: [30.  27.3]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  27.408764877385455
  29  1.57e+00  2.79e+01  7.14e+01  1.40e+02    8.55e+01      0   Skip BFGS
geophys. misfits: 30.5 (target 30.0 [False]); 27.4 (target 30.0 [True]) | smallness misfit: 256.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [30.5 27.4]; minimum progress targets: [30. 30.]
Decreasing beta to counter data misfit increase.
Updating scaling for data misfits by  1.0941076921213695
New scales: [0.24148374 0.75851626]
  30  7.84e-01  2.82e+01  7.13e+01  8.41e+01    9.51e+01      0
geophys. misfits: 26.0 (target 30.0 [True]); 25.8 (target 30.0 [True]) | smallness misfit: 295.2 (target: 200.0 [False])
Beta cooling evaluation: progress: [26.  25.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  31.803487663320233
  31  7.84e-01  2.58e+01  7.62e+01  8.56e+01    9.13e+01      0
geophys. misfits: 26.2 (target 30.0 [True]); 25.4 (target 30.0 [True]) | smallness misfit: 270.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [26.2 25.4]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  36.949415944533285
  32  7.84e-01  2.56e+01  7.92e+01  8.77e+01    8.83e+01      0
geophys. misfits: 26.2 (target 30.0 [True]); 25.1 (target 30.0 [True]) | smallness misfit: 255.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [26.2 25.1]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  43.27495806708066
  33  7.84e-01  2.53e+01  8.27e+01  9.02e+01    8.99e+01      0
geophys. misfits: 26.1 (target 30.0 [True]); 24.6 (target 30.0 [True]) | smallness misfit: 239.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [26.1 24.6]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  51.24387351187036
  34  7.84e-01  2.50e+01  8.70e+01  9.32e+01    9.45e+01      0
geophys. misfits: 25.8 (target 30.0 [True]); 23.9 (target 30.0 [True]) | smallness misfit: 218.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [25.8 23.9]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  61.84113317462196
  35  7.84e-01  2.44e+01  9.21e+01  9.67e+01    1.02e+02      0
geophys. misfits: 25.6 (target 30.0 [True]); 23.6 (target 30.0 [True]) | smallness misfit: 206.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [25.6 23.6]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  75.62682308365137
  36  7.84e-01  2.41e+01  9.84e+01  1.01e+02    1.05e+02      0
geophys. misfits: 25.5 (target 30.0 [True]); 23.3 (target 30.0 [True]) | smallness misfit: 193.0 (target: 200.0 [True])
All targets have been reached
Beta cooling evaluation: progress: [25.5 23.3]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  93.03694468843317
------------------------- STOP! -------------------------
1 : |fc-fOld| = 0.0000e+00 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 1.6714e-01 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 1.0512e+02 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 1.0512e+02 <= 1e3*eps       = 1.0000e-02
0 : maxIter   =      50    <= iter          =     37
------------------------- DONE! -------------------------

Running inversion with SimPEG v0.24.1.dev27+ge1af3e81a
simpeg.InvProblem will set Regularization.reference_model to m0.
simpeg.InvProblem will set Regularization.reference_model to m0.
simpeg.InvProblem will set Regularization.reference_model to m0.

                    simpeg.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.
                    ***Done using the default solver Pardiso and no solver_opts.***

Alpha scales: [np.float64(0.00035005933966265846), np.float64(0.0), np.float64(3.5002561904909406e-06), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09674557 0.90325443]
<class 'simpeg.regularization.pgi.PGIsmallness'>
Initial data misfit scales:  [0.09674557 0.90325443]
model has any nan: 0
=============================== Projected GNCG ===============================
  #     beta     phi_d     phi_m       f      |proj(x-g)-x|  LS    Comment
-----------------------------------------------------------------------------
x0 has any nan: 0
   0  1.93e+03  3.00e+05  0.00e+00  3.00e+05    1.41e+02      0
geophys. misfits: 87550.5 (target 30.0 [False]); 62675.8 (target 30.0 [False]) | smallness misfit: 273.7 (target: 200.0 [False])
Beta cooling evaluation: progress: [87550.5 62675.8]; minimum progress targets: [240000. 240000.]
   1  1.93e+03  6.51e+04  6.62e-01  6.64e+04    9.27e+01      0
geophys. misfits: 624.2 (target 30.0 [False]); 27.9 (target 30.0 [True]) | smallness misfit: 101.2 (target: 200.0 [True])
Beta cooling evaluation: progress: [624.2  27.9]; minimum progress targets: [70040.4 50140.6]
Updating scaling for data misfits by  1.076979442178532
New scales: [0.10342276 0.89657724]
   2  1.93e+03  8.95e+01  2.81e-01  6.34e+02    8.11e+01      0   Skip BFGS
geophys. misfits: 135.4 (target 30.0 [False]); 24.5 (target 30.0 [True]) | smallness misfit: 60.4 (target: 200.0 [True])
Beta cooling evaluation: progress: [135.4  24.5]; minimum progress targets: [499.4  30. ]
Updating scaling for data misfits by  1.222571131456211
New scales: [0.12359662 0.87640338]
   3  1.93e+03  3.82e+01  1.52e-01  3.32e+02    8.91e+01      0   Skip BFGS
geophys. misfits: 100.0 (target 30.0 [False]); 24.3 (target 30.0 [True]) | smallness misfit: 46.6 (target: 200.0 [True])
Beta cooling evaluation: progress: [100.   24.3]; minimum progress targets: [108.3  30. ]
Updating scaling for data misfits by  1.2364718737042402
New scales: [0.14848398 0.85151602]
   4  1.93e+03  3.55e+01  1.26e-01  2.80e+02    7.57e+01      0
geophys. misfits: 79.4 (target 30.0 [False]); 24.3 (target 30.0 [True]) | smallness misfit: 47.3 (target: 200.0 [True])
Beta cooling evaluation: progress: [79.4 24.3]; minimum progress targets: [80. 30.]
Updating scaling for data misfits by  1.2345165869470793
New scales: [0.17713766 0.82286234]
   5  1.93e+03  3.41e+01  1.28e-01  2.81e+02    5.57e+01      0   Skip BFGS
geophys. misfits: 65.2 (target 30.0 [False]); 24.6 (target 30.0 [True]) | smallness misfit: 47.8 (target: 200.0 [True])
Beta cooling evaluation: progress: [65.2 24.6]; minimum progress targets: [63.5 30. ]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.2206111666570432
New scales: [0.20808456 0.79191544]
   6  9.67e+02  3.30e+01  1.29e-01  1.58e+02    9.52e+01      0   Skip BFGS
geophys. misfits: 33.8 (target 30.0 [False]); 22.6 (target 30.0 [True]) | smallness misfit: 50.4 (target: 200.0 [True])
Beta cooling evaluation: progress: [33.8 22.6]; minimum progress targets: [52.2 30. ]
Updating scaling for data misfits by  1.324677844118581
New scales: [0.25820084 0.74179916]
   7  9.67e+02  2.55e+01  1.34e-01  1.55e+02    4.89e+01      0
geophys. misfits: 30.5 (target 30.0 [False]); 22.8 (target 30.0 [True]) | smallness misfit: 50.8 (target: 200.0 [True])
Beta cooling evaluation: progress: [30.5 22.8]; minimum progress targets: [30. 30.]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.3147163052041795
New scales: [0.31394933 0.68605067]
   8  4.84e+02  2.52e+01  1.35e-01  9.04e+01    7.78e+01      0   Skip BFGS
geophys. misfits: 24.9 (target 30.0 [True]); 21.8 (target 30.0 [True]) | smallness misfit: 52.4 (target: 200.0 [True])
All targets have been reached
Beta cooling evaluation: progress: [24.9 21.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  1.289682010661877
------------------------- STOP! -------------------------
1 : |fc-fOld| = 0.0000e+00 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 9.1210e-02 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 7.7812e+01 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 7.7812e+01 <= 1e3*eps       = 1.0000e-02
0 : maxIter   =      50    <= iter          =      9
------------------------- DONE! -------------------------

Running inversion with SimPEG v0.24.1.dev27+ge1af3e81a
simpeg.InvProblem will set Regularization.reference_model to m0.
simpeg.InvProblem will set Regularization.reference_model to m0.

                    simpeg.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.
                    ***Done using the default solver Pardiso and no solver_opts.***

Alpha scales: [np.float64(3.50701058124783e-05), np.float64(0.0), np.float64(3.5283698871926646e-05), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09674557 0.90325443]
/home/vsts/work/1/s/simpeg/directives/_directives.py:333: UserWarning:

There is no PGI regularization. Smallness target is turned off (TriggerSmall flag)

Initial data misfit scales:  [0.09674557 0.90325443]
model has any nan: 0
=============================== Projected GNCG ===============================
  #     beta     phi_d     phi_m       f      |proj(x-g)-x|  LS    Comment
-----------------------------------------------------------------------------
x0 has any nan: 0
   0  1.04e+06  3.00e+05  0.00e+00  3.00e+05    1.41e+02      0
geophys. misfits: 55963.5 (target 30.0 [False]); 35936.3 (target 30.0 [False])
   1  2.09e+05  3.79e+04  4.26e-02  4.68e+04    1.38e+02      0
geophys. misfits: 8280.2 (target 30.0 [False]); 3903.2 (target 30.0 [False])
   2  4.18e+04  4.33e+03  1.07e-01  8.78e+03    1.31e+02      0   Skip BFGS
geophys. misfits: 556.2 (target 30.0 [False]); 272.2 (target 30.0 [False])
   3  8.35e+03  3.00e+02  1.41e-01  1.47e+03    1.03e+02      0   Skip BFGS
geophys. misfits: 49.9 (target 30.0 [False]); 44.3 (target 30.0 [False])
   4  1.67e+03  4.49e+01  1.51e-01  2.98e+02    7.58e+01      0   Skip BFGS
geophys. misfits: 25.9 (target 30.0 [True]); 22.6 (target 30.0 [True])
All targets have been reached
------------------------- STOP! -------------------------
1 : |fc-fOld| = 0.0000e+00 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 6.5113e-01 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 7.5752e+01 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 7.5752e+01 <= 1e3*eps       = 1.0000e-02
0 : maxIter   =      50    <= iter          =      5
------------------------- DONE! -------------------------
/home/vsts/work/1/s/examples/10-pgi/plot_inv_1_PGI_Linear_1D_joint_WithRelationships.py:302: UserWarning:

marker is redundantly defined by the 'marker' keyword argument and the fmt string "b.-" (-> marker='.'). The keyword argument will take precedence.

/home/vsts/work/1/s/examples/10-pgi/plot_inv_1_PGI_Linear_1D_joint_WithRelationships.py:309: UserWarning:

marker is redundantly defined by the 'marker' keyword argument and the fmt string "r.-" (-> marker='.'). The keyword argument will take precedence.

/home/vsts/work/1/s/examples/10-pgi/plot_inv_1_PGI_Linear_1D_joint_WithRelationships.py:353: UserWarning:

marker is redundantly defined by the 'marker' keyword argument and the fmt string "b.-" (-> marker='.'). The keyword argument will take precedence.

/home/vsts/work/1/s/examples/10-pgi/plot_inv_1_PGI_Linear_1D_joint_WithRelationships.py:360: UserWarning:

marker is redundantly defined by the 'marker' keyword argument and the fmt string "r.-" (-> marker='.'). The keyword argument will take precedence.

/home/vsts/work/1/s/examples/10-pgi/plot_inv_1_PGI_Linear_1D_joint_WithRelationships.py:367: UserWarning:

The following kwargs were not used by contour: 'label'

/home/vsts/work/1/s/examples/10-pgi/plot_inv_1_PGI_Linear_1D_joint_WithRelationships.py:412: UserWarning:

marker is redundantly defined by the 'marker' keyword argument and the fmt string "b.-" (-> marker='.'). The keyword argument will take precedence.

/home/vsts/work/1/s/examples/10-pgi/plot_inv_1_PGI_Linear_1D_joint_WithRelationships.py:419: UserWarning:

marker is redundantly defined by the 'marker' keyword argument and the fmt string "r.-" (-> marker='.'). The keyword argument will take precedence.

import discretize as Mesh
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
import numpy as np
from simpeg import (
    data_misfit,
    directives,
    inverse_problem,
    inversion,
    maps,
    optimization,
    regularization,
    simulation,
    utils,
)

# Random seed for reproductibility
np.random.seed(1)
# Mesh
N = 100
mesh = Mesh.TensorMesh([N])

# Survey design parameters
nk = 30
jk = np.linspace(1.0, 59.0, nk)
p = -0.25
q = 0.25


# Physics
def g(k):
    return np.exp(p * jk[k] * mesh.cell_centers_x) * np.cos(
        np.pi * q * jk[k] * mesh.cell_centers_x
    )


G = np.empty((nk, mesh.nC))

for i in range(nk):
    G[i, :] = g(i)

m0 = np.zeros(mesh.nC)
m0[20:41] = np.linspace(0.0, 1.0, 21)
m0[41:57] = np.linspace(-1, 0.0, 16)

poly0 = maps.PolynomialPetroClusterMap(coeffyx=np.r_[0.0, -4.0, 4.0])
poly1 = maps.PolynomialPetroClusterMap(coeffyx=np.r_[-0.0, 3.0, 6.0, 6.0])
poly0_inverse = maps.PolynomialPetroClusterMap(coeffyx=-np.r_[0.0, -4.0, 4.0])
poly1_inverse = maps.PolynomialPetroClusterMap(coeffyx=-np.r_[0.0, 3.0, 6.0, 6.0])
cluster_mapping = [maps.IdentityMap(), poly0_inverse, poly1_inverse]

m1 = np.zeros(100)
m1[20:41] = 1.0 + (poly0 * np.vstack([m0[20:41], m1[20:41]]).T)[:, 1]
m1[41:57] = -1.0 + (poly1 * np.vstack([m0[41:57], m1[41:57]]).T)[:, 1]

model2d = np.vstack([m0, m1]).T
m = utils.mkvc(model2d)

clfmapping = utils.GaussianMixtureWithNonlinearRelationships(
    mesh=mesh,
    n_components=3,
    covariance_type="full",
    tol=1e-8,
    reg_covar=1e-3,
    max_iter=1000,
    n_init=100,
    init_params="kmeans",
    random_state=None,
    warm_start=False,
    means_init=np.array(
        [
            [0, 0],
            [m0[20:41].mean(), m1[20:41].mean()],
            [m0[41:57].mean(), m1[41:57].mean()],
        ]
    ),
    verbose=0,
    verbose_interval=10,
    cluster_mapping=cluster_mapping,
)
clfmapping = clfmapping.fit(model2d)

clfnomapping = utils.WeightedGaussianMixture(
    mesh=mesh,
    n_components=3,
    covariance_type="full",
    tol=1e-8,
    reg_covar=1e-3,
    max_iter=1000,
    n_init=100,
    init_params="kmeans",
    random_state=None,
    warm_start=False,
    verbose=0,
    verbose_interval=10,
)
clfnomapping = clfnomapping.fit(model2d)

wires = maps.Wires(("m1", mesh.nC), ("m2", mesh.nC))

relatrive_error = 0.01
noise_floor = 0.0

prob1 = simulation.LinearSimulation(mesh, G=G, model_map=wires.m1)
survey1 = prob1.make_synthetic_data(
    m, relative_error=relatrive_error, noise_floor=noise_floor, add_noise=True
)

prob2 = simulation.LinearSimulation(mesh, G=G, model_map=wires.m2)
survey2 = prob2.make_synthetic_data(
    m, relative_error=relatrive_error, noise_floor=noise_floor, add_noise=True
)


dmis1 = data_misfit.L2DataMisfit(simulation=prob1, data=survey1)
dmis2 = data_misfit.L2DataMisfit(simulation=prob2, data=survey2)
dmis = dmis1 + dmis2
minit = np.zeros_like(m)

# Distance weighting
wr1 = np.sum(prob1.G**2.0, axis=0) ** 0.5 / mesh.cell_volumes
wr1 = wr1 / np.max(wr1)
wr2 = np.sum(prob2.G**2.0, axis=0) ** 0.5 / mesh.cell_volumes
wr2 = wr2 / np.max(wr2)

reg_simple = regularization.PGI(
    mesh=mesh,
    gmmref=clfmapping,
    gmm=clfmapping,
    approx_gradient=True,
    wiresmap=wires,
    non_linear_relationships=True,
    weights_list=[wr1, wr2],
)

opt = optimization.ProjectedGNCG(
    maxIter=50,
    tolX=1e-6,
    maxIterCG=100,
    tolCG=1e-3,
    lower=-10,
    upper=10,
)

invProb = inverse_problem.BaseInvProblem(dmis, reg_simple, opt)

# directives
scales = directives.ScalingMultipleDataMisfits_ByEig(
    chi0_ratio=np.r_[1.0, 1.0], verbose=True, n_pw_iter=10
)
scaling_schedule = directives.JointScalingSchedule(verbose=True)
alpha0_ratio = np.r_[1e6, 1e4, 1, 1]
alphas = directives.AlphasSmoothEstimate_ByEig(
    alpha0_ratio=alpha0_ratio, n_pw_iter=10, verbose=True
)
beta = directives.BetaEstimate_ByEig(beta0_ratio=1e-5, n_pw_iter=10)
betaIt = directives.PGI_BetaAlphaSchedule(
    verbose=True,
    coolingFactor=2.0,
    progress=0.2,
)
targets = directives.MultiTargetMisfits(verbose=True)
petrodir = directives.PGI_UpdateParameters(update_gmm=False)

# Setup Inversion
inv = inversion.BaseInversion(
    invProb,
    directiveList=[alphas, scales, beta, petrodir, targets, betaIt, scaling_schedule],
)

mcluster_map = inv.run(minit)

# Inversion with no nonlinear mapping
reg_simple_no_map = regularization.PGI(
    mesh=mesh,
    gmmref=clfnomapping,
    gmm=clfnomapping,
    approx_gradient=True,
    wiresmap=wires,
    non_linear_relationships=False,
    weights_list=[wr1, wr2],
)

opt = optimization.ProjectedGNCG(
    maxIter=50,
    tolX=1e-6,
    maxIterCG=100,
    tolCG=1e-3,
    lower=-10,
    upper=10,
)

invProb = inverse_problem.BaseInvProblem(dmis, reg_simple_no_map, opt)

# directives
scales = directives.ScalingMultipleDataMisfits_ByEig(
    chi0_ratio=np.r_[1.0, 1.0], verbose=True, n_pw_iter=10
)
scaling_schedule = directives.JointScalingSchedule(verbose=True)
alpha0_ratio = np.r_[100.0 * np.ones(2), 1, 1]
alphas = directives.AlphasSmoothEstimate_ByEig(
    alpha0_ratio=alpha0_ratio, n_pw_iter=10, verbose=True
)
beta = directives.BetaEstimate_ByEig(beta0_ratio=1e-5, n_pw_iter=10)
betaIt = directives.PGI_BetaAlphaSchedule(
    verbose=True,
    coolingFactor=2.0,
    progress=0.2,
)
targets = directives.MultiTargetMisfits(
    chiSmall=1.0, TriggerSmall=True, TriggerTheta=False, verbose=True
)
petrodir = directives.PGI_UpdateParameters(update_gmm=False)

# Setup Inversion
inv = inversion.BaseInversion(
    invProb,
    directiveList=[alphas, scales, beta, petrodir, targets, betaIt, scaling_schedule],
)

mcluster_no_map = inv.run(minit)

# WeightedLeastSquares Inversion

reg1 = regularization.WeightedLeastSquares(
    mesh, alpha_s=1.0, alpha_x=1.0, mapping=wires.m1, weights={"cell_weights": wr1}
)

reg2 = regularization.WeightedLeastSquares(
    mesh, alpha_s=1.0, alpha_x=1.0, mapping=wires.m2, weights={"cell_weights": wr2}
)

reg = reg1 + reg2

opt = optimization.ProjectedGNCG(
    maxIter=50,
    tolX=1e-6,
    maxIterCG=100,
    tolCG=1e-3,
    lower=-10,
    upper=10,
)

invProb = inverse_problem.BaseInvProblem(dmis, reg, opt)

# directives
alpha0_ratio = np.r_[1, 1, 1, 1]
alphas = directives.AlphasSmoothEstimate_ByEig(
    alpha0_ratio=alpha0_ratio, n_pw_iter=10, verbose=True
)
scales = directives.ScalingMultipleDataMisfits_ByEig(
    chi0_ratio=np.r_[1.0, 1.0], verbose=True, n_pw_iter=10
)
scaling_schedule = directives.JointScalingSchedule(verbose=True)
beta = directives.BetaEstimate_ByEig(beta0_ratio=1e-5, n_pw_iter=10)
beta_schedule = directives.BetaSchedule(coolingFactor=5.0, coolingRate=1)
targets = directives.MultiTargetMisfits(
    TriggerSmall=False,
    verbose=True,
)

# Setup Inversion
inv = inversion.BaseInversion(
    invProb,
    directiveList=[alphas, scales, beta, targets, beta_schedule, scaling_schedule],
)

mtik = inv.run(minit)


# Final Plot
fig, axes = plt.subplots(3, 4, figsize=(25, 15))
axes = axes.reshape(12)
left, width = 0.25, 0.5
bottom, height = 0.25, 0.5
right = left + width
top = bottom + height

axes[0].set_axis_off()
axes[0].text(
    0.5 * (left + right),
    0.5 * (bottom + top),
    ("Using true nonlinear\npetrophysical relationships"),
    horizontalalignment="center",
    verticalalignment="center",
    fontsize=20,
    color="black",
    transform=axes[0].transAxes,
)

axes[1].plot(mesh.cell_centers_x, wires.m1 * mcluster_map, "b.-", ms=5, marker="v")
axes[1].plot(mesh.cell_centers_x, wires.m1 * m, "k--")
axes[1].set_title("Problem 1")
axes[1].legend(["Recovered Model", "True Model"], loc=1)
axes[1].set_xlabel("X")
axes[1].set_ylabel("Property 1")

axes[2].plot(mesh.cell_centers_x, wires.m2 * mcluster_map, "r.-", ms=5, marker="v")
axes[2].plot(mesh.cell_centers_x, wires.m2 * m, "k--")
axes[2].set_title("Problem 2")
axes[2].legend(["Recovered Model", "True Model"], loc=1)
axes[2].set_xlabel("X")
axes[2].set_ylabel("Property 2")

x, y = np.mgrid[-1:1:0.01, -4:2:0.01]
pos = np.empty(x.shape + (2,))
pos[:, :, 0] = x
pos[:, :, 1] = y
CS = axes[3].contour(
    x,
    y,
    np.exp(clfmapping.score_samples(pos.reshape(-1, 2)).reshape(x.shape)),
    100,
    alpha=0.25,
    cmap="viridis",
)
cs_proxy = mlines.Line2D([], [], label="True Petrophysical Distribution")

ps = axes[3].scatter(
    wires.m1 * mcluster_map,
    wires.m2 * mcluster_map,
    marker="v",
    label="Recovered model crossplot",
)
axes[3].set_title("Petrophysical Distribution")
axes[3].legend(handles=[cs_proxy, ps])
axes[3].set_xlabel("Property 1")
axes[3].set_ylabel("Property 2")

axes[4].set_axis_off()
axes[4].text(
    0.5 * (left + right),
    0.5 * (bottom + top),
    ("Using a pure\nGaussian distribution"),
    horizontalalignment="center",
    verticalalignment="center",
    fontsize=20,
    color="black",
    transform=axes[4].transAxes,
)

axes[5].plot(mesh.cell_centers_x, wires.m1 * mcluster_no_map, "b.-", ms=5, marker="v")
axes[5].plot(mesh.cell_centers_x, wires.m1 * m, "k--")
axes[5].set_title("Problem 1")
axes[5].legend(["Recovered Model", "True Model"], loc=1)
axes[5].set_xlabel("X")
axes[5].set_ylabel("Property 1")

axes[6].plot(mesh.cell_centers_x, wires.m2 * mcluster_no_map, "r.-", ms=5, marker="v")
axes[6].plot(mesh.cell_centers_x, wires.m2 * m, "k--")
axes[6].set_title("Problem 2")
axes[6].legend(["Recovered Model", "True Model"], loc=1)
axes[6].set_xlabel("X")
axes[6].set_ylabel("Property 2")

CSF = axes[7].contour(
    x,
    y,
    np.exp(clfmapping.score_samples(pos.reshape(-1, 2)).reshape(x.shape)),
    100,
    alpha=0.5,
    label="True Petro. Distribution",
)
CS = axes[7].contour(
    x,
    y,
    np.exp(clfnomapping.score_samples(pos.reshape(-1, 2)).reshape(x.shape)),
    500,
    cmap="viridis",
    linestyles="--",
)
axes[7].scatter(
    wires.m1 * mcluster_no_map,
    wires.m2 * mcluster_no_map,
    marker="v",
    label="Recovered model crossplot",
)
cs_modeled_proxy = mlines.Line2D(
    [], [], linestyle="--", label="Modeled Petro. Distribution"
)

axes[7].set_title("Petrophysical Distribution")
axes[7].legend(handles=[cs_proxy, cs_modeled_proxy, ps])
axes[7].set_xlabel("Property 1")
axes[7].set_ylabel("Property 2")

# Tikonov

axes[8].set_axis_off()
axes[8].text(
    0.5 * (left + right),
    0.5 * (bottom + top),
    ("Least-Squares\n~Using a single cluster"),
    horizontalalignment="center",
    verticalalignment="center",
    fontsize=20,
    color="black",
    transform=axes[8].transAxes,
)

axes[9].plot(mesh.cell_centers_x, wires.m1 * mtik, "b.-", ms=5, marker="v")
axes[9].plot(mesh.cell_centers_x, wires.m1 * m, "k--")
axes[9].set_title("Problem 1")
axes[9].legend(["Recovered Model", "True Model"], loc=1)
axes[9].set_xlabel("X")
axes[9].set_ylabel("Property 1")

axes[10].plot(mesh.cell_centers_x, wires.m2 * mtik, "r.-", ms=5, marker="v")
axes[10].plot(mesh.cell_centers_x, wires.m2 * m, "k--")
axes[10].set_title("Problem 2")
axes[10].legend(["Recovered Model", "True Model"], loc=1)
axes[10].set_xlabel("X")
axes[10].set_ylabel("Property 2")

CS = axes[11].contour(
    x,
    y,
    np.exp(clfmapping.score_samples(pos.reshape(-1, 2)).reshape(x.shape)),
    100,
    alpha=0.25,
    cmap="viridis",
)
axes[11].scatter(wires.m1 * mtik, wires.m2 * mtik, marker="v")
axes[11].set_title("Petro Distribution")
axes[11].legend(handles=[cs_proxy, ps])
axes[11].set_xlabel("Property 1")
axes[11].set_ylabel("Property 2")
plt.subplots_adjust(wspace=0.3, hspace=0.3, top=0.85)
plt.show()

Total running time of the script: (0 minutes 40.539 seconds)

Estimated memory usage: 290 MB

Gallery generated by Sphinx-Gallery