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.dev41+g7d721d035
Alpha scales: [np.float64(3.428251980035151), np.float64(0.0), np.float64(3.4278237288720794e-06), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09041516 0.90958484]
<class 'simpeg.regularization.pgi.PGIsmallness'>
Initial data misfit scales:  [0.09041516 0.90958484]
================================================= 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.90e+01  3.00e+05  0.00e+00  3.00e+05                         0           inf          inf
   1  1.90e+01  1.11e+03  1.71e+02  4.36e+03    1.41e+02      0      20       4.71e-04     4.28e+03
geophys. misfits: 7003.2 (target 30.0 [False]); 527.8 (target 30.0 [False]) | smallness misfit: 4037.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [7003.2  527.8]; minimum progress targets: [240000. 240000.]
   2  1.90e+01  6.90e+01  4.08e+01  8.44e+02    1.40e+02      0     100       5.56e-03     2.41e+01   Skip BFGS
geophys. misfits: 501.3 (target 30.0 [False]); 26.0 (target 30.0 [True]) | smallness misfit: 1526.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [501.3  26. ]; minimum progress targets: [5602.6  422.3]
Updating scaling for data misfits by  1.1537750229438315
New scales: [0.10288824 0.89711176]
   3  1.90e+01  6.58e+01  4.03e+01  8.30e+02    6.52e+01      0     100       3.24e-02     6.20e+00   Skip BFGS
geophys. misfits: 411.3 (target 30.0 [False]); 26.2 (target 30.0 [True]) | smallness misfit: 1293.2 (target: 200.0 [False])
Beta cooling evaluation: progress: [411.3  26.2]; minimum progress targets: [401.  30.]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.147166455249313
New scales: [0.11626942 0.88373058]
   4  9.49e+00  3.26e+01  4.29e+01  4.39e+02    8.48e+01      0     100       4.30e-02     1.58e+01
geophys. misfits: 138.8 (target 30.0 [False]); 18.6 (target 30.0 [True]) | smallness misfit: 1410.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [138.8  18.6]; minimum progress targets: [329.  30.]
Updating scaling for data misfits by  1.6104580927455672
New scales: [0.17483748 0.82516252]
   5  9.49e+00  3.20e+01  4.35e+01  4.45e+02    6.92e+01      0     100       2.27e-01     3.72e+01   Skip BFGS
geophys. misfits: 90.4 (target 30.0 [False]); 19.6 (target 30.0 [True]) | smallness misfit: 1288.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [90.4 19.6]; minimum progress targets: [111.1  30. ]
Updating scaling for data misfits by  1.5318095267854863
New scales: [0.24503436 0.75496564]
   6  9.49e+00  3.10e+01  4.40e+01  4.49e+02    6.91e+01      0     100       2.52e+00     4.47e+02   Skip BFGS
geophys. misfits: 63.3 (target 30.0 [False]); 20.6 (target 30.0 [True]) | smallness misfit: 1202.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [63.3 20.6]; minimum progress targets: [72.4 30. ]
Updating scaling for data misfits by  1.4570329541943086
New scales: [0.32106722 0.67893278]
   7  9.49e+00  2.94e+01  4.44e+01  4.51e+02    8.49e+01      0     100       1.29e+00     5.55e+02   Skip BFGS
geophys. misfits: 46.5 (target 30.0 [False]); 21.4 (target 30.0 [True]) | smallness misfit: 1140.7 (target: 200.0 [False])
Beta cooling evaluation: progress: [46.5 21.4]; minimum progress targets: [50.6 30. ]
Updating scaling for data misfits by  1.4027171505511487
New scales: [0.39880172 0.60119828]
   8  9.49e+00  2.94e+01  4.45e+01  4.52e+02    8.67e+01      0     100       8.71e-02     6.00e+01
geophys. misfits: 40.3 (target 30.0 [False]); 22.2 (target 30.0 [True]) | smallness misfit: 1104.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [40.3 22.2]; minimum progress targets: [37.2 30. ]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.3499332613816515
New scales: [0.47242668 0.52757332]
   9  4.75e+00  2.14e+01  4.58e+01  2.39e+02    7.80e+01      0     100       1.71e-01     5.12e+01
geophys. misfits: 24.9 (target 30.0 [True]); 18.2 (target 30.0 [True]) | smallness misfit: 1247.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.9 18.2]; minimum progress targets: [32.2 30. ]
Warming alpha_pgi to favor clustering:  1.4256506707490755
  10  4.75e+00  2.24e+01  4.66e+01  2.44e+02    4.56e+01      0     100       1.12e+00     5.77e+01
