# ax.set_title('obs'+str(ii)) # fig.savefig(filename + '/observations' + str(iter) + '.eps') # plt.close(fig) # stopping criterion (gradient) if gradnorm < gradnorm0 * tolgrad or gradnorm < 1e-12: print '\nGradient sufficiently reduced -- optimization stopped' break # search direction tolcg = min(0.5, np.sqrt(gradnorm / gradnorm0)) cgiter, cgres, cgid, tolcg = compute_searchdirection( waveobj, 'Newt', tolcg) myplot.set_varname('srchdir' + str(iter)) myplot.plot_vtk(waveobj.srchdir) # line search cost_old = waveobj.cost statusLS, LScount, alpha = bcktrcklinesearch(waveobj, 12) cost = waveobj.cost print '{:11.3f} {:12.2e} {:10d}'.\ format(alpha, tolcg, cgiter) # stopping criterion (cost) if np.abs(cost - cost_old) / np.abs(cost_old) < tolcost: print 'Cost function stagnates -- optimization stopped' break # Compute eigenspectrum waveobj.alpha_reg = 0.0 # no regularization Omega = np.random.randn(Vm.dim() * 60).reshape((Vm.dim(), 60)) #TODO: need to left-multiply Omega by R^{-1/2}.M (to be checked) d, U = doublePassG(waveobj, regul.precond, regul.getprecond(), Omega, 40) np.savetxt(filename + str(Nxy) + '/eigenvalues.txt', d) # myplot.set_varname('eigenvectors')
def run_problem(): # Domain, f-e spaces and boundary conditions: mesh = UnitSquareMesh(20,20) V = FunctionSpace(mesh, 'Lagrange', 2) # space for state and adjoint variables Vm = FunctionSpace(mesh, 'Lagrange', 1) # space for medium parameter Vme = FunctionSpace(mesh, 'Lagrange', 5) # sp for target med param # Define zero Boundary conditions: def u0_boundary(x, on_boundary): return on_boundary u0 = Constant("0.0") bc = DirichletBC(V, u0, u0_boundary) # Define target medium and rhs: mtrue_exp = Expression('1 + 7*(pow(pow(x[0] - 0.5,2) +' + \ ' pow(x[1] - 0.5,2),0.5) > 0.2)') mtrue = interpolate(mtrue_exp, Vme) f = Expression("1.0") # Compute target data: noisepercent = 0.05 # e.g., 0.02 = 2% noise level ObsOp = ObsEntireDomain({'V': V,'noise':noisepercent}) goal = ObjFctalElliptic(V, Vme, bc, bc, [f], ObsOp) goal.update_m(mtrue) goal.solvefwd() UDnoise = goal.U # Solve reconstruction problem: Regul = LaplacianPrior({'Vm':Vm,'gamma':1e-3,'beta':1e-14}) ObsOp.noise = False InvPb = ObjFctalElliptic(V, Vm, bc, bc, [f], ObsOp, UDnoise, Regul, [], False) InvPb.update_m(1.0) # Set initial medium InvPb.solvefwd_cost() # Choose between steepest descent and Newton's method: METHODS = ['sd','Newt'] meth = METHODS[1] if meth == 'sd': alpha_init = 1e3 elif meth == 'Newt': alpha_init = 1.0 nbcheck = 0 # Grad and Hessian checks nbLS = 20 # Max nb of line searches # Prepare results outputs: PP = PostProcessor(meth, Vm, mtrue) PP.getResults0(InvPb) # Get results for index 0 (before first iteration) PP.printResults() # Start iteration: maxiter = 100 for it in range(1, maxiter+1): InvPb.solveadj_constructgrad() # Check gradient and Hessian: if nbcheck and (it == 1 or it % 10 == 0): checkgradfd(InvPb, nbcheck) checkhessfd(InvPb, nbcheck) # Compute search direction: if it == 1: gradnorm_init = InvPb.getGradnorm() if meth == 'Newt': if it == 1: maxtolcg = .5 else: maxtolcg = CGresults[3] else: maxtolcg = None CGresults = compute_searchdirection(InvPb, meth, gradnorm_init, maxtolcg) # Compute line search: LSresults = bcktrcklinesearch(InvPb, nbLS, alpha_init) InvPb.plotm(it) # Plot current medium reconstruction # Print results: PP.getResults(InvPb, LSresults, CGresults) PP.printResults() if PP.Stop(): break # Stopping criterion alpha_init = PP.alpha_init() # Initialize next alpha when using sd InvPb.gatherm() # Create one plot for all intermediate reconstructions if it == maxiter: print "Max nb of iterations reached."
print '[a]: iter={}, final norm={}, <dp,MG>={}'.format(\ solvera.iter, solvera.final_norm,\ waveobja.srchdir.vector().inner(MGaa.vector())) diffa = sola.vector() - waveobja.srchdir.vector() diffanorm = diffa.norm('l2') srchanorm = waveobja.srchdir.vector().norm('l2') if mpirank == 0: print '|sola|={:.16e}, |srcha|={:.16e}, reldiff={:.2e}'.format(\ solanorm, srchanorm, diffanorm/srchanorm) # Test each search direction dpMG = waveobjab.srchdir.vector().inner(waveobjab.MGv) print '[ab]: <dp,MG>={}'.format(dpMG) _, LScount, alpha = bcktrcklinesearch(waveobjab) meda, medb = waveobjab.mediummisfit(mt) print '[ab]: LScount={}, alpha={}'.format(LScount, alpha) print '[ab]: meda={:.16e}, medb={:.6e}'.format(meda, medb) waveobjab.solveadj_constructgrad() gradnorm = np.sqrt(waveobjab.MGv.inner(waveobjab.Grad.vector())) print '[ab]: |G|={:.16e}'.format(gradnorm) waveobjab.update_PDE(evaluationpoint) waveobjab.solvefwd_cost() waveobjab.solveadj_constructgrad() waveobjab.srchdir.vector().zero() dl.assign(waveobjab.srchdir.sub(0), waveobja.srchdir) dpMG = waveobjab.srchdir.vector().inner(waveobjab.MGv) print '[a]: <dp,MG>={}'.format(dpMG) _, LScount, alpha = bcktrcklinesearch(waveobjab)
def inversion(self, initial_medium, target_medium, mpicomm, \ parameters_in=[], myplot=None): """ solve inverse problem with that objective function """ parameters = {'tolgrad':1e-10, 'tolcost':1e-14, 'maxnbNewtiter':50, \ 'maxtolcg':0.5} parameters.update(parameters_in) maxnbNewtiter = parameters['maxnbNewtiter'] tolgrad = parameters['tolgrad'] tolcost = parameters['tolcost'] tolcg = parameters['maxtolcg'] mpirank = MPI.rank(mpicomm) self.update_m(initial_medium) self._plotm(myplot, 'init') if mpirank == 0: print '\t{:12s} {:10s} {:12s} {:12s} {:12s} {:10s} \t{:10s} {:12s} {:12s}'.format(\ 'iter', 'cost', 'misfit', 'reg', '|G|', 'medmisf', 'a_ls', 'tol_cg', 'n_cg') dtruenorm = np.sqrt(target_medium.vector().\ inner(self.MM*target_medium.vector())) self.solvefwd_cost() for it in xrange(maxnbNewtiter): self.solveadj_constructgrad() # compute gradient if it == 0: gradnorm0 = self.Gradnorm diff = self.m.vector() - target_medium.vector() medmisfit = np.sqrt(diff.inner(self.MM * diff)) if mpirank == 0: print '{:12d} {:12.4e} {:12.2e} {:12.2e} {:11.4e} {:10.2e} ({:4.2f})'.\ format(it, self.cost, self.misfit, self.regul, \ self.Gradnorm, medmisfit, medmisfit/dtruenorm), self._plotm(myplot, str(it)) self._plotgrad(myplot, str(it)) if self.Gradnorm < gradnorm0 * tolgrad or self.Gradnorm < 1e-12: if mpirank == 0: print '\nGradient sufficiently reduced -- optimization stopped' break # Compute search direction: tolcg = min(tolcg, np.sqrt(self.Gradnorm / gradnorm0)) self.assemble_hessian() # for regularization cgiter, cgres, cgid, tolcg = compute_searchdirection( self, 'Newt', tolcg) self._plotsrchdir(myplot, str(it)) # Line search: cost_old = self.cost statusLS, LScount, alpha = bcktrcklinesearch(self, 12) if mpirank == 0: print '{:11.3f} {:12.2e} {:10d}'.format(alpha, tolcg, cgiter) if self.PD: self.Regul.update_w(self.srchdir.vector(), alpha) if np.abs(self.cost - cost_old) / np.abs(cost_old) < tolcost: if mpirank == 0: if tolcg < 1e-14: print 'Cost function stagnates -- optimization aborted' break tolcg = 0.001 * tolcg
nbLS = 20 # Max nb of line searches # Prepare results outputs: PP = PostProcessor(meth, Vm, mtrue, mycomm) PP.getResults0(InvPb) # Get results for index 0 (before first iteration) PP.printResults(myrank) # Start iteration: maxiter = 100 for it in range(1, maxiter+1): InvPb.solveadj_constructgrad() # Check gradient and Hessian: if nbcheck and (it == 1 or it % 10 == 0): checkgradfd(InvPb, nbcheck) checkhessfd(InvPb, nbcheck) # Compute search direction: if it == 1: gradnorm_init = InvPb.getGradnorm() if meth == 'Newt': if it == 1: maxtolcg = .5 else: maxtolcg = CGresults[3] else: maxtolcg = None CGresults = compute_searchdirection(InvPb, meth, gradnorm_init, maxtolcg) # Compute line search: LSresults = bcktrcklinesearch(InvPb, nbLS, alpha_init) InvPb.plotm(it) # Plot current medium reconstruction # Print results: PP.getResults(InvPb, LSresults, CGresults) PP.printResults(myrank) if PP.Stop(myrank): break # Stopping criterion alpha_init = PP.alpha_init() # Initialize next alpha when using sd InvPb.gatherm() # Create one plot for all intermediate reconstructions if it == maxiter: print "Max nb of iterations reached."