Example #1
0
    def _assemble(self):
        # Get input:
        self.gamma = self.Parameters['gamma']
        if self.Parameters.has_key('beta'): self.beta = self.Parameters['beta']
        else: self.beta = 0.0
        self.Vm = self.Parameters['Vm']
        self.m0 = Function(self.Vm)
        if self.Parameters.has_key('m0'):
            setfct(self.m0, self.Parameters['m0'])
        self.mtrial = TrialFunction(self.Vm)
        self.mtest = TestFunction(self.Vm)
        self.mysample = Function(self.Vm)
        self.draw = Function(self.Vm)
        # Assemble:
        self.R = assemble(inner(nabla_grad(self.mtrial), \
        nabla_grad(self.mtest))*dx)
        self.M = assemble(inner(self.mtrial, self.mtest) * dx)

        self.Msolver = PETScKrylovSolver('cg', 'jacobi')
        self.Msolver.parameters["maximum_iterations"] = 2000
        self.Msolver.parameters["relative_tolerance"] = 1e-24
        self.Msolver.parameters["absolute_tolerance"] = 1e-24
        self.Msolver.parameters["error_on_nonconvergence"] = True
        self.Msolver.parameters["nonzero_initial_guess"] = False
        self.Msolver.set_operator(self.M)

        # preconditioner is Gamma^{-1}:
        if self.beta > 1e-10:
            self.precond = self.gamma * self.R + self.beta * self.M
        else:
            self.precond = self.gamma * self.R + (1e-10) * self.M
        # Minvprior is M.A^2 (if you use M inner-product):
        self.Minvprior = self.gamma * self.R + self.beta * self.M
Example #2
0
 def linesearch(self):
     """ Perform inexact backtracking line search """
     regularization = self.parameters["regularization"]
     # compute new direction for dual variables
     if regularization == "TV" and self.Reg.isPD():
         self.Reg.compute_dw(self.dg)
     # line search for primal variable
     self.alpha = self.parameters["alpha0"]
     rho = self.parameters["rho"]
     c = self.parameters["c"]
     self.computecost()
     costref = self.cost
     cdJdf = ((self.MG).inner(self.dg.vector())) * c
     self.LS = False
     for ii in xrange(self.parameters["max_backtrack"]):
         setfct(self.gtmp, self.g.vector() + self.dg.vector() * self.alpha)
         if self.computecost(self.gtmp) < costref + self.alpha * cdJdf:
             self.g.vector().axpy(self.alpha, self.dg.vector())
             self.LS = True
             break
         else:
             self.alpha *= rho
     # update dual variable
     if regularization == "TV" and self.Reg.isPD():
         self.Reg.update_w(self.alpha)
Example #3
0
    def assemble_hessian(self, m):
        """ build Hessian matrix at given point m """
        setfct(self.m, m)
        self._assemble_invMw()

        self.Ax = assemble(self.wkformAx)
        Hxasym = MatMatMult(self.Htvx, MatMatMult(self.invMwMat, self.Ax))
        Hx = (Hxasym + Transpose(Hxasym)) * 0.5
        Axrs = assemble(self.wkformAxrs)
        Hxrsasym = MatMatMult(self.Htvx, MatMatMult(self.invMwMat, Axrs))
        Hxrs = (Hxrsasym + Transpose(Hxrsasym)) * 0.5

        self.Ay = assemble(self.wkformAy)
        Hyasym = MatMatMult(self.Htvy, MatMatMult(self.invMwMat, self.Ay))
        Hy = (Hyasym + Transpose(Hyasym)) * 0.5
        Ayrs = assemble(self.wkformAyrs)
        Hyrsasym = MatMatMult(self.Htvy, MatMatMult(self.invMwMat, Ayrs))
        Hyrs = (Hyrsasym + Transpose(Hyrsasym)) * 0.5

        self.H = Hx + Hy
        self.Hrs = Hxrs + Hyrs

        PCGN = self.parameters['PCGN']
        if PCGN:
            HGN = assemble(self.wkformGNhess)
            self.precond = HGN + self.sMass
        else:
            self.precond = self.Hrs + self.sMass
 def hessianab(self, m1h, m2h):
     """ m1h, m2h = Vector(V) """
     setfct(self.m1h, m1h)
     setfct(self.m2h, m2h)
     assign(self.m12h.sub(0), self.m1h)
     assign(self.m12h.sub(1), self.m2h)
     return self.H * self.m12h.vector()
Example #5
0
 def iteration_centered(self, tt):
     setfct(self.rhs, (self.Dt**2)*self.ftime(tt))
     self.rhs.vector().axpy(-1.0, self.MminD*self.u0.vector())
     self.rhs.vector().axpy(2.0, self.M*self.u1.vector())
     self.rhs.vector().axpy(-self.Dt**2, self.K*self.u1.vector())
     if not self.bc == None: self.bc.apply(self.rhs.vector())
     self.solverMplD.solve(self.u2.vector(), self.rhs.vector())
 def copy(self):
     """(hard) copy constructor"""
     newobj = self.__class__(self.PDE.copy())
     setfct(newobj.MG, self.MG)
     setfct(newobj.srchdir, self.srchdir)
     newobj.obsop = self.obsop
     return newobj
Example #7
0
    def linesearch(self, MG):
        """ Perform inexact backtracking line search """

        alphaLS = self.parametersLS['alpha0']
        rhoLS = self.parametersLS['rho']
        cLS = self.parametersLS['c']

        cost, misfit, reg = self.costmisfitreg()
        costref = cost
        setfct(self.ucopy, self.u)

        MGdu = MG.inner(self.du.vector()) * cLS
        success = False
        for ii in xrange(self.parametersLS['max_backtrack']):
            setfct(self.u, self.ucopy)
            self.u.vector().axpy(alphaLS, self.du.vector())
            cost, misfit, reg = self.costmisfitreg()
            if cost < costref + alphaLS * MGdu:
                success = True
                break
            else:
                alphaLS *= rhoLS

        if self.Regul.isPD(): self.Regul.update_w(self.du.vector(), alphaLS)

        return success, alphaLS, cost, misfit, reg
 def hessianab(self, m1h, m2h):
     """ m1h, m2h = Vector(V) """
     setfct(self.m1, m1h)
     setfct(self.m2, m2h)
     assign(self.m.sub(0), self.m1)
     assign(self.m.sub(1), self.m2)
     return self.regTV.hessian(self.m.vector())
 def hessianab(self, ahat, bhat):
     """ ahat, bhat = Vector(V) """
     setfct(self.ahat, ahat)
     setfct(self.bhat, bhat)
     assign(self.abhat.sub(0), self.ahat)
     assign(self.abhat.sub(1), self.bhat)
     return self.H * self.abhat.vector()
