0025635: Wrong result of 2D-extrema between two ellipsis
authoraml <aml@opencascade.com>
Thu, 5 Feb 2015 13:13:39 +0000 (16:13 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 5 Feb 2015 13:14:55 +0000 (16:14 +0300)
Fixed Lipschitz constant evaluation in case co-parametrized objects.
Fixed 2dextrema output.
Testcase update to new behavior.

Test cases for issue CR25635

Correction of test cases for issue CR25635

src/GeomliteTest/GeomliteTest_API2dCommands.cxx
src/math/math_GlobOptMin.cxx
tests/bugs/fclasses/bug25635_1 [new file with mode: 0755]
tests/bugs/fclasses/bug25635_2 [new file with mode: 0755]
tests/bugs/moddata_1/buc60890

index 000f758..dc21320 100644 (file)
@@ -250,20 +250,23 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
 
     gp_Pnt2d P1,P2;
     Ex.Points(i,P1,P2);
-    di << "dist " << i << ": " << Ex.Distance(i) << " \n";
+    di << "dist " << i << ": " << Ex.Distance(i) << "  ";
     if (Ex.Distance(i) <= Precision::PConfusion()) {
       Handle(Draw_Marker2D) mark = new Draw_Marker2D( P1, Draw_X, Draw_vert); 
       dout << mark;
       dout.Flush();
+      Sprintf(name,"%s%d","ext_",i);
+      char* temp = name;
+      DrawTrSurf::Set(temp, P1);
+      di << name << "\n";
     }
     else {
       Handle(Geom2d_Line) L = new Geom2d_Line(P1,gp_Vec2d(P1,P2));
-      Handle(Geom2d_TrimmedCurve) CT = 
-       new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2));
+      Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2));
       Sprintf(name,"%s%d","ext_",i);
       char* temp = name; // portage WNT
       DrawTrSurf::Set(temp, CT);
-      di << name << " ";
+      di << name << "\n";
     }
   }
   if (i==1)
index 42f6a8b..0efeedb 100644 (file)
@@ -23,6 +23,7 @@
 #include <math_Powell.hxx>
 #include <Standard_Integer.hxx>
 #include <Standard_Real.hxx>
+#include <Precision.hxx>
 
 
 //=======================================================================
@@ -194,9 +195,6 @@ void math_GlobOptMin::Perform()
 {
   Standard_Integer i;
 
-  // Compute initial values for myF, myY, myC.
-  computeInitialValues();
-
   // Compute parameters range
   Standard_Real minLength = RealLast();
   Standard_Real maxLength = RealFirst();
@@ -209,6 +207,18 @@ void math_GlobOptMin::Perform()
       maxLength = currentLength;
   }
 
+  if (minLength < Precision::PConfusion())
+  {
+    #ifdef OCCT_DEBUG
+    cout << "math_GlobOptMin::Perform(): Degenerated parameters space" << endl;
+    #endif
+
+    return;
+  }
+
+  // Compute initial values for myF, myY, myC.
+  computeInitialValues();
+
   myE1 = minLength * myTol;
   myE2 = maxLength * myTol;
   if (myC > 1.0)
@@ -293,7 +303,7 @@ void math_GlobOptMin::computeInitialValues()
   Standard_Integer i;
   math_Vector aCurrPnt(1, myN);
   math_Vector aBestPnt(1, myN);
-
+  math_Vector aParamStep(1, myN);
   Standard_Real aCurrVal = RealLast();
   Standard_Real aBestVal = RealLast();
 
@@ -324,21 +334,29 @@ void math_GlobOptMin::computeInitialValues()
   mySolCount++;
 
   // Lipschitz const approximation
-  Standard_Real aLipConst = 0.0, aPrevVal;
+  Standard_Real aLipConst = 0.0, aPrevValDiag, aPrevValProj;
   Standard_Integer aPntNb = 13;
-  myFunc->Value(myA, aPrevVal);
+  myFunc->Value(myA, aPrevValDiag);
+  aPrevValProj = aPrevValDiag;
   Standard_Real aStep = (myB - myA).Norm() / aPntNb;
+  aParamStep = (myB - myA) / aPntNb;
   for(i = 1; i <= aPntNb; i++)
   {
-    aCurrPnt = myA + (myB - myA) * i / (aPntNb - 1);
-    myFunc->Value(aCurrPnt, aCurrVal);
+    aCurrPnt = myA + aParamStep * i;
 
-    if(Abs(aCurrVal - aPrevVal) / aStep > aLipConst)
-      aLipConst = Abs(aCurrVal - aPrevVal) / aStep;
+    // Walk over diagonal.
+    myFunc->Value(aCurrPnt, aCurrVal);
+    aLipConst = Max (Abs(aCurrVal - aPrevValDiag), aLipConst);
+    aPrevValDiag = aCurrVal;
 
-    aPrevVal = aCurrVal;
+    // Walk over diag in projected space aPnt(1) = myA(1) = const.
+    aCurrPnt(1) = myA(1);
+    myFunc->Value(aCurrPnt, aCurrVal);
+    aLipConst = Max (Abs(aCurrVal - aPrevValProj), aLipConst);
+    aPrevValProj = aCurrVal;
   }
