0025708: GeomAPI_ExtremaCurveCurve does not return all intersection points in 6.8.0
authoraml <aml@opencascade.com>
Thu, 5 Feb 2015 13:01:40 +0000 (16:01 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 5 Feb 2015 13:03:36 +0000 (16:03 +0300)
Added expanding coefficients between neighboring indexes, changed local optimization starting condition.

Test case for issue CR25708

src/math/math_GlobOptMin.cxx
src/math/math_GlobOptMin.hxx
tests/bugs/modalg_5/bug23706_14
tests/bugs/modalg_5/bug25708 [new file with mode: 0755]

index 30f2dbd..42f6a8b 100644 (file)
 #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
@@ -48,7 +43,8 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
   myX(1, myN),
   myTmp(1, myN),
   myV(1, myN),
-  myMaxV(1, myN)
+  myMaxV(1, myN),
+  myExpandCoeff(1, myN)
 {
   Standard_Integer i;
 
@@ -71,6 +67,12 @@ math_GlobOptMin::math_GlobOptMin(math_MultipleVarFunction* theFunc,
     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;
 
@@ -104,6 +106,17 @@ void math_GlobOptMin::SetGlobalParams(math_MultipleVarFunction* theFunc,
     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;
 
@@ -133,6 +146,12 @@ void math_GlobOptMin::SetLocalParams(const math_Vector& theLocalA,
     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;
 }
 
@@ -340,9 +359,9 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
   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;
 
@@ -356,52 +375,61 @@ void math_GlobOptMin::computeGlobalExtremum(Standard_Integer j)
     {
       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;
+      }
     }
   }
 }
index ac5a4db..27d4834 100644 (file)
@@ -29,15 +29,15 @@ class math_GlobOptMin
 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);
@@ -61,7 +61,7 @@ public:
   //! 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();
@@ -75,15 +75,16 @@ private:
   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.
@@ -114,10 +115,9 @@ private:
   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
index 622b96e..72c0e5d 100755 (executable)
@@ -13,7 +13,7 @@ set info [2dextrema b9 b10]
 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
     }
diff --git a/tests/bugs/modalg_5/bug25708 b/tests/bugs/modalg_5/bug25708
new file mode 100755 (executable)
index 0000000..c8704a0
--- /dev/null
@@ -0,0 +1,44 @@
+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 "
+   }
+
+}