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.25.2.dev23+g390d5f500
Alpha scales: [np.float64(3.4700404765874278), np.float64(0.0), np.float64(3.4776412391370852e-06), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09474081 0.90525919]
<class 'simpeg.regularization.pgi.PGIsmallness'>
Initial data misfit scales:  [0.09474081 0.90525919]
================================================= Projected GNCG =================================================
  #     beta     phi_d     phi_m       f      |proj(x-g)-x|  LS   iter_CG   CG |Ax-b|/|b|  CG |Ax-b|   Comment
-----------------------------------------------------------------------------------------------------------------
   0  1.93e+01  3.00e+05  0.00e+00  3.00e+05                         0           inf          inf
   1  1.93e+01  1.23e+03  1.71e+02  4.54e+03    1.40e+02      0      20       6.55e-04     6.02e+03
geophys. misfits: 6887.1 (target 30.0 [False]); 640.1 (target 30.0 [False]) | smallness misfit: 4022.2 (target: 200.0 [False])
Beta cooling evaluation: progress: [6887.1  640.1]; minimum progress targets: [240000. 240000.]
   2  1.93e+01  6.98e+01  4.05e+01  8.53e+02    1.39e+02      0     100       1.21e+00     7.26e+03   Skip BFGS
geophys. misfits: 484.6 (target 30.0 [False]); 26.4 (target 30.0 [True]) | smallness misfit: 1491.5 (target: 200.0 [False])
Beta cooling evaluation: progress: [484.6  26.4]; minimum progress targets: [5509.7  512. ]
Updating scaling for data misfits by  1.1351912675794176
New scales: [0.10618886 0.89381114]
   3  1.93e+01  6.65e+01  4.01e+01  8.41e+02    7.69e+01      0      72       8.99e-04     7.32e+00   Skip BFGS
geophys. misfits: 409.1 (target 30.0 [False]); 25.8 (target 30.0 [True]) | smallness misfit: 1321.8 (target: 200.0 [False])
Beta cooling evaluation: progress: [409.1  25.8]; minimum progress targets: [387.7  30. ]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.1610117359494485
New scales: [0.12121404 0.87878596]
   4  9.66e+00  3.30e+01  4.27e+01  4.45e+02    8.63e+01      0     100       1.52e-02     5.87e+00
geophys. misfits: 128.8 (target 30.0 [False]); 19.8 (target 30.0 [True]) | smallness misfit: 1354.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [128.8  19.8]; minimum progress targets: [327.3  30. ]
Updating scaling for data misfits by  1.5149211093097112
New scales: [0.17284168 0.82715832]
   5  9.66e+00  3.23e+01  4.32e+01  4.50e+02    6.63e+01      0     100       6.02e+00     8.66e+02   Skip BFGS
geophys. misfits: 89.6 (target 30.0 [False]); 20.4 (target 30.0 [True]) | smallness misfit: 1279.2 (target: 200.0 [False])
Beta cooling evaluation: progress: [89.6 20.4]; minimum progress targets: [103.1  30. ]
Updating scaling for data misfits by  1.4725688097377314
New scales: [0.2353019 0.7646981]
   6  9.66e+00  3.08e+01  4.37e+01  4.53e+02    7.36e+01      0     100       1.01e+00     1.21e+03   Skip BFGS
geophys. misfits: 62.8 (target 30.0 [False]); 21.0 (target 30.0 [True]) | smallness misfit: 1231.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [62.8 21. ]; minimum progress targets: [71.7 30. ]
Updating scaling for data misfits by  1.4283661856120973
New scales: [0.30532221 0.69467779]
   7  9.66e+00  2.78e+01  4.42e+01  4.55e+02    7.35e+01      0     100       2.50e-01     3.95e+02   Skip BFGS
geophys. misfits: 42.6 (target 30.0 [False]); 21.3 (target 30.0 [True]) | smallness misfit: 1199.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [42.6 21.3]; minimum progress targets: [50.3 30. ]
Updating scaling for data misfits by  1.4059481073631332
New scales: [0.381929 0.618071]
   8  9.66e+00  2.82e+01  4.43e+01  4.56e+02    7.41e+01      0     100       2.79e+00     1.42e+03