-  aLipConst *= Sqrt(myN);
+
+  aLipConst *= Sqrt(myN) / aStep;
 
   if (aLipConst < myC * 0.1)
   {
diff --git a/tests/bugs/fclasses/bug25635_1 b/tests/bugs/fclasses/bug25635_1
new file mode 100755 (executable)
index 0000000..0aba7dc
--- /dev/null
@@ -0,0 +1,46 @@
+puts "============"
+puts "OCC25635"
+puts "============"
+puts ""
+######################################################
+# Wrong result of 2D-extrema between two ellipsis
+######################################################
+
+ellipse c1 0 0 2 1
+ellipse c2 4 0 2 1
+
+set info [2dextrema c1 c2]
+
+set tol_abs 1.e-7
+set tol_rel 0.01
+
+#-1
+regexp "dist 1: +(\[-0-9.+eE\]+)" ${info} full dist_1
+
+set expected_dist_1 7.9e-09
+checkreal "Distance" ${dist_1} ${expected_dist_1} ${tol_abs} ${tol_rel}
+
+#-2
+set dump_list [dump ext_1]
+
+regexp { *Parameters *: *([-0-9.+eE]+) *([-0-9.+eE]+)} ${dump_list} full Parameter1 Parameter2
+regexp { *Origin *:([-0-9.+eE]+), *([-0-9.+eE]+) } ${dump_list} full OriginX OriginY
+regexp { *Axis *:([-0-9.+eE]+), *([-0-9.+eE]+) } ${dump_list} full AxisX AxisY
+
+set expected_Parameter1 0.
+checkreal "Parameter1" ${Parameter1} ${expected_Parameter1} ${tol_abs} ${tol_rel}
+
+set expected_Parameter2 7.94518140168066e-09
+checkreal "Parameter2" ${Parameter2} ${expected_Parameter2} ${tol_abs} ${tol_rel}
+
+set expected_OriginX 1.99999999602741
+checkreal "OriginX" ${OriginX} ${expected_OriginX} ${tol_abs} ${tol_rel}
+
+set expected_OriginY -6.30284903027441e-05 
+checkreal "OriginY" ${OriginY} ${expected_OriginY} ${tol_abs} ${tol_rel}
+
+set expected_AxisX 1.
+checkreal "AxisX" ${AxisX} ${expected_AxisX} ${tol_abs} ${tol_rel}
+
+set expected_AxisY -9.65456920683062e-09 
+checkreal "AxisY" ${AxisY} ${expected_AxisY} ${tol_abs} ${tol_rel}
diff --git a/tests/bugs/fclasses/bug25635_2 b/tests/bugs/fclasses/bug25635_2
new file mode 100755 (executable)
index 0000000..ee04803
--- /dev/null
@@ -0,0 +1,47 @@
+puts "============"
+puts "OCC25635"
+puts "============"
+puts ""
+######################################################
+# Wrong result of 2D-extrema between two ellipsis
+######################################################
+
+circle c1 0 0 2
+circle c2 4 0 2
+
+set info [2dextrema c1 c2]
+
+#-1
+if { [regexp "dist 1: +(\[-0-9.+eE\]+) +ext_1" ${info}] } {
+  puts "OK: Good ext_1"
+} else {
+  puts "Error: Wrong ext_1"
+}
+
+if { [regexp "dist 2: +(\[-0-9.+eE\]+) +ext_2" ${info}] } {
+  puts "OK: Good ext_2"
+} else {
+  puts "Error: Wrong ext_2"
+}
+
+if { [regexp "dist 3: +(\[-0-9.+eE\]+) +ext_3" ${info}] } {
+  puts "OK: Good ext_3"
+} else {
+  puts "Error: Wrong ext_3"
+}
+
+if { [regexp "dist 4: +(\[-0-9.+eE\]+) +ext_4" ${info}] } {
+  puts "OK: Good ext_4"
+} else {
+  puts "Error: Wrong ext_4"
+}
+
+
+#-2
+set dump_list [dump ext_2]
+
+if { [regexp {Point 2d} ${dump_list}] } {
+  puts "OK: Good result of 2D-extrema between two circles"
+} else {
+  puts "Error: Wrong result of 2D-extrema between two circles"
+}
index e2cb21f..453b19b 100755 (executable)
@@ -15,7 +15,7 @@ circle curve_2 5.3 -0.5 2
 
 set err [llength [2dextrema curve_1 curve_2]]
 
-if {$err == 6} {
+if {$err == 8} {
     puts "BUC60890 OK: Function 2dextrema works properly."
 } else {
     puts "Faulty BUC60890 : Function 2dextrema works wrongly."