Example #10
0
 def assemble_GNhessian(self, m_in):
     """ Assemble the Gauss-Newton Hessian at m_in 
     Not used anymore (wkformhess selects GN Hessian if needed)
     Left here for back-compatibility """
     setfct(self.m, m_in)
     self.H = assemble(self.wkformGNhess)
     self.precond = self.H + self.sMass
Example #11
0
 def iteration_backward(self, tt):
     setfct(self.rhs, self.Dt*self.ftime(tt))
     self.rhs.vector().axpy(-self.Dt, self.K*self.u1.vector())
     self.rhs.vector().axpy(-1.0, self.D*(self.u1.vector()-self.u0.vector()))
     if not self.bc == None: self.bc.apply(self.rhs.vector())
     self.solverM.solve(self.sol.vector(), self.rhs.vector())
     setfct(self.u2, 2.0*self.u1.vector())
     self.u2.vector().axpy(-1.0, self.u0.vector())
     self.u2.vector().axpy(self.Dt, self.sol.vector())
Example #12
0
 def plot_timeseries(self, timeseries, varname, index, skip, function):
     """ Plot every 'skip' entry of entry 'index' of a 'timeseries'.
     'function' = dl.Function """
     self.set_varname(varname)
     for ii, sol in enumerate(timeseries):
         if ii % skip == 0:
             setfct(function, sol[index])
             self.plot_vtk(function, ii)
     self.gather_vtkplots()
Example #13
0
 def plot_timeseries(self, timeseries, varname, index, skip, function):
     """ Plot every 'skip' entry of entry 'index' of a 'timeseries'.
     'function' = dl.Function """
     self.set_varname(varname)
     for ii, sol in enumerate(timeseries):
         if ii%skip == 0:
             setfct(function, sol[index])
             self.plot_vtk(function, ii)
     self.gather_vtkplots()
Example #14
0
 def assemble_hessian(self, m_in):
     """ Assemble the Hessian of TV at m_in """
     setfct(self.m, m_in)
     self.H = assemble(self.wkformhess)
     PCGN = self.parameters['PCGN']
     if PCGN:
         HGN = assemble(self.wkformGNhess)
         self.precond = HGN + self.sMass
     else:
         self.precond = self.H + self.sMass
Example #15
0
    def solveTV(self):
        """ Solve image denoising pb """

        self.u.vector().zero()
        normu_true = self.mediummisfit()

        # initial state = noisy image
        setfct(self.u, self.u_0)
        print 'min(u)={}, max(u)={}'.format(\
        np.amin(self.u.vector().array()), np.amax(self.u.vector().array()))

        cost, misfit, reg = self.costmisfitreg()
        costold = cost
        MG, normMG = self.gradient()
        normMG0 = normMG

        print '\t{:12s} {:12s} {:12s} {:12s} {:12s} {:12s} {:12s}\t{:12s} {:12s}'.format(\
        'iter', 'cost', 'misfit', 'reg', '||G||', 'a_LS', 'medmisfit', 'tol_cg', 'n_cg')
        print '{:12d} {:12.4e} {:12.4e} {:12.4e} {:12.4e} {:12s} {:12.2e} ({:7.2f} %)'.format(\
        0, cost, misfit, reg, normMG, '', self.mediummisfit(), 100.*self.mediummisfit()/normu_true)

        cgtol = self.parametersLS['cgtol']
        maxiter = self.parametersLS['maxiter']
        for ii in xrange(maxiter):
            if self.inexact:
                cgtol = min(cgtol, np.sqrt(normMG / normMG0))
                #cgtol = min(0.5, np.sqrt(normMG/normMG0)))
            else:
                cgtol = 1e-12
            cgiter, MGdu = self.searchdirection(MG, cgtol)
            success, alphaLS, cost, misfit, reg = self.linesearch(MG)
            MG, normMG = self.gradient()
            print '{:12d} {:12.4e} {:12.4e} {:12.4e} {:12.4e} {:12.4e} {:12.2e} ({:7.2f} %) {:12.2e} {:12d}'.format(\
            ii+1, cost, misfit, reg, normMG, alphaLS, \
            self.mediummisfit(), 100.*self.mediummisfit()/normu_true, cgtol, cgiter)

            if normMG < min(1e-12, 1e-10 * normMG0):
                print 'gradient sufficiently reduced -- optimization converged'
                break
            if not success:
                print 'Line search failed -- optimization aborted'
                break
            if np.abs(cost - costold) / costold < 1e-14:
                if cgtol < 1e-10:
                    print 'cost functional stagnates -- optimization aborted'
                    break
                else:
                    cgtol *= 1e-3

            costold = cost

        print 'min(u)={}, max(u)={}'.format(\
        np.amin(self.u.vector().array()), np.amax(self.u.vector().array()))
Example #16
0
    def ftimeincradj(self, tt):
        """ Compute rhs for incremental adjoint at time tt """
        try:
            indexf = int(np.where(isequal(self.PDE.times, tt, 1e-14))[0])
            indexa = int(np.where(isequal(self.PDE.times[::-1], tt, 1e-14))[0])
        except:
            print 'Error in ftimeincradj at time {}'.format(tt)
            print np.min(np.abs(self.PDE.times-tt))
            sys.exit(0)

        # B* B phat
#        assert isequal(tt, self.solincrfwd[indexf][1], 1e-16)
        setfct(self.phat, self.solincrfwd[indexf][0])
        self.qhat.vector().zero()
        self.qhat.vector().axpy(1.0, self.obsop.incradj(self.phat, tt))

        if not self.GN:
            # bhat: bhat*grad(ptilde).grad(v)