geophys. misfits: 37.5 (target 30.0 [False]); 22.5 (target 30.0 [True]) | smallness misfit: 1130.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [37.5 22.5]; minimum progress targets: [34.1 30. ]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.3343123823824994
New scales: [0.45191098 0.54808902]
   9  4.83e+00  1.97e+01  4.55e+01  2.39e+02    8.23e+01      0     100       7.72e-01     1.33e+03
geophys. misfits: 20.4 (target 30.0 [True]); 19.1 (target 30.0 [True]) | smallness misfit: 1242.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [20.4 19.1]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  1.5229065965001332
  10  4.83e+00  2.05e+01  4.66e+01  2.45e+02    8.54e+01      0     100       9.53e-01     1.27e+03
geophys. misfits: 19.9 (target 30.0 [True]); 21.0 (target 30.0 [True]) | smallness misfit: 1061.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [19.9 21. ]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  2.23375029740058
  11  4.83e+00  2.07e+01  4.81e+01  2.53e+02    6.71e+01      0     100       5.87e-01     7.46e+02   Skip BFGS
geophys. misfits: 18.9 (target 30.0 [True]); 22.1 (target 30.0 [True]) | smallness misfit: 956.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [18.9 22.1]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  3.2889781427123124
  12  4.83e+00  2.14e+01  5.00e+01  2.63e+02    6.12e+01      0     100       2.87e-01     2.14e+02
geophys. misfits: 18.3 (target 30.0 [True]); 24.0 (target 30.0 [True]) | smallness misfit: 860.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [18.3 24. ]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  4.753358202208385
  13  4.83e+00  2.21e+01  5.25e+01  2.76e+02    6.26e+01      0     100       1.93e+00     4.34e+02
geophys. misfits: 17.5 (target 30.0 [True]); 25.9 (target 30.0 [True]) | smallness misfit: 758.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [17.5 25.9]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  6.82326000608938
  14  4.83e+00  2.35e+01  5.56e+01  2.92e+02    7.56e+01      0     100       2.65e+00     1.18e+03
geophys. misfits: 17.9 (target 30.0 [True]); 28.0 (target 30.0 [True]) | smallness misfit: 675.7 (target: 200.0 [False])
Beta cooling evaluation: progress: [17.9 28. ]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  9.371322422656338
  15  4.83e+00  2.50e+01  5.89e+01  3.10e+02    8.81e+01      0     100       1.60e+00     1.91e+03
geophys. misfits: 16.8 (target 30.0 [True]); 31.7 (target 30.0 [False]) | smallness misfit: 595.7 (target: 200.0 [False])
Beta cooling evaluation: progress: [16.8 31.7]; minimum progress targets: [30. 30.]
Decreasing beta to counter data misfit increase.
Updating scaling for data misfits by  1.7872969944117632
New scales: [0.31568857 0.68431143]
  16  2.41e+00  1.98e+01  6.07e+01  1.66e+02    8.86e+01      0     100       3.46e-01     4.61e+02
geophys. misfits: 15.8 (target 30.0 [True]); 21.7 (target 30.0 [True]) | smallness misfit: 659.5 (target: 200.0 [False])
Beta cooling evaluation: progress: [15.8 21.7]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  15.382184232746768
  17  2.41e+00  2.17e+01  6.79e+01  1.86e+02    8.34e+01      0     100       2.82e+00     1.37e+03
geophys. misfits: 16.9 (target 30.0 [True]); 23.9 (target 30.0 [True]) | smallness misfit: 537.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [16.9 23.9]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  23.27325057431955
  18  2.41e+00  2.17e+01  7.65e+01  2.06e+02    9.93e+01      0     100       1.31e+00     1.82e+03