geophys. misfits: 24.9 (target 30.0 [True]); 20.2 (target 30.0 [True]) | smallness misfit: 1067.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.9 20.2]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  1.9160903313537365
  11  4.75e+00  2.28e+01  4.75e+01  2.48e+02    5.08e+01      0     100       1.58e+00     9.02e+01   Skip BFGS
geophys. misfits: 23.9 (target 30.0 [True]); 21.7 (target 30.0 [True]) | smallness misfit: 956.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.9 21.7]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  2.5245820633036913
  12  4.75e+00  2.36e+01  4.86e+01  2.54e+02    5.82e+01      0     100       1.60e-01     1.50e+01
geophys. misfits: 23.9 (target 30.0 [True]); 23.2 (target 30.0 [True]) | smallness misfit: 868.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.9 23.2]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  3.2133651821936042
  13  4.75e+00  2.41e+01  4.97e+01  2.60e+02    2.95e+01      0     100       5.90e-01     2.06e+01
geophys. misfits: 23.7 (target 30.0 [True]); 24.5 (target 30.0 [True]) | smallness misfit: 794.5 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.7 24.5]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  4.006487688384849
  14  4.75e+00  2.47e+01  5.08e+01  2.66e+02    4.06e+01      0     100       9.22e-01     4.36e+01
geophys. misfits: 23.8 (target 30.0 [True]); 25.6 (target 30.0 [True]) | smallness misfit: 734.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.8 25.6]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  4.872936701510822
  15  4.75e+00  2.53e+01  5.20e+01  2.72e+02    5.62e+01      0     100       2.54e+00     1.76e+02
geophys. misfits: 23.9 (target 30.0 [True]); 26.6 (target 30.0 [True]) | smallness misfit: 676.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.9 26.6]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  5.808325860281779
  16  4.75e+00  2.57e+01  5.33e+01  2.79e+02    7.35e+01      0     100       7.54e-01     1.38e+02
geophys. misfits: 23.8 (target 30.0 [True]); 27.5 (target 30.0 [True]) | smallness misfit: 625.5 (target: 200.0 [False])
Beta cooling evaluation: progress: [23.8 27.5]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  6.834220064432398
  17  4.75e+00  2.66e+01  5.44e+01  2.85e+02    7.32e+01      0     100       5.66e-01     8.67e+01
geophys. misfits: 24.6 (target 30.0 [True]); 28.4 (target 30.0 [True]) | smallness misfit: 579.4 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.6 28.4]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  7.783033944851308
  18  4.75e+00  2.67e+01  5.55e+01  2.90e+02    6.58e+01      0     100       1.90e+00     2.05e+02
geophys. misfits: 24.2 (target 30.0 [True]); 28.9 (target 30.0 [True]) | smallness misfit: 538.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.2 28.9]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  8.859100177541267
  19  4.75e+00  2.73e+01  5.66e+01  2.96e+02    8.37e+01      0     100       1.43e+00     3.09e+02
geophys. misfits: 24.3 (target 30.0 [True]); 29.9 (target 30.0 [True]) | smallness misfit: 498.3 (target: 200.0 [False])
Beta cooling evaluation: progress: [24.3 29.9]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  9.915295211002007
  20  4.75e+00  2.89e+01  5.72e+01  3.01e+02    8.80e+01      0     100       1.21e+00     3.87e+02
geophys. misfits: 26.4 (target 30.0 [True]); 31.2 (target 30.0 [False]) | smallness misfit: 450.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [26.4 31.2]; minimum progress targets: [30. 30.]
Decreasing beta to counter data misfit increase.
Updating scaling for data misfits by  1.1356309694360949
New scales: [0.44087943 0.55912057]
  21  2.37e+00  2.39e+01  5.87e+01  1.63e+02    9.33e+01      0     100       6.78e-01     3.01e+02
geophys. misfits: 22.7 (target 30.0 [True]); 24.9 (target 30.0 [True]) | smallness misfit: 509.1 (target: 200.0 [False])
Beta cooling evaluation: progress: [22.7 24.9]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  12.53816102728801
  22  2.37e+00  2.32e+01  6.16e+01  1.69e+02    8.14e+01      0     100       4.67e-01     1.41e+02
geophys. misfits: 21.3 (target 30.0 [True]); 24.7 (target 30.0 [True]) | smallness misfit: 454.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [21.3 24.7]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  16.459906582360404
  23  2.37e+00  2.26e+01  6.54e+01  1.78e+02    7.98e+01      0     100       7.98e-01     1.40e+02
