From: aml Date: Mon, 15 Feb 2016 07:42:32 +0000 (+0300) Subject: Possibility to freeze Lipchitz constant is added to improve performance. X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=6d65d762817e739420eb2cafadf17451a8600ca4;p=occt-copy.git Possibility to freeze Lipchitz constant is added to improve performance. --- diff --git a/src/Extrema/Extrema_GenExtCC.gxx b/src/Extrema/Extrema_GenExtCC.gxx index a342a61b9a..d81b6af1b9 100644 --- a/src/Extrema/Extrema_GenExtCC.gxx +++ b/src/Extrema/Extrema_GenExtCC.gxx @@ -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); diff --git a/src/math/math_GlobOptMin.cxx b/src/math/math_GlobOptMin.cxx index b8f0869c6b..bf75a6af71 100644 --- a/src/math/math_GlobOptMin.cxx +++ b/src/math/math_GlobOptMin.cxx @@ -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 diff --git a/src/math/math_GlobOptMin.hxx b/src/math/math_GlobOptMin.hxx index 5bf006ac05..4c4e52096f 100644 --- a/src/math/math_GlobOptMin.hxx +++ b/src/math/math_GlobOptMin.hxx @@ -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 myCellSize; diff --git a/tests/bugs/modalg_5/bug23706_14 b/tests/bugs/modalg_5/bug23706_14 index 516eaee789..8cd60bb33e 100755 --- a/tests/bugs/modalg_5/bug23706_14 +++ b/tests/bugs/modalg_5/bug23706_14 @@ -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 }