KASKADE 7 development version
composite_step.hh
Go to the documentation of this file.
1#ifndef COMPOSITE_STEP_HH
2#define COMPOSITE_STEP_HH
3
4#include <memory>
5#include "newton_base.hh"
6#include "newton_damped.hh"
7
8namespace Kaskade
9{
10
12{
13public:
14 virtual ~NormalStep() {};
16 virtual void getTrialIterate(
17 AbstractFunctionSpaceElement& trialIterate,
18 AbstractFunctionSpaceElement const& correction,
19 AbstractFunctionSpaceElement const& iterate,
20 double damping) = 0;
21
22 virtual void getSearchDirection(AbstractFunctionSpaceElement& correction) = 0;
23};
24
26{
27public:
28 virtual ~TangentialStep() {};
30 virtual void getTrialIterate(
31 AbstractFunctionSpaceElement& trialIterate,
32 AbstractFunctionSpaceElement const& correction,
33 AbstractFunctionSpaceElement const& iterate,
34 double damping) =0;
35
36 virtual void getSearchDirection(AbstractFunctionSpaceElement& scorrection, AbstractFunctionSpaceElement const& correction) =0;
37};
38
39
40template<class Newton>
42{
43public:
44 TangentialStepNewton(StepPolicy& s, AbstractNorm& n, typename Newton::Parameters& p, AbstractLinearSolver& linSolver_)
45 : sp(s), norm(n), pars(p), linSolver(linSolver_)
46 {}
47
49 {
50 pars.reset();
51 newton.reset(new Newton(linSolver,sp,norm,pars));
52 linPtr = lin;
53 fPtr = f;
54 }
55 virtual void getTrialIterate(
56 AbstractFunctionSpaceElement& trialIterate,
57 AbstractFunctionSpaceElement const& correction,
58 AbstractFunctionSpaceElement const& iterate,
59 double damping)
60 {
61 trialIterate = iterate;
62 trialIterate.axpy(damping,correction);
63 }
64
66 {
67 assert(linPtr);
68 assert(newton.get());
69 scorrection=linPtr->getOrigin();
70 scorrection += correction;
71 newton->reportOnIteration(report);
72 newton->oneStep(fPtr, linPtr, scorrection);
73 scorrection -= linPtr->getOrigin();
74 scorrection -= correction;
75 }
76
77private:
78 std::unique_ptr<Newton> newton;
79 StepPolicy& sp;
80 AbstractNorm& norm;
83 typename Newton::Parameters& pars;
84 AbstractLinearSolver& linSolver;
85public:
86 int report;
87};
88
90{
91public:
92 TangentialStepArmijo(StepPolicy& s, AbstractNorm& n, AbstractLinearSolver& linSolver_)
93 : sp(s), norm(n), linSolver(linSolver_)
94 {}
95
97 {
98 linPtr = lin;
99 fPtr = f;
100 iterate=linPtr->getOrigin().clone();
101 correction=linPtr->getOrigin().clone();
102 trialIterate=linPtr->getOrigin().clone();
103 gradient=linPtr->getOrigin().clone();
104 }
105 virtual void getTrialIterate(
106 AbstractFunctionSpaceElement& trialIterate,
107 AbstractFunctionSpaceElement const& correction,
108 AbstractFunctionSpaceElement const& iterate,
109 double damping)
110 {
111 trialIterate = iterate;
112// trialIterate.axpy(damping,correction);
113 trialIterate+=correction;
114 sp.getTrialIterate(trialIterate,correction, iterate,damping);
115 }
116
118
119private:
120 int performArmijoLoop();
121
122bool evaluateTrialIterate(
123 AbstractFunctionSpaceElement const& trialIterate,
124 AbstractFunctionSpaceElement const& correction,
125 AbstractLinearization const& lin);
126
127
128 std::unique_ptr<AbstractFunctionSpaceElement> iterate,correction, trialIterate, scorrection, gradient;
129 StepPolicy& sp;
130 AbstractNorm& norm;
131 AbstractLinearization* linPtr;
132 std::unique_ptr<AbstractLinearization> simplifiedLinearization;
133 AbstractFunctional* fPtr;
134 AbstractLinearSolver& linSolver;
135
136 double dampingFactor, functionalAtIterate, armijopar;
137public:
139};
140
141
142
143template<class UpdatePolicy>
144class StepPolicyProjectedRHS : public UpdatePolicy
145{
146public:
147 StepPolicyProjectedRHS(int rhsstart_, int rhsend_) : rhsstart(rhsstart_), rhsend(rhsend_) {}
148
150 {
151 assert(UpdatePolicy::linPtr);
152 assert(UpdatePolicy::linearSolver);
153 std::vector<double> sorig, sp;
154 for(int i=0; i<rhsstart; ++i) sp.push_back(0.0);
155 for(int i=rhsstart; i<rhsend; ++i) sp.push_back(1.0);
156 for(int i=rhsend; i <correction.nComponents(); ++i) sp.push_back(0.0);
157 UpdatePolicy::linPtr->getScalePars(sorig);
158 UpdatePolicy::linPtr->scaleRHS(sp);
159 UpdatePolicy::linearSolver->solve(correction, *UpdatePolicy::linPtr);
160 UpdatePolicy::linPtr->scaleRHS(sorig);
161 correction *= -1.0;
162 }
163
165 AbstractLinearization& linRHS)
166 {
167 assert(UpdatePolicy::linPtr);
168 assert(UpdatePolicy::linearSolver);
169
170 std::vector<double> sorig, sp;
171 for(int i=0; i<rhsstart; ++i) sp.push_back(0.0);
172 for(int i=rhsstart; i<rhsend; ++i) sp.push_back(1.0);
173 for(int i=rhsend ; i <correction.nComponents(); ++i) sp.push_back(0.0);
174 linRHS.getScalePars(sorig);
175 linRHS.scaleRHS(sp);
176 UpdatePolicy::linearSolver->resolve(correction, linRHS, *UpdatePolicy::linPtr);
177 linRHS.scaleRHS(sorig);
178 correction *= -1.0;
179 }
181};
182
183template <class Newton>
185{
186public:
187 NormalStepNewton(StepPolicy& s, AbstractNorm& n, typename Newton::Parameters& p, AbstractLinearSolver& linSolver_)
188 : sp(s), norm(n), pars(p), linSolver(linSolver_)
189 {
190
191 }
192
194 {
195 pars.reset();
196 newton.reset(new Newton(linSolver,sp,norm,pars));
197 linPtr = lin;
198 fPtr = f;
199 }
200 virtual void getTrialIterate(
201 AbstractFunctionSpaceElement& trialIterate,
202 AbstractFunctionSpaceElement const& correction,
203 AbstractFunctionSpaceElement const& iterate,
204 double damping)
205 {
206 trialIterate = iterate;
207 trialIterate.axpy(damping,correction);
208// sp.getTrialIterate(trialIterate,correction, iterate,damping);
209 }
210
212 {
213 assert(linPtr);
214 assert(newton.get());
215 correction=linPtr->getOrigin();
216 newton->reportOnIteration(report);
217 newton->oneStep(fPtr, linPtr, correction);
218 correction -= linPtr->getOrigin();
219 }
220private:
221 std::unique_ptr<Newton> newton;
222 StepPolicy& sp;
223 AbstractNorm& norm;
224 AbstractLinearization* linPtr;
225 AbstractFunctional* fPtr;
226 typename Newton::Parameters& pars;
227 AbstractLinearSolver& linSolver;
228public:
230};
231
232
234{
235public:
236
237 virtual ~CompositeStep() {}
238
240 CompositeStep(NormalStep& normalStep_, TangentialStep& tangentialStep_, AbstractNorm& n, IterationParameters& p_):
241 normalStep(normalStep_), tangentialStep(tangentialStep_), norm(n), p(p_) {}
242
245
246 virtual IterationParameters const& getParameters() {return p;}
248 void setDesiredAccuracy(double da) { assert(da>0); p.desiredAccuracy=da;}
250 virtual void setDesiredRelativeAccuracy(double ra) { assert(false); }
252 void resetParameters() {p.reset();}
253
254 int stepsPerformed() {return step;}
255 int maxSteps() {return p.maxSteps;}
256protected:
258 AbstractFunctionSpaceElement const& trialIterate,
259 AbstractFunctionSpaceElement const& correction,
260 AbstractLinearization const& lin) { return NewtonsMethod::AcceptanceTestPassed;}
261
262
265
267 AbstractFunctionSpaceElement& trialIterate,
268 AbstractLinearization const& lin)
269 {
270 iterate.swap(trialIterate);
271 }
272
273
274 virtual NewtonsMethod::RegularityTest regularityTest(double scalingFactor)
275 {
276 return NewtonsMethod::RegularityTestPassed;
277 }
278
279 void terminationMessage(int flag);
280
281private:
282 int runAlgorithm();
283 AbstractFunctional* functional;
284 NormalStep& normalStep;
285 TangentialStep& tangentialStep;
286 AbstractNorm& norm;
288 int step;
289
290 std::unique_ptr<AbstractFunctionSpaceElement> iterate, trialIterate, correction, scorrection, trialIterate2;
291
292 std::unique_ptr<AbstractLinearization> newtonLinearization;
293};
294
295} // namespace Kaskade
296#endif
Abstract Vector for function space algorithms.
AbstractFunctionSpaceElement & axpy(double alpha, AbstractFunctionSpaceElement const &l, int component)
*this += alpha*l
virtual std::unique_ptr< AbstractFunctionSpaceElement > clone() const =0
Construction of a vector of the same type.
virtual int nComponents() const =0
void swap(AbstractFunctionSpaceElement &v)
Shallow swap.
Representation of a nonlinear functional.
virtual AbstractFunctionSpaceElement const & getOrigin() const =0
Get point of linearization.
Base class for algorithms. Provides a unified interface and some simple wrapper routines,...
virtual NewtonsMethod::RegularityTest regularityTest(double scalingFactor)
void terminationMessage(int flag)
virtual NewtonsMethod::Convergence convergenceTest(AbstractFunctionSpaceElement const &correction, AbstractFunctionSpaceElement const &iterate)
Return true, if convergence is detected, false otherwise.
void resetParameters()
Reset all algorithmic parameters to their default values.
virtual void setDesiredRelativeAccuracy(double ra)
set the desired accuracy
void setDesiredAccuracy(double da)
set the desired accuracy
virtual IterationParameters const & getParameters()
virtual void updateIterate(AbstractFunctionSpaceElement &iterate, AbstractFunctionSpaceElement &trialIterate, AbstractLinearization const &lin)
virtual NewtonsMethod::AcceptanceTest evaluateTrialIterate(AbstractFunctionSpaceElement const &trialIterate, AbstractFunctionSpaceElement const &correction, AbstractLinearization const &lin)
void solve(AbstractFunctional *f, AbstractFunctionSpaceElement &x)
Solve the system f=0 with starting value x. On (successful) exit, the solution is x,...
CompositeStep(NormalStep &normalStep_, TangentialStep &tangentialStep_, AbstractNorm &n, IterationParameters &p_)
Create Newton's Method, providing a solver, a norm and algorithmic parameters.
Base class for algorithmic parameters.
virtual void reset()
Reset all quantities in this class.
virtual void getTrialIterate(AbstractFunctionSpaceElement &trialIterate, AbstractFunctionSpaceElement const &correction, AbstractFunctionSpaceElement const &iterate, double damping)=0
virtual void setLinearization(AbstractFunctional *f, AbstractLinearization *lin)=0
virtual void getSearchDirection(AbstractFunctionSpaceElement &correction)=0
virtual void getTrialIterate(AbstractFunctionSpaceElement &trialIterate, AbstractFunctionSpaceElement const &correction, AbstractFunctionSpaceElement const &iterate, double damping)
virtual void getSearchDirection(AbstractFunctionSpaceElement &correction)
void setLinearization(AbstractFunctional *f, AbstractLinearization *lin)
NormalStepNewton(StepPolicy &s, AbstractNorm &n, typename Newton::Parameters &p, AbstractLinearSolver &linSolver_)
virtual void getSimplifiedSearchDirection(AbstractFunctionSpaceElement &correction, AbstractLinearization &linRHS)
StepPolicyProjectedRHS(int rhsstart_, int rhsend_)
virtual void getSearchDirection(AbstractFunctionSpaceElement &correction)
virtual void getTrialIterate(AbstractFunctionSpaceElement &trialIterate, AbstractFunctionSpaceElement const &correction, AbstractFunctionSpaceElement const &iterate, double damping)
TangentialStepArmijo(StepPolicy &s, AbstractNorm &n, AbstractLinearSolver &linSolver_)
void getSearchDirection(AbstractFunctionSpaceElement &scorrection, AbstractFunctionSpaceElement const &correction)
void setLinearization(AbstractFunctional *f, AbstractLinearization *lin)
virtual void getTrialIterate(AbstractFunctionSpaceElement &trialIterate, AbstractFunctionSpaceElement const &correction, AbstractFunctionSpaceElement const &iterate, double damping)=0
virtual void setLinearization(AbstractFunctional *f, AbstractLinearization *lin)=0
virtual void getSearchDirection(AbstractFunctionSpaceElement &scorrection, AbstractFunctionSpaceElement const &correction)=0
void getSearchDirection(AbstractFunctionSpaceElement &scorrection, AbstractFunctionSpaceElement const &correction)
virtual void getTrialIterate(AbstractFunctionSpaceElement &trialIterate, AbstractFunctionSpaceElement const &correction, AbstractFunctionSpaceElement const &iterate, double damping)
void setLinearization(AbstractFunctional *f, AbstractLinearization *lin)
TangentialStepNewton(StepPolicy &s, AbstractNorm &n, typename Newton::Parameters &p, AbstractLinearSolver &linSolver_)