geophys. misfits: 20.9 (target 30.0 [True]); 24.0 (target 30.0 [True]) | smallness misfit: 417.6 (target: 200.0 [False])
Beta cooling evaluation: progress: [20.9 24. ]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  22.119147815513635
  24  2.37e+00  2.21e+01  7.04e+01  1.89e+02    9.27e+01      0     100       2.17e+00     4.78e+02
geophys. misfits: 20.3 (target 30.0 [True]); 23.4 (target 30.0 [True]) | smallness misfit: 368.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [20.3 23.4]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  30.48699299330211
  25  2.37e+00  2.21e+01  7.66e+01  2.04e+02    1.05e+02      0     100       8.42e-01     4.62e+02
geophys. misfits: 20.1 (target 30.0 [True]); 23.7 (target 30.0 [True]) | smallness misfit: 335.0 (target: 200.0 [False])
Beta cooling evaluation: progress: [20.1 23.7]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  42.06103380252559
  26  2.37e+00  2.24e+01  8.42e+01  2.22e+02    1.13e+02      0     100       1.15e+00     6.86e+02
geophys. misfits: 19.8 (target 30.0 [True]); 24.4 (target 30.0 [True]) | smallness misfit: 284.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [19.8 24.4]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  57.716535610672516
  27  2.37e+00  2.36e+01  9.28e+01  2.44e+02    1.18e+02      0     100       4.36e+00     3.71e+03
geophys. misfits: 21.0 (target 30.0 [True]); 25.7 (target 30.0 [True]) | smallness misfit: 270.2 (target: 200.0 [False])
Beta cooling evaluation: progress: [21.  25.7]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  74.85841475555637
  28  2.37e+00  2.41e+01  1.02e+02  2.65e+02    1.19e+02      0     100       1.20e+00     4.51e+03
geophys. misfits: 22.5 (target 30.0 [True]); 25.4 (target 30.0 [True]) | smallness misfit: 215.8 (target: 200.0 [False])
Beta cooling evaluation: progress: [22.5 25.4]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  94.1212250793135
  29  2.37e+00  2.79e+01  1.05e+02  2.76e+02    1.25e+02      0     100       7.31e-01     3.35e+03
geophys. misfits: 25.8 (target 30.0 [True]); 29.5 (target 30.0 [True]) | smallness misfit: 189.2 (target: 200.0 [True])
All targets have been reached
Beta cooling evaluation: progress: [25.8 29.5]; minimum progress targets: [30. 30.]
Warming alpha_pgi to favor clustering:  102.61421289835057
------------------------- STOP! -------------------------
1 : |fc-fOld| = 1.1608e+01 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 4.8441e-01 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 1.2536e+02 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 1.2536e+02 <= 1e3*eps       = 1.0000e-02
0 : maxIter   =      50    <= iter          =     29
------------------------- DONE! -------------------------

Running inversion with SimPEG v0.25.2.dev41+g7d721d035
Alpha scales: [np.float64(0.00034928024314171574), np.float64(0.0), np.float64(3.4882957394587844e-06), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09041516 0.90958484]
<class 'simpeg.regularization.pgi.PGIsmallness'>
Initial data misfit scales:  [0.09041516 0.90958484]
================================================= 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.89e+03  3.00e+05  0.00e+00  3.00e+05                         0           inf          inf
   1  1.89e+03  6.42e+04  2.32e+01  1.08e+05    1.41e+02      0      15       3.00e-04     2.72e+03
geophys. misfits: 94916.6 (target 30.0 [False]); 61155.3 (target 30.0 [False]) | smallness misfit: 251.9 (target: 200.0 [False])
Beta cooling evaluation: progress: [94916.6 61155.3]; minimum progress targets: [240000. 240000.]
   2  1.89e+03  8.26e+01  5.51e-01  1.12e+03    1.36e+02      0     100       4.83e-03     1.29e+02   Skip BFGS
geophys. misfits: 636.9 (target 30.0 [False]); 27.5 (target 30.0 [True]) | smallness misfit: 141.7 (target: 200.0 [True])
Beta cooling evaluation: progress: [636.9  27.5]; minimum progress targets: [75933.3 48924.3]
Updating scaling for data misfits by  1.0899353106657237
New scales: [0.09775181 0.90224819]
   3  1.89e+03  3.38e+01  1.31e-01  2.82e+02    1.03e+02      0     100       1.36e-02     3.92e+01
geophys. misfits: 119.9 (target 30.0 [False]); 24.4 (target 30.0 [True]) | smallness misfit: 69.4 (target: 200.0 [True])
Beta cooling evaluation: progress: [119.9  24.4]; minimum progress targets: [509.6  30. ]
Updating scaling for data misfits by  1.2278042359708572
New scales: [0.11740566 0.88259434]
   4  1.89e+03  3.36e+01  1.26e-01  2.72e+02    6.60e+01      0     100       1.08e+00     1.61e+03
