mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +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:
parent
14a35e5d91
commit
3f733bb126
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -13,7 +13,7 @@ set info [2dextrema b9 b10]
|
||||
set status 0
|
||||
for { set i 1 } { $i <= 1 } { incr i 1 } {
|
||||
regexp "dist $i: +(\[-0-9.+eE\]+)" $info full pp
|
||||
if { abs($pp - 3.8268201236765877) > 1.0e-7 } {
|
||||
if { abs($pp - 3.6710601078037173) > 1.0e-7 } {
|
||||
puts "Error : Extrema is wrong on dist $i"
|
||||
set status 1
|
||||
}
|
||||
|
44
tests/bugs/modalg_5/bug25708
Executable file
44
tests/bugs/modalg_5/bug25708
Executable file
@ -0,0 +1,44 @@
|
||||
puts "========"
|
||||
puts "OCC25708"
|
||||
puts "========"
|
||||
puts ""
|
||||
###########################################################
|
||||
# GeomAPI_ExtremaCurveCurve does not return all intersection points in 6.8.0
|
||||
###########################################################
|
||||
|
||||
set BugNumber OCC25708
|
||||
|
||||
restore [locate_data_file bug25708_interror.brep] b
|
||||
|
||||
explode b e
|
||||
|
||||
mkcurve c1 b_1
|
||||
mkcurve c2 b_2
|
||||
|
||||
set extrema_res [extrema c1 c2]
|
||||
set extrema_length [llength ${extrema_res} ]
|
||||
|
||||
if {${extrema_length} != 2 } {
|
||||
puts "Error: GeomAPI_ExtremaCurveCurve does not return all intersection points"
|
||||
} else {
|
||||
puts "OK: GeomAPI_ExtremaCurveCurve return all intersection points"
|
||||
|
||||
# Distance check
|
||||
|
||||
set info [dump ext_1]
|
||||
regexp "Parameters : 0 +(\[-0-9*\.+eE\]+)" $info full extLength1
|
||||
if {${extLength1} > 1e-14 } {
|
||||
puts "1. Error: bad distance points obtained"
|
||||
} else {
|
||||
puts "1. OK: good distance between obtained points "
|
||||
}
|
||||
|
||||
set info [dump ext_2]
|
||||
regexp "Parameters : 0 +(\[-0-9*\.+eE\]+)" $info full extLength2
|
||||
if {${extLength2} > 1e-14 } {
|
||||
puts "2. Error: bad distance points obtained"
|
||||
} else {
|
||||
puts "2. OK: good distance between obtained points "
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user