]> OCCT Git - occt-copy.git/commitdiff
0027371: Regression: BRepExtrema works too much slower in 691 (from 670)
authoraml <aml@opencascade.com>
Mon, 18 Apr 2016 04:46:45 +0000 (07:46 +0300)
committeraml <aml@opencascade.com>
Mon, 25 Apr 2016 08:44:28 +0000 (11:44 +0300)
Lipschitz constant tuning.
Shubert estimation for minimal value is added.

Test case is added.

src/Extrema/Extrema_GenExtCC.gxx
src/math/math_GlobOptMin.cxx
tests/bugs/fclasses/bug25635_1
tests/bugs/fclasses/bug27371 [new file with mode: 0644]

index d81b6af1b9b7d4debe5cdeabe0caaacd7ab9ca4f..473d663e853d5bd4f1599fe46df68929ce1523d8 100644 (file)
@@ -198,8 +198,14 @@ void Extrema_GenExtCC::Perform()
   C1.Intervals(anIntervals1, GeomAbs_C2);
   C2.Intervals(anIntervals2, GeomAbs_C2);
 
-  // Lipchitz constant approximation.
+  // Lipchitz constant computation.
   Standard_Real aLC = 9.0; // Default value.
+  const Standard_Real aMaxDer1 = 1.0 / C1.Resolution(1.0);
+  const Standard_Real aMaxDer2 = 1.0 / C2.Resolution(1.0);
+  const Standard_Real aMaxDer = Max(aMaxDer1, aMaxDer2) * Sqrt(2.0);
+  if (aLC > aMaxDer)
+    aLC = aMaxDer;
+
   Standard_Boolean isConstLockedFlag = Standard_False;
   if (C1.GetType() == GeomAbs_Line)
   {
index bf75a6af713a6c2790514868eae1e3b8ec98a1e2..e696d178b44f50c3b6faf911ab9f512b4d0f4efa 100644 (file)
 #include <Standard_Real.hxx>
 #include <Precision.hxx>
 
+//=======================================================================
+//function : DistanceToBorder
+//purpose  :
+//=======================================================================
+static Standard_Real DistanceToBorder(const math_Vector & theX,
+                                      const math_Vector & theMin,
+                                      const math_Vector & theMax)
+{
+  Standard_Real aDist = RealLast();
+
+  for (Standard_Integer anIdx = theMin.Lower(); anIdx <= theMin.Upper(); ++anIdx)
+  {
+    const Standard_Real aDist1 = Abs (theX(anIdx) - theMin(anIdx));
+    const Standard_Real aDist2 = Abs (theX(anIdx) - theMax(anIdx));
+
+    aDist = Min (aDist, Min (aDist1, aDist2));
+  }
+
+  return aDist;
+}
+
 
 //=======================================================================
 //function : math_GlobOptMin
@@ -74,12 +95,6 @@ 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;
 
@@ -125,12 +140,6 @@ void math_GlobOptMin::SetGlobalParams(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;
 
@@ -161,12 +170,6 @@ 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;
 }
 
@@ -394,18 +397,15 @@ void math_GlobOptMin::computeInitialValues()
 void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
 {
   Standard_Integer i;
-  Standard_Real d; // Functional in moved point.
+  Standard_Real d = RealLast(), aPrevVal; // Functional in original and moved points.
   Standard_Real val = RealLast(); // Local extrema computed in moved point.
   Standard_Real aStepBestValue = RealLast();
   math_Vector aStepBestPoint(1, myN);
-  Standard_Boolean isInside = Standard_False;
-  Standard_Real r;
-  Standard_Boolean isReached = Standard_False;
+  Standard_Boolean isInside = Standard_False,
+                   isReached = Standard_False;
+  Standard_Real r1, r2, r;
 
-
-  for(myX(j) = myA(j) + myE1;
-     (myX(j) < myB(j) + myE1) && (!isReached);
-      myX(j) += myV(j))
+  for(myX(j) = myA(j) + myE1; !isReached; myX(j) += myV(j))
   {
     if (myX(j) > myB(j))
     {
@@ -419,11 +419,30 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
     if (j == 1)
     {
       isInside = Standard_False;
+      aPrevVal = d;
       myFunc->Value(myX, d);
-      r = (d + myZ * myC * myLastStep - myF) * myZ;
+      r1 = (d + myZ * myC * myLastStep - myF) * myZ; // Evtushenko estimation.
+      r2 = ((d + aPrevVal - myC * myLastStep) * 0.5 - myF) * myZ; // Shubert / Piyavsky estimation.
+      r = Min(r1, r2);
       if(r > myE3)
       {
-        isInside = computeLocalExtremum(myX, val, myTmp);
+        Standard_Real aSaveParam = myX(1);
+
+        // Piyavsky midpoint estimation.
+        Standard_Real aParam = (2 * myX(1) - myV(1) ) * 0.5 + (aPrevVal - d) * 0.5 / myC;
+        if (Precision::IsInfinite(aPrevVal))
+          aParam = myX(1) - myV(1) * 0.5; // Protection from upper dimension step.
+
+        myX(1) = aParam;
+        Standard_Real aVal = 0;
+        myFunc->Value(myX, aVal);
+        myX(1) = aSaveParam;
+
+        if ( (aVal < d && aVal < aPrevVal) ||
+              DistanceToBorder(myX, myA, myB) < myE1 ) // Condition optimization case near the border.
+        {
+          isInside = computeLocalExtremum(myX, val, myTmp);
+        }
       }
       aStepBestValue = (isInside && (val < d))? val : d;
       aStepBestPoint = (isInside && (val < d))? myTmp : myX;
@@ -478,7 +497,7 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
     // Compute step in (j + 1) dimension according to scale.
     if (j < myN)
     {
-      Standard_Real aUpperDimStep =  myV(j) * myExpandCoeff(j + 1);
+      Standard_Real aUpperDimStep =  Max(myV(j), myE2);
       if (myV(j + 1) > aUpperDimStep)
       {
         if (aUpperDimStep > myMaxV(j + 1)) // Case of too big step.
index 2ae860f420caafbb4c28df5f5d7e3c6c5d08b753..0770219c53a1fc09e97c276cfe542cdc1d002d4e 100755 (executable)
@@ -11,7 +11,7 @@ ellipse c2 4 0 2 1
 
 set info [2dextrema c1 c2]
 
-set tol_abs 1.e-5
+set tol_abs 7.e-5
 set tol_rel 0.01
 
 #-1
@@ -36,7 +36,7 @@ checkreal "Parameter2" ${Parameter2} ${expected_Parameter2} ${tol_abs} ${tol_rel
 set expected_OriginX 2.
 checkreal "OriginX" ${OriginX} ${expected_OriginX} ${tol_abs} ${tol_rel}
 
-set expected_OriginY 7.e-05 
+set expected_OriginY 0.0
 checkreal "OriginY" ${OriginY} ${expected_OriginY} ${tol_abs} ${tol_rel}
 
 set expected_AxisX 1.
diff --git a/tests/bugs/fclasses/bug27371 b/tests/bugs/fclasses/bug27371
new file mode 100644 (file)
index 0000000..04663ca
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========"
+puts "OCC27371"
+puts "========"
+puts ""
+##############################################
+# Regression: BRepExtrema works too much slower in 691 (from 670) 
+##############################################
+restore [locate_data_file bug27371.brep] aShape
+explode aShape
+
+cpulimit 200
+
+# Check computation time
+chrono h reset; chrono h start
+for { set i 1 } { $i <= 100 } { incr i } {
+  distmini d aShape_1 aShape_2
+  distmini d aShape_2 aShape_1
+}
+chrono h stop; chrono h show
+
+regexp {CPU user time: (\d*)} [dchrono h show] dummy sec
+if {$sec > 1} {
+  puts "Error: too long computation time $sec seconds"
+} else {
+  puts "Computation time is OK"
+}
+
+# Check result of distance distance
+set absTol 1.0e-10
+set relTol 0.001
+set aDist_Exp 0.2
+set aDist [dval d_val]
+checkreal "Distance value check" $aDist $aDist_Exp $absTol $relTol
\ No newline at end of file