C1.Intervals(anIntervals1, GeomAbs_C2);
C2.Intervals(anIntervals2, GeomAbs_C2);
+ // Lipchitz constant approximation.
+ Standard_Real aLC = 9.0; // Default value.
+ Standard_Boolean isConstLockedFlag = Standard_False;
+ if (C1.GetType() == GeomAbs_Line)
+ {
+ Standard_Real aMaxDer = 1.0 / C2.Resolution(1.0);
+ if (aLC > aMaxDer)
+ {
+ isConstLockedFlag = Standard_True;
+ aLC = aMaxDer;
+ }
+ }
+ if (C2.GetType() == GeomAbs_Line)
+ {
+ 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);
+ 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);
aFinder.SetTol(aDiscTol, aSameTol);
- aFinder.SetFunctionalMinimalValue(0.0); // Best disntance cannot be lower than 0.0
+ aFinder.SetFunctionalMinimalValue(0.0); // Best distance cannot be lower than 0.0.
// Size computed to have cell index inside of int32 value.
const Standard_Real aCellSize = Max(anIntervals1.Upper() - anIntervals1.Lower(),
// Check for infinity solutions case, for this:
// Sort points lexicographically and check midpoint between each two neighboring points.
// If all midpoints functional value is acceptable
- // then set myParallel flag to true and return one soulution.
+ // then set myParallel flag to true and return one solution.
std::sort(aPnts.begin(), aPnts.end(), comp);
Standard_Boolean isParallel = Standard_False;
Standard_Real aVal = 0.0;
myB(1, myN),
myGlobA(1, myN),
myGlobB(1, myN),
+ myIsConstLocked(Standard_False),
myX(1, myN),
myTmp(1, myN),
myV(1, myN),
myFunc = theFunc;
myC = theC;
+ myInitC = theC;
myIsFindSingleSolution = Standard_False;
myFunctionalMinimalValue = -Precision::Infinite();
myZ = -1;
Standard_Integer aSolNb = Standard_Integer(Pow(3.0, Standard_Real(myN)));
myMinCellFilterSol = Max(2 * aSolNb, aMaxSquareSearchSol);
initCellSize();
+ ComputeInitSol();
myDone = Standard_False;
}
//=======================================================================
//function : SetGlobalParams
-//purpose : Set params without memory allocation.
+//purpose : Set parameters without memory allocation.
//=======================================================================
void math_GlobOptMin::SetGlobalParams(math_MultipleVarFunction* theFunc,
const math_Vector& theA,
myFunc = theFunc;
myC = theC;
+ myInitC = theC;
myZ = -1;
mySolCount = 0;
mySameTol = theSameTol;
initCellSize();
+ ComputeInitSol();
myDone = Standard_False;
}
//=======================================================================
//function : SetLocalParams
-//purpose : Set params without memory allocation.
+//purpose : Set parameters without memory allocation.
//=======================================================================
void math_GlobOptMin::SetLocalParams(const math_Vector& theLocalA,
const math_Vector& theLocalB)
Standard_Integer i;
myZ = -1;
- mySolCount = 0;
-
for(i = 1; i <= myN; i++)
{
myA(i) = theLocalA(i);
return;
}
- // Compute initial values for myF, myY, myC.
- computeInitialValues();
+ if (!myIsConstLocked)
+ {
+ // Compute initial value for myC.
+ computeInitialValues();
+ }
myE1 = minLength * myTol;
myE2 = maxLength * myTol;
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
myE3 = - maxLength * myTol * myC / 4.0;
}
- // Search single solution and current solution in its neighbourhood.
+ // Search single solution and current solution in its neighborhood.
if (CheckFunctionalStopCriteria())
{
myDone = Standard_True;
return;
}
+ myLastStep = 0.0;
isFirstCellFilterInvoke = Standard_True;
computeGlobalExtremum(myN);
math_Vector aBestPnt(1, myN);
math_Vector aParamStep(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
+ // Lipchitz const approximation.
Standard_Real aLipConst = 0.0, aPrevValDiag, aPrevValProj;
Standard_Integer aPntNb = 13;
myFunc->Value(myA, aPrevValDiag);
aPrevValProj = aCurrVal;
}
+ myC = myInitC;
aLipConst *= Sqrt(myN) / aStep;
-
if (aLipConst < myC * 0.1)
- {
myC = Max(aLipConst * 0.1, 0.01);
- }
- else if (aLipConst > myC * 10)
+ else if (aLipConst > myC * 5)
+ myC = Min(myC * 5, 50.0);
+
+ // Clear all solutions except one.
+ if (myY.Size() != myN)
{
- myC = Min(myC * 2, 30.0);
+ for(i = 1; i <= myN; i++)
+ aBestPnt(i) = myY(i);
+ myY.Clear();
+ for(i = 1; i <= myN; i++)
+ myY.Append(aBestPnt(i));
}
+ mySolCount = 1;
}
//=======================================================================
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;
Standard_Boolean isReached = Standard_False;
+
for(myX(j) = myA(j) + myE1;
(myX(j) < myB(j) + myE1) && (!isReached);
myX(j) += myV(j))
{
isInside = Standard_False;
myFunc->Value(myX, d);
- r = (d + myZ * myC * aRealStep - myF) * myZ;
+ r = (d + myZ * myC * myLastStep - myF) * myZ;
if(r > myE3)
{
isInside = computeLocalExtremum(myX, val, myTmp);
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
{
//=======================================================================
Standard_Boolean math_GlobOptMin::CheckFunctionalStopCriteria()
{
- // Search single solution and current solution in its neighbourhood.
+ // Search single solution and current solution in its neighborhood.
if (myIsFindSingleSolution &&
Abs (myF - myFunctionalMinimalValue) < mySameTol * 0.01)
return Standard_True;
return Standard_False;
}
+
+//=======================================================================
+//function : ComputeInitSol
+//purpose :
+//=======================================================================
+void math_GlobOptMin::ComputeInitSol()
+{
+ Standard_Real aCurrVal, aBestVal;
+ math_Vector aCurrPnt(1, myN);
+ math_Vector aBestPnt(1, myN);
+ math_Vector aParamStep(1, myN);
+ // Check functional value in midpoint, lower and upper border points and
+ // in each point try to perform local optimization.
+ aBestPnt = (myGlobA + myGlobB) * 0.5;
+ myFunc->Value(aBestPnt, aBestVal);
+
+ Standard_Integer i;
+ for(i = 1; i <= 3; i++)
+ {
+ aCurrPnt = myA + (myB - myA) * (i - 1) / 2.0;
+
+ if(computeLocalExtremum(aCurrPnt, aCurrVal, aCurrPnt))
+ {
+ // Local search tries to find 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 = 1;
+
+ myDone = Standard_False;
+}
+
+//=======================================================================
+//function : SetLipConstState
+//purpose :
+//=======================================================================
+void math_GlobOptMin::SetLipConstState(const Standard_Boolean theFlag)
+{
+ myIsConstLocked = theFlag;
+}
\ No newline at end of file
//! 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();
// Compute cell size.
void initCellSize();
+ // Compute initial solution
+ void ComputeInitSol();
+
math_GlobOptMin & operator = (const math_GlobOptMin & theOther);
Standard_Boolean computeLocalExtremum(const math_Vector& thePnt, Standard_Real& theVal, math_Vector& theOutPnt);
Standard_Real mySameTol; // points with ||p1 - p2|| < mySameTol is equal,
// function values |val1 - val2| * 0.01 < mySameTol is equal,
// default value is 1.0e-7.
- Standard_Real myC; //Lipschitz constant, default 9
+ Standard_Real myC; //Lipchitz constant, default 9
+ 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;
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;