In [1]:
import numpy as np
%pylab inline


Populating the interactive namespace from numpy and matplotlib

$A(t,T) = \Sigma_i A_i e^{-t/\tau_i} / (1 + e^{-T/2\tau_i})$


In [2]:
def AofT(time,T, ai, taui):
    return ai*np.exp(-time/taui)/(1.+np.exp(-T/(2*taui)))

In [3]:
from SimPEG import *
import sys
sys.path.append("./DoubleLog/")
from plotting import mapDat

In [4]:
class LinearSurvey(Survey.BaseSurvey):
    nD = None
    def __init__(self, time, **kwargs): 
        self.time = time
        self.nD = time.size
        
    def projectFields(self, u):
        return u

class LinearProblem(Problem.BaseProblem):

    surveyPair = LinearSurvey

    def __init__(self, mesh, G, **kwargs):
        Problem.BaseProblem.__init__(self, mesh, **kwargs)
        self.G = G

    def fields(self, m, u=None):
        return self.G.dot(m)

    def Jvec(self, m, v, u=None):
        return self.G.dot(v)

    def Jtvec(self, m, v, u=None):
        return self.G.T.dot(v)

Simple exponential basis

$$ \mathbf{A}\mathbf{\alpha} = \mathbf{d}$$

In [42]:
time = np.cumsum(np.r_[0., 1e-5*np.ones(10), 5e-5*np.ones(10), 1e-4*np.ones(10), 5e-4*np.ones(10), 1e-3*np.ones(10)])
# time = np.cumsum(np.r_[0., 1e-5*np.ones(10), 5e-5*np.ones(10),1e-4*np.ones(10), 5e-4*np.ones(10)])
M = 41
tau = np.logspace(-4.5, -1, M)

In [43]:
N = time.size
A = np.zeros((N, M))
for j in range(M):
    A[:,j] = np.exp(-time/tau[j])//tau[j]

In [44]:
mtrue = np.zeros(M)

In [57]:
np.random.seed(1)
inds = np.random.random_integers(0, 41, size=5)
mtrue[inds] = np.r_[-10, 2, 1, 4, 5]

In [58]:
out = np.dot(A,mtrue)

In [59]:
fig = plt.figure(figsize=(6,4.5))
ax = plt.subplot(111)

for i, ind in enumerate(inds):
    temp, dum, dum = mapDat(mtrue[inds][i]*np.exp(-time/tau[ind])/tau[j], 1e-1, stretch=2)
    plt.semilogx(time, temp, 'k', alpha = 0.5)    
outmap, ticks, tickLabels = mapDat(out, 1e-1, stretch=2)    
ax.semilogx(time, outmap, 'k', lw=2)
ax.set_yticks(ticks)
ax.set_yticklabels(tickLabels)
# ax.set_ylim(ticks.min(), ticks.max())
ax.set_ylim(ticks.min(), ticks.max())
ax.set_xlim(time.min(), time.max())
ax.grid(True)



In [60]:
# from pymatsolver import MumpsSolver

In [61]:
abs(survey.dobs).min()


Out[61]:
27.023041276921603

In [76]:
mesh = Mesh.TensorMesh([M])
prob = LinearProblem(mesh, A)
survey = LinearSurvey(time)
survey.pair(prob)
survey.makeSyntheticData(mtrue, std=0.01)
# survey.dobs = out
reg = Regularization.BaseRegularization(mesh)
dmis = DataMisfit.l2_DataMisfit(survey)
dmis.Wd = 1./(0.05*abs(survey.dobs)+0.05*300.)
opt = Optimization.ProjectedGNCG(maxIter=20)
# opt = Optimization.InexactGaussNewton(maxIter=20)
opt.lower = -1e-10
invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
invProb.beta = 1e-4
beta = Directives.BetaSchedule()
beta.coolingFactor = 2
target = Directives.TargetMisfit()
inv = Inversion.BaseInversion(invProb, directiveList=[beta, target])
m0 = np.zeros_like(survey.mtrue)
mrec = inv.run(m0)


SimPEG.InvProblem will set Regularization.mref to m0.
SimPEG.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.
                    ***Done using same solver as the problem***
=============================== Projected GNCG ===============================
  #     beta     phi_d     phi_m       f      |proj(x-g)-x|  LS    Comment   