#            assert isequal(tt, self.soladji[indexa][1], 1e-16)
            setfct(self.q, self.soladji[indexa][0])
            self.qhat.vector().axpy(1.0, self.C*self.q.vector())

            # ahat: ahat*ptilde*q'':
            setfct(self.q, self.solppadji[indexa][0])
            self.qhat.vector().axpy(1.0, self.get_incra(self.q.vector()))

            # ABC:
            if self.PDE.parameters['abc']:
                setfct(self.phat, self.solpadji[indexa][0])
                self.qhat.vector().axpy(-0.5, self.Dp*self.phat.vector())

        return -1.0*self.qhat.vector()
Example #17
0
 def solvefwd(self, cost=False):
     self.PDE.set_fwd()
     self.PDE.ftime = self.fwdsource
     self.solfwd,_ = self.PDE.solve()
     # observations:
     self.Bp = np.zeros((len(self.obsop.PtwiseObs.Points),len(self.solfwd)))
     for index, sol in enumerate(self.solfwd):
         setfct(self.p, sol[0])
         self.Bp[:,index] = self.obsop.obs(self.p)
     if cost:
         assert not self.dd == None, "Provide observations"
         self.misfit = self.obsop.costfct(self.Bp, self.dd, self.PDE.times)
         self.cost_reg = self.regularization.cost(self.PDE.lam)
         self.cost = self.misfit + self.alpha_reg*self.cost_reg
Example #18
0
    def solve(self):
        """ General solver method """
        if self.timestepper == 'backward':
            def iterate(tt):  self.iteration_backward(tt)
        elif self.timestepper == 'centered':
            def iterate(tt):  self.iteration_centered(tt)
        else:
            print "Time stepper not implemented"
            sys.exit(1)

        if self.verbose:    print 'Compute solution'
        solout = [] # Store computed solution
        # u0:
        tt = self.get_tt(0)
        if self.verbose:    print 'Compute solution -- time {}'.format(tt)
        setfct(self.u0, self.u0init)
        solout.append([self.u0.vector().array(), tt])
        # Compute u1:
        if not self.u1init == None: self.u1 = self.u1init
        else:
            assert(not self.utinit == None)
            setfct(self.rhs, self.ftime(tt))
            self.rhs.vector().axpy(-self.fwdadj, self.D*self.utinit.vector())
            self.rhs.vector().axpy(-1.0, self.K*self.u0.vector())
            if not self.bc == None: self.bc.apply(self.rhs.vector())
            self.solverM.solve(self.sol.vector(), self.rhs.vector())
            setfct(self.u1, self.u0)
            self.u1.vector().axpy(self.fwdadj*self.Dt, self.utinit.vector())
            self.u1.vector().axpy(0.5*self.Dt**2, self.sol.vector())
        tt = self.get_tt(1)
        if self.verbose:    print 'Compute solution -- time {}'.format(tt)
        solout.append([self.u1.vector().array(), tt])
        # Iteration
        for nn in xrange(2, self.Nt+1):
            iterate(tt)
            # Advance to next time step
            setfct(self.u0, self.u1)
            setfct(self.u1, self.u2)
            tt = self.get_tt(nn)
            if self.verbose:    
                print 'Compute solution -- time {}, rhs {}'.\
                format(tt, np.max(np.abs(self.ftime(tt))))
            solout.append([self.u1.vector().array(),tt])
        if self.fwdadj > 0.0:   
            assert isequal(tt, self.Tf, 1e-16), \
            'tt={}, Tf={}, reldiff={}'.format(tt, self.Tf, abs(tt-self.Tf)/self.Tf)
        else:
            assert isequal(tt, self.t0, 1e-16), \
            'tt={}, t0={}, reldiff={}'.format(tt, self.t0, abs(tt-self.t0))
        return solout, self.computeerror()
Example #19
0
 def generatedata(self, noisepercent):
     """ compute data and add noisepercent (%) of noise """
     sigma = noisepercent * np.linalg.norm(self.f_true.vector().array()) / np.sqrt(self.dimV)
     print "sigma_noise = ", sigma
     np.random.seed(11)  # TODO: tmp
     eta = sigma * np.random.randn(self.dimV)
     self.dn = dl.Function(self.V)
     setfct(self.dn, eta)
     self.dn.vector().axpy(1.0, self.f_true.vector())
     print "min(true)={}, max(true)={}".format(
         np.amin(self.f_true.vector().array()), np.amax(self.f_true.vector().array())
     )
     print "min(noisy)={}, max(noisy)={}".format(
         np.amin(self.dn.vector().array()), np.amax(self.dn.vector().array())
     )
Example #20
0
    def grad(self, m):
        """ compute the gradient at m """
        setfct(self.m, m)
        self._assemble_invMw()

        self.gwx.vector().zero()
        self.gwx.vector().axpy(1.0, assemble(self.misfitwx))
        normgwx = norm(self.gwx.vector())

        self.gwy.vector().zero()
        self.gwy.vector().axpy(1.0, assemble(self.misfitwy))
        normgwy = norm(self.gwy.vector())

        if self.parameters['print']:
            print '[TVPD] |gw|={}'.format(np.sqrt(normgwx**2 + normgwy**2))

        return self.Htvx*(self.wx.vector() - self.invMwd*self.gwx.vector()) \
        + self.Htvy*(self.wy.vector() - self.invMwd*self.gwy.vector())
Example #21
0
    def solvefwd(self, cost=False):
        self.PDE.set_fwd()
        self.solfwd, self.solpfwd, self.solppfwd = [], [], [] 
        self.Bp = []

        #TODO: make fwdsource iterable to return source term
        Ricker = self.fwdsource[0]
        srcv = self.fwdsource[2]
        for sii in self.srcindex:
            ptsrc = self.fwdsource[1][sii]
            def srcterm(tt):
                srcv.zero()
                srcv.axpy(Ricker(tt), ptsrc)
                return srcv
            self.PDE.ftime = srcterm
            solfwd, solpfwd, solppfwd,_ = self.PDE.solve()
            self.solfwd.append(solfwd)
            self.solpfwd.append(solpfwd)
            self.solppfwd.append(solppfwd)

            self.PDEcount += 1

            #TODO: come back and parallellize this too (over time steps)
            Bp = np.zeros((len(self.obsop.PtwiseObs.Points),len(solfwd)))
            for index, sol in enumerate(solfwd):
                setfct(self.p, sol[0])
                Bp[:,index] = self.obsop.obs(self.p)
            self.Bp.append(Bp)

        if cost:
            assert not self.dd == None, "Provide data observations to compute cost"
            self.cost_misfit_local = 0.0
            for Bp, dd in izip(self.Bp, self.dd):
                self.cost_misfit_local += self.obsop.costfct(\
                Bp[:,self.tsteps], dd[:,self.tsteps],\
                self.PDE.times[self.tsteps], self.factors[self.tsteps])
            self.cost_misfit = MPI.sum(self.mpicomm_global, self.cost_misfit_local)
            self.cost_misfit /= len(self.fwdsource[1])
            self.cost_reg = self.regularization.costab(self.PDE.a, self.PDE.b)
            self.cost = self.cost_misfit + self.alpha_reg*self.cost_reg
            if DEBUG:   
                print 'cost_misfit={}, cost_reg={}'.format(\
                self.cost_misfit, self.cost_reg)
Example #22
0
 def test_gradient(self, f=None, n=5):
     """ test gradient with FD approx around point f """
     if f == None:
         f = self.f_true
     pm = [1.0, -1.0]
     eps = 1e-5
     self.gradient(f)
     for nn in xrange(1, n + 1):
         expr = dl.Expression("sin(n*pi*x[0]/200)*sin(n*pi*x[1]/100)", n=nn)
         df = dl.interpolate(expr, self.V)
         MGdf = self.MG.inner(df.vector())
         cost = []
         for sign in pm:
             setfct(self.g, f)
             self.g.vector().axpy(sign * eps, df.vector())
             cost.append(self.computecost(self.g))
         MGFD = (cost[0] - cost[1]) / (2 * eps)
         print "n={}:\tMGFD={:.5e}, MGdf={:.5e}, error={:.2e}".format(
             nn, MGFD, MGdf, np.abs(MGdf - MGFD) / np.abs(MGdf)
         )
Example #23
0
 def test_hessian(self, f=None, n=5):
     """ test Hessian with FD approx around point f """
     if f == None:
         f = self.f_true
     pm = [1.0, -1.0]
     eps = 1e-5
     self.Hessian(f)
     for nn in xrange(1, n + 1):
         expr = dl.Expression("sin(n*pi*x[0]/200)*sin(n*pi*x[1]/100)", n=nn)
         df = dl.interpolate(expr, self.V)
         Hdf = (self.Hess * df.vector()).array()
         MG = []
         for sign in pm:
             setfct(self.g, f)
             self.g.vector().axpy(sign * eps, df.vector())
             self.gradient(self.g)
             MG.append(self.MG.array())
         HFD = (MG[0] - MG[1]) / (2 * eps)
         print "n={}:\tHFD={:.5e}, Hdf={:.5e}, error={:.2e}".format(
             nn, np.linalg.norm(HFD), np.linalg.norm(Hdf), np.linalg.norm(Hdf - HFD) / np.linalg.norm(Hdf)
         )
Example #24
0
 def update_w(self, alpha):
     """ update w and re-scale wH """
     self.w.vector().axpy(alpha, self.dw.vector())
     # project each w (coord-wise) onto unit sphere to get wH
     (wx, wy) = self.w.split(deepcopy=True)
     wxa, wya = wx.vector().array(), wy.vector().array()
     normw = np.sqrt(wxa**2 + wya**2)
     factorw = [max(1.0, ii) for ii in normw]
     setfct(wx, wxa/factorw)
     setfct(wy, wya/factorw)
     assign(self.wH.sub(0), wx)
     assign(self.wH.sub(1), wy)
     # check
     (wx,wy) = self.wH.split(deepcopy=True)
     wxa, wya = wx.vector().array(), wy.vector().array()
     assert np.amax(np.sqrt(wxa**2 + wya**2)) <= 1.0 + 1e-14
     # Print results
     dualresnorm = assemble(self.dualresnorm)
     normgraddm = assemble(self.normgraddm)
     print 'line search dual variable: max(|w|)={}, err(w,df)={}, |grad(dm)|={}'.\
     format(np.amax(np.sqrt(normw)), np.sqrt(dualresnorm), np.sqrt(normgraddm))
Example #25
0
    def ftimeincrfwd(self, tt):
        """ Compute rhs for incremental forward at time tt """
        try:
            index = int(np.where(isequal(self.PDE.times, tt, 1e-14))[0])
        except:
            print 'Error in ftimeincrfwd at time {}'.format(tt)
            print np.min(np.abs(self.PDE.times-tt))
            sys.exit(0)

        # bhat: bhat*grad(p).grad(qtilde)
#        assert isequal(tt, self.solfwdi[index][1], 1e-16)
        setfct(self.p, self.solfwdi[index][0])
        self.q.vector().zero()
        self.q.vector().axpy(1.0, self.C*self.p.vector())

        # ahat: ahat*p''*qtilde:
        setfct(self.p, self.solppfwdi[index][0])
        self.q.vector().axpy(1.0, self.get_incra(self.p.vector()))

        # ABC:
        if self.PDE.parameters['abc']:
            setfct(self.phat, self.solpfwdi[index][0])
            self.q.vector().axpy(0.5, self.Dp*self.phat.vector())

        return -1.0*self.q.vector()
Example #26
0
def checkhessfd_med(ObjFctal, Medium, tolgradchk=1e-6, H = [1e-5, 1e-6, 1e-4], doublesided=True):
    """Finite-difference check for the Hessian of an ObjectiveFunctional
    object"""
    lenm = len(ObjFctal.getmarray())
    ObjFctal.backup_m()
    MGref = ObjFctal.getMGarray()
    if doublesided: factor = [1.0, -1.0]
    else:   factor = [1.0]
    hessxdir = ObjFctal.srchdir
    dirfct = ObjFctal.delta_m
    for textnb, dirct in zip(range(lenm), Medium):
        # Do computations for analytical Hessian:
        setfct(dirfct, dirct)
        ObjFctal.mult(dirfct.vector(), hessxdir.vector())
        normhess = np.linalg.norm(hessxdir.vector().array())
        print 'Hessian check -- direction {0}: ||H.x||={1:.5e}'\
        .format(textnb+1, normhess)
        # Do computations for FD Hessian:
        for hh in H:
            MG = []
            for fact in factor:
                ObjFctal.update_m(ObjFctal.getmcopyarray() + fact*hh*dirct)
                ObjFctal.solvefwd_cost()
                ObjFctal.solveadj_constructgrad()
                MG.append(ObjFctal.getMGarray())
            if doublesided: FDHessx = (MG[0] - MG[1])/(2.0*hh)
            else:   FDHessx = (MG[0] - MGref)/hh
            # Compute errors:
            err = np.linalg.norm(hessxdir.vector().array()-FDHessx)/normhess
            if err < tolgradchk:   
                print '\th={0:.1e}: ||FDH.x||={1:.5e}, error={2:.2e} -> OK!'\
                .format(hh, np.linalg.norm(FDHessx), err)
                break
            else:
                print '\th={0:.1e}: ||FDH.x||={1:.5e}, error={2:.2e}'\
                .format(hh, np.linalg.norm(FDHessx), err)
    # Restore initial value of m:
    ObjFctal.restore_m()
    ObjFctal.solvefwd_cost()
    ObjFctal.solveadj_constructgrad()
Example #27
0
 def copy(self):
     """(hard) copy constructor"""
     newobj = self.__class__(self.PDE.copy())
     setfct(newobj.MG, self.MG)
     setfct(newobj.Grad, self.Grad)
     setfct(newobj.srchdir, self.srchdir)
     newobj.obsop = self.obsop
     newobj.dd = self.dd
     newobj.fwdsource = self.fwdsource
     newobj.srcindex = self.srcindex
     newobj.tsteps = self.tsteps
     return newobj
Example #28
0
 def ftimeincradj(self, tt):
     """ Compute rhs for incremental adjoint at time tt """
     try:
         indexf = int(np.where(isequal(self.PDE.times, tt, 1e-14))[0])
         indexa = int(np.where(isequal(self.PDE.times[::-1], tt, 1e-14))[0])
     except:
         print 'Error in ftimeincradj at time {}'.format(tt)
         print np.min(np.abs(self.PDE.times-tt))
         sys.exit(0)
     # lamhat * grad(ptilde).grad(v)
     assert isequal(tt, self.soladj[indexa][1], 1e-16)
     setfct(self.v, self.soladj[indexa][0])
     setfct(self.vhat, self.C*self.v.vector())
     # B* B phat
     assert isequal(tt, self.solincrfwd[indexf][1], 1e-16)
     setfct(self.phat, self.solincrfwd[indexf][0])
     self.vhat.vector().axpy(1.0, self.obsop.incradj(self.phat, tt))
     # D'.dot(v)
     if self.PDE.abc and indexa > 0:
             setfct(self.v, \
             self.soladj[indexa-1][0] - self.soladj[indexa+1][0])
             self.vhat.vector().axpy(-.5*self.invDt, self.Dp*self.v.vector())
     return -1.0*self.vhat.vector().array()
Example #29
0
 def ftimeincrfwd(self, tt):
     """ Compute rhs for incremental forward at time tt """
     try:
         index = int(np.where(isequal(self.PDE.times, tt, 1e-14))[0])
     except:
         print 'Error in ftimeincrfwd at time {}'.format(tt)
         print np.min(np.abs(self.PDE.times-tt))
         sys.exit(0)
     # lamhat * grad(p).grad(vtilde)
     assert isequal(tt, self.solfwd[index][1], 1e-16)
     setfct(self.p, self.solfwd[index][0])
     setfct(self.v, self.C*self.p.vector())
     # D'.dot(p)
     if self.PDE.abc and index > 0:
             setfct(self.p, \
             self.solfwd[index+1][0] - self.solfwd[index-1][0])
             self.v.vector().axpy(.5*self.invDt, self.Dp*self.p.vector())
     return -1.0*self.v.vector().array()
Example #30
0
 def cost(self, m_in):
     """ returns the cost functional for self.m=m_in """
     setfct(self.m, m_in)
     return assemble(self.wkformcost)
Example #31
0
    def solveadj(self, grad=False):
        self.PDE.set_adj()
        self.obsop.assemble_rhsadj(self.Bp, self.dd, self.PDE.times, self.PDE.bc)
        self.PDE.ftime = self.obsop.ftimeadj
        self.soladj,_ = self.PDE.solve()
        if grad:
            self.MGv.zero()
            if self.PDE.abc:
                self.vD.vector().zero(); self.pD.vector().zero();
                self.p1D.vector().zero(); self.p2D.vector().zero();
            index = 0
            for fwd, adj, fact in \
            zip(self.solfwd, reversed(self.soladj), self.factors):
                ttf, tta = fwd[1], adj[1]
                assert isequal(ttf, tta, 1e-16), \
                'tfwd={}, tadj={}, reldiff={}'.format(ttf, tta, abs(ttf-tta)/ttf)
                setfct(self.p, fwd[0])
                setfct(self.v, adj[0])
                self.MGv.axpy(fact, assemble(self.wkformgrad))
#                self.MGv.axpy(fact, assemble(self.wkformgrad, \
#                form_compiler_parameters={'optimize':True,\
#                'representation':'quadrature'}))
                if self.PDE.abc:
                    if index%2 == 0:
                        self.p2D.vector().axpy(1.0, self.p.vector())
                        setfct(self.pD, self.p2D)
                        #self.MGv.axpy(1.0*0.5*self.invDt, assemble(self.wkformgradD))
                        self.MGv.axpy(fact*0.5*self.invDt, assemble(self.wkformgradD))
                        setfct(self.p2D, -1.0*self.p.vector())
                        setfct(self.vD, self.v)
                    else:
                        self.p1D.vector().axpy(1.0, self.p.vector())
                        setfct(self.pD, self.p1D)
                        #self.MGv.axpy(1.0*0.5*self.invDt, assemble(self.wkformgradD))
                        self.MGv.axpy(fact*0.5*self.invDt, assemble(self.wkformgradD))
                        setfct(self.p1D, -1.0*self.p.vector())
                        setfct(self.vD, self.v)
                index += 1
            self.MGv.axpy(self.alpha_reg, self.regularization.grad(self.PDE.lam))
            self.solverM.solve(self.Gradv, self.MGv)
 def assemble_hessianab(self, a, b):
     setfct(self.a, a)
     setfct(self.b, b)
     self.H = assemble(self.hessian)
     self.Hprecond = assemble(self.precond)
 def gradab(self, ma_in, mb_in):
     """ ma_in, mb_in = Function(V) """
     setfct(self.a, ma_in)
     setfct(self.b, mb_in)
     return assemble(self.grad)
