From 26d119b201a066242b5851455562765ec889fb94 Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Thu, 12 Dec 2013 19:11:51 +0000 Subject: [PATCH] Use the Gram-Schmidt solver instead of CG CG seems to converge to quickly. If too few iterations are performed, then ADOL-C has trouble determining the correct second derivatives. Since the Gram-Schmidt solver is a direct solver, OTOH, the derivatives should be perfect. It is also faster than the Gauss-Seidel solver I was previously using. [[Imported from SVN: r9581]] --- dune/gfe/targetspacertrsolver.cc | 53 +++++++++++++------------------- dune/gfe/targetspacertrsolver.hh | 17 +++++----- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/dune/gfe/targetspacertrsolver.cc b/dune/gfe/targetspacertrsolver.cc index a3b91483..25909b44 100644 --- a/dune/gfe/targetspacertrsolver.cc +++ b/dune/gfe/targetspacertrsolver.cc @@ -6,6 +6,8 @@ #include "maxnormtrustregion.hh" +#include <dune/gfe/gramschmidtsolver.hh> + template <class TargetSpace> void TargetSpaceRiemannianTRSolver<TargetSpace>:: setup(const AverageDistanceAssembler<TargetSpace>* assembler, @@ -26,21 +28,7 @@ setup(const AverageDistanceAssembler<TargetSpace>* assembler, this->verbosity_ = NumProc::QUIET; minNumberOfIterations_ = 4; -#ifdef USE_TCGSOLVER - /////////////////////////////////////////////////// - // Create a truncated CG solver - /////////////////////////////////////////////////// - - innerSolver_ = std::auto_ptr<TruncatedCGSolver<MatrixType, CorrectionType> > - (new TruncatedCGSolver<MatrixType, CorrectionType>(NULL, - 3,//innerIterations, - -1,//innerTolerance, - NULL, //energyNorm_.get(), - NULL, - Solver::QUIET, - false)); - -#else +#ifdef USE_GAUSS_SEIDEL_SOLVER // //////////////////////////////// // Create a projected gauss-seidel solver // //////////////////////////////// @@ -86,26 +74,27 @@ void TargetSpaceRiemannianTRSolver<TargetSpace>::solve() CorrectionType rhs(1); // length is 1 _block_ CorrectionType corr(1); // length is 1 _block_ -#ifdef USE_TCGSOLVER - // CG stops to early when started from zero. - // ADOLC needs at least a few iterations to pick up the correct derivatives - corr = 1; -#else +#ifdef USE_GAUSS_SEIDEL_SOLVER corr = 0; #endif MatrixType hesseMatrix(1,1); +#ifdef USE_GAUSS_SEIDEL_SOLVER assembler_->assembleGradient(x_, rhs[0]); assembler_->assembleHessian(x_, hesseMatrix[0][0]); +#else + /** \todo Fix this sense copying */ + typename TargetSpace::EmbeddedTangentVector foo; + assembler_->assembleEmbeddedGradient(x_, foo); + rhs[0] = foo; + assembler_->assembleEmbeddedHessian(x_, hesseMatrix[0][0]); +#endif // The right hand side is the _negative_ gradient rhs *= -1; -#ifdef USE_TCGSOLVER - CorrectionType rhsBackup = rhs; // TruncatedCGSolver overwrites rhs - innerSolver_->setProblem(hesseMatrix, &corr, &rhs, trustRegion.obstacles()[0].upper(0)); -#else +#ifdef USE_GAUSS_SEIDEL_SOLVER dynamic_cast<LinearIterationStep<MatrixType,CorrectionType>*>(innerSolver_->iterationStep_)->setProblem(hesseMatrix, corr, rhs); dynamic_cast<TrustRegionGSStep<MatrixType,CorrectionType>*>(innerSolver_->iterationStep_)->obstacles_ = &trustRegion.obstacles(); @@ -115,14 +104,17 @@ void TargetSpaceRiemannianTRSolver<TargetSpace>::solve() // ///////////////////////////// // Solve ! // ///////////////////////////// - +#ifdef USE_GAUSS_SEIDEL_SOLVER innerSolver_->solve(); - -#ifdef USE_TCGSOLVER - corr = *innerSolver_->x_; #else + Dune::FieldMatrix<field_type,blocksize,embeddedBlocksize> basis = x_.orthonormalFrame(); + GramSchmidtSolver<field_type, blocksize, embeddedBlocksize>::solve(hesseMatrix[0][0], corr[0], rhs[0], basis); +#endif + +#ifdef USE_GAUSS_SEIDEL_SOLVER corr = innerSolver_->iterationStep_->getSol(); #endif + //std::cout << "Corr: " << corr << std::endl; if (this->verbosity_ == NumProc::FULL) @@ -153,11 +145,8 @@ void TargetSpaceRiemannianTRSolver<TargetSpace>::solve() CorrectionType tmp(corr.size()); tmp = 0; hesseMatrix.umv(corr, tmp); -#ifdef USE_TCGSOLVER - field_type modelDecrease = (rhsBackup*corr) - 0.5 * (corr*tmp); -#else field_type modelDecrease = (rhs*corr) - 0.5 * (corr*tmp); -#endif + if (this->verbosity_ == NumProc::FULL) { std::cout << "Absolute model decrease: " << modelDecrease << ", functional decrease: " << oldEnergy - energy << std::endl; diff --git a/dune/gfe/targetspacertrsolver.hh b/dune/gfe/targetspacertrsolver.hh index 99ba1646..9ffcc002 100644 --- a/dune/gfe/targetspacertrsolver.hh +++ b/dune/gfe/targetspacertrsolver.hh @@ -2,14 +2,12 @@ #define TARGET_SPACE_RIEMANNIAN_TRUST_REGION_SOLVER_HH -//#define USE_TCGSOLVER +//#define USE_GAUSS_SEIDEL_SOLVER #include <dune/istl/matrix.hh> #include <dune/solvers/common/boxconstraint.hh> -#ifdef USE_TCGSOLVER -#include <dune/solvers/solvers/tcgsolver.hh> -#else +#ifdef USE_GAUSS_SEIDEL_SOLVER #include <dune/solvers/solvers/loopsolver.hh> #include <dune/solvers/iterationsteps/trustregiongsstep.hh> #endif @@ -23,6 +21,7 @@ class TargetSpaceRiemannianTRSolver : public NumProc { const static int blocksize = TargetSpace::TangentVector::dimension; + const static int embeddedBlocksize = TargetSpace::EmbeddedTangentVector::dimension; // Centralize the field type here typedef typename TargetSpace::ctype field_type; @@ -30,8 +29,13 @@ class TargetSpaceRiemannianTRSolver // Some types that I need // The types have the dynamic outer type because the dune-solvers solvers expect // this sort of type. +#ifdef USE_GAUSS_SEIDEL_SOLVER typedef Dune::Matrix<Dune::FieldMatrix<field_type, blocksize, blocksize> > MatrixType; typedef Dune::BlockVector<Dune::FieldVector<field_type, blocksize> > CorrectionType; +#else + typedef Dune::Matrix<Dune::FieldMatrix<field_type, embeddedBlocksize, embeddedBlocksize> > MatrixType; + typedef Dune::BlockVector<Dune::FieldVector<field_type, embeddedBlocksize> > CorrectionType; +#endif public: @@ -79,10 +83,7 @@ protected: /** \brief The assembler for the average-distance functional */ const AverageDistanceAssembler<TargetSpace>* assembler_; -#ifdef USE_TCGSOLVER - /** \brief The solver for the quadratic inner problems */ - std::auto_ptr<TruncatedCGSolver<MatrixType, CorrectionType> > innerSolver_; -#else +#ifdef USE_GAUSS_SEIDEL_SOLVER /** \brief The solver for the quadratic inner problems */ std::auto_ptr< ::LoopSolver<CorrectionType> > innerSolver_; -- GitLab