1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0025708: GeomAPI_ExtremaCurveCurve does not return all intersection points in 6.8.0

Added expanding coefficients between neighboring indexes, changed local optimization starting condition.

Test case for issue CR25708
This commit is contained in:
aml
2015-02-05 16:01:40 +03:00
committed by bugmaster
parent 14a35e5d91
commit 3f733bb126
4 changed files with 112 additions and 40 deletions

View File

@@ -24,11 +24,6 @@
#include <Standard_Integer.hxx>
#include <Standard_Real.hxx>
const Handle(Standard_Type)& STANDARD_TYPE(math_GlobOptMin)
{
static Handle(Standard_Type) _atype = new Standard_Type ("math_GlobOptMin", sizeof (math_GlobOptMin));
return _atype;
}
//=======================================================================
//function : math_GlobOptMin
@@ -48,7 +43,8 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
myX(1, myN),
myTmp(1, myN),
myV(1, myN),
myMaxV(1, myN)
myMaxV(1, myN),
myExpandCoeff(1, myN)
{
Standard_Integer i;
@@ -71,6 +67,12 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
myMaxV(i) = (myB(i) - myA(i)) / 3.0;
}
myExpandCoeff(1) = 1.0;
for(i = 2; i <= myN; i++)
{
myExpandCoeff(i) = (myB(i) - myA(i)) / (myB(i - 1) - myA(i - 1));
}
myTol = theDiscretizationTol;
mySameTol = theSameTol;
@@ -104,6 +106,17 @@ void math_GlobOptMin::SetGlobalParams(math_MultipleVarFunction* theFunc,
myB(i) = theB(i);
}
for(i = 1; i <= myN; i++)
{
myMaxV(i) = (myB(i) - myA(i)) / 3.0;
}
myExpandCoeff(1) = 1.0;
for(i = 2; i <= myN; i++)
{
myExpandCoeff(i) = (myB(i) - myA(i)) / (myB(i - 1) - myA(i - 1));
}
myTol = theDiscretizationTol;
mySameTol = theSameTol;
@@ -133,6 +146,12 @@ void math_GlobOptMin::SetLocalParams(const math_Vector& theLocalA,
myMaxV(i) = (myB(i) - myA(i)) / 3.0;
}
myExpandCoeff(1) = 1.0;
for(i = 2; i <= myN; i++)
{
myExpandCoeff(i) = (myB(i) - myA(i)) / (myB(i - 1) - myA(i - 1));
}
myDone = Standard_False;
}
@@ -340,9 +359,9 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
Standard_Integer i;
Standard_Real d; // Functional in moved point.
Standard_Real val = RealLast(); // Local extrema computed in moved point.
Standard_Real stepBestValue = RealLast();
Standard_Real realStep = RealLast();
math_Vector stepBestPoint(1, myN);
Standard_Real aStepBestValue = RealLast();
Standard_Real aRealStep = 0.0;
math_Vector aStepBestPoint(1, myN);
Standard_Boolean isInside = Standard_False;
Standard_Real r;
@@ -356,52 +375,61 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
{
isInside = Standard_False;
myFunc->Value(myX, d);
r = (d - myF) * myZ;
r = (d + myZ * myC * aRealStep - myF) * myZ;
if(r > myE3)
{
isInside = computeLocalExtremum(myX, val, myTmp);
}
stepBestValue = (isInside && (val < d))? val : d;
stepBestPoint = (isInside && (val < d))? myTmp : myX;
aStepBestValue = (isInside && (val < d))? val : d;
aStepBestPoint = (isInside && (val < d))? myTmp : myX;
// Solutions are close to each other.
if (Abs(stepBestValue - myF) < mySameTol * 0.01)
if (Abs(aStepBestValue - myF) < mySameTol * 0.01)
{
if (!isStored(stepBestPoint))
if (!isStored(aStepBestPoint))
{
if ((stepBestValue - myF) * myZ > 0.0)
myF = stepBestValue;
if ((aStepBestValue - myF) * myZ > 0.0)
myF = aStepBestValue;
for(i = 1; i <= myN; i++)
myY.Append(stepBestPoint(i));
myY.Append(aStepBestPoint(i));
mySolCount++;
}
}
// New best solution.
if ((stepBestValue - myF) * myZ > mySameTol * 0.01)
if ((aStepBestValue - myF) * myZ > mySameTol * 0.01)
{
mySolCount = 0;
myF = stepBestValue;
myF = aStepBestValue;
myY.Clear();
for(i = 1; i <= myN; i++)
myY.Append(stepBestPoint(i));
myY.Append(aStepBestPoint(i));
mySolCount++;
}
realStep = myE2 + Abs(myF - d) / myC;
myV(1) = Min(realStep, myMaxV(1));
aRealStep = myE2 + Abs(myF - d) / myC;
myV(1) = Min(aRealStep, myMaxV(1));
}
else
{
myV(j) = RealLast() / 2.0;
computeGlobalExtremum(j - 1);
// Nullify steps on lower dimensions.
for(i = 1; i < j; i++)
myV(i) = 0.0;
}
if ((j < myN) && (myV(j + 1) > realStep))
// Compute step in (j + 1) dimension according to scale.
if (j < myN)
{
if (realStep > myMaxV(j + 1)) // Case of too big step.
myV(j + 1) = myMaxV(j + 1);
else
myV(j + 1) = realStep;
Standard_Real aUpperDimStep = myV(j) * myExpandCoeff(j + 1);
if (myV(j + 1) > aUpperDimStep)
{
if (aUpperDimStep > myMaxV(j + 1)) // Case of too big step.
myV(j + 1) = myMaxV(j + 1);
else
myV(j + 1) = aUpperDimStep;
}
}
}
}