geophys. misfits: 18.5 (target 30.0 [True]); 23.2 (target 30.0 [True]) | smallness misfit: 452.2 (target: 200.0 [False])
Beta cooling evaluation: progress: [18.5 23.2]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  33.89082048789787
  19  2.41e+00  2.69e+01  8.39e+01  2.30e+02    1.05e+02      0     100       1.07e+00     1.96e+03
geophys. misfits: 23.2 (target 30.0 [True]); 28.7 (target 30.0 [True]) | smallness misfit: 360.8 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.2 28.7]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  39.66596976897929
  20  2.41e+00  3.02e+01  8.67e+01  2.40e+02    9.98e+01      0     100       9.46e-01     1.86e+03
geophys. misfits: 22.7 (target 30.0 [True]); 33.7 (target 30.0 [False]) | smallness misfit: 330.8 (target: 200.0 [False])
Beta cooling evaluation: progress: [22.7 33.7]; minimum progress targets: [30. 30.]
Decreasing beta to counter data misfit increase.
Updating scaling for data misfits by  1.318943061993772
New scales: [0.25913147 0.74086853]
  21  1.21e+00  2.23e+01  9.12e+01  1.32e+02    1.01e+02      0     100       7.57e-01     1.29e+03
geophys. misfits: 18.8 (target 30.0 [True]); 23.5 (target 30.0 [True]) | smallness misfit: 364.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [18.8 23.5]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  56.97409719941942
  22  1.21e+00  2.09e+01  1.06e+02  1.48e+02    9.13e+01      0     100       8.50e-01     1.10e+03
