raises DimensionError,
NotDone
is static;
-
-
+
+ SetBoundary(me: in out;
+ theLeftBorder : in Vector;
+ theRightBorder: in Vector)
+ ---Purpose: Set boundaries.
+ is static;
+
Minimum(me)
---Purpose: returns the value of the minimum.
-- Exception NotDone is raised if the minimum was not found.
nbiter: Integer is protected;
NoConvexTreatement: Boolean is protected;
Convex : Boolean is protected;
+myIsBoundsDefined : Boolean is protected;
+myLeft : Vector is protected;
+myRight : Vector is protected;
Itermax: Integer;
//#endif
#include <math_NewtonMinimum.ixx>
+#include <Precision.hxx>
#include <math_Gauss.hxx>
#include <math_Jacobi.hxx>
nbiter (0),
NoConvexTreatement(theWithSingularity),
Convex (Standard_True),
+ myIsBoundsDefined(Standard_False),
+ myLeft(1, theFunction.NbVariables(), 0.0),
+ myRight(1, theFunction.NbVariables(), 0.0),
Done (Standard_False),
Itermax (theNbIterations)
{
{
}
+//=======================================================================
+//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
//purpose :
TheStatus = math_DirectionSearchError;
return;
}
-
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;
do
{
--- /dev/null
+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}