Example #34
0
 def assemble_GNhessian(self, m_in):
     """ Assemble the Gauss-Newton Hessian at m_in """
     setfct(self.m, m_in)
     self.H = assemble(self.wkformGNhess)
Example #35
0
    def mult(self, abhat, y):
        """
        mult(self, abhat, y): return y = Hessian * abhat
        inputs:
            y, abhat = Function(V).vector()
        """
        setfct(self.ab, abhat)
        ahat, bhat = self.ab.split(deepcopy=True)
        setfct(self.ahat, ahat)
        setfct(self.bhat, bhat)
        if not self.inverta:
            self.ahat.vector().zero()
        if not self.invertb:
            self.bhat.vector().zero()

        self.C = assemble(self.wkformrhsincrb)
        if not self.PDE.parameters['lumpM']:    self.E = assemble(self.wkformrhsincra)
        if self.PDE.parameters['abc']:  self.Dp = assemble(self.wkformincrrhsABC)

        t0, t1 = self.tsteps[0], self.tsteps[-1]+1

        # Compute Hessian*abhat
        self.ab.vector().zero()
        yaF_local, ybF_local = self.ab.split(deepcopy=True)
        ya_local, yb_local = yaF_local.vector(), ybF_local.vector()

        # iterate over sources:
        for self.solfwdi, self.solpfwdi, self.solppfwdi, \
        self.soladji, self.solpadji, self.solppadji \
        in izip(self.solfwd, self.solpfwd, self.solppfwd, \
        self.soladj, self.solpadj, self.solppadj):
            # incr. fwd
            self.PDE.set_fwd()
            self.PDE.ftime = self.ftimeincrfwd
            self.solincrfwd,solpincrfwd,self.solppincrfwd,_ = self.PDE.solve()
            self.PDEcount += 1

            # incr. adj
            self.PDE.set_adj()
            self.PDE.ftime = self.ftimeincradj
            solincradj,_,_,_ = self.PDE.solve()
            self.PDEcount += 1

            # assemble Hessian-vect product:
            for fwd, adj, fwdp, incrfwdp, \
            fwdpp, incrfwdpp, incrfwd, incradj, fact \
            in izip(self.solfwdi[t0:t1], self.soladji[::-1][t0:t1],\
            self.solpfwdi[t0:t1], solpincrfwd[t0:t1], \
            self.solppfwdi[t0:t1], self.solppincrfwd[t0:t1],\
            self.solincrfwd[t0:t1], solincradj[::-1][t0:t1], self.factors[t0:t1]):
#                ttf, tta, ttf2 = incrfwd[1], incradj[1], fwd[1]
#                assert isequal(ttf, tta, 1e-16), 'tfwd={}, tadj={}, reldiff={}'.\
#                format(ttf, tta, abs(ttf-tta)/ttf)
#                assert isequal(ttf, ttf2, 1e-16), 'tfwd={}, tadj={}, reldiff={}'.\
#                format(ttf, ttf2, abs(ttf-ttf2)/ttf)

                setfct(self.q, adj[0])
                setfct(self.qhat, incradj[0])
                if self.invertb:
                    # Hessian b
                    setfct(self.p, fwd[0])
                    setfct(self.phat, incrfwd[0])
                    if self.GN:
                        yb_local.axpy(fact, assemble(self.wkformhessbGN))
                    else:
                        yb_local.axpy(fact, assemble(self.wkformhessb))

                if self.inverta:
                    # Hessian a
                    setfct(self.p, fwdpp[0])
                    setfct(self.phat, incrfwdpp[0])
                    ya_local.axpy(fact, self.get_hessiana())

                if self.PDE.parameters['abc']:
                    if not self.GN:
                        setfct(self.p, incrfwdp[0])
                        if self.inverta:
                            ya_local.axpy(0.5*fact, assemble(self.wkformgradaABC))
                        if self.invertb:
                            yb_local.axpy(0.5*fact, assemble(self.wkformgradbABC))

                    setfct(self.p, fwdp[0])
                    setfct(self.q, incradj[0])
                    if self.inverta:
                        ya_local.axpy(0.5*fact, assemble(self.wkformgradaABC))
                    if self.invertb:
                        yb_local.axpy(0.5*fact, assemble(self.wkformgradbABC))

                    if not self.GN:
                        setfct(self.q, adj[0])
                        if self.inverta:
                            ya_local.axpy(0.25*fact, assemble(self.wkformhessaABC))
                        if self.invertb:
                            yb_local.axpy(0.25*fact, assemble(self.wkformhessbABC))

        yaF, ybF = self.ab.split(deepcopy=True)
        MPIAllReduceVector(ya_local, yaF.vector(), self.mpicomm_global)
        MPIAllReduceVector(yb_local, ybF.vector(), self.mpicomm_global)
        self.ab.vector().zero()
        if self.inverta:
            assign(self.ab.sub(0), yaF)
        if self.invertb:
            assign(self.ab.sub(1), ybF)
        y.zero()
        y.axpy(1.0/len(self.fwdsource[1]), self.ab.vector())
        if DEBUG:
            print 'Hess_misfit={}, Hess_reg={}'.format(\
            y.norm('l2'),\
            self.regularization.hessianab(self.ahat.vector(),\
            self.bhat.vector()).norm('l2'))

        y.axpy(self.alpha_reg, \
        self.regularization.hessianab(self.ahat.vector(), self.bhat.vector()))
 def gradabvect(self, m1, m2):
     setfct(self.tmpm1, m1)
     setfct(self.tmpm2, m2)
     return self.gradab(self.tmpm1, self.tmpm2)
Example #37
0
 def grad(self, m_in):
     """ returns the gradient (in vector format) evaluated at self.m = m_in """
     setfct(self.m, m_in)
     self.H = None
     return assemble(self.wkformgrad)
