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
+
+
+
+
+
+
-
-