diff --git a/src/Mod/Sketcher/App/Sketch.h b/src/Mod/Sketcher/App/Sketch.h index 5283149ba..ad40385ae 100644 --- a/src/Mod/Sketcher/App/Sketch.h +++ b/src/Mod/Sketcher/App/Sketch.h @@ -377,6 +377,7 @@ protected: public: GCS::Algorithm defaultSolver; GCS::Algorithm defaultSolverRedundant; + inline void setDogLegGaussStep(GCS::DogLegGaussStep mode){GCSsys.dogLegGaussStep=mode;} inline void setDebugMode(GCS::DebugMode mode) {debugMode=mode;GCSsys.debugMode=mode;} inline GCS::DebugMode getDebugMode(void) {return debugMode;} inline void setMaxIter(int maxiter){GCSsys.maxIter=maxiter;} diff --git a/src/Mod/Sketcher/App/planegcs/GCS.cpp b/src/Mod/Sketcher/App/planegcs/GCS.cpp index 9620a4dca..cb12453ed 100644 --- a/src/Mod/Sketcher/App/planegcs/GCS.cpp +++ b/src/Mod/Sketcher/App/planegcs/GCS.cpp @@ -198,6 +198,7 @@ System::System() , convergence(1e-10) , convergenceRedundant(1e-10) , qrAlgorithm(EigenSparseQR) + , dogLegGaussStep(FullPivLU) , qrpivotThreshold(1E-13) , debugMode(Minimal) , LM_eps(1E-10) @@ -1453,6 +1454,7 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) << ", tolx: " << tolx << ", tolf: " << tolf << ", convergence: " << (isRedundantsolving?convergenceRedundant:convergence) + << ", dogLegGaussStep: " << (dogLegGaussStep==FullPivLU?"FullPivLU":(dogLegGaussStep==LeastNormFullPivLU?"LeastNormFullPivLU":"LeastNormLdlt")) << ", xsize: " << xsize << ", csize: " << csize << ", maxIter: " << maxIterNumber << "\n"; @@ -1505,7 +1507,20 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) h_sd = alpha*g; // get the gauss-newton step - h_gn = Jx.fullPivLu().solve(-fx); + // http://forum.freecadweb.org/viewtopic.php?f=10&t=12769&start=50#p106220 + // https://forum.kde.org/viewtopic.php?f=74&t=129439#p346104 + switch (dogLegGaussStep){ + case FullPivLU: + h_gn = Jx.fullPivLu().solve(-fx); + break; + case LeastNormFullPivLU: + h_gn = Jx.adjoint()*(Jx*Jx.adjoint()).fullPivLu().solve(-fx); + break; + case LeastNormLdlt: + h_gn = Jx.adjoint()*(Jx*Jx.adjoint()).ldlt().solve(-fx); + break; + } + double rel_error = (Jx*h_gn + fx).norm() / fx.norm(); if (rel_error > 1e15) break; diff --git a/src/Mod/Sketcher/App/planegcs/GCS.h b/src/Mod/Sketcher/App/planegcs/GCS.h index 0810b1f2e..99688df5a 100644 --- a/src/Mod/Sketcher/App/planegcs/GCS.h +++ b/src/Mod/Sketcher/App/planegcs/GCS.h @@ -51,6 +51,12 @@ namespace GCS DogLeg = 2 }; + enum DogLegGaussStep { + FullPivLU = 0, + LeastNormFullPivLU = 1, + LeastNormLdlt = 2 + }; + enum QRAlgorithm { EigenDenseQR = 0, EigenSparseQR = 1 @@ -108,6 +114,7 @@ namespace GCS double convergence; double convergenceRedundant; QRAlgorithm qrAlgorithm; + DogLegGaussStep dogLegGaussStep; double qrpivotThreshold; DebugMode debugMode; double LM_eps; diff --git a/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.cpp b/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.cpp index 38a91d5ec..86a01e77a 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.cpp @@ -58,6 +58,7 @@ #define QR_PIVOT_THRESHOLD 1E-13 // under this value a Jacobian value is regarded as zero #define DEFAULT_SOLVER_DEBUG 1 // None=0, Minimal=1, IterationLevel=2 #define MAX_ITER_MULTIPLIER false +#define DEFAULT_DOGLEG_GAUSS_STEP 0 // FullPivLU = 0, LeastNormFullPivLU = 1, LeastNormLdlt = 2 using namespace SketcherGui; using namespace Gui::TaskView; @@ -75,6 +76,7 @@ TaskSketcherSolverAdvanced::TaskSketcherSolverAdvanced(ViewProviderSketch *sketc this->groupLayout()->addWidget(proxy); ui->comboBoxDefaultSolver->onRestore(); + ui->comboBoxDogLegGaussStep->onRestore(); ui->spinBoxMaxIter->onRestore(); ui->checkBoxSketchSizeMultiplier->onRestore(); ui->lineEditConvergence->onRestore(); @@ -98,7 +100,15 @@ void TaskSketcherSolverAdvanced::updateDefaultMethodParameters(void) { ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/SolverAdvanced"); - switch(ui->comboBoxDefaultSolver->currentIndex()) + int currentindex = ui->comboBoxDefaultSolver->currentIndex(); + int redundantcurrentindex = ui->comboBoxRedundantDefaultSolver->currentIndex(); + + if(redundantcurrentindex == 2 || currentindex == 2) + ui->comboBoxDogLegGaussStep->setEnabled(true); + else + ui->comboBoxDogLegGaussStep->setEnabled(false); + + switch(currentindex) { case 0: // BFGS ui->labelSolverParam1->setText(QString::fromLatin1("")); @@ -156,7 +166,15 @@ void TaskSketcherSolverAdvanced::updateRedundantMethodParameters(void) { ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/SolverAdvanced"); - switch(ui->comboBoxRedundantDefaultSolver->currentIndex()) + int currentindex = ui->comboBoxDefaultSolver->currentIndex(); + int redundantcurrentindex = ui->comboBoxRedundantDefaultSolver->currentIndex(); + + if(redundantcurrentindex == 2 || currentindex == 2) + ui->comboBoxDogLegGaussStep->setEnabled(true); + else + ui->comboBoxDogLegGaussStep->setEnabled(false); + + switch(redundantcurrentindex) { case 0: // BFGS ui->labelRedundantSolverParam1->setText(QString::fromLatin1("")); @@ -385,6 +403,13 @@ void TaskSketcherSolverAdvanced::on_comboBoxDefaultSolver_currentIndexChanged(in updateDefaultMethodParameters(); } +void TaskSketcherSolverAdvanced::on_comboBoxDogLegGaussStep_currentIndexChanged(int index) +{ + ui->comboBoxDogLegGaussStep->onSave(); + sketchView->getSketchObject()->getSolvedSketch().setDogLegGaussStep((GCS::DogLegGaussStep) index); + updateDefaultMethodParameters(); +} + void TaskSketcherSolverAdvanced::on_spinBoxMaxIter_valueChanged(int i) { ui->spinBoxMaxIter->onSave(); @@ -505,6 +530,8 @@ void TaskSketcherSolverAdvanced::on_pushButtonDefaults_clicked(bool checked/* = hGrp->SetASCII("Redundant_DL_tolf",QString::number(DL_TOLF).toUtf8()); // Set other settings hGrp->SetInt("DefaultSolver",DEFAULT_SOLVER); + hGrp->SetInt("DogLegGaussStep",DEFAULT_DOGLEG_GAUSS_STEP); + hGrp->SetInt("RedundantDefaultSolver",DEFAULT_RSOLVER); hGrp->SetInt("MaxIter",MAX_ITER); hGrp->SetInt("RedundantSolverMaxIterations",MAX_ITER); @@ -517,6 +544,7 @@ void TaskSketcherSolverAdvanced::on_pushButtonDefaults_clicked(bool checked/* = hGrp->SetInt("DebugMode",DEFAULT_SOLVER_DEBUG); ui->comboBoxDefaultSolver->onRestore(); + ui->comboBoxDogLegGaussStep->onRestore(); ui->spinBoxMaxIter->onRestore(); ui->checkBoxSketchSizeMultiplier->onRestore(); ui->lineEditConvergence->onRestore(); @@ -543,7 +571,8 @@ void TaskSketcherSolverAdvanced::updateSketchObject(void) sketchView->getSketchObject()->getSolvedSketch().setConvergence(ui->lineEditConvergence->text().toDouble()); sketchView->getSketchObject()->getSolvedSketch().setSketchSizeMultiplier(ui->checkBoxSketchSizeMultiplier->isChecked()); sketchView->getSketchObject()->getSolvedSketch().setMaxIter(ui->spinBoxMaxIter->value()); - sketchView->getSketchObject()->getSolvedSketch().defaultSolver=(GCS::Algorithm) ui->comboBoxDefaultSolver->currentIndex(); + sketchView->getSketchObject()->getSolvedSketch().defaultSolver=(GCS::Algorithm) ui->comboBoxDefaultSolver->currentIndex(); + sketchView->getSketchObject()->getSolvedSketch().setDogLegGaussStep((GCS::DogLegGaussStep) ui->comboBoxDogLegGaussStep->currentIndex()); updateDefaultMethodParameters(); updateRedundantMethodParameters(); diff --git a/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.h b/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.h index d387d4edd..92b1423bc 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.h +++ b/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.h @@ -47,7 +47,8 @@ public: ~TaskSketcherSolverAdvanced(); private Q_SLOTS: - void on_comboBoxDefaultSolver_currentIndexChanged(int index); + void on_comboBoxDefaultSolver_currentIndexChanged(int index); + void on_comboBoxDogLegGaussStep_currentIndexChanged(int index); void on_spinBoxMaxIter_valueChanged(int i); void on_checkBoxSketchSizeMultiplier_stateChanged(int state); void on_lineEditConvergence_editingFinished(); diff --git a/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.ui b/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.ui index 565d9ecbd..708ab9eb6 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.ui +++ b/src/Mod/Sketcher/Gui/TaskSketcherSolverAdvanced.ui @@ -56,6 +56,48 @@ + + + + + + Type of function to apply in DogLeg for the Gauss step + + + DogLeg Gauss step: + + + + + + + 0 + + + DogLegGaussStep + + + Mod/Sketcher/SolverAdvanced + + + + FullPivLU + + + + + LeastNorm-FullPivLU + + + + + LeastNorm-LDLT + + + + + +