Example #38
0
 def mult(self, lamhat, y):
     """
     mult(self, lamhat, y): return y = Hessian * lamhat
     inputs:
         y, lamhat = Function(V).vector()
     """
     self.regularization.assemble_hessian(lamhat)
     setfct(self.lamhat, lamhat)
     self.C = assemble(self.wkformrhsincr)
     if self.PDE.abc:    self.Dp = assemble(self.wkformDprime)
     # solve for phat
     self.PDE.set_fwd()
     self.PDE.ftime = self.ftimeincrfwd
     self.solincrfwd,_ = self.PDE.solve()
     # solve for vhat
     self.PDE.set_adj()
     self.PDE.ftime = self.ftimeincradj
     self.solincradj,_ = self.PDE.solve()
     # Compute Hessian*lamhat
     y.zero()
     index = 0
     if self.PDE.abc:
         self.vD.vector().zero(); self.vhatD.vector().zero(); 
         self.p1D.vector().zero(); self.p2D.vector().zero();
         self.p1hatD.vector().zero(); self.p2hatD.vector().zero();
     for fwd, adj, incrfwd, incradj, fact in \
     zip(self.solfwd, reversed(self.soladj), \
     self.solincrfwd, reversed(self.solincradj), self.factors):
         ttf, tta, ttf2 = incrfwd[1], incradj[1], fwd[1]
         assert isequal(ttf, tta, 1e-16), 'tfwd={}, tadj={}, reldiff={}'.\
         format(ttf, tta, abs(ttf-tta)/ttf)
         assert isequal(ttf, ttf2, 1e-16), 'tfwd={}, tadj={}, reldiff={}'.\
         format(ttf, ttf2, abs(ttf-ttf2)/ttf)
         setfct(self.p, fwd[0])
         setfct(self.v, adj[0])
         setfct(self.phat, incrfwd[0])
         setfct(self.vhat, incradj[0])
         y.axpy(fact, assemble(self.wkformhess))
         if self.PDE.abc:
             if index%2 == 0:
                 self.p2D.vector().axpy(1.0, self.p.vector())
                 self.p2hatD.vector().axpy(1.0, self.phat.vector())
                 setfct(self.dp, self.p2D)
                 setfct(self.dph, self.p2hatD)
                 y.axpy(1.0*0.5*self.invDt, assemble(self.wkformhessD))
                 setfct(self.p2D, -1.0*self.p.vector())
                 setfct(self.p2hatD, -1.0*self.phat.vector())
             else:
                 self.p1D.vector().axpy(1.0, self.p.vector())
                 self.p1hatD.vector().axpy(1.0, self.phat.vector())
                 setfct(self.dp, self.p1D)
                 setfct(self.dph, self.p1hatD)
                 y.axpy(1.0*0.5*self.invDt, assemble(self.wkformhessD))
                 setfct(self.p1D, -1.0*self.p.vector())
                 setfct(self.p1hatD, -1.0*self.phat.vector())
             setfct(self.vD, self.v)
             setfct(self.vhatD, self.vhat)
         index += 1
     # add regularization term
     y.axpy(self.alpha_reg, self.regularization.hessian(lamhat))
Example #39
0
 def update(self, parameters_m):
     assert not self.timestepper == None, "You need to set a time stepping method"
     # Time options:
     if parameters_m.has_key('t0'):   self.t0 = parameters_m['t0'] 
     if parameters_m.has_key('tf'):   self.tf = parameters_m['tf'] 
     if parameters_m.has_key('Dt'):   self.Dt = parameters_m['Dt'] 
     if parameters_m.has_key('t0') or parameters_m.has_key('tf') or parameters_m.has_key('Dt'):
         self.Nt = int(round((self.tf-self.t0)/self.Dt))
         self.Tf = self.t0 + self.Dt*self.Nt
         self.times = np.linspace(self.t0, self.Tf, self.Nt+1)
         assert isequal(self.times[1]-self.times[0], self.Dt, 1e-16), "Dt modified"
         self.Dt = self.times[1] - self.times[0]
         assert isequal(self.Tf, self.tf, 1e-2), "Final time differs by more than 1%"
         if not isequal(self.Tf, self.tf, 1e-12):
             print 'Final time modified from {} to {} ({}%)'.\
             format(self.tf, self.Tf, abs(self.Tf-self.tf)/self.tf)
     # Initial conditions:
     if parameters_m.has_key('u0init'):   self.u0init = parameters_m['u0init']
     if parameters_m.has_key('utinit'):   self.utinit = parameters_m['utinit']
     if parameters_m.has_key('u1init'):   self.u1init = parameters_m['u1init']
     if parameters_m.has_key('um1init'):   self.um1init = parameters_m['um1init']
     # Medium parameters:
     setfct(self.lam, parameters_m['lambda'])
     if self.verbose: print 'lambda updated '
     if self.elastic == True:    
         setfct(self.mu, parameters_m['mu'])
         if self.verbose: print 'mu updated'
     if self.verbose: print 'assemble K',
     self.K = assemble(self.weak_k)
     if self.verbose: print ' -- K assembled'
     if parameters_m.has_key('rho'):
         setfct(self.rho, parameters_m['rho'])
         # Mass matrix:
         if self.verbose: print 'rho updated\nassemble M',
         Mfull = assemble(self.weak_m)
         if self.lump:
             self.solverM = LumpedMatrixSolverS(self.V)
             self.solverM.set_operator(Mfull, self.bc)
             self.M = self.solverM
         else:
             if mpisize == 1:
                 self.solverM = LUSolver()
                 self.solverM.parameters['reuse_factorization'] = True
                 self.solverM.parameters['symmetric'] = True
             else:
                 self.solverM = KrylovSolver('cg', 'amg')
                 self.solverM.parameters['report'] = False
             self.M = Mfull
             if not self.bc == None: self.bc.apply(Mfull)
             self.solverM.set_operator(Mfull)
         if self.verbose: print ' -- M assembled'
     # Matrix D for abs BC
     if self.abc == True:    
         if self.verbose:    print 'assemble D',
         Mfull = assemble(self.weak_m)
         Dfull = assemble(self.weak_d)
         if self.lumpD:
             self.D = LumpedMatrixSolverS(self.V)
             self.D.set_operator(Dfull, None, False)
             if self.lump:
                 self.solverMplD = LumpedMatrixSolverS(self.V)
                 self.solverMplD.set_operators(Mfull, Dfull, .5*self.Dt, self.bc)
                 self.MminD = LumpedMatrixSolverS(self.V)
                 self.MminD.set_operators(Mfull, Dfull, -.5*self.Dt, self.bc)
         else:
             self.D = Dfull
         if self.verbose:    print ' -- D assembled'
     else:   self.D = 0.0
 def assemble_hessianab(self, m1, m2):
     """ Assemble Hessian matrix for regularization """
     setfct(self.m1, m1)
     setfct(self.m2, m2)
     self.H = assemble(self.hessian)
 def assemble_hessianab(self, m1, m2):
     setfct(self.m1, m1)
     setfct(self.m2, m2)
     assign(self.m.sub(0), self.m1)
     assign(self.m.sub(1), self.m2)
     self.regTV.assemble_hessian(self.m)
 def grad(self, uin, udin):
     isFunction(uin)
     isFunction(udin)
     setfct(self.diff, uin.vector() - udin.vector())
     return self.W * self.diffv
 def costfct_F(self, uin, udin):
     isFunction(uin)
     isFunction(udin)
     setfct(self.diff, uin.vector()-udin.vector())
     return 0.5 * (self.W*self.diffv).inner(self.diffv)
 def costabvect(self, m1, m2):
     setfct(self.tmpm1, m1)
     setfct(self.tmpm2, m2)
     return self.costab(self.tmpm1, self.tmpm2)
 def costab(self, ma_in, mb_in):
     setfct(self.a, ma_in)
     setfct(self.b, mb_in)
     return assemble(self.cost)