geophys. misfits: 18.1 (target 30.0 [True]); 21.8 (target 30.0 [True]) | smallness misfit: 318.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [18.1 21.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  86.2553879032618
  23  1.21e+00  2.13e+01  1.25e+02  1.72e+02    1.05e+02      0     100       2.20e+00     2.48e+03
geophys. misfits: 21.0 (target 30.0 [True]); 21.4 (target 30.0 [True]) | smallness misfit: 292.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [21.  21.4]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  122.20925527863776
  24  1.21e+00  2.07e+01  1.45e+02  1.96e+02    1.14e+02      1     100       1.21e+00     3.04e+03
geophys. misfits: 19.9 (target 30.0 [True]); 21.0 (target 30.0 [True]) | smallness misfit: 255.8 (target: 200.0 [False])
Beta cooling evaluation: progress: [19.9 21. ]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  179.52362241873712
  25  1.21e+00  2.10e+01  1.76e+02  2.34e+02    1.18e+02      0     100       4.10e-01     9.49e+02
geophys. misfits: 24.5 (target 30.0 [True]); 19.8 (target 30.0 [True]) | smallness misfit: 228.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.5 19.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  245.98291541903055
  26  1.21e+00  3.05e+01  2.04e+02  2.77e+02    1.22e+02      0     100       1.86e+00     2.22e+03
geophys. misfits: 51.2 (target 30.0 [False]); 23.2 (target 30.0 [True]) | smallness misfit: 215.7 (target: 200.0 [False])
Beta cooling evaluation: progress: [51.2 23.2]; minimum progress targets: [30. 30.]
Decreasing beta to counter data misfit increase.
Updating scaling for data misfits by  1.2923955555925977
New scales: [0.31131256 0.68868744]
  27  6.04e-01  2.33e+01  2.13e+02  1.52e+02    1.12e+02      0     100       8.59e-01     1.97e+03
geophys. misfits: 19.5 (target 30.0 [True]); 25.0 (target 30.0 [True]) | smallness misfit: 218.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [19.5 25. ]; minimum progress targets: [41. 30.]
Warming alpha_pgi to favor clustering:  336.64142282223116
  28  6.04e-01  2.23e+01  2.48e+02  1.72e+02    1.18e+02      1     100       2.10e+00     4.28e+03
geophys. misfits: 17.5 (target 30.0 [True]); 24.5 (target 30.0 [True]) | smallness misfit: 202.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [17.5 24.5]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  494.4792026580972
  29  6.04e-01  2.63e+01  3.10e+02  2.13e+02    1.22e+02      0     100       5.63e-01     1.01e+03
geophys. misfits: 25.3 (target 30.0 [True]); 26.8 (target 30.0 [True]) | smallness misfit: 173.4 (target: 200.0 [True])
All targets have been reached
Beta cooling evaluation: progress: [25.3 26.8]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  570.1034060654368
------------------------- STOP! -------------------------
1 : |fc-fOld| = 5.3266e+00 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 6.0193e-01 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 1.2218e+02 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 1.2218e+02 <= 1e3*eps       = 1.0000e-02
0 : maxIter   =      50    <= iter          =     29
------------------------- DONE! -------------------------

Running inversion with SimPEG v0.25.2.dev23+g390d5f500
Alpha scales: [np.float64(0.00034969266069668223), np.float64(0.0), np.float64(3.493888005438109e-06), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09474081 0.90525919]
<class 'simpeg.regularization.pgi.PGIsmallness'>
Initial data misfit scales:  [0.09474081 0.90525919]
================================================= Projected GNCG =================================================
  #     beta     phi_d     phi_m       f      |proj(x-g)-x|  LS   iter_CG   CG |Ax-b|/|b|  CG |Ax-b|   Comment
-----------------------------------------------------------------------------------------------------------------
   0  1.94e+03  3.00e+05  0.00e+00  3.00e+05                         0           inf          inf
   1  1.94e+03  6.59e+04  2.25e+01  1.10e+05    1.41e+02      0      15       4.06e-04     3.74e+03
geophys. misfits: 92525.0 (target 30.0 [False]); 63101.9 (target 30.0 [False]) | smallness misfit: 245.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [92525.  63101.9]; minimum progress targets: [240000. 240000.]
   2  1.94e+03  7.31e+01  5.48e-01  1.14e+03    1.35e+02      0     100       2.88e-02     7.84e+02   Skip BFGS
geophys. misfits: 578.0 (target 30.0 [False]); 20.3 (target 30.0 [True]) | smallness misfit: 104.0 (target: 200.0 [True])
Beta cooling evaluation: progress: [578.   20.3]; minimum progress targets: [74020.  50481.5]
Updating scaling for data misfits by  1.4774471695185354
New scales: [0.13391698 0.86608302]
   3  1.94e+03  2.55e+01  1.36e-01  2.90e+02    1.18e+02      0     100       2.27e+00     5.82e+03   Skip BFGS
geophys. misfits: 79.0 (target 30.0 [False]); 17.2 (target 30.0 [True]) | smallness misfit: 61.3 (target: 200.0 [True])
Beta cooling evaluation: progress: [79.  17.2]; minimum progress targets: [462.4  30. ]
Updating scaling for data misfits by  1.741832174045479
New scales: [0.21218192 0.78781808]
   4  1.94e+03  2.35e+01  1.33e-01  2.81e+02    9.45e+01      0     100       5.86e-02     5.49e+02
geophys. misfits: 46.1 (target 30.0 [False]); 17.4 (target 30.0 [True]) | smallness misfit: 73.6 (target: 200.0 [True])
Beta cooling evaluation: progress: [46.1 17.4]; minimum progress targets: [63.2 30. ]
Updating scaling for data misfits by  1.7231697148478857
New scales: [0.316986 0.683014]
   5  1.94e+03  2.19e+01  1.30e-01  2.75e+02    8.46e+01      0     100       5.16e-02     8.37e+01
geophys. misfits: 30.8 (target 30.0 [False]); 17.8 (target 30.0 [True]) | smallness misfit: 57.6 (target: 200.0 [True])
Beta cooling evaluation: progress: [30.8 17.8]; minimum progress targets: [36.8 30. ]
Updating scaling for data misfits by  1.6883187418243892
New scales: [0.43931944 0.56068056]
   6  1.94e+03  2.20e+01  1.29e-01  2.73e+02    8.71e+01      0     100       9.01e-02     6.20e+01
geophys. misfits: 24.0 (target 30.0 [True]); 20.4 (target 30.0 [True]) | smallness misfit: 47.7 (target: 200.0 [True])
All targets have been reached
Beta cooling evaluation: progress: [24.  20.4]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  1.3611633600523336
------------------------- STOP! -------------------------
1 : |fc-fOld| = 3.3394e+01 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 1.1108e-01 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 8.7149e+01 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 8.7149e+01 <= 1e3*eps       = 1.0000e-02
0 : maxIter   =      50    <= iter          =      6
------------------------- DONE! -------------------------

Running inversion with SimPEG v0.25.2.dev23+g390d5f500
Alpha scales: [np.float64(3.410383120208843e-05), np.float64(0.0), np.float64(3.701966407904588e-05), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09474081 0.90525919]
/home/vsts/work/1/s/simpeg/directives/_directives.py:334: UserWarning: There is no PGI regularization. Smallness target is turned off (TriggerSmall flag)
  getattr(r, ruleType)()
Initial data misfit scales:  [0.09474081 0.90525919]
================================================= Projected GNCG =================================================
  #     beta     phi_d     phi_m       f      |proj(x-g)-x|  LS   iter_CG   CG |Ax-b|/|b|  CG |Ax-b|   Comment
-----------------------------------------------------------------------------------------------------------------
   0  1.04e+06  3.00e+05  0.00e+00  3.00e+05                         0           inf          inf
   1  1.04e+06  4.11e+04  4.23e-02  8.52e+04    1.40e+02      0      23       9.16e-04     8.42e+03
geophys. misfits: 59486.5 (target 30.0 [False]); 39202.6 (target 30.0 [False])
   2  2.08e+05  4.33e+03  1.07e-01  2.66e+04    1.37e+02      0     100       1.08e-02     1.97e+02   Skip BFGS
geophys. misfits: 8374.9 (target 30.0 [False]); 3912.0 (target 30.0 [False])
   3  4.17e+04  2.89e+02  1.41e-01  6.17e+03    1.31e+02      0     100       1.73e-03     8.85e+00   Skip BFGS
geophys. misfits: 554.2 (target 30.0 [False]); 261.6 (target 30.0 [False])
   4  8.34e+03  3.37e+01  1.52e-01  1.30e+03    1.03e+02      0     100       4.38e-02     5.12e+01   Skip BFGS
geophys. misfits: 40.9 (target 30.0 [False]); 33.0 (target 30.0 [False])
   5  1.67e+03  1.53e+01  1.56e-01  2.75e+02    8.19e+01      0     100       2.98e+00     7.38e+02   Skip BFGS
geophys. misfits: 15.4 (target 30.0 [True]); 15.3 (target 30.0 [True])
All targets have been reached
------------------------- STOP! -------------------------
1 : |fc-fOld| = 1.1702e+01 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 5.1717e-01 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 8.1893e+01 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 8.1893e+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.
  axes[1].plot(mesh.cell_centers_x, wires.m1 * mcluster_map, "b.-", ms=5, marker="v")
/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.
  axes[2].plot(mesh.cell_centers_x, wires.m2 * mcluster_map, "r.-", ms=5, marker="v")
/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.
  axes[5].plot(mesh.cell_centers_x, wires.m1 * mcluster_no_map, "b.-", ms=5, marker="v")
/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.
  axes[6].plot(mesh.cell_centers_x, wires.m2 * mcluster_no_map, "r.-", ms=5, marker="v")
/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.
  axes[9].plot(mesh.cell_centers_x, wires.m1 * mtik, "b.-", ms=5, marker="v")
/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.
  axes[10].plot(mesh.cell_centers_x, wires.m2 * mtik, "r.-", ms=5, marker="v")

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,
    cg_maxiter=100,
    cg_rtol=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,
    cg_maxiter=100,
    cg_rtol=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,
    cg_maxiter=100,
    cg_rtol=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 27.507 seconds)

Estimated memory usage: 332 MB

Gallery generated by Sphinx-Gallery