mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0025004: Extrema curve/curve incorrect result
Fixed bug in extrema clustering algorithm. Tolerances changing is available now. Testcase with Branin function added. Test cases for issue CR25004
This commit is contained in:
@@ -21,7 +21,6 @@
|
||||
#include <math_MultipleVarFunctionWithHessian.hxx>
|
||||
#include <math_NewtonMinimum.hxx>
|
||||
#include <math_Powell.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
|
||||
@@ -38,7 +37,9 @@ const Handle(Standard_Type)& STANDARD_TYPE(math_GlobOptMin)
|
||||
math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
|
||||
const math_Vector& theA,
|
||||
const math_Vector& theB,
|
||||
Standard_Real theC)
|
||||
const Standard_Real theC,
|
||||
const Standard_Real theDiscretizationTol,
|
||||
const Standard_Real theSameTol)
|
||||
: myN(theFunc->NbVariables()),
|
||||
myA(1, myN),
|
||||
myB(1, myN),
|
||||
@@ -46,7 +47,8 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
|
||||
myGlobB(1, myN),
|
||||
myX(1, myN),
|
||||
myTmp(1, myN),
|
||||
myV(1, myN)
|
||||
myV(1, myN),
|
||||
myMaxV(1, myN)
|
||||
{
|
||||
Standard_Integer i;
|
||||
|
||||
@@ -64,6 +66,14 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
|
||||
myB(i) = theB(i);
|
||||
}
|
||||
|
||||
for(i = 1; i <= myN; i++)
|
||||
{
|
||||
myMaxV(i) = (myB(i) - myA(i)) / 3.0;
|
||||
}
|
||||
|
||||
myTol = theDiscretizationTol;
|
||||
mySameTol = theSameTol;
|
||||
|
||||
myDone = Standard_False;
|
||||
}
|
||||
|
||||
@@ -74,7 +84,9 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
|
||||
void math_GlobOptMin::SetGlobalParams(math_MultipleVarFunction* theFunc,
|
||||
const math_Vector& theA,
|
||||
const math_Vector& theB,
|
||||
Standard_Real theC)
|
||||
const Standard_Real theC,
|
||||
const Standard_Real theDiscretizationTol,
|
||||
const Standard_Real theSameTol)
|
||||
{
|
||||
Standard_Integer i;
|
||||
|
||||
@@ -92,6 +104,9 @@ void math_GlobOptMin::SetGlobalParams(math_MultipleVarFunction* theFunc,
|
||||
myB(i) = theB(i);
|
||||
}
|
||||
|
||||
myTol = theDiscretizationTol;
|
||||
mySameTol = theSameTol;
|
||||
|
||||
myDone = Standard_False;
|
||||
}
|
||||
|
||||
@@ -113,9 +128,36 @@ void math_GlobOptMin::SetLocalParams(const math_Vector& theLocalA,
|
||||
myB(i) = theLocalB(i);
|
||||
}
|
||||
|
||||
for(i = 1; i <= myN; i++)
|
||||
{
|
||||
myMaxV(i) = (myB(i) - myA(i)) / 3.0;
|
||||
}
|
||||
|
||||
myDone = Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetTol
|
||||
//purpose : Set algorithm tolerances.
|
||||
//=======================================================================
|
||||
void math_GlobOptMin::SetTol(const Standard_Real theDiscretizationTol,
|
||||
const Standard_Real theSameTol)
|
||||
{
|
||||
myTol = theDiscretizationTol;
|
||||
mySameTol = theSameTol;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetTol
|
||||
//purpose : Get algorithm tolerances.
|
||||
//=======================================================================
|
||||
void math_GlobOptMin::GetTol(Standard_Real& theDiscretizationTol,
|
||||
Standard_Real& theSameTol)
|
||||
{
|
||||
theDiscretizationTol = myTol;
|
||||
theSameTol = mySameTol;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ~math_GlobOptMin
|
||||
//purpose :
|
||||
@@ -145,13 +187,11 @@ void math_GlobOptMin::Perform()
|
||||
maxLength = currentLength;
|
||||
}
|
||||
|
||||
Standard_Real myTol = 1e-2;
|
||||
myE1 = minLength * myTol / myC;
|
||||
myE2 = maxLength * myTol * 2.0 / myC;
|
||||
myE3 = - maxLength * myTol / 4.0;
|
||||
|
||||
myE1 = minLength * myTol / myC;
|
||||
myE2 = 2.0 * myTol / myC * maxLength;
|
||||
myE3 = - maxLength * myTol / 4;
|
||||
|
||||
// Compure start point.
|
||||
// Compute start point.
|
||||
math_Vector aPnt(1,myN);
|
||||
for(i = 1; i <= myN; i++)
|
||||
{
|
||||
@@ -255,10 +295,12 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
|
||||
Standard_Real d; // Functional in moved point.
|
||||
Standard_Real val = RealLast(); // Local extrema computed in moved point.
|
||||
Standard_Real stepBestValue = RealLast();
|
||||
math_Vector stepBestPoint(1,2);
|
||||
Standard_Real realStep = RealLast();
|
||||
math_Vector stepBestPoint(1, myN);
|
||||
Standard_Boolean isInside = Standard_False;
|
||||
Standard_Real r;
|
||||
|
||||
|
||||
for(myX(j) = myA(j) + myE1; myX(j) < myB(j) + myE1; myX(j) += myV(j))
|
||||
{
|
||||
if (myX(j) > myB(j))
|
||||
@@ -277,7 +319,7 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
|
||||
stepBestPoint = (isInside && (val < d))? myTmp : myX;
|
||||
|
||||
// Solutions are close to each other.
|
||||
if (Abs(stepBestValue - myF) < Precision::Confusion() * 0.01)
|
||||
if (Abs(stepBestValue - myF) < mySameTol * 0.01)
|
||||
{
|
||||
if (!isStored(stepBestPoint))
|
||||
{
|
||||
@@ -290,7 +332,7 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
|
||||
}
|
||||
|
||||
// New best solution.
|
||||
if ((stepBestValue - myF) * myZ > Precision::Confusion() * 0.01)
|
||||
if ((stepBestValue - myF) * myZ > mySameTol * 0.01)
|
||||
{
|
||||
mySolCount = 0;
|
||||
myF = stepBestValue;
|
||||
@@ -300,19 +342,20 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
|
||||
mySolCount++;
|
||||
}
|
||||
|
||||
myV(1) = myE2 + Abs(myF - d) / myC;
|
||||
realStep = myE2 + Abs(myF - d) / myC;
|
||||
myV(1) = Min(realStep, myMaxV(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
myV(j) = RealLast() / 2.0;
|
||||
computeGlobalExtremum(j - 1);
|
||||
}
|
||||
if ((j < myN) && (myV(j + 1) > myV(j)))
|
||||
if ((j < myN) && (myV(j + 1) > realStep))
|
||||
{
|
||||
if (myV(j) > (myB(j + 1) - myA(j + 1)) / 3.0) // Case of too big step.
|
||||
myV(j + 1) = (myB(j + 1) - myA(j + 1)) / 3.0;
|
||||
if (realStep > myMaxV(j + 1)) // Case of too big step.
|
||||
myV(j + 1) = myMaxV(j + 1);
|
||||
else
|
||||
myV(j + 1) = myV(j);
|
||||
myV(j + 1) = realStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,7 +390,7 @@ Standard_Boolean math_GlobOptMin::isStored(const math_Vector& thePnt)
|
||||
isSame = Standard_True;
|
||||
for(j = 1; j <= myN; j++)
|
||||
{
|
||||
if ((Abs(thePnt(j) - myY(i * myN + j))) > (myB(j) - myA(j)) * Precision::Confusion())
|
||||
if ((Abs(thePnt(j) - myY(i * myN + j))) > (myB(j) - myA(j)) * mySameTol)
|
||||
{
|
||||
isSame = Standard_False;
|
||||
break;
|
||||
|
@@ -31,16 +31,26 @@ public:
|
||||
Standard_EXPORT math_GlobOptMin(math_MultipleVarFunction* theFunc,
|
||||
const math_Vector& theA,
|
||||
const math_Vector& theB,
|
||||
Standard_Real theC = 9);
|
||||
const Standard_Real theC = 9,
|
||||
const Standard_Real theDiscretizationTol = 1.0e-2,
|
||||
const Standard_Real theSameTol = 1.0e-7);
|
||||
|
||||
Standard_EXPORT void SetGlobalParams(math_MultipleVarFunction* theFunc,
|
||||
const math_Vector& theA,
|
||||
const math_Vector& theB,
|
||||
Standard_Real theC = 9);
|
||||
const Standard_Real theC = 9,
|
||||
const Standard_Real theDiscretizationTol = 1.0e-2,
|
||||
const Standard_Real theSameTol = 1.0e-7);
|
||||
|
||||
Standard_EXPORT void SetLocalParams(const math_Vector& theLocalA,
|
||||
const math_Vector& theLocalB);
|
||||
|
||||
Standard_EXPORT void SetTol(const Standard_Real theDiscretizationTol,
|
||||
const Standard_Real theSameTol);
|
||||
|
||||
Standard_EXPORT void GetTol(Standard_Real& theDiscretizationTol,
|
||||
Standard_Real& theSameTol);
|
||||
|
||||
Standard_EXPORT ~math_GlobOptMin();
|
||||
|
||||
Standard_EXPORT void Perform();
|
||||
@@ -54,6 +64,8 @@ public:
|
||||
//! Return solution i, 1 <= i <= NbExtrema.
|
||||
Standard_EXPORT void Points(const Standard_Integer theIndex, math_Vector& theSol);
|
||||
|
||||
Standard_Boolean isDone();
|
||||
|
||||
private:
|
||||
|
||||
math_GlobOptMin & operator = (const math_GlobOptMin & theOther);
|
||||
@@ -66,8 +78,6 @@ private:
|
||||
Standard_Boolean isInside(const math_Vector& thePnt);
|
||||
|
||||
Standard_Boolean isStored(const math_Vector &thePnt);
|
||||
|
||||
Standard_Boolean isDone();
|
||||
|
||||
// Input.
|
||||
math_MultipleVarFunction* myFunc;
|
||||
@@ -76,6 +86,11 @@ private:
|
||||
math_Vector myB; // Right border on current C2 interval.
|
||||
math_Vector myGlobA; // Global left border.
|
||||
math_Vector myGlobB; // Global right border.
|
||||
Standard_Real myTol; // Discretization tolerance, default 1.0e-2.
|
||||
Standard_Real mySameTol; // points with ||p1 - p2|| < mySameTol is equal,
|
||||
// function values |val1 - val2| * 0.01 < mySameTol is equal,
|
||||
// default value is 1.0e-7.
|
||||
Standard_Real myC; //Lipschitz constant, default 9
|
||||
|
||||
// Output.
|
||||
Standard_Boolean myDone;
|
||||
@@ -84,14 +99,14 @@ private:
|
||||
|
||||
// Algorithm data.
|
||||
Standard_Real myZ;
|
||||
Standard_Real myC; //Lipschitz constant
|
||||
Standard_Real myE1; // Border coeff.
|
||||
Standard_Real myE2; // Minimum step size.
|
||||
Standard_Real myE3; // Local extrema starting parameter.
|
||||
|
||||
math_Vector myX; // Current modified solution
|
||||
math_Vector myTmp; // Current modified solution
|
||||
math_Vector myX; // Current modified solution.
|
||||
math_Vector myTmp; // Current modified solution.
|
||||
math_Vector myV; // Steps array.
|
||||
math_Vector myMaxV; // Max Steps array.
|
||||
|
||||
Standard_Real myF; // Current value of Global optimum.
|
||||
};
|
||||
|
Reference in New Issue
Block a user