-----------------------------------------------------------------------------
   0  1.00e-04  5.23e+03  0.00e+00  5.23e+03    4.09e+03      0              
   1  1.00e-04  4.00e+03  3.86e+00  4.00e+03    7.52e+01      0              
   2  1.00e-04  3.29e+03  9.21e+00  3.29e+03    4.29e+00      0   Skip BFGS  
   3  5.00e-05  9.31e+02  6.13e+00  9.31e+02    5.51e+01      0              
   4  5.00e-05  7.77e+02  1.05e+01  7.77e+02    4.58e+00      1              
   5  5.00e-05  7.04e+02  1.57e+01  7.04e+02    5.60e+00      1   Skip BFGS  
   6  2.50e-05  5.79e+02  1.25e+01  5.79e+02    1.57e+01      0              
   7  2.50e-05  5.63e+02  2.15e+01  5.63e+02    6.56e+00      3              
   8  2.50e-05  5.35e+02  2.51e+01  5.35e+02    7.09e+00      1   Skip BFGS  
   9  1.25e-05  5.28e+02  2.34e+01  5.28e+02    2.58e+00      0              
  10  1.25e-05  5.26e+02  2.79e+01  5.26e+02    7.47e+00      3              
  11  1.25e-05  5.24e+02  2.69e+01  5.24e+02    2.34e+00      0              
  12  6.25e-06  5.13e+02  5.97e+01  5.13e+02    1.65e+00      2   Skip BFGS  
  13  6.25e-06  5.12e+02  6.95e+01  5.12e+02    6.07e+00      4   Skip BFGS  
  14  6.25e-06  5.12e+02  6.85e+01  5.12e+02    1.78e-15      0              
------------------------- STOP! -------------------------
1 : |fc-fOld| = 2.6700e-01 <= tolF*(1+|f0|) = 5.2354e+02
1 : |xc-x_last| = 8.7988e-02 <= tolX*(1+|x0|) = 1.0000e-01
1 : |proj(x-g)-x|    = 1.7764e-15 <= tolG          = 1.0000e-01
1 : |proj(x-g)-x|    = 1.7764e-15 <= 1e3*eps       = 1.0000e-02
0 : maxIter   =      20    <= iter          =     14
------------------------- DONE! -------------------------

In [77]:
plt.semilogx(tau, mtrue, '.')
plt.semilogx(tau, mrec, '.')


Out[77]:
[<matplotlib.lines.Line2D at 0x108c08510>]

In [78]:
fig = plt.figure(figsize=(6,4.5))
ax = plt.subplot(111)
obsmap, ticks, tickLabels = mapDat(survey.dobs, 1e0, stretch=2)    
predmap, dum, dum = mapDat(invProb.dpred, 1e0, stretch=2)    
ax.loglog(time, survey.dobs, 'k', lw=2)
ax.loglog(time, invProb.dpred, 'k.', lw=2)
# ax.set_yticks(ticks)
# ax.set_yticklabels(tickLabels)
# ax.set_ylim(ticks.min(), ticks.max())
# ax.set_ylim(ticks.min(), ticks.max())
ax.set_xlim(time.min(), time.max())
ax.grid(True)



In [79]:
time = np.cumsum(np.r_[0., 1e-5*np.ones(10), 5e-5*np.ones(10), 1e-4*np.ones(10), 5e-4*np.ones(10), 1e-3*np.ones(10)])
N = time.size
A = np.zeros((N, M))
for j in range(M):
    A[:,j] = np.exp(-time/tau[j]) /tau[j]

In [80]:
mfund = mtrue.copy()
mfund[mfund<0.] = 0.
obs = np.dot(A, mtrue)
fund = np.dot(A, mfund)
pred = np.dot(A, mrec)

In [81]:
ip = obs-fund
ipobs = obs-pred

In [82]:
plt.loglog(time, obs, 'k.-', lw=2)
plt.loglog(time, -obs, 'k--', lw=2)
plt.loglog(time, fund, 'b.', lw=2)
plt.loglog(time, pred, 'b-', lw=2)
plt.loglog(time, -ip, 'r--', lw=2)
plt.loglog(time, abs(ipobs), 'r.', lw=2)
plt.ylim(abs(obs).min(), abs(obs).max())
plt.xlim(time.min(), time.max())


Out[82]:
(1.0000000000000001e-05, 0.016600000000000007)

Range of tau is really important to fit ...


In [ ]: