KASKADE 7 development version
ip_aux.hh
Go to the documentation of this file.
1#ifndef IP_AUX_HH
2#define IP_AUX_HH
3
4#include <memory>
5#include "ipfunctional.hh"
6#include "fem/variables.hh"
8#include "dune_bridge.hh"
9#include "newton_damped.hh"
10#include "homotopy_base.hh"
12#include <limits.h>
13#include <boost/timer/timer.hpp>
15
22namespace Bridge{
24
27template<class BarrierFunctional,
28 class VectorImpl,
29 class ImageImpl=VectorImpl,
30 class QuadRule = TrapezoidalRule<typename BarrierFunctional::AnsatzVars::Grid::ctype, BarrierFunctional::AnsatzVars::Grid::dimension> >
32{
33public:
34 typedef BarrierFunctional IPFunctional;
35 typedef typename BarrierFunctional::AnsatzVars::Grid Grid;
36 typedef typename Grid::LeafGridView GridView;
37 typedef VectorImpl DomainElement;
38 typedef ImageImpl ImageElement;
39 typedef typename BarrierFunctional::Scalar Scalar;
40
41 typedef KaskadeLinearization<typename BarrierFunctional::OptimalityFunctional, VectorImpl> Unconstrained;
42 typedef KaskadeLinearization<BarrierFunctional, VectorImpl, QuadRule> Barrier;
43 typedef Dune::LinearOperator<DomainElement, ImageElement> OperatorType;
44
45 IPLinearization(BarrierFunctional const& fu, DomainElement const& x_)
46 : blin(fu,x_), vlin(fu.unconstrainedFunctional,x_), bfun(fu), prepared(false)
47 {
48 flush();
49 bfun.prepareConstraintsCache(vlin.getOriginImpl());
50 prepared=true;
51 }
52
53 void precompute() {
54 if(!prepared)
55 {
56 bfun.prepareConstraintsCache(vlin.getOriginImpl());
57 prepared=true;
58 }
59 vlin.precompute();
60 blin.precompute();
61 }
62
63
65 double getMu() const {return bfun.mu; }
66
67 int cols(int cbegin, int cend) const { return vlin.cols(cbegin, cend);}
68 int rows(int cbegin, int cend) const { return vlin.rows(cbegin, cend);}
69
70 void getMatrixBlocks(MatrixAsTriplet<Scalar>& mat, int rbegin, int rend, int colbegin, int colend) const
71 {
72 matb.resize(0);
73 if(!prepared)
74 {
75 bfun.prepareConstraintsCache(vlin.getOriginImpl());
76 prepared=true;
77 }
78 vlin.getMatrixBlocks(mat, rbegin, rend, colbegin, colend);
79 blin.getMatrixBlocks(matb, rbegin, rend, colbegin, colend);
80 mat+=matb;
81 }
82 void getRHSBlocks(std::vector<Scalar>& rhs, int rbegin, int rend) const
83 {
84 vlin.getRHSBlocks(rhs, rbegin, rend);
85 if(BarrierFunctional::parameterLin!=1)
86 {
87 if(!prepared)
88 {
89 bfun.prepareConstraintsCache(vlin.getOriginImpl());
90 prepared=true;
91 }
92 blin.getRHSBlocks(rhsb, rbegin, rend);
93 int iend=std::min(rhs.size(),rhsb.size());
94 if(BarrierFunctional::parameterLin==0) for(int i=0; i<iend;++i) rhs[i]+=rhsb[i];
95 if(BarrierFunctional::parameterLin==2) for(int i=0; i<iend;++i) rhs[i]=rhsb[i];
96 }
97 }
98
99 DomainElement const& getOriginImpl() const {return vlin.getOriginImpl(); }
100
101 int nRowBlocks() const { return vlin.nRowBlocks(); }
102 int nColBlocks() const { return vlin.nColBlocks(); }
103
104 void flush() { vlin.flush(); blin.flush(); matb.resize(0); rhsb.resize(0); prepared=false; }
105
106 void touch() { vlin.touch(); blin.touch(); }
107
108 double getValue() const
109 {
110 if(!prepared)
111 {
112 bfun.prepareConstraintsCache(vlin.getOriginImpl());
113 prepared=true;
114 }
115 return vlin.getValue()+blin.getValue();
116 }
117
118 double getL1norm() const
119 {
120 if(!prepared)
121 {
122 bfun.prepareConstraintsCache(vlin.getOriginImpl());
123 prepared=true;
124 }
125 return vlin.getL1norm()+blin.getL1norm();
126 }
127
128 Barrier const& getBarrier() const {return blin;}
129 Unconstrained const& getUnconstrained() const {return vlin;}
130
131private:
132 mutable MatrixAsTriplet<Scalar> matb;
133 mutable std::vector<Scalar> rhsb;
134 Barrier blin;
135 Unconstrained vlin;
136 BarrierFunctional const& bfun;
137 mutable bool prepared;
138};
139
140
141
143template<class Descr, class Functional, class BarrierFu, int paralin>
144 class LinearizationTraits<VariableSet<Descr>, IPFunctional<Functional,BarrierFu, paralin> >
145 {
146 typedef IPFunctional<Functional,BarrierFu, paralin> Func;
147 public:
149 };
150
151}
152
153template<class BarrierFunction, int yIdx>
155{
156 double H,r,mu,upper;
157 template<class Cache, class Arg>
158 void computeRHS(Cache const& cache,Arg const& arg,double const& trial)
159 {
160 r= cache.template d1<yIdx>(arg)+H*trial;
161 }
162
163 double operator()(double y) const { return H*y-BarrierFunction::db(mu,mu/(upper-y))-r; }
164};
165
166template<class BarrierFunction,int yIdx>
168{
169 double H,r,mu,upper;
170 template<class Cache, class Arg>
171 void computeRHS(Cache const& cache,Arg const& arg,double const& trial)
172 {
173 r=cache.d0()+H*trial;
174 }
175 double operator()(double y) const { return H*y-BarrierFunction::b(mu,mu/(upper-y))-r; }
176};
177
178#include "algorithm/opt_aux/src/include/zeroin.cpp"
179
181template<template <class BF, int yIdx> class PolyEquation>
183{
184public:
185template<class DomainElement, class QuadraticModelBarrier, class UnconstrainedLinearizationAt>
186void correct(DomainElement& tx, const DomainElement& x, QuadraticModelBarrier const& blin, UnconstrainedLinearizationAt const& ulin, double mu)
187{
188 using namespace boost::fusion;
189 boost::timer::cpu_timer refTimer;
190
191 typedef typename UnconstrainedLinearizationAt::Functional Unconstrained;
192 typedef typename Unconstrained::AnsatzVars::Spaces Spaces;
193 typedef typename Unconstrained::Scalar Scalar;
194
195 int const yIdx = Unconstrained::yIdx;
196 int const ySIdx = boost::fusion::result_of::value_at_c<typename Unconstrained::AnsatzVars::Variables,yIdx>::type::spaceIndex;
197
198 typedef typename result_of::template value_at_c<typename DomainElement::Functions, yIdx>::type::Space YSpace;
199 int const dim = YSpace::dim;
200 YSpace const& yspace(at_c<yIdx>(tx.data).space());
201
202 if(Unconstrained::ConstraintsCache::template bounds<yIdx>::upper==false) return;
203
204 typedef ShapeFunctionCache<typename YSpace::Grid,Scalar> SfCache;
205 SfCache sfCache;
206 typedef typename result_of::as_vector<typename result_of::transform<Spaces, GetEvaluators<SfCache> >::type>::type SFEvaluators;
207 SFEvaluators evaluators(transform(tx.descriptions.spaces,GetEvaluators<SfCache>(&sfCache)));
208
209 typename QuadraticModelBarrier::DomainCache bdomc(blin.template createDomainCache());
210 typename Unconstrained::ConstraintsCache uconc(ulin.getFunctional().createConstraintsCache(tx));
211 typename Unconstrained::DomainCache udomc(ulin.template createDomainCache(8));
212
213 typedef typename QuadraticModelBarrier::Linearization::Functional::BarrierFunction BarrierFunction;
214
215 VariationalArg<Scalar,dim> unitarg;
216 unitarg.value=1.0;
217 unitarg.gradient=0.0;
218
219 PolyEquation<BarrierFunction,yIdx> pe;
220 pe.mu = mu;
221
222 int nnodes(0),maxiter(0),sumiter(0);
223 double ratio(2.0);
224 std::vector<int> visited(yspace.degreesOfFreedom(),0);
225
226 std::cout << "PwD " << std::flush;
227
228 typedef typename YSpace::Grid::LeafGridView GridView;
229
230 typedef typename GridView::template Codim<0>::Iterator CellIterator;
231
232 for (CellIterator ci=yspace.gridView().template begin<0>(); ci!=yspace.gridView().template end<0>(); ++ci)
233 {
234
235 moveEvaluatorsToCell(evaluators,*ci);
236 bdomc.moveTo(*ci);
237 uconc.moveTo(*ci);
238 udomc.moveTo(*ci);
239
240 std::vector<Dune::FieldVector<typename YSpace::Grid::ctype, dim> >const & iNodes(at_c<ySIdx>(evaluators).shapeFunctions().interpolationNodes());
241
242 for (int i=0; i<iNodes.size(); ++i)
243 {
244 int globalIdx=at_c<ySIdx>(evaluators).globalIndices()[i];
245 if(!visited[globalIdx])
246 {
247 visited[globalIdx]++;
248 double trial = (*at_c<yIdx>(tx.data))[globalIdx][0];
249 double iterate = (*at_c<yIdx>( x.data))[globalIdx][0];
250 if(trial > iterate)
251 {
252 moveEvaluatorsToIntegrationPoint(evaluators,iNodes[i]);
253 uconc.evaluateAt(iNodes[i],evaluators);
254 pe.upper = uconc.upperbound();
255 assert(iterate <= pe.upper);
256
257 if(pe.upper < 1e30)
258 {
259 nnodes++;
260 udomc.evaluateAt(iNodes[i],evaluators);
261 bdomc.evaluateAt(iNodes[i],evaluators);
262
263// Initialize Polynomial Equation
264// H y+b'(y)=r
265// H = Lyy (Hessian of the Lagrangian)
266// r = b'(y_)+b''(y_)delta y+Lyy y_+
267
268 pe.H = udomc.template d2<yIdx,yIdx,dim>(unitarg,unitarg)[0][0];
269 pe.computeRHS(bdomc,unitarg,trial);
270
271 int iterations;
272 double upperB = std::min(trial,pe.upper);
273 double lowerB = (upperB+iterate)/2.0;
274
275// Here the solution of the pointwise damping equation takes place
276
277 double solution = zeroin(lowerB,upperB,pe,(upperB-lowerB)*1e-12+4*std::numeric_limits<Scalar>::epsilon()*(1+upperB),iterations,100);
278
279 (*at_c<yIdx>(tx.data))[globalIdx][0] = solution;
280
281// Statistics and Warnings
282
283 maxiter = std::max(maxiter,iterations);
284 sumiter += iterations;
285 ratio=std::min(ratio,std::fabs((solution-iterate)/(trial-iterate)));
286
287// if(iterations >= 100)
288// {
289// std::cout << "Warning: too many iterations: " << pe.upper-solution << std::endl;
290// std::cout << "Interval: [" << upperB << "," << lowerB << "] " << solution << std::endl;
291// std::cout << "mu:" << pe.mu << " r:" << pe.r << " H:" << pe.H << std::endl;
292// }
293// if(std::fabs((solution-iterate)/(trial-iterate)) < 1e-3
294// || std::fabs((solution-iterate)/(trial-iterate) > 1.0
295// && std::fabs(trial-iterate)>1e-12 ) )
296// {
297// std::cout << "Small ratio:" << std::fabs((solution-iterate)/(trial-iterate)) << std::endl;
298// std::cout << "Interval: [" << upperB << "," << lowerB << "] " << trial << " " << solution << std::endl;
299// std::cout << trial - iterate << "="<< trial-solution << "+" << solution - iterate << std::endl;
300// std::cout << "mu:" << pe.mu << " r:" << pe.r << " H:" << pe.H << std::endl;
301// }
302 }
303 }
304 }
305 }
306 }
307 std::cout << (double)(refTimer.elapsed().user)/1e9 << " sec.";
308 std::cout << "MaxRatio: " << ratio << std::endl;
309}
310};
311
312template<class Functional, class DomainElement,class Implementation=Bridge::IPLinearization<Functional, DomainElement> >
313class PWDampingChart: public AbstractChart
314{
315 typedef typename Functional::OptimalityFunctional Unconstrained;
316 typedef Functional Combined;
317
318public:
319
320 PWDampingChart(bool includeDuals_=true) :includeDuals(includeDuals_){}
321
322private:
323
324 void addPerturbation(AbstractFunctionSpaceElement & trialIterate,
325 AbstractFunctionSpaceElement const& correction,
326 AbstractLinearization const& lin,
327 std::vector<AbstractFunctionSpaceElement* > basis = std::vector<AbstractFunctionSpaceElement* >()) const
328 {
329 trialIterate = lin.getOrigin();
330
331 if(includeDuals)
332 trialIterate += correction;
333 else
334 for(int i=0; i<trialIterate.nComponents();++i)
335 if(trialIterate.getRole(i)!="dual")
336 trialIterate.axpy(1.0,correction,i);
337
338 using namespace boost::fusion;
339 DomainElement const& x=Bridge::getImpl<DomainElement>(lin.getOrigin());
340 DomainElement& tx=Bridge::getImpl<DomainElement>(trialIterate);
341
342
343 Bridge::Linearization<Implementation> const& limpl(dynamic_cast<Bridge::Linearization<Implementation> const& >(lin));
344 double mu = limpl.getLinImpl().getMu();
345
346 LinearizationAt<Unconstrained> ulin(limpl.getLinImpl().getUnconstrained().getLinImpl().getFunctional(),tx);
347 QuadraticModel<LinearizationAt<Combined>,false> blin(linearization(limpl.getLinImpl().getBarrier().getLinImpl().getFunctional(),x),
348 Bridge::getImpl<DomainElement>(correction));
350
351 pc.correct(tx, x, blin, ulin, mu);
352 }
353private:
354 bool includeDuals;
355};
356
358template<class DomainElement, class QBarrierModel, class ParameterModel, class LModel>
359void corrTangent(DomainElement& tx,const DomainElement& x, QBarrierModel const& blin, ParameterModel const& plin, LModel const& ulin, double muLast, double mu)
360 {
361 using namespace boost::fusion;
362
363 typedef typename LModel::Functional Unconstrained;
364 typedef typename LModel::AnsatzVars::Spaces Spaces;
365 typedef typename LModel::AnsatzVars::IndexSet IndexSet;
366 typedef typename Unconstrained::Entity Entity;
367 typedef typename LModel::Scalar Scalar;
368 int const yIdx = Unconstrained::yIdx;
369 typedef typename result_of::template value_at_c<typename DomainElement::Functions, yIdx>::type::Space YSpace;
370 int const dim = YSpace::dim;
371
372 double deltaMu = muLast-mu;
373
374 if(Unconstrained::ConstraintsCache::template bounds<yIdx>::upper==0) return;
375
376 YSpace const& yspace(at_c<yIdx>(tx.data).space());
377 typename YSpace::Evaluator ysfs(yspace);
378
379 typedef ShapeFunctionCache<typename YSpace::Grid,Scalar> SfCache;
380 SfCache sfCache;
381
382 typedef typename result_of::as_vector<typename result_of::transform<Spaces, GetEvaluators<SfCache> >::type>::type Evaluators;
383 Evaluators evaluators(transform(tx.descriptions.spaces,GetEvaluators<SfCache>(&sfCache)));
384
385 typename QBarrierModel::DomainCache bdc(blin.template createDomainCache());
386 typename ParameterModel::DomainCache pdc(plin.template createDomainCache());
387 typename Unconstrained::ConstraintsCache udc(ulin.getFunctional().createConstraintsCache(tx));
388
389 VariationalArg<Scalar,dim> unitarg;
390 unitarg.value[0]=1.0;
391 for(int i=0; i < dim; ++i) unitarg.gradient[0][i]=0.0;
392
393 typedef typename IndexSet::template Codim<0>::template Partition<Dune::All_Partition>::Iterator CellIterator;
394 for (CellIterator ci=yspace.indexSet().template begin<0,Dune::All_Partition>();
395 ci!=yspace.indexSet().template end<0,Dune::All_Partition>(); ++ci)
396 {
397 ysfs.moveTo(*ci);
398 moveEvaluatorsToCell(evaluators,*ci);
399 bdc.moveTo(*ci);
400 pdc.moveTo(*ci);
401 udc.moveTo(*ci);
402 std::vector<Dune::FieldVector<typename YSpace::Grid::ctype, dim> >const & iNodes(ysfs.shapeFunctions().interpolationNodes());
404 for (int i=0; i<iNodes.size(); ++i)
405 {
406 ysfs.evaluateAt(iNodes[i]);
407 moveEvaluatorsToIntegrationPoint(evaluators,iNodes[i]);
408 udc.evaluateAt(iNodes[i],evaluators);
409 bdc.evaluateAt(iNodes[i],evaluators);
410 pdc.evaluateAt(iNodes[i],evaluators);
411 pe.aqp = udc.quadTermA();
412 pe.aq=(bdc.template d1<yIdx,dim>(unitarg))[0]+deltaMu*(pdc.template d1<yIdx,dim>(unitarg))[0]+udc.quadTermB();
413 pe.mu= mu;
414 double yc2;
415 double trial= -(*at_c<yIdx>(tx.data))[ysfs.globalIndices()[i]][0]+udc.upperbound();
416 double iterate= -(*at_c<yIdx>(x.data))[ysfs.globalIndices()[i]][0]+udc.upperbound();
417 double upper = std::max(trial,iterate);
418 double lower = std::min(trial,iterate);
419 int iterations;
420 yc2=bisection(std::max(0.0,lower),upper,pe,upper*1e-6+4*std::numeric_limits<Scalar>::epsilon()*(1+upper),iterations);
421 (*at_c<yIdx>(tx.data))[ysfs.globalIndices()[i]][0]= udc.upperbound()-yc2;
422 }
423 }
424 }
425
427{
428 double k; // order of predictor (k=0 : classical, k=1 : tangential)
429 double err; // estimated iteration error of last step
430 double eta; // order coefficent : (k=0 : slope, k=1 : curvature);
431 double mu; // homotopy parameter
432 double alpha; // assumed negative exponent for model of slope of path (usually alpha = 1/2)
433 double Theta; // desired contraction
434 double omega; // aff. cov. Lipschitz constant for Newton's method
435 double beta; // assumed exponent for model of omega (usually beta = 1/2)
436 double operator()(double sigma) const
437{ return -(err+eta*std::pow(mu,k+1)*std::pow(sigma,-alpha-k)*std::pow(1-sigma,k+1)-Theta/omega*std::pow(sigma,beta)); }
438};
439
440template<class IPF, class DomainVector>
441class InteriorPointTangentialPredictor : public HomotopyBase
442{
443 typedef typename IPF::OptimalityFunctional Unconstrained;
444 typedef IPF Barrier;
446
447public:
448 InteriorPointTangentialPredictor(NewtonsMethod& n_, AbstractNorm const& norm_, InteriorPointParameters& p_,
449 AbstractLinearSolver& solver_, AbstractNorm const* normPlain_=0,
450 NewtonsMethod* finalsolver_=0) :
451 HomotopyBase(n_, p_),
452 norm(norm_),
453 solver(solver_),
454 stp(0),
455 normPlain(normPlain_),
456 finalsolver(finalsolver_)
457 {
458 if(!normPlain_) normPlain=&norm;
459 if(!finalsolver_) finalsolver=&n_;
460 }
461
462 virtual void initialize() {
463 iterate=trialIterate->clone();
464 predictor=trialIterate->clone();
465 tangent=trialIterate->clone();
466 ptangent=trialIterate->clone();
467 nNewton=0;
468 };
469 virtual void finalize() {};
470
471
472 virtual double muOnSuccess(int step) {
473 double b = pp.omega*pp.accuracyCorrector;
474 double c = pp.eta*pp.omega*p.mu;
475 double a = c+p.desiredContraction;
476 double sigma = (b+sqrt(b*b+4*a*c))/(2*a);
477 sigma = sigma*sigma;
478
479 StepEquation f;
480 f.k=1;
481 f.err = pp.accuracyCorrector;
482 f.eta = pp.eta;
483 f.mu = p.mu;
484 f.alpha = 0.5;
485 f.Theta = p.desiredContraction;
486 f.omega = pp.omega;
487 f.beta = 0.5;
488 int iter;
489 double sig = bisection(1e-20,1.0-1e-15,f,1e-6,iter);
490 sigma = sig;
491 sigma = std::min(sigma,p.reductionFactorWorst);
492 sigma = std::max(sigma,p.reductionFactorBest);
493 if(step==2) sigma=p.reductionStart;
494
495 return sigma*p.mu;
496 };
497
498 virtual double muOnFailure() {
499 p.sigma=0.5+p.sigma/2.0;
500 return p.mu*p.sigma;
501 };
502
503 virtual double muFinal() { return p.muFinal;};
504
505 virtual void updateModelOfHomotopy()
506 {
507 *predictor -= *trialIterate;
508 double n(norm(*predictor));
509 *iterate *= 0.0;
510 std::unique_ptr<AbstractFunctional> fuPtr(functional->getParameterLinFunctional(makePars(p.muTrial.value())));
511 std::unique_ptr<AbstractLinearization> paraLinearization(fuPtr->getLinearization(*trialIterate));
512 solver.solve(*tangent,*paraLinearization);
513 double nD=norm(*tangent);
514 double nDp=norm(*ptangent);
515
516 if(stp>=2)
517 {
518 *ptangent -= *tangent;
519 std::cout << "Difference in Tangent vectors:" << norm(*ptangent)/std::max(nD,nDp) << std::endl;
520 }
521
522 std::unique_ptr<AbstractFunctional> fuVPtr(functional->getLinFunctionValue(makePars(p.muTrial.value())));
523 std::unique_ptr<AbstractLinearization> paraLinFu(fuVPtr->getLinearization(*trialIterate));
524 paraLinFu->evald(*iterate);
525 double slopeJ = iterate->applyAsDualTo(*tangent);
526 pp.jpl=p.mu.value()*slopeJ;
527 double nDP=(*normPlain)(*tangent);
528 *ptangent -= *tangent;
529 double nDiff=norm(*ptangent);
530
531 pp.slope=nDP;
532 pp.curvature=nDiff/p.deltaMu;
533 pp.eta=pp.curvature;
534 GuardedCovariantNewtonParameters const& cnp(dynamic_cast<GuardedCovariantNewtonParameters const&>(corrector.getParameters()));
535 pp.omega=cnp.omega0.value();
536 pp.accuracyCorrector=cnp.accuracyReached;
537 std::cout << "Norm:" << n/p.deltaMu << " ||x'||_2:" << nDP << " Dmu:" << p.deltaMu << " ||x'||_x:"<< pp.eta << " omega:" << pp.omega << std::endl;
538 };
539
540 virtual void computePredictor(int step)
541 {
542 stp=step;
543 if(p.mu==p.muTrial) return;
544 if(step==2)
545 {
546 std::unique_ptr<AbstractFunctional> fuPtr(functional->getParameterLinFunctional(makePars(p.muTrial.value())));
547 std::unique_ptr<AbstractLinearization> paraLinearization(fuPtr->getLinearization(*trialIterate));
548 solver.solve(*tangent,*paraLinearization);
549 }
550 *predictor=*iterate;
551 predictor->axpy(p.mu-p.muTrial,*tangent);
552 DomainVector& tx=Bridge::getImpl<DomainVector>(*iterate);
553 DomainVector& px=Bridge::getImpl<DomainVector>(*predictor);
554 DomainVector const& cx=Bridge::getImpl<DomainVector>(*tangent);
555 std::unique_ptr<AbstractFunctional> fuPtr(functional->getFunctional(makePars(p.mu.value())));
556 std::unique_ptr<AbstractLinearization> linPtr(fuPtr->getLinearization(*iterate));
557 std::unique_ptr<AbstractLinearization> paraLinearization(fuPtr->getLinearization(*iterate));
558
559 Bridge::Linearization<Implementation> const& limpl(dynamic_cast<Bridge::Linearization<Implementation> const& >(*linPtr));
560 Bridge::Linearization<Implementation> const& plimpl(dynamic_cast<Bridge::Linearization<Implementation> const& >(*paraLinearization));
561
562 LinearizationAt<Barrier> blin(limpl.getLinImpl().getBarrier().getLinImpl().getFunctional(),tx);
563 LinearizationAt<Barrier> plin(plimpl.getLinImpl().getBarrier().getLinImpl().getFunctional(),tx);
564 LinearizationAt<Unconstrained> ulin(limpl.getLinImpl().getUnconstrained().getLinImpl().getFunctional(),tx);
565 Dune::BlockVector<Dune::FieldVector<typename Unconstrained::Scalar, 1> > temp(*boost::fusion::at_c<Unconstrained::yIdx>(px.data));
566 corrTangent(px, tx, blin, plin, ulin, p.muTrial, p.mu);
567 for (int i=0; i<temp.size(); ++i)
568 if((*boost::fusion::at_c<Barrier::yIdx>(cx.data))[i][0] < 0) (*boost::fusion::at_c<Barrier::yIdx>(px.data))[i][0] = temp[i];
569 *trialIterate=*predictor;
570 *predictor-=*iterate;
571 std::unique_ptr<AbstractFunctional> fuPtr2(functional->getParameterLinFunctional(makePars(p.muTrial.value())));
572 std::unique_ptr<AbstractLinearization> paraLinearization2(fuPtr2->getLinearization(*trialIterate));
573 solver.solve(*ptangent,*paraLinearization2);
574 }
575
576
577 virtual void initializeCorrector()
578 {
579 if(p.muTrial < p.muFinal) corrector.setDesiredAccuracy(p.accfinal);
580 else
581 {
582 if(pp.eta.isValid()) corrector.setDesiredAccuracy(1000000*std::max(p.accfinal*0.25,lengthOfPath()*p.relDistanceToPath));
583 else corrector.setDesiredAccuracy(sqrt(p.muTrial)*p.relDistanceToPath);
584 corrector.setDesiredRelativeAccuracy(p.relDistanceToPath);//std::sqrt(p.muTrial/p.mu));
585 }
586 };
587 virtual void finalizeCorrector() { nNewton += corrector.stepsPerformed(); pp.newtonSum=nNewton;};
588
589 virtual void finalizeHomotopy()
590 {
591 std::cout << "----------------------- Final Correction Step ---------------------" << std::endl;
592 finalsolver->resetParameters();
593 finalsolver->setDesiredAccuracy(p.accfinal);
594 finalsolver->setDesiredRelativeAccuracy(1.0);
595 std::unique_ptr<AbstractFunctional> fuPtr(functional->getFunctional(makePars(p.muTrial.value())));
596 std::cout << "muTrial: " << p.muTrial << std::endl;
597 finalsolver->reportOnIteration(true);
598 finalsolver->solve(fuPtr.get(), *trialIterate);
599 p.correctorTermination=corrector.getParameters().termination;
600 }
601
602 virtual void updateIterate() {
603 *iterate=*trialIterate;
604 p.j=functional->getFunctional(makePars(p.muTrial.value()))->getLinearization(*iterate)->eval();
605 jModelL.update(p.muTrial,p.j);
606 jModelL.fixUpdate();
607 p.jp=jModelL.getValue(p.muTrial);
608 std::cout << "Est. Error in Functional:" << p.jp << std::endl;
609 pp.timemeasured=overalltime.elapsed();
610 };
611
612 virtual void recoverIterate() { *trialIterate=*iterate; }
613
614
615 virtual double lengthOfPath()
616 {
617 if(pp.eta.isValid())
618 return 2*p.mu*pp.slope;
619 else
620 return 1e300;
621 };
622
623 virtual void logQuantities()
624 {
625 HomotopyBase::logQuantities();
626 pp.logStep();
628 }
629
631 {
632 std::ofstream eout("eta.log"); pp.eta.print(eout);
633 std::ofstream epout("slope.log"); pp.slope.print(epout);
634 std::ofstream cpout("curvature.log"); pp.curvature.print(cpout);
635 std::ofstream nout("newtonSum.log"); pp.newtonSum.print(nout);
636 std::ofstream oout("omega.log"); pp.omega.print(oout);
637 std::ofstream sout("sigma.log"); p.sigma.print(sout);
638 std::ofstream outmu("mu.log"); p.muTrial.print(outmu);
639 std::ofstream outj("j.log"); p.j.print(outj);
640 std::ofstream outjp("jp.log"); p.jp.print(outjp);
641 std::ofstream outjpl("jplin.log"); pp.jpl.print(outjpl);
642 std::ofstream outac("ac.log"); pp.accuracyCorrector.print(outac);
643 std::ofstream outtm("time.log"); pp.timemeasured.print(outtm);
644 }
645
646private:
647 std::unique_ptr<AbstractFunctionSpaceElement> iterate, predictor, tangent, ptangent;
648
649 AbstractNorm const& norm;
650 AbstractLinearSolver& solver;
651 InteriorPointParametersSqrt pp;
652 JModelLin jModelL;
653 int stp;
654 AbstractNorm const* normPlain;
655 NewtonsMethod* finalsolver;
656 int nNewton;
657 boost::timer::cpu_timer overalltime;
658};
659
660
662// template<class Functional, class DomainElement,class Implementation=Bridge::IPLinearization<Functional, DomainElement> >
663// class StepPolicyPointwiseDamping : public StepPolicyPlainNewton
664// {
665// public:
666// typedef typename Functional::OptimalityFunctional Unconstrained;
667// typedef Functional Combined;
668
669// virtual void setLinearization(AbstractLinearization& lin, AbstractLinearSolver& solver)
670// {
671// linPtr= &lin;
672// linearSolver=&solver;
673// mu=dynamic_cast<Bridge::Linearization<Implementation>& >(lin).getLinImpl().getMu();
674// }
675
676// virtual void getTrialIterate(
677// AbstractFunctionSpaceElement& trialIterate,
678// AbstractFunctionSpaceElement const& correction,
679// AbstractFunctionSpaceElement const& iterate,
680// double damping)
681// {
682// trialIterate = iterate;
683// trialIterate.axpy(damping,correction);
684// dcorrection = correction.clone();
685// *dcorrection*=damping;
686// correctIterate(trialIterate, *dcorrection, *linPtr, iterate, mu);
687// }
688// private:
689
690// std::unique_ptr<AbstractFunctionSpaceElement> dcorrection;
691
692// /* Makes a pointwise damping correction. The following parameters are used:
693// * - trialIterate: iterate after (simplified) Newton step -> iterate after pointwise damping
694// * - correction: (simplified) Newton correction
695// * - lin : point of linearization/ iterate before Newton step
696// * - siterate : point, where rhs is evaluated, iterate after Newton step
697// *
698// */
699// void correctIterate(AbstractFunctionSpaceElement & trialIterate,
700// AbstractFunctionSpaceElement const& correction,
701// AbstractLinearization const& lin,
702// AbstractFunctionSpaceElement const& siterate,
703// double mu)
704// {
705// using namespace boost::fusion;
706// DomainElement const& x=Bridge::getImpl<DomainElement>(lin.getOrigin());
707// DomainElement const& sx=Bridge::getImpl<DomainElement>(siterate);
708// DomainElement& tx=Bridge::getImpl<DomainElement>(trialIterate);
709
710// Bridge::Linearization<Implementation> const& limpl(dynamic_cast<Bridge::Linearization<Implementation> const& >(lin));
711
712// LinearizationAt<Unconstrained> ulin(limpl.getLinImpl().getUnconstrained().getLinImpl().getFunctional(),tx);
713// QuadraticModel<LinearizationAt<Combined>,true> blin(linearization(limpl.getLinImpl().getBarrier().getLinImpl().getFunctional(),sx),
714// linearization(limpl.getLinImpl().getBarrier().getLinImpl().getFunctional(),x),
715// Bridge::getImpl<DomainElement>(correction));
716// PointwiseCorrection<FirstOrderEquation> pc;
717
718// pc.correct(tx, sx, blin, ulin, mu);
719// }
720// double mu;
721
722// };
723
724
725#endif
Linearization for Constrained Optimization with Barrier methods.
Definition: ip_aux.hh:32
BarrierFunctional IPFunctional
Definition: ip_aux.hh:34
BarrierFunctional::AnsatzVars::Grid Grid
Definition: ip_aux.hh:35
DomainElement const & getOriginImpl() const
Definition: ip_aux.hh:99
double getL1norm() const
Definition: ip_aux.hh:118
int rows(int cbegin, int cend) const
Definition: ip_aux.hh:68
double getMu() const
Return gap parameter.
Definition: ip_aux.hh:65
IPLinearization(BarrierFunctional const &fu, DomainElement const &x_)
Definition: ip_aux.hh:45
int cols(int cbegin, int cend) const
Definition: ip_aux.hh:67
BarrierFunctional::Scalar Scalar
Definition: ip_aux.hh:39
double getValue() const
Definition: ip_aux.hh:108
int nRowBlocks() const
Definition: ip_aux.hh:101
Unconstrained const & getUnconstrained() const
Definition: ip_aux.hh:129
Barrier const & getBarrier() const
Definition: ip_aux.hh:128
Dune::LinearOperator< DomainElement, ImageElement > OperatorType
Definition: ip_aux.hh:43
Grid::LeafGridView GridView
Definition: ip_aux.hh:36
int nColBlocks() const
Definition: ip_aux.hh:102
KaskadeLinearization< typename BarrierFunctional::OptimalityFunctional, VectorImpl > Unconstrained
Definition: ip_aux.hh:41
void getRHSBlocks(std::vector< Scalar > &rhs, int rbegin, int rend) const
Definition: ip_aux.hh:82
VectorImpl DomainElement
Definition: ip_aux.hh:37
KaskadeLinearization< BarrierFunctional, VectorImpl, QuadRule > Barrier
Definition: ip_aux.hh:42
ImageImpl ImageElement
Definition: ip_aux.hh:38
void getMatrixBlocks(MatrixAsTriplet< Scalar > &mat, int rbegin, int rend, int colbegin, int colend) const
Definition: ip_aux.hh:70
IPLinearization< Func, typename Func::AnsatzVars::VariableSet > Linearization
Definition: ip_aux.hh:148
virtual void finalizeCorrector()
Definition: ip_aux.hh:587
virtual void updateIterate()
Definition: ip_aux.hh:602
virtual double muFinal()
Definition: ip_aux.hh:503
virtual void finalizeHomotopy()
Definition: ip_aux.hh:589
virtual void updateModelOfHomotopy()
Definition: ip_aux.hh:505
virtual void recoverIterate()
Definition: ip_aux.hh:612
virtual void logQuantities()
Definition: ip_aux.hh:623
virtual void computePredictor(int step)
Definition: ip_aux.hh:540
InteriorPointTangentialPredictor(NewtonsMethod &n_, AbstractNorm const &norm_, InteriorPointParameters &p_, AbstractLinearSolver &solver_, AbstractNorm const *normPlain_=0, NewtonsMethod *finalsolver_=0)
Definition: ip_aux.hh:448
virtual double muOnSuccess(int step)
Definition: ip_aux.hh:472
virtual void initializeCorrector()
Definition: ip_aux.hh:577
virtual double muOnFailure()
Definition: ip_aux.hh:498
virtual double lengthOfPath()
Definition: ip_aux.hh:615
PWDampingChart(bool includeDuals_=true)
Definition: ip_aux.hh:320
Pointwise damping strategy.
Definition: ip_aux.hh:183
void correct(DomainElement &tx, const DomainElement &x, QuadraticModelBarrier const &blin, UnconstrainedLinearizationAt const &ulin, double mu)
Definition: ip_aux.hh:186
Utility classes for the definition and use of variational functionals.
Parameters< ParameterType > makePars(ParameterType const &p)
void moveEvaluatorsToIntegrationPoint(Evaluators &evals, Dune::FieldVector< CoordType, dim > const &x, Dune::QuadratureRule< CoordType, subDim > const &qr, int ip, int subId)
Moves all provided evaluators to the given integration point, evaluating the shape functions there.
typename boost::fusion::result_of::as_vector< typename boost::fusion::result_of::transform< Spaces, GetEvaluatorTypes >::type >::type Evaluators
the heterogeneous sequence type of Evaluators for the given spaces
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
Definition: fixdune.hh:122
void corrTangent(DomainElement &tx, const DomainElement &x, QBarrierModel const &blin, ParameterModel const &plin, LModel const &ulin, double muLast, double mu)
Pointwise damping strategy.
Definition: ip_aux.hh:359
Functional for Barrier/Interior Point methods.
double bisection(double a, double b, Equation const &f, double accuracy, int &iterations)
Performs bisection algorithm to find a zero of a.
void moveEvaluatorsToCell(Evaluators &evals, Cell const &cell)
Moves all provided evaluators to the given cell.
double operator()(double y) const
Definition: ip_aux.hh:163
void computeRHS(Cache const &cache, Arg const &arg, double const &trial)
Definition: ip_aux.hh:158
void computeRHS(Cache const &cache, Arg const &arg, double const &trial)
Definition: ip_aux.hh:171
double operator()(double y) const
Definition: ip_aux.hh:175
double err
Definition: ip_aux.hh:429
double eta
Definition: ip_aux.hh:430
double k
Definition: ip_aux.hh:428
double Theta
Definition: ip_aux.hh:433
double omega
Definition: ip_aux.hh:434
double beta
Definition: ip_aux.hh:435
double operator()(double sigma) const
Definition: ip_aux.hh:436
double alpha
Definition: ip_aux.hh:432
double mu
Definition: ip_aux.hh:431
Variables and their descriptions.