mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-21 10:13:43 +03:00
0026022: Extrema_ExtCC gives not precise solution
Conditional optimization added to Newton optimization algorithm. Test case for issue CR26022
This commit is contained in:
parent
b5913c3c89
commit
b97a779a9f
@ -258,8 +258,8 @@ Standard_Boolean math_GlobOptMin::computeLocalExtremum(const math_Vector& thePnt
|
|||||||
{
|
{
|
||||||
math_MultipleVarFunctionWithHessian* myTmp =
|
math_MultipleVarFunctionWithHessian* myTmp =
|
||||||
dynamic_cast<math_MultipleVarFunctionWithHessian*> (myFunc);
|
dynamic_cast<math_MultipleVarFunctionWithHessian*> (myFunc);
|
||||||
|
|
||||||
math_NewtonMinimum newtonMinimum(*myTmp);
|
math_NewtonMinimum newtonMinimum(*myTmp);
|
||||||
|
newtonMinimum.SetBoundary(myGlobA, myGlobB);
|
||||||
newtonMinimum.Perform(*myTmp, thePnt);
|
newtonMinimum.Perform(*myTmp, thePnt);
|
||||||
|
|
||||||
if (newtonMinimum.IsDone())
|
if (newtonMinimum.IsDone())
|
||||||
|
@ -98,6 +98,11 @@ is
|
|||||||
NotDone
|
NotDone
|
||||||
is static;
|
is static;
|
||||||
|
|
||||||
|
SetBoundary(me: in out;
|
||||||
|
theLeftBorder : in Vector;
|
||||||
|
theRightBorder: in Vector)
|
||||||
|
---Purpose: Set boundaries.
|
||||||
|
is static;
|
||||||
|
|
||||||
Minimum(me)
|
Minimum(me)
|
||||||
---Purpose: returns the value of the minimum.
|
---Purpose: returns the value of the minimum.
|
||||||
@ -166,6 +171,9 @@ CTol: Real is protected;
|
|||||||
nbiter: Integer is protected;
|
nbiter: Integer is protected;
|
||||||
NoConvexTreatement: Boolean is protected;
|
NoConvexTreatement: Boolean is protected;
|
||||||
Convex : Boolean is protected;
|
Convex : Boolean is protected;
|
||||||
|
myIsBoundsDefined : Boolean is protected;
|
||||||
|
myLeft : Vector is protected;
|
||||||
|
myRight : Vector is protected;
|
||||||
Itermax: Integer;
|
Itermax: Integer;
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
#include <math_NewtonMinimum.ixx>
|
#include <math_NewtonMinimum.ixx>
|
||||||
|
#include <Precision.hxx>
|
||||||
|
|
||||||
#include <math_Gauss.hxx>
|
#include <math_Gauss.hxx>
|
||||||
#include <math_Jacobi.hxx>
|
#include <math_Jacobi.hxx>
|
||||||
@ -49,6 +50,9 @@ math_NewtonMinimum::math_NewtonMinimum(
|
|||||||
nbiter (0),
|
nbiter (0),
|
||||||
NoConvexTreatement(theWithSingularity),
|
NoConvexTreatement(theWithSingularity),
|
||||||
Convex (Standard_True),
|
Convex (Standard_True),
|
||||||
|
myIsBoundsDefined(Standard_False),
|
||||||
|
myLeft(1, theFunction.NbVariables(), 0.0),
|
||||||
|
myRight(1, theFunction.NbVariables(), 0.0),
|
||||||
Done (Standard_False),
|
Done (Standard_False),
|
||||||
Itermax (theNbIterations)
|
Itermax (theNbIterations)
|
||||||
{
|
{
|
||||||
@ -62,6 +66,18 @@ math_NewtonMinimum::~math_NewtonMinimum()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : SetBoundary
|
||||||
|
//purpose : Set boundaries for conditional optimization
|
||||||
|
//=======================================================================
|
||||||
|
void math_NewtonMinimum::SetBoundary(const math_Vector& theLeftBorder,
|
||||||
|
const math_Vector& theRightBorder)
|
||||||
|
{
|
||||||
|
myLeft = theLeftBorder;
|
||||||
|
myRight = theRightBorder;
|
||||||
|
myIsBoundsDefined = Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Perform
|
//function : Perform
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -134,8 +150,52 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
|
|||||||
TheStatus = math_DirectionSearchError;
|
TheStatus = math_DirectionSearchError;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LU.Solve(TheGradient, TheStep);
|
LU.Solve(TheGradient, TheStep);
|
||||||
|
|
||||||
|
if (myIsBoundsDefined)
|
||||||
|
{
|
||||||
|
// Project point on bounds or nullify TheStep coords if point lies on boudary.
|
||||||
|
|
||||||
|
*suivant = *precedent - TheStep;
|
||||||
|
Standard_Real aMult = RealLast();
|
||||||
|
for(Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++)
|
||||||
|
{
|
||||||
|
if (suivant->Value(anIdx) < myLeft(anIdx))
|
||||||
|
{
|
||||||
|
Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / Abs(TheStep(anIdx));
|
||||||
|
aMult = Min (aValue, aMult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suivant->Value(anIdx) > myRight(anIdx))
|
||||||
|
{
|
||||||
|
Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / Abs(TheStep(anIdx));
|
||||||
|
aMult = Min (aValue, aMult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aMult != RealLast())
|
||||||
|
{
|
||||||
|
if (aMult > Precision::PConfusion())
|
||||||
|
{
|
||||||
|
// Project point into param space.
|
||||||
|
TheStep *= aMult;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Old point on border and new point out of border:
|
||||||
|
// Nullify corresponding TheStep indexes.
|
||||||
|
for(Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++)
|
||||||
|
{
|
||||||
|
if (Abs(precedent->Value(anIdx) - myRight(anIdx)) < Precision::PConfusion() ||
|
||||||
|
Abs(precedent->Value(anIdx) - myLeft(anIdx) ) < Precision::PConfusion())
|
||||||
|
{
|
||||||
|
TheStep(anIdx) = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Standard_Boolean hasProblem = Standard_False;
|
Standard_Boolean hasProblem = Standard_False;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ checkreal "Parameter2" ${Parameter2} ${expected_Parameter2} ${tol_abs} ${tol_rel
|
|||||||
set expected_OriginX 2.
|
set expected_OriginX 2.
|
||||||
checkreal "OriginX" ${OriginX} ${expected_OriginX} ${tol_abs} ${tol_rel}
|
checkreal "OriginX" ${OriginX} ${expected_OriginX} ${tol_abs} ${tol_rel}
|
||||||
|
|
||||||
set expected_OriginY -6.e-05
|
set expected_OriginY 7.e-05
|
||||||
checkreal "OriginY" ${OriginY} ${expected_OriginY} ${tol_abs} ${tol_rel}
|
checkreal "OriginY" ${OriginY} ${expected_OriginY} ${tol_abs} ${tol_rel}
|
||||||
|
|
||||||
set expected_AxisX 1.
|
set expected_AxisX 1.
|
||||||
|
40
tests/bugs/fclasses/bug26022
Normal file
40
tests/bugs/fclasses/bug26022
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC26022"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
##############################################
|
||||||
|
# Extrema_ExtCC gives not precise solution
|
||||||
|
##############################################
|
||||||
|
|
||||||
|
restore [locate_data_file bug26022_splitnoproblem671_notria.brep] a
|
||||||
|
|
||||||
|
explode a
|
||||||
|
explode a_2 e
|
||||||
|
subshape a_2 e 2
|
||||||
|
mkcurve c1 a_1
|
||||||
|
mkcurve c2 a_2_2
|
||||||
|
|
||||||
|
extrema c1 c2 1
|
||||||
|
|
||||||
|
cvalue c1 prm_1_1 x1 y1 z1
|
||||||
|
bounds c1 u1 u2
|
||||||
|
cvalue c1 u2 x2 y2 z2
|
||||||
|
|
||||||
|
regexp {is ([\d.\-e]+)} [length ext_1] str dist
|
||||||
|
set dist_to_end [dval sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))]
|
||||||
|
set parametric_dist_to_end [dval u2-prm_1_1]
|
||||||
|
|
||||||
|
puts "dist of solution $dist"
|
||||||
|
puts "parametric dist to end of curve $parametric_dist_to_end"
|
||||||
|
puts "dist to end of curve $dist_to_end"
|
||||||
|
|
||||||
|
set tol_abs 4.0e-12
|
||||||
|
set tol_rel 1.0e-2
|
||||||
|
|
||||||
|
set expected_dist 0.0
|
||||||
|
set expected_parametric_dist_to_end 0.0
|
||||||
|
set expected_dist_to_end 0.0
|
||||||
|
|
||||||
|
checkreal "dist of solution" ${dist} ${expected_dist} ${tol_abs} ${tol_rel}
|
||||||
|
checkreal "parametric dist to end of curve" ${parametric_dist_to_end} ${expected_parametric_dist_to_end} ${tol_abs} ${tol_rel}
|
||||||
|
checkreal "dist to end of curve" ${dist_to_end} ${expected_dist_to_end} ${tol_abs} ${tol_rel}
|
@ -13,7 +13,7 @@ set info [2dextrema b9 b10]
|
|||||||
set status 0
|
set status 0
|
||||||
for { set i 1 } { $i <= 1 } { incr i 1 } {
|
for { set i 1 } { $i <= 1 } { incr i 1 } {
|
||||||
regexp "dist $i: +(\[-0-9.+eE\]+)" $info full pp
|
regexp "dist $i: +(\[-0-9.+eE\]+)" $info full pp
|
||||||
if { abs($pp - 3.6710601078037173) > 1.0e-7 } {
|
if { abs($pp - 3.6712618987696386) > 1.0e-7 } {
|
||||||
puts "Error : Extrema is wrong on dist $i"
|
puts "Error : Extrema is wrong on dist $i"
|
||||||
set status 1
|
set status 1
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user