]> OCCT Git - occt-copy.git/commitdiff
Possibility to freeze Lipchitz constant is added to improve performance.
authoraml <aml@opencascade.com>
Mon, 15 Feb 2016 07:42:32 +0000 (10:42 +0300)
committeraml <aml@opencascade.com>
Tue, 16 Feb 2016 04:48:33 +0000 (07:48 +0300)
src/Extrema/Extrema_GenExtCC.gxx
src/math/math_GlobOptMin.cxx
src/math/math_GlobOptMin.hxx
tests/bugs/modalg_5/bug23706_14

index a342a61b9afc16708f60c62ce6ebc7fa3c9600b2..d81b6af1b9b7d4debe5cdeabe0caaacd7ab9ca4f 100644 (file)
@@ -200,13 +200,29 @@ void Extrema_GenExtCC::Perform()
 
   // Lipchitz constant approximation.
   Standard_Real aLC = 9.0; // Default value.
+  Standard_Boolean isConstLockedFlag = Standard_False;
   if (C1.GetType() == GeomAbs_Line)
-    aLC = Min(aLC, 1.0 / C2.Resolution(1.0));
+  {
+    Standard_Real aMaxDer = 1.0 / C2.Resolution(1.0);
+    if (aLC > aMaxDer)
+    {
+      isConstLockedFlag = Standard_True;
+      aLC = aMaxDer;
+    }
+  }
   if (C2.GetType() == GeomAbs_Line)
-    aLC = Min(aLC, 1.0 / C1.Resolution(1.0));
+  {
+    Standard_Real aMaxDer = 1.0 / C1.Resolution(1.0);
+    if (aLC > aMaxDer)
+    {
+      isConstLockedFlag = Standard_True;
+      aLC = aMaxDer;
+    }
+  }
 
   Extrema_GlobOptFuncCCC2 aFunc (C1, C2);
   math_GlobOptMin aFinder(&aFunc, myLowBorder, myUppBorder, aLC);
+  aFinder.SetLipConstState(isConstLockedFlag);
   Standard_Real aDiscTol = 1.0e-2;
   Standard_Real aValueTol = 1.0e-2;
   Standard_Real aSameTol = myCurveMinTol / (aDiscTol);
index b8f0869c6bde208bc8fc2ff88281956e7ba199fc..bf75a6af713a6c2790514868eae1e3b8ec98a1e2 100644 (file)
@@ -41,6 +41,7 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
   myB(1, myN),
   myGlobA(1, myN),
   myGlobB(1, myN),
+  myIsConstLocked(Standard_False),
   myX(1, myN),
   myTmp(1, myN),
   myV(1, myN),
@@ -229,8 +230,11 @@ void math_GlobOptMin::Perform(const Standard_Boolean isFindSingleSolution)
     return;
   }
 
-  // Compute initial value for myC.
-  computeInitialValues();
+  if (!myIsConstLocked)
+  {
+    // Compute initial value for myC.
+    computeInitialValues();
+  }
 
   myE1 = minLength * myTol;
   myE2 = maxLength * myTol;
@@ -238,8 +242,7 @@ void math_GlobOptMin::Perform(const Standard_Boolean isFindSingleSolution)
   myIsFindSingleSolution = isFindSingleSolution;
   if (isFindSingleSolution)
   {
-    // Run local optimization 
-    // if current value better than optimal.
+    // Run local optimization if current value better than optimal.
     myE3 = 0.0;
   }
   else
@@ -257,6 +260,7 @@ void math_GlobOptMin::Perform(const Standard_Boolean isFindSingleSolution)
     return;
   }
 
+  myLastStep = 0.0;
   isFirstCellFilterInvoke = Standard_True;
   computeGlobalExtremum(myN);
 
@@ -368,8 +372,8 @@ void math_GlobOptMin::computeInitialValues()
   aLipConst *= Sqrt(myN) / aStep;
   if (aLipConst < myC * 0.1)
     myC = Max(aLipConst * 0.1, 0.01);
-  else if (aLipConst > myC * 10)
-    myC = Min(myC * 2, 30.0);
+  else if (aLipConst > myC * 5)
+    myC = Min(myC * 5, 50.0);
 
   // Clear all solutions except one.
   if (myY.Size() != myN)
@@ -393,7 +397,6 @@ 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 aStepBestValue = RealLast();
-  Standard_Real aRealStep = 0.0;
   math_Vector aStepBestPoint(1, myN);
   Standard_Boolean isInside = Standard_False;
   Standard_Real r;
@@ -417,7 +420,7 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
     {
       isInside = Standard_False;
       myFunc->Value(myX, d);
-      r = (d + myZ * myC * myV(1) - myF) * myZ;
+      r = (d + myZ * myC * myLastStep - myF) * myZ;
       if(r > myE3)
       {
         isInside = computeLocalExtremum(myX, val, myTmp);
@@ -460,8 +463,8 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
       if (CheckFunctionalStopCriteria())
         return; // Best possible value is obtained.
 
-      aRealStep = myE2 + Abs(myF - d) / myC;
-      myV(1) = Min(aRealStep, myMaxV(1));
+      myV(1) = Min(myE2 + Abs(myF - d) / myC, myMaxV(1));
+      myLastStep = myV(1);
     }
     else
     {
@@ -690,3 +693,12 @@ void math_GlobOptMin::ComputeInitSol()
 
   myDone = Standard_False;
 }
+
+//=======================================================================
+//function : SetLipConstState
+//purpose  :
+//=======================================================================
+void math_GlobOptMin::SetLipConstState(const Standard_Boolean theFlag)
+{
+  myIsConstLocked = theFlag;
+}
\ No newline at end of file
index 5bf006ac0534de211d210a39c41f350bc970c998..4c4e52096fb4eede3622aab559d0bf57dcd7e41f 100644 (file)
@@ -146,6 +146,9 @@ public:
   //! Set functional minimal value.
   Standard_EXPORT void SetFunctionalMinimalValue(const Standard_Real theMinimalValue);
 
+  //! Lock/Unlock Lipchitz constant for internal modifications.
+  Standard_EXPORT void SetLipConstState(const Standard_Boolean theFlag);
+
   //! Get functional minimal value.
   Standard_EXPORT Standard_Real GetFunctionalMinimalValue();
 
@@ -195,6 +198,7 @@ private:
   Standard_Real myInitC; // Lipchitz constant initial value.
   Standard_Boolean myIsFindSingleSolution; // Default value is false.
   Standard_Real myFunctionalMinimalValue; // Default value is -Precision::Infinite
+  Standard_Boolean myIsConstLocked;  // Is constant locked for modifications.
 
   // Output.
   Standard_Boolean myDone;
@@ -211,6 +215,7 @@ private:
   math_Vector myTmp; // Current modified solution.
   math_Vector myV; // Steps array.
   math_Vector myMaxV; // Max Steps array.
+  Standard_Real myLastStep; // Last step.
   math_Vector myExpandCoeff; // Define expand coefficient between neighboring indiced dimensions.
 
   NCollection_Array1<Standard_Real> myCellSize;
index 516eaee789da328c126b6f1321b4a7dbe6518d20..8cd60bb33e958d30eccd66f1847637536adccbe1 100755 (executable)
@@ -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.6712618987696386) > 1.0e-7 } {
+    if { abs($pp - 3.6710534171261284) > 1.0e-7 } {
        puts "Error : Extrema is wrong on dist $i"
        set status 1
     }