View File

@@ -29,15 +29,15 @@ class math_GlobOptMin
public:
Standard_EXPORT math_GlobOptMin(math_MultipleVarFunction* theFunc,
const math_Vector& theA,
const math_Vector& theB,
const math_Vector& theLowerBorder,
const math_Vector& theUpperBorder,
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,
const math_Vector& theLowerBorder,
const math_Vector& theUpperBorder,
const Standard_Real theC = 9,
const Standard_Real theDiscretizationTol = 1.0e-2,
const Standard_Real theSameTol = 1.0e-7);
@@ -61,7 +61,7 @@ public:
//! Return count of global extremas.
Standard_EXPORT Standard_Integer NbExtrema();
//! Return solution i, 1 <= i <= NbExtrema.
//! Return solution theIndex, 1 <= theIndex <= NbExtrema.
Standard_EXPORT void Points(const Standard_Integer theIndex, math_Vector& theSol);
Standard_Boolean isDone();
@@ -75,15 +75,16 @@ private:
void computeGlobalExtremum(Standard_Integer theIndex);
//! Computes starting value / approximation:
// myF - initial best value.
// myY - initial best point.
// myC - approximation of Lipschitz constant.
// to imporve convergence speed.
//! myF - initial best value.
//! myY - initial best point.
//! myC - approximation of Lipschitz constant.
//! to imporve convergence speed.
void computeInitialValues();
//! Check that myA <= pnt <= myB
//! Check that myA <= thePnt <= myB
Standard_Boolean isInside(const math_Vector& thePnt);
//! Check presence of thePnt in GlobOpt sequence.
Standard_Boolean isStored(const math_Vector &thePnt);
// Input.
@@ -114,10 +115,9 @@ private:
math_Vector myTmp; // Current modified solution.
math_Vector myV; // Steps array.
math_Vector myMaxV; // Max Steps array.
math_Vector myExpandCoeff; // Define expand coefficient between neighboring indiced dimensions.
Standard_Real myF; // Current value of Global optimum.
};
const Handle(Standard_Type)& TYPE(math_GlobOptMin);
#endif