Added expanding coefficients between neighboring indexes, changed local optimization starting condition.
Test case for issue CR25708
#include <Standard_Integer.hxx>
#include <Standard_Real.hxx>
-const Handle(Standard_Type)& STANDARD_TYPE(math_GlobOptMin)
-{
- static Handle(Standard_Type) _atype = new Standard_Type ("math_GlobOptMin", sizeof (math_GlobOptMin));
- return _atype;
-}
//=======================================================================
//function : math_GlobOptMin
myX(1, myN),
myTmp(1, myN),
myV(1, myN),
- myMaxV(1, myN)
+ myMaxV(1, myN),
+ myExpandCoeff(1, myN)
{
Standard_Integer i;
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;
myB(i) = theB(i);
}
+ for(i = 1; i <= myN; i++)
+ {
+ 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;
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;
}
Standard_Integer i;
Standard_Real d; // Functional in moved point.
Standard_Real val = RealLast(); // Local extrema computed in moved point.
- Standard_Real stepBestValue = RealLast();
- Standard_Real realStep = RealLast();
- math_Vector stepBestPoint(1, myN);
+ Standard_Real aStepBestValue = RealLast();
+ Standard_Real aRealStep = 0.0;
+ math_Vector aStepBestPoint(1, myN);
Standard_Boolean isInside = Standard_False;
Standard_Real r;
{
isInside = Standard_False;
myFunc->Value(myX, d);
- r = (d - myF) * myZ;
+ r = (d + myZ * myC * aRealStep - myF) * myZ;
if(r > myE3)
{
isInside = computeLocalExtremum(myX, val, myTmp);
}
- stepBestValue = (isInside && (val < d))? val : d;
- stepBestPoint = (isInside && (val < d))? myTmp : myX;
+ aStepBestValue = (isInside && (val < d))? val : d;
+ aStepBestPoint = (isInside && (val < d))? myTmp : myX;
// Solutions are close to each other.
- if (Abs(stepBestValue - myF) < mySameTol * 0.01)
+ if (Abs(aStepBestValue - myF) < mySameTol * 0.01)
{
- if (!isStored(stepBestPoint))
+ if (!isStored(aStepBestPoint))
{
- if ((stepBestValue - myF) * myZ > 0.0)
- myF = stepBestValue;
+ if ((aStepBestValue - myF) * myZ > 0.0)
+ myF = aStepBestValue;
for(i = 1; i <= myN; i++)
- myY.Append(stepBestPoint(i));
+ myY.Append(aStepBestPoint(i));
mySolCount++;
}
}
// New best solution.
- if ((stepBestValue - myF) * myZ > mySameTol * 0.01)
+ if ((aStepBestValue - myF) * myZ > mySameTol * 0.01)
{
mySolCount = 0;
- myF = stepBestValue;
+ myF = aStepBestValue;
myY.Clear();
for(i = 1; i <= myN; i++)
- myY.Append(stepBestPoint(i));
+ myY.Append(aStepBestPoint(i));
mySolCount++;
}
- realStep = myE2 + Abs(myF - d) / myC;
- myV(1) = Min(realStep, myMaxV(1));
+ aRealStep = myE2 + Abs(myF - d) / myC;
+ myV(1) = Min(aRealStep, myMaxV(1));
}
else
{
myV(j) = RealLast() / 2.0;
computeGlobalExtremum(j - 1);
+
+ // Nullify steps on lower dimensions.
+ for(i = 1; i < j; i++)
+ myV(i) = 0.0;
}
- if ((j < myN) && (myV(j + 1) > realStep))
+ // Compute step in (j + 1) dimension according to scale.
+ if (j < myN)
{
- if (realStep > myMaxV(j + 1)) // Case of too big step.
- myV(j + 1) = myMaxV(j + 1);
- else
- myV(j + 1) = realStep;
+ Standard_Real aUpperDimStep = myV(j) * myExpandCoeff(j + 1);
+ if (myV(j + 1) > aUpperDimStep)
+ {
+ if (aUpperDimStep > myMaxV(j + 1)) // Case of too big step.
+ myV(j + 1) = myMaxV(j + 1);
+ else
+ myV(j + 1) = aUpperDimStep;
+ }
}
}
}
public:
Standard_EXPORT math_GlobOptMin(math_MultipleVarFunction* theFunc,
- const math_Vector& theA,
- const math_Vector& theB,
+ const math_Vector& theLowerBorder,
+ const math_Vector& theUpperBorder,
const Standard_Real theC = 9,
const Standard_Real theDiscretizationTol = 1.0e-2,
const Standard_Real theSameTol = 1.0e-7);
Standard_EXPORT void SetGlobalParams(math_MultipleVarFunction* theFunc,
- const math_Vector& theA,
- const math_Vector& theB,
+ const math_Vector& theLowerBorder,
+ const math_Vector& theUpperBorder,
const Standard_Real theC = 9,
const Standard_Real theDiscretizationTol = 1.0e-2,
const Standard_Real theSameTol = 1.0e-7);
//! Return count of global extremas.
Standard_EXPORT Standard_Integer NbExtrema();
- //! Return solution i, 1 <= i <= NbExtrema.
+ //! Return solution theIndex, 1 <= theIndex <= NbExtrema.
Standard_EXPORT void Points(const Standard_Integer theIndex, math_Vector& theSol);
Standard_Boolean isDone();
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.
+ //! 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 <= thePnt <= myB
Standard_Boolean isInside(const math_Vector& thePnt);
+ //! Check presence of thePnt in GlobOpt sequence.
Standard_Boolean isStored(const math_Vector &thePnt);
// Input.
math_Vector myTmp; // Current modified solution.
math_Vector myV; // Steps array.
math_Vector myMaxV; // Max Steps array.
+ math_Vector myExpandCoeff; // Define expand coefficient between neighboring indiced dimensions.
Standard_Real myF; // Current value of Global optimum.
};
-const Handle(Standard_Type)& TYPE(math_GlobOptMin);
-
#endif
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.8268201236765877) > 1.0e-7 } {
+ if { abs($pp - 3.6710601078037173) > 1.0e-7 } {
puts "Error : Extrema is wrong on dist $i"
set status 1
}
--- /dev/null
+puts "========"
+puts "OCC25708"
+puts "========"
+puts ""
+###########################################################
+# GeomAPI_ExtremaCurveCurve does not return all intersection points in 6.8.0
+###########################################################
+
+set BugNumber OCC25708
+
+restore [locate_data_file bug25708_interror.brep] b
+
+explode b e
+
+mkcurve c1 b_1
+mkcurve c2 b_2
+
+set extrema_res [extrema c1 c2]
+set extrema_length [llength ${extrema_res} ]
+
+if {${extrema_length} != 2 } {
+ puts "Error: GeomAPI_ExtremaCurveCurve does not return all intersection points"
+} else {
+ puts "OK: GeomAPI_ExtremaCurveCurve return all intersection points"
+
+# Distance check
+
+ set info [dump ext_1]
+ regexp "Parameters : 0 +(\[-0-9*\.+eE\]+)" $info full extLength1
+ if {${extLength1} > 1e-14 } {
+ puts "1. Error: bad distance points obtained"
+ } else {
+ puts "1. OK: good distance between obtained points "
+ }
+
+ set info [dump ext_2]
+ regexp "Parameters : 0 +(\[-0-9*\.+eE\]+)" $info full extLength2
+ if {${extLength2} > 1e-14 } {
+ puts "2. Error: bad distance points obtained"
+ } else {
+ puts "2. OK: good distance between obtained points "
+ }
+
+}