FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
nlcg.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
8#include <kernel/solver/base.hpp>
9#include <kernel/solver/iterative.hpp>
10#include <kernel/solver/linesearch.hpp>
11#include <kernel/solver/nloptls.hpp>
12#include <kernel/solver/nlopt_precond.hpp>
13
14#include <deque>
15namespace FEAT
16{
17 namespace Solver
18 {
23 {
24 undefined = 0,
25 DaiYuan,
26 DYHSHybrid,
27 FletcherReeves,
28 HagerZhang, // warning: Experimental, inefficient
29 HestenesStiefel,
30 PolakRibiere
31 };
32
34
37 inline std::ostream& operator<<(std::ostream& os, NLCGDirectionUpdate update)
38 {
39 switch(update)
40 {
41 case NLCGDirectionUpdate::undefined:
42 return os << "undefined";
43 case NLCGDirectionUpdate::DaiYuan:
44 return os << "DaiYuan";
45 case NLCGDirectionUpdate::DYHSHybrid:
46 return os << "DYHSHybrid";
47 case NLCGDirectionUpdate::FletcherReeves:
48 return os << "FletcherReeves";
49 case NLCGDirectionUpdate::HagerZhang:
50 return os << "HagerZhang";
51 case NLCGDirectionUpdate::HestenesStiefel:
52 return os << "HestenesStiefel";
53 case NLCGDirectionUpdate::PolakRibiere:
54 return os << "PolakRibiere";
55 default:
56 return os << "-unknown-";
57 }
58 }
59
60 inline void operator<<(NLCGDirectionUpdate& update, const String& update_name)
61 {
62 if(update_name == "undefined")
63 update = NLCGDirectionUpdate::undefined;
64 else if(update_name == "DaiYuan")
65 update = NLCGDirectionUpdate::DaiYuan;
66 else if(update_name == "DYHSHybrid")
67 update = NLCGDirectionUpdate::DYHSHybrid;
68 else if(update_name == "FletcherReeves")
69 update = NLCGDirectionUpdate::FletcherReeves;
70 else if(update_name == "HagerZhang")
71 update = NLCGDirectionUpdate::HagerZhang;
72 else if(update_name == "HestenesStiefel")
73 update = NLCGDirectionUpdate::HestenesStiefel;
74 else if(update_name == "PolakRibiere")
75 update = NLCGDirectionUpdate::PolakRibiere;
76 else
77 XABORTM("Unknown NLCGDirectionUpdate identifier string " +update_name);
78 }
79
81
96 template<typename Functional_, typename Filter_>
97 class NLCG : public NLOptLS<Functional_, Filter_>
98 {
99 public:
101 typedef Functional_ FunctionalType;
103 typedef Filter_ FilterType;
106
108 typedef typename Functional_::GradientType GradientType;
110 typedef typename Functional_::VectorTypeR VectorType;
112 typedef typename Functional_::DataType DataType;
113
119 static constexpr NLCGDirectionUpdate direction_update_default = NLCGDirectionUpdate::DYHSHybrid;
120
121 protected:
123 std::shared_ptr<LinesearchType> _linesearch;
126 std::shared_ptr<PrecondType> _precond;
127
130
139
146
147 public:
149 std::deque<VectorType>* iterates;
150
151 public:
174 explicit NLCG(Functional_& functional, Filter_& filter, std::shared_ptr<LinesearchType> linesearch,
176 bool keep_iterates = false, std::shared_ptr<PrecondType> precond = nullptr) :
177 BaseClass("NLCG", functional, filter, precond),
178 _linesearch(linesearch),
179 _precond(precond),
182 _num_restarts(0),
183 _restart_freq(0),
184 iterates(nullptr)
185 {
186 XASSERT(_linesearch != nullptr);
187
188 this->_min_stag_iter = 0;
189 _restart_freq = this->_functional.columns() + Index(3);
190
191 this->set_ls_iter_digits(Math::ilog10(_linesearch->get_max_iter()));
192
193 if(keep_iterates)
194 {
195 iterates = new std::deque<VectorType>;
196 }
197 }
198
221 explicit NLCG(const String& section_name, const PropertyMap* section, Functional_& functional, Filter_& filter,
222 std::shared_ptr<LinesearchType> linesearch, std::shared_ptr<PrecondType> precond = nullptr) :
223 BaseClass("NLCG", section_name, section, functional, filter, precond),
224 _linesearch(linesearch),
225 _precond(precond),
228 _num_restarts(0),
229 _restart_freq(0),
230 iterates(nullptr)
231 {
232 XASSERT(_linesearch != nullptr);
233
234 this->_min_stag_iter = 0;
235 _restart_freq = this->_functional.columns() + Index(3);
236
237 this->set_ls_iter_digits(Math::ilog10(_linesearch->get_max_iter()));
238
239 // Get direction update
240 auto direction_update_p = section->query("direction_update");
241 if(direction_update_p.second)
242 {
243 NLCGDirectionUpdate my_update;
244 my_update << direction_update_p.first;
245 set_direction_update(my_update);
246 }
247
248 // Check if we have to keep the iterates
249 auto keep_iterates_p = section->query("keep_iterates");
250 if(keep_iterates_p.second && std::stoul(keep_iterates_p.first) == 1)
251 {
252 iterates = new std::deque<VectorType>;
253 }
254
255 auto max_num_restarts_p = section->query("max_num_restarts");
256 if(max_num_restarts_p.second)
257 {
258 set_max_num_restarts(Index(std::stoul(max_num_restarts_p.first)));
259 }
260
261 }
262
266 virtual ~NLCG()
267 {
268 if(iterates != nullptr)
269 delete iterates;
270 }
271
273 virtual void init_symbolic() override
274 {
276 // create three temporary vectors
277 _vec_r = this->_functional.create_vector_r();
278 _vec_p = this->_functional.create_vector_r();
279 _vec_y = this->_functional.create_vector_r();
280 _vec_z = this->_functional.create_vector_r();
281
282 _vec_z.format();
283 _linesearch->init_symbolic();
284 }
285
287 virtual void done_symbolic() override
288 {
289 if(iterates != nullptr)
290 iterates->clear();
291
292 this->_vec_p.clear();
293 this->_vec_r.clear();
294 this->_vec_y.clear();
295 this->_vec_z.clear();
296 _restart_freq = Index(0);
297 _linesearch->done_symbolic();
299 }
300
302 virtual String name() const override
303 {
304 return "NLCG";
305 }
306
308 virtual Status apply(VectorType& vec_cor, const VectorType& vec_def) override
309 {
310 // clear solution vector
311 vec_cor.format();
312
313 // Evaluate the functional at the new state
314 this->_functional.prepare(vec_cor, this->_filter);
315 this->_functional.eval_fval_grad(this->_fval, this->_vec_r);
316
317 // Copy back given defect
318 this->_vec_r.copy(vec_def);
319 //this->_system_filter.filter_def(this->_vec_r);
320
321 // Prepare the preconditioner (if any)
322 if(this->_precond != nullptr)
323 {
324 this->_precond->prepare(vec_cor, this->_filter);
325 }
326
327 // apply
328 this->_status = _apply_intern(vec_cor);
329 this->plot_summary();
330 return this->_status;
331 }
332
334 virtual Status correct(VectorType& vec_sol, const VectorType& DOXY(vec_rhs)) override
335 {
336 //std::cout << std::scientific;
337 //std::cout << std::setprecision(16);
338 // Evaluate the functional at the new state
339 this->_functional.prepare(vec_sol, this->_filter);
340 // Compute defect
341 this->_functional.eval_fval_grad(this->_fval, this->_vec_r);
342 this->_vec_r.scale(this->_vec_r,DataType(-1));
343 this->_filter.filter_def(this->_vec_r);
344
345 // Prepare the preconditioner (if any)
346 if(this->_precond != nullptr)
347 {
348 this->_precond->prepare(vec_sol, this->_filter);
349 }
350
351 // apply
352 this->_status = _apply_intern(vec_sol);
353 this->plot_summary();
354 return this->_status;
355 }
356
360 void set_keep_iterates(bool keep_iterates)
361 {
362 if(iterates != nullptr)
363 {
364 delete iterates;
365 }
366
367 if(keep_iterates)
368 {
369 iterates = new std::deque<VectorType>;
370 }
371
372 }
373
378 void set_max_num_restarts(Index max_num_restarts)
379 {
381
382 _max_num_restarts = max_num_restarts;
383 }
384
389 void set_restart_freq(Index restart_freq)
390 {
392
393 _restart_freq = restart_freq;
394 }
395
403 {
404 _direction_update = update_;
405 }
406
407 protected:
422 {
423 IterationStats pre_iter(*this);
424 Statistics::add_solver_expression(std::make_shared<ExpressionStartSolve>(this->name()));
425
426 // p[k+1] <- r[k+1] + _beta * p[k+1]
427 DataType beta;
428 // eta[k] = <r[k], p[k]>
429 DataType eta;
430 // Reset member variables in the LineSearch
431 _linesearch->reset();
432
433 if(iterates != nullptr)
434 {
435 iterates->push_back(std::move(vec_sol.clone()));
436 }
437
438 // Set initial defect. The defect vector was calculated in the calling function
439 Status status = this->_set_initial_defect(this->_vec_r, vec_sol);
440 if(status != Status::progress)
441 {
442 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
443 return status;
444 }
445
446 // apply preconditioner to defect vector
447 if(!this->_apply_precond(this->_vec_z, this->_vec_r, this->_filter))
448 {
449 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::aborted, this->get_num_iter()));
450 return Status::aborted;
451 }
452 //this->_vec_z.copy(this->_vec_r);
453
454 // The first direction has to be the (preconditioned) steepest descent direction
455 this->_vec_p.copy(this->_vec_z);
456
457
459 //DataType max_elem(this->_vec_p.max_element());
460 //DataType scale1 = DataType(1)/max_elem;
461 //std::cout << "max_elem " << max_elem << " " << scale1 << "\n";
462 //DataType scale2(DataType(1)/new_norm);
463 //std::cout << " new norm " << new_norm << " " << scale2 << "\n";
464
465 // Compute initial eta = < p, r>
466 eta = this->_vec_p.dot(this->_vec_r);
467
468 // If the preconditioner was not pd in the first step, reset the search direction to steepest descent
469 if(eta <= DataType(0))
470 {
471 this->_vec_p.copy(this->_vec_r);
472 }
473
474 // compute initial gamma = < z[0], r[0] >
475 DataType gamma(this->_vec_z.dot(this->_vec_r));
476 DataType gamma_prev(0);
477
478 if(this->_def_init <= this->_tol_rel)
479 {
480 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::success, this->get_num_iter()));
481 return Status::success;
482 }
483
484 Index its_since_restart(0);
485 _num_restarts = Index(0);
486 Index first_restart(_restart_freq+Index(1));
487
488 pre_iter.destroy();
489
490 // start iterating
491 while(status == Status::progress)
492 {
493 IterationStats stat(*this);
494
495 // Clear statistics if we have a preconditioner. Otherwise this tends to overflow the main memory if the
496 // preconditioner does too many iterations
497 // \todo: fix this
498 //FEAT::Statistics::reset_solver_statistics();
499
500 this->_fval_prev = this->_fval;
501
502 this->_vec_y.copy(this->_vec_r);
503
504 // Copy information to the linesearch
505 _linesearch->set_initial_fval(this->_fval);
506 _linesearch->set_grad_from_defect(this->_vec_r);
507 // If we are using a preconditioner, use the additional information about the preconditioned step length in the line search
508 if(this->_precond != nullptr)
509 {
510 _linesearch->set_dir_scaling(true);
511 }
512
513 // Call the linesearch to update vec_sol
514 Status linesearch_status = _linesearch->correct(vec_sol, this->_vec_p);
515
516 // Copy back information from the linesearch
517 this->_fval = _linesearch->get_final_fval();
518 this->_ls_its = _linesearch->get_num_iter();
519 this->_steplength = _linesearch->get_rel_update();
520 _linesearch->get_defect_from_grad(this->_vec_r);
521 this->_vec_y.scale(this->_vec_y, -DataType(1));
522 this->_vec_y.axpy(this->_vec_r);
523
524 // Log iterates if necessary
525 if(iterates != nullptr)
526 {
527 iterates->push_back(vec_sol.clone());
528 }
529
530 // Compute defect norm. This also performs the convergence/divergence checks.
531 status = this->_set_new_defect(this->_vec_r, vec_sol);
532
533 if(status != Status::progress)
534 {
535 stat.destroy();
536 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), status, this->get_num_iter()));
537 return status;
538 }
539
540 // Update preconditioner if necessary
541 if(this->_precond != nullptr)
542 {
543 this->_precond->prepare(vec_sol, this->_filter);
544 }
545
546 // apply preconditioner
547 if(!this->_apply_precond(_vec_z, _vec_r, this->_filter))
548 {
549 stat.destroy();
550 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::aborted, this->get_num_iter()));
551 return Status::aborted;
552 }
553
554 // Save old gamma and compute new
555 gamma_prev = gamma;
556 gamma = this->_vec_r.dot(this->_vec_z);
557
558 //String info("");
559 bool restart(false);
560 // We need to perform a steepest descent step if the Wolfe conditions do not hold (linesearch status
561 // != success).
562 if(linesearch_status != Status::success)
563 {
564 //info += " Wolfe Conditions do not hold";
565 restart = true;
567 }
568 else
569 {
570 _num_restarts = Index(0);
571 }
572
573 if(_restart_freq > Index(0) && this->_num_iter >= first_restart && its_since_restart%_restart_freq == 0)
574 {
575 //info += " Scheduled restart";
576 restart = true;
577 its_since_restart = Index(0);
578 }
579 // This needs to be done after all the checks
580 ++its_since_restart;
581
582 // Set beta = 0 or compute depending on the restart flag
583 restart ? beta = DataType(0) : beta = compute_beta(gamma, gamma_prev);
584
585 //std::cout << "Beta " << beta << info << "\n";
586
587 // We need to check beta again here as some direction updates might set it to zero
588 // Discard the old search direction and perform (preconditioned) steepest descent
589 if(beta == DataType(0))
590 {
591 this->_vec_p.copy(this->_vec_z);
592 }
593 else
594 {
595 this->_vec_p.scale(this->_vec_p, beta);
596 this->_vec_p.axpy(this->_vec_z);
597 }
598
599
600 //max_elem = this->_vec_p.max_element();
601 //scale1 = DataType(1)/max_elem;
602 //std::cout << "max_elem " << max_elem << " " << scale1 << "\n";
603 //scale2 = DataType(1)/new_norm;
604 //std::cout << " new norm " << new_norm << " " << scale2 << "\n";
605
606 eta = this->_vec_p.dot(this->_vec_r);
607
608 // Safeguard as this should not happen
609 // TODO: Correct the output of the preconditioner if it turns out to not have been positive definite
610 if(eta <= DataType(0))
611 {
612 this->_vec_p.copy(this->_vec_r);
613 //return Status::aborted;
614 }
615
616 }
617
618 // We should never come to this point
619 Statistics::add_solver_expression(std::make_shared<ExpressionEndSolve>(this->name(), Status::undefined, this->get_num_iter()));
620 return Status::undefined;
621 }
622
636 DataType compute_beta(const DataType& gamma, const DataType& gamma_prev) const
637 {
638 switch(_direction_update)
639 {
640 case NLCGDirectionUpdate::DaiYuan:
641 return dai_yuan(gamma);
642 case NLCGDirectionUpdate::DYHSHybrid:
643 return dy_hs_hybrid(gamma);
644 case NLCGDirectionUpdate::FletcherReeves:
645 return fletcher_reeves(gamma, gamma_prev);
646 case NLCGDirectionUpdate::HagerZhang:
647 // Warning: This update is not very efficient in its current implementation.
648 return hager_zhang(gamma);
649 case NLCGDirectionUpdate::HestenesStiefel:
650 return hestenes_stiefel();
651 case NLCGDirectionUpdate::PolakRibiere:
652 return polak_ribiere(gamma_prev);
653 default:
654 XABORTM("Unhandled direction update: "+stringify(_direction_update));
655 }
656 }
657
673 virtual Status _set_new_defect(const VectorType& vec_r, const VectorType& vec_sol) override
674 {
675
676 Status st = BaseClass::_set_new_defect(vec_r, vec_sol);
677
678 if(st != Status::progress)
679 {
680 return st;
681 }
682
683 // If there were too many subsequent restarts, the solver is stagnated
685 {
686 return Status::stagnated;
687 }
688
689 // continue iterating
690 return Status::progress;
691 }
692
713 DataType dai_yuan(const DataType gamma) const
714 {
715 // <r[k+1] - r[k], p[k]>
716 DataType eta_dif = this->_vec_p.dot(this->_vec_y);
717
718 return gamma/(-eta_dif);
719 }
720
742 DataType dy_hs_hybrid(const DataType gamma) const
743 {
744
745 // <r[k+1] - r[k], z[k+1]>
746 DataType gamma_dif = this->_vec_z.dot(this->_vec_y);
747 // <r[k+1] - r[k], p[k]>
748 DataType eta_dif = this->_vec_p.dot(this->_vec_y);
749
750 DataType beta(Math::min(gamma/(-eta_dif), gamma_dif/(-eta_dif)));
751 beta = Math::max(DataType(0), beta);
752
753 return beta;
754
755 }
756
777 DataType fletcher_reeves(const DataType gamma, const DataType gamma_prev) const
778 {
779 return gamma/gamma_prev;
780 }
781
812 DataType hager_zhang(const DataType gamma) const
813 {
814
815 DataType thresh = DataType(0.01);
816
817 // <r[k+1] - r[k], p[k]>
818 DataType eta_dif = this->_vec_p.dot(this->_vec_y);
819 // <r[k+1] - r[k], z[k+1]>
820 DataType gamma_dif = this->_vec_y.dot(this->_vec_z);
821 // <p[k], z[k+1]>
822 DataType omega_mid = this->_vec_p.dot(this->_vec_z);
823 // || r[k+1] - r[k]
824 DataType norm_y = this->_vec_y.norm2();
825
826 DataType beta = -( gamma_dif/(eta_dif) + DataType(2)*(norm_y)*omega_mid/Math::sqr(eta_dif));
827 beta = Math::max(beta,-DataType(1)/(this->_vec_p.norm2()*Math::min(thresh, Math::sqrt(gamma))));
828
829 return beta;
830 }
831
852 {
853 // <r[k+1] - r[k], p[k]>
854 DataType eta_dif = this->_vec_p.dot(this->_vec_y);
855 // <r[k+1] - r[k], z[k+1]>
856 DataType gamma_dif = this->_vec_z.dot(this->_vec_y);
857
858 return gamma_dif/( -eta_dif);
859 }
860
876 DataType polak_ribiere(const DataType gamma_prev) const
877 {
878 // <r[k+1] - r[k], z[k+1]>
879 DataType gamma_dif = this->_vec_z.dot(this->_vec_y);
880
881 return Math::max(gamma_dif/gamma_prev, DataType(0));
882 }
883
884 }; // class NLCG
885
910 template<typename Functional_, typename Filter_, typename Linesearch_>
911 inline std::shared_ptr<NLCG<Functional_, Filter_>> new_nlcg(
912 Functional_& functional, Filter_& filter, Linesearch_& linesearch,
914 bool keep_iterates = false,
915 std::shared_ptr<NLOptPrecond<typename Functional_::VectorTypeL, Filter_>> precond = nullptr)
916 {
917 return std::make_shared<NLCG<Functional_, Filter_>>(functional, filter, linesearch, direction_update,
918 keep_iterates, precond);
919 }
920
945 template<typename Functional_, typename Filter_, typename Linesearch_>
946 inline std::shared_ptr<NLCG<Functional_, Filter_>> new_nlcg(
947 const String& section_name, const PropertyMap* section,
948 Functional_& functional, Filter_& filter, Linesearch_& linesearch,
949 std::shared_ptr<NLOptPrecond<typename Functional_::VectorTypeL, Filter_>> precond = nullptr)
950 {
951 return std::make_shared<NLCG<Functional_, Filter_>>(section_name, section, functional, filter, linesearch,
952 precond);
953 }
954 } //namespace Solver
955} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
FEAT Kernel base header.
A class organizing a tree of key-value pairs.
std::pair< String, bool > query(String key_path) const
Queries a value by its key path.
Helper class for iteration statistics collection.
Definition: base.hpp:392
void destroy()
destroy the objects contents (and generate Statistics::expression) before the actual destructor call
Definition: base.hpp:464
Index get_num_iter() const
Returns number of performed iterations.
Definition: iterative.hpp:462
Status _status
current status of the solver
Definition: iterative.hpp:213
Index _num_iter
number of performed iterations
Definition: iterative.hpp:231
DataType _tol_rel
relative tolerance parameter
Definition: iterative.hpp:215
virtual void plot_summary() const
Plot a summary of the last solver run.
Definition: iterative.hpp:627
Index _min_stag_iter
minimum number of stagnation iterations
Definition: iterative.hpp:233
Linesearch base class.
Definition: linesearch.hpp:34
Nonlinear Conjugate Gradient method for finding a minimum of an functional's gradient.
Definition: nlcg.hpp:98
virtual void init_symbolic() override
Symbolic initialization method.
Definition: nlcg.hpp:273
DataType fletcher_reeves(const DataType gamma, const DataType gamma_prev) const
Fletcher-Reeves update.
Definition: nlcg.hpp:777
DataType dy_hs_hybrid(const DataType gamma) const
Dai-Yuan-Hestenes-Stiefel update.
Definition: nlcg.hpp:742
Functional_ FunctionalType
The nonlinear functional type.
Definition: nlcg.hpp:101
Solver::Linesearch< Functional_, Filter_ > LinesearchType
Our type of linesearch.
Definition: nlcg.hpp:105
NLCG(Functional_ &functional, Filter_ &filter, std::shared_ptr< LinesearchType > linesearch, const NLCGDirectionUpdate du=direction_update_default, bool keep_iterates=false, std::shared_ptr< PrecondType > precond=nullptr)
Standard constructor.
Definition: nlcg.hpp:174
DataType polak_ribiere(const DataType gamma_prev) const
Modified Polak-Ribiere-Polyak.
Definition: nlcg.hpp:876
NLOptPrecond< typename Functional_::VectorTypeL, Filter_ > PrecondType
Generic preconditioner.
Definition: nlcg.hpp:117
Filter_ FilterType
The filter type.
Definition: nlcg.hpp:103
virtual Status apply(VectorType &vec_cor, const VectorType &vec_def) override
Solver application method.
Definition: nlcg.hpp:308
void set_restart_freq(Index restart_freq)
Sets the restart frquency.
Definition: nlcg.hpp:389
DataType hager_zhang(const DataType gamma) const
Hager-Zhang update.
Definition: nlcg.hpp:812
void set_keep_iterates(bool keep_iterates)
Sets the iterates deque according to a bool.
Definition: nlcg.hpp:360
std::deque< VectorType > * iterates
For debugging purposes, all iterates can be logged to here.
Definition: nlcg.hpp:149
virtual Status _apply_intern(VectorType &vec_sol)
Internal function, applies the solver.
Definition: nlcg.hpp:421
virtual Status correct(VectorType &vec_sol, const VectorType &vec_rhs) override
Solver correction method.
Definition: nlcg.hpp:334
Index _num_restarts
Number of these restarts performed consecutively.
Definition: nlcg.hpp:143
virtual Status _set_new_defect(const VectorType &vec_r, const VectorType &vec_sol) override
Internal function: sets the new defect norm.
Definition: nlcg.hpp:673
VectorType _vec_r
defect vector
Definition: nlcg.hpp:132
virtual String name() const override
Returns a descriptive string.
Definition: nlcg.hpp:302
VectorType _vec_y
temporary vector: y[k+1] = r[k+1] - r[k]
Definition: nlcg.hpp:138
VectorType _vec_p
descend direction vector
Definition: nlcg.hpp:134
VectorType _vec_z
temporary vector: Preconditioned defect
Definition: nlcg.hpp:136
DataType dai_yuan(const DataType gamma) const
Dai-Yuan update.
Definition: nlcg.hpp:713
Functional_::VectorTypeR VectorType
Input type for the gradient.
Definition: nlcg.hpp:110
virtual void done_symbolic() override
Symbolic finalization method.
Definition: nlcg.hpp:287
DataType compute_beta(const DataType &gamma, const DataType &gamma_prev) const
Computes the parameter beta for the search direction update.
Definition: nlcg.hpp:636
Index _restart_freq
Restart frequency, defaults to problemsize+3.
Definition: nlcg.hpp:145
NLOptLS< FunctionalType, FilterType > BaseClass
Our baseclass.
Definition: nlcg.hpp:115
std::shared_ptr< PrecondType > _precond
Definition: nlcg.hpp:126
void set_max_num_restarts(Index max_num_restarts)
Sets the restart frquency.
Definition: nlcg.hpp:378
std::shared_ptr< LinesearchType > _linesearch
The linesearch used along the descent direction.
Definition: nlcg.hpp:123
NLCG(const String &section_name, const PropertyMap *section, Functional_ &functional, Filter_ &filter, std::shared_ptr< LinesearchType > linesearch, std::shared_ptr< PrecondType > precond=nullptr)
Constructor using a PropertyMap.
Definition: nlcg.hpp:221
virtual ~NLCG()
Virtual destructor.
Definition: nlcg.hpp:266
static constexpr NLCGDirectionUpdate direction_update_default
Default search direction update.
Definition: nlcg.hpp:119
void set_direction_update(NLCGDirectionUpdate update_)
Sets the direction update method.
Definition: nlcg.hpp:402
DataType hestenes_stiefel() const
Hestenes-Stiefel update.
Definition: nlcg.hpp:851
NLCGDirectionUpdate _direction_update
Method to update the search direction.
Definition: nlcg.hpp:129
Functional_::GradientType GradientType
Type of the functional's gradient has.
Definition: nlcg.hpp:108
Functional_::DataType DataType
Underlying floating point type.
Definition: nlcg.hpp:112
Index _max_num_restarts
Maximum number of restarts triggered by the strong Wolfe conditions not holding.
Definition: nlcg.hpp:141
Base class for line search based nonlinear optimizers.
Definition: nloptls.hpp:43
virtual Status _set_initial_defect(const VectorType &vec_def, const VectorType &vec_sol) override
Internal function: sets the initial defect vector.
Definition: nloptls.hpp:267
DataType _fval_prev
Functional value from the previous iteration.
Definition: nloptls.hpp:80
virtual Status _set_new_defect(const VectorType &vec_r, const VectorType &vec_sol) override
Internal function: sets the new defect norm.
Definition: nloptls.hpp:325
DataType _fval
Current functional value.
Definition: nloptls.hpp:78
Functional_ & _functional
Our nonlinear functional.
Definition: nloptls.hpp:66
virtual void set_ls_iter_digits(Index digits)
Sets the number of digits used to plot line search iteration numbers.
Definition: nloptls.hpp:258
Index _ls_its
The number of iterations the linesearch performed in the last iteration of this solver.
Definition: nloptls.hpp:86
Filter_ & _filter
The filter we apply to the gradient.
Definition: nloptls.hpp:68
DataType _steplength
The last step length of the line search.
Definition: nloptls.hpp:82
Abstract base class for preconditioners for nonlinear optimization.
bool _apply_precond(VectorType &vec_cor, const VectorType &vec_def, const Filter_ &filter)
Applies the preconditioner onto a defect vector.
Definition: iterative.hpp:1140
virtual void init_symbolic()
Symbolic initialization method.
Definition: base.hpp:227
virtual void done_symbolic()
Symbolic finalization method.
Definition: base.hpp:255
String class implementation.
Definition: string.hpp:46
T_ sqrt(T_ x)
Returns the square-root of a value.
Definition: math.hpp:300
T_ sqr(T_ x)
Returns the square of a value.
Definition: math.hpp:95
T_ min(T_ a, T_ b)
Returns the minimum of two values.
Definition: math.hpp:123
T_ ilog10(T_ x)
Computes the integral base-10 logarithm of an integer, i.e. its number of non-zero decimal digits.
Definition: math.hpp:231
T_ max(T_ a, T_ b)
Returns the maximum of two values.
Definition: math.hpp:137
NLCGDirectionUpdate
Enum for NLCG search direction updates.
Definition: nlcg.hpp:23
Status
Solver status return codes enumeration.
Definition: base.hpp:47
@ success
solving successful (convergence criterion fulfilled)
@ progress
continue iteration (internal use only)
@ undefined
undefined status
@ stagnated
solver stagnated (stagnation criterion fulfilled)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
std::shared_ptr< NLCG< Functional_, Filter_ > > new_nlcg(Functional_ &functional, Filter_ &filter, Linesearch_ &linesearch, NLCGDirectionUpdate direction_update=NLCG< Functional_, Filter_ >::direction_update_default, bool keep_iterates=false, std::shared_ptr< NLOptPrecond< typename Functional_::VectorTypeL, Filter_ > > precond=nullptr)
Creates a new NLCG solver object.
Definition: nlcg.hpp:911
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
std::uint64_t Index
Index data type.