geophys. misfits: 100.1 (target 30.0 [False]); 24.8 (target 30.0 [True]) | smallness misfit: 46.3 (target: 200.0 [True])
Beta cooling evaluation: progress: [100.1  24.8]; minimum progress targets: [95.9 30. ]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.2100927101039762
New scales: [0.13865174 0.86134826]
   5  9.45e+02  2.64e+01  1.32e-01  1.51e+02    1.03e+02      0     100       1.48e-01     2.78e+02
geophys. misfits: 44.3 (target 30.0 [False]); 23.5 (target 30.0 [True]) | smallness misfit: 48.8 (target: 200.0 [True])
Beta cooling evaluation: progress: [44.3 23.5]; minimum progress targets: [80.1 30. ]
Updating scaling for data misfits by  1.2745549891128587
New scales: [0.1702387 0.8297613]
   6  9.45e+02  2.61e+01  1.33e-01  1.52e+02    8.59e+01      0     100       7.73e-01     2.17e+02   Skip BFGS
geophys. misfits: 38.3 (target 30.0 [False]); 23.6 (target 30.0 [True]) | smallness misfit: 49.2 (target: 200.0 [True])
Beta cooling evaluation: progress: [38.3 23.6]; minimum progress targets: [35.4 30. ]
Decreasing beta to counter data misfit decrase plateau.
Updating scaling for data misfits by  1.2689199364229402
New scales: [0.20656272 0.79343728]
   7  4.73e+02  2.36e+01  1.37e-01  8.82e+01    9.73e+01      0     100       2.47e-01     7.58e+01
geophys. misfits: 26.7 (target 30.0 [True]); 22.8 (target 30.0 [True]) | smallness misfit: 51.1 (target: 200.0 [True])
All targets have been reached
Beta cooling evaluation: progress: [26.7 22.8]; minimum progress targets: [30.6 30. ]
Warming alpha_pgi to favor clustering:  1.2202956011897852
------------------------- STOP! -------------------------
1 : |fc-fOld| = 1.1478e+00 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 6.7895e-02 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 9.7284e+01 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 9.7284e+01 <= 1e3*eps       = 1.0000e-02
0 : maxIter   =      50    <= iter          =      7
------------------------- DONE! -------------------------

Running inversion with SimPEG v0.25.2.dev41+g7d721d035
Alpha scales: [np.float64(3.486809571975142e-05), np.float64(0.0), np.float64(3.48703327050052e-05), np.float64(0.0)]
Calculating the scaling parameter.
Scale Multipliers:  [0.09041516 0.90958484]
/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.09041516 0.90958484]
================================================= 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.02e+06  3.00e+05  0.00e+00  3.00e+05                         0           inf          inf
   1  1.02e+06  3.99e+04  4.31e-02  8.39e+04    1.41e+02      0      24       9.20e-04     8.36e+03
geophys. misfits: 61686.3 (target 30.0 [False]); 37781.7 (target 30.0 [False])
   2  2.04e+05  4.17e+03  1.07e-01  2.60e+04    1.37e+02      0      99       8.29e-04     1.50e+01   Skip BFGS
geophys. misfits: 8955.4 (target 30.0 [False]); 3695.8 (target 30.0 [False])
   3  4.08e+04  2.86e+02  1.41e-01  6.02e+03    1.30e+02      0     100       7.71e-03     3.86e+01   Skip BFGS
geophys. misfits: 615.2 (target 30.0 [False]); 253.5 (target 30.0 [False])
   4  8.16e+03  3.39e+01  1.52e-01  1.27e+03    1.03e+02      0     100       1.70e-01     1.94e+02   Skip BFGS
geophys. misfits: 49.9 (target 30.0 [False]); 32.3 (target 30.0 [False])
   5  1.63e+03  1.15e+01  1.57e-01  2.67e+02    9.19e+01      0     100       1.04e-02     3.26e+00   Skip BFGS
geophys. misfits: 19.7 (target 30.0 [True]); 10.6 (target 30.0 [True])
All targets have been reached
------------------------- STOP! -------------------------
1 : |fc-fOld| = 1.4036e+01 <= tolF*(1+|f0|) = 3.0000e+04
0 : |xc-x_last| = 7.1792e-01 <= tolX*(1+|x0|) = 1.0000e-06
0 : |proj(x-g)-x|    = 9.1940e+01 <= tolG          = 1.0000e-01
0 : |proj(x-g)-x|    = 9.1940e+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 28.084 seconds)

Estimated memory usage: 329 MB

Gallery generated by Sphinx-Gallery