mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-06-30 12:14:08 +03:00
0025058: Regression of performance of BRepExtrema_ExtCC (1000 times slower)
Added initial values approximation to improve performance. Local optimization start coefficient fixed. Test case for issue CR25058
This commit is contained in:
parent
6bc6a6fc07
commit
797d11c6f5
@ -175,6 +175,9 @@ void math_GlobOptMin::Perform()
|
|||||||
{
|
{
|
||||||
Standard_Integer i;
|
Standard_Integer i;
|
||||||
|
|
||||||
|
// Compute initial values for myF, myY, myC.
|
||||||
|
computeInitialValues();
|
||||||
|
|
||||||
// Compute parameters range
|
// Compute parameters range
|
||||||
Standard_Real minLength = RealLast();
|
Standard_Real minLength = RealLast();
|
||||||
Standard_Real maxLength = RealFirst();
|
Standard_Real maxLength = RealFirst();
|
||||||
@ -187,36 +190,12 @@ void math_GlobOptMin::Perform()
|
|||||||
maxLength = currentLength;
|
maxLength = currentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
myE1 = minLength * myTol / myC;
|
myE1 = minLength * myTol;
|
||||||
myE2 = maxLength * myTol * 2.0 / myC;
|
myE2 = maxLength * myTol;
|
||||||
myE3 = - maxLength * myTol / 4.0;
|
if (myC > 1.0)
|
||||||
|
myE3 = - maxLength * myTol / 4.0;
|
||||||
// Compute start point.
|
else
|
||||||
math_Vector aPnt(1,myN);
|
myE3 = - maxLength * myTol * myC / 4.0;
|
||||||
for(i = 1; i <= myN; i++)
|
|
||||||
{
|
|
||||||
Standard_Real currCentral = (myA(i) + myB(i)) / 2.0;
|
|
||||||
aPnt(i) = currCentral;
|
|
||||||
}
|
|
||||||
|
|
||||||
myFunc->Value(aPnt, myF);
|
|
||||||
|
|
||||||
math_Vector aExtremumPoint(1,myN);
|
|
||||||
Standard_Real aExtremumValue = RealLast();
|
|
||||||
if (computeLocalExtremum(aPnt, aExtremumValue, aExtremumPoint))
|
|
||||||
{
|
|
||||||
// Local Extremum finds better solution than midpoint.
|
|
||||||
if (aExtremumValue < myF)
|
|
||||||
{
|
|
||||||
myF = aExtremumValue;
|
|
||||||
aPnt = aExtremumPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
myY.Clear();
|
|
||||||
for(i = 1; i <= myN; i++)
|
|
||||||
myY.Append(aPnt(i));
|
|
||||||
mySolCount++;
|
|
||||||
|
|
||||||
computeGlobalExtremum(myN);
|
computeGlobalExtremum(myN);
|
||||||
|
|
||||||
@ -285,6 +264,72 @@ Standard_Boolean math_GlobOptMin::computeLocalExtremum(const math_Vector& thePnt
|
|||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : computeInitialValues
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void math_GlobOptMin::computeInitialValues()
|
||||||
|
{
|
||||||
|
Standard_Integer i;
|
||||||
|
math_Vector aCurrPnt(1, myN);
|
||||||
|
math_Vector aBestPnt(1, myN);
|
||||||
|
|
||||||
|
Standard_Real aCurrVal = RealLast();
|
||||||
|
Standard_Real aBestVal = RealLast();
|
||||||
|
|
||||||
|
// Check functional value in midpoint, low and upp point border and
|
||||||
|
// in each point try to perform local optimization.
|
||||||
|
aBestPnt = (myA + myB) * 0.5;
|
||||||
|
myFunc->Value(aBestPnt, aBestVal);
|
||||||
|
|
||||||
|
for(i = 1; i <= 3; i++)
|
||||||
|
{
|
||||||
|
aCurrPnt = myA + (myB - myA) * (i - 1) / 2.0;
|
||||||
|
|
||||||
|
if(computeLocalExtremum(aCurrPnt, aCurrVal, aCurrPnt))
|
||||||
|
{
|
||||||
|
// Local Extremum finds better solution than current point.
|
||||||
|
if (aCurrVal < aBestVal)
|
||||||
|
{
|
||||||
|
aBestVal = aCurrVal;
|
||||||
|
aBestPnt = aCurrPnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
myF = aBestVal;
|
||||||
|
myY.Clear();
|
||||||
|
for(i = 1; i <= myN; i++)
|
||||||
|
myY.Append(aBestPnt(i));
|
||||||
|
mySolCount++;
|
||||||
|
|
||||||
|
// Lipschitz const approximation
|
||||||
|
Standard_Real aLipConst = 0.0, aPrevVal;
|
||||||
|
Standard_Integer aPntNb = 13;
|
||||||
|
myFunc->Value(myA, aPrevVal);
|
||||||
|
Standard_Real aStep = (myB - myA).Norm() / aPntNb;
|
||||||
|
for(i = 1; i <= aPntNb; i++)
|
||||||
|
{
|
||||||
|
aCurrPnt = myA + (myB - myA) * i / (aPntNb - 1);
|
||||||
|
myFunc->Value(aCurrPnt, aCurrVal);
|
||||||
|
|
||||||
|
if(Abs(aCurrVal - aPrevVal) / aStep > aLipConst)
|
||||||
|
aLipConst = Abs(aCurrVal - aPrevVal) / aStep;
|
||||||
|
|
||||||
|
aPrevVal = aCurrVal;
|
||||||
|
}
|
||||||
|
aLipConst *= Sqrt(myN);
|
||||||
|
|
||||||
|
if (aLipConst < myC * 0.1)
|
||||||
|
{
|
||||||
|
myC = Max(aLipConst * 0.1, 0.01);
|
||||||
|
}
|
||||||
|
else if (aLipConst > myC * 10)
|
||||||
|
{
|
||||||
|
myC = Min(myC * 2, 30.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : ComputeGlobalExtremum
|
//function : ComputeGlobalExtremum
|
||||||
//purpose :
|
//purpose :
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
//! Get best functional value.
|
//! Get best functional value.
|
||||||
Standard_EXPORT Standard_Real GetF();
|
Standard_EXPORT Standard_Real GetF();
|
||||||
|
|
||||||
//! Return count of global extremas. NbExtrema <= MAX_SOLUTIONS.
|
//! Return count of global extremas.
|
||||||
Standard_EXPORT Standard_Integer NbExtrema();
|
Standard_EXPORT Standard_Integer NbExtrema();
|
||||||
|
|
||||||
//! Return solution i, 1 <= i <= NbExtrema.
|
//! Return solution i, 1 <= i <= NbExtrema.
|
||||||
@ -74,6 +74,13 @@ private:
|
|||||||
|
|
||||||
void computeGlobalExtremum(Standard_Integer theIndex);
|
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.
|
||||||
|
void computeInitialValues();
|
||||||
|
|
||||||
//! Check that myA <= pnt <= myB
|
//! Check that myA <= pnt <= myB
|
||||||
Standard_Boolean isInside(const math_Vector& thePnt);
|
Standard_Boolean isInside(const math_Vector& thePnt);
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ bsplinecurve r1 2 5 1 3 2 1 3 1 4 1 5 3 2 5 3 1 3 7 3 1 4 8 3 1 4 8 3 1 5 9 3 1
|
|||||||
bsplinecurve r2 2 5 2 3 2.5 1 3 1 3.5 1 4 3 -1 2 3 1 1 11 3 1 3 9 3 1 3 9 3 1 3 9 3 1 5 7 3 1 7 4 3 1
|
bsplinecurve r2 2 5 2 3 2.5 1 3 1 3.5 1 4 3 -1 2 3 1 1 11 3 1 3 9 3 1 3 9 3 1 3 9 3 1 5 7 3 1 7 4 3 1
|
||||||
set info [extrema r1 r2]
|
set info [extrema r1 r2]
|
||||||
|
|
||||||
if { [llength $info] != 3 } {
|
if { [llength $info] != 1 } {
|
||||||
puts "Error : Extrema is wrong"
|
puts "Error : Extrema is wrong"
|
||||||
} else {
|
} else {
|
||||||
puts "OK: Extrema is valid"
|
puts "OK: Extrema is valid"
|
||||||
|
45
tests/bugs/modalg_5/bug25058
Executable file
45
tests/bugs/modalg_5/bug25058
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
puts "============"
|
||||||
|
puts "OCC25058"
|
||||||
|
puts "============"
|
||||||
|
puts ""
|
||||||
|
###############################
|
||||||
|
## Regression of performance of BRepExtrema_ExtCC (1000 times slower)
|
||||||
|
###############################
|
||||||
|
|
||||||
|
if { [regexp {Debug mode} [dversion]] } {
|
||||||
|
if { [regexp {Windows} [dversion]] } {
|
||||||
|
set max_time 1
|
||||||
|
set max_time2 1
|
||||||
|
} else {
|
||||||
|
set max_time 1
|
||||||
|
set max_time2 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if { [regexp {Windows} [dversion]] } {
|
||||||
|
set max_time 1
|
||||||
|
set max_time2 1
|
||||||
|
} else {
|
||||||
|
set max_time 1
|
||||||
|
set max_time2 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
restore [locate_data_file bug25058_e1.brep] e1
|
||||||
|
restore [locate_data_file bug25058_e2.brep] e2
|
||||||
|
|
||||||
|
dchrono h reset
|
||||||
|
dchrono h start
|
||||||
|
|
||||||
|
distmini r e1 e2
|
||||||
|
|
||||||
|
dchrono h stop
|
||||||
|
set q [dchrono h show]
|
||||||
|
|
||||||
|
regexp {CPU user time: ([-0-9.+eE]+) seconds} $q full z
|
||||||
|
puts "$z"
|
||||||
|
|
||||||
|
if { $z > ${max_time} } {
|
||||||
|
puts "Elapsed time of distmini is more than ${max_time} seconds - Faulty"
|
||||||
|
} else {
|
||||||
|
puts "Elapsed time of distmini is less than ${max_time} seconds - OK"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user