Example #46
0
 def grad(self, m_in):
     """ returns the gradient (in vector format) evaluated at self.m = m_in """
     setfct(self.m, m_in)
     return assemble(self.wkformgrad)
Example #47
0
 def compute_dw(self, dm):
     """ Compute dw """
     setfct(self.dm, dm)
     b = assemble(self.rhswwk)
     solve(self.Mw, self.dw.vector(), b)
 def gradab(self, m1, m2):
     """ returns gradient at (m1,m2) as a vector """
     setfct(self.m1, m1)
     setfct(self.m2, m2)
     return assemble(self.gradm)
Example #49
0
 def cost(self, m_in):
     """ returns the cost functional for self.m=m_in """
     setfct(self.m, m_in)
     self.H = None
     return assemble(self.wkformcost)
 def costab(self, m1, m2):
     """ Compute value of cost function at (m1,m2) """
     setfct(self.m1, m1)
     setfct(self.m2, m2)
     return assemble(self.wkformcost)
Example #51
0
 def assemble_hessian(self, m_in):
     """ Assemble the Hessian of TV at m_in """
     setfct(self.m, m_in)
     self.H = assemble(self.wkformhess)
Example #52
0
 def cost(self, m):
     """ evaluate the cost functional at m """
     setfct(self.m, m)
     return assemble(self.wkformcost)
Example #53
0
 def update_m(self, medparam):
     """ medparam contains both med parameters """
     setfct(self.ab, medparam)
     a, b = self.ab.split(deepcopy=True)
     self.update_PDE({'a':a, 'b':b})
Example #54
0
    def solveadj(self, grad=False):
        self.PDE.set_adj()
        self.soladj, self.solpadj, self.solppadj = [], [], []

        for Bp, dd in zip(self.Bp, self.dd):
            self.obsop.assemble_rhsadj(Bp, dd, self.PDE.times, self.PDE.bc)
            self.PDE.ftime = self.obsop.ftimeadj
            soladj,solpadj,solppadj,_ = self.PDE.solve()
            self.soladj.append(soladj)
            self.solpadj.append(solpadj)
            self.solppadj.append(solppadj)

            self.PDEcount += 1

        if grad:
            self.MG.vector().zero()
            MGa_local, MGb_local = self.MG.split(deepcopy=True)
            MGav_local, MGbv_local = MGa_local.vector(), MGb_local.vector()

            t0, t1 = self.tsteps[0], self.tsteps[-1]+1

            for solfwd, solpfwd, solppfwd, soladj in \
            izip(self.solfwd, self.solpfwd, self.solppfwd, self.soladj):

                for fwd, fwdp, fwdpp, adj, fact in \
                izip(solfwd[t0:t1], solpfwd[t0:t1], solppfwd[t0:t1],\
                soladj[::-1][t0:t1], self.factors[t0:t1]):
                    setfct(self.q, adj[0])
                    if self.inverta:
                        # gradient a
                        setfct(self.p, fwdpp[0])
                        MGav_local.axpy(fact, self.get_gradienta()) 
                    if self.invertb:
                        # gradient b
                        setfct(self.p, fwd[0])
                        assemble(form=self.wkformgradb, tensor=self.wkformgradbout)
                        MGbv_local.axpy(fact, self.wkformgradbout)

                    if self.PDE.parameters['abc']:
                        setfct(self.p, fwdp[0])
                        if self.inverta:
                            assemble(form=self.wkformgradaABC, tensor=self.wkformgradaABCout)
                            MGav_local.axpy(0.5*fact, self.wkformgradaABCout)
                        if self.invertb:
                            assemble(form=self.wkformgradbABC, tensor=self.wkformgradbABCout)
                            MGbv_local.axpy(0.5*fact, self.wkformgradbABCout)

            MGa, MGb = self.MG.split(deepcopy=True)
            MPIAllReduceVector(MGav_local, MGa.vector(), self.mpicomm_global)
            MPIAllReduceVector(MGbv_local, MGb.vector(), self.mpicomm_global)
            setfct(MGa, MGa.vector()/len(self.fwdsource[1]))
            setfct(MGb, MGb.vector()/len(self.fwdsource[1]))
            self.MG.vector().zero()
            if self.inverta:
                assign(self.MG.sub(0), MGa)
            if self.invertb:
                assign(self.MG.sub(1), MGb)
            if DEBUG:
                print 'grad_misfit={}, grad_reg={}'.format(\
                self.MG.vector().norm('l2'),\
                self.regularization.gradab(self.PDE.a, self.PDE.b).norm('l2'))

            self.MG.vector().axpy(self.alpha_reg, \
            self.regularization.gradab(self.PDE.a, self.PDE.b))

            try:
                self.solverM.solve(self.Grad.vector(), self.MG.vector())
            except:
                # if |G|<<1, first residuals may diverge
                # caveat: Hope that ALL processes throw an exception
                pseudoGradnorm = np.sqrt(self.MGv.inner(self.MGv))
                if pseudoGradnorm < 1e-8:
                    print '*** Warning: Increasing divergence_limit for Mass matrix solver'
                    self.solverM.parameters["divergence_limit"] = 1e6
                    self.solverM.solve(self.Grad.vector(), self.MG.vector())
                else:
                    print '*** Error: Problem with Mass matrix solver'
                    sys.exit(1)