core: update solveLP() interface
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Mon, 15 Oct 2018 18:58:11 +0000 (18:58 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Mon, 15 Oct 2018 18:58:11 +0000 (18:58 +0000)
modules/core/include/opencv2/core/optim.hpp
modules/core/src/lpsolver.cpp
modules/core/test/test_lpsolver.cpp

index c4729a9..36c798a 100644 (file)
@@ -293,7 +293,7 @@ and the remaining to \f$A\f$. It should contain 32- or 64-bit floating point num
 formulation above. It will contain 64-bit floating point numbers.
 @return One of cv::SolveLPResult
  */
-CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z);
+CV_EXPORTS_W int solveLP(InputArray Func, InputArray Constr, OutputArray z);
 
 //! @}
 
index 1a1307d..951da3f 100644 (file)
@@ -90,18 +90,20 @@ static void swap_columns(Mat_<double>& A,int col1,int col2);
 #define SWAP(type,a,b) {type tmp=(a);(a)=(b);(b)=tmp;}
 
 //return codes:-2 (no_sol - unbdd),-1(no_sol - unfsbl), 0(single_sol), 1(multiple_sol=>least_l2_norm)
-int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
+int solveLP(InputArray Func_, InputArray Constr_, OutputArray z_)
+{
     dprintf(("call to solveLP\n"));
 
     //sanity check (size, type, no. of channels)
-    CV_Assert(Func.type()==CV_64FC1 || Func.type()==CV_32FC1);
-    CV_Assert(Constr.type()==CV_64FC1 || Constr.type()==CV_32FC1);
-    CV_Assert((Func.rows==1 && (Constr.cols-Func.cols==1))||
-            (Func.cols==1 && (Constr.cols-Func.rows==1)));
-    if (!z.empty())
-        CV_CheckTypeEQ(z.type(), CV_64FC1, "");
-    else
-        CV_CheckType(z.type(), z.type() == CV_64FC1 || z.type() == CV_8UC1/*empty cv::Mat*/, "");
+    CV_Assert(Func_.type()==CV_64FC1 || Func_.type()==CV_32FC1);
+    CV_Assert(Constr_.type()==CV_64FC1 || Constr_.type()==CV_32FC1);
+    CV_Assert((Func_.rows()==1 && (Constr_.cols()-Func_.cols()==1))||
+            (Func_.cols()==1 && (Constr_.cols()-Func_.rows()==1)));
+    if (z_.fixedType())
+        CV_CheckType(z_.type(), z_.type() == CV_64FC1 || z_.type() == CV_32FC1 || z_.type() == CV_32SC1, "");
+
+    Mat Func = Func_.getMat();
+    Mat Constr = Constr_.getMat();
 
     //copy arguments for we will shall modify them
     Mat_<double> bigC=Mat_<double>(1,(Func.rows==1?Func.cols:Func.rows)+1),
@@ -129,7 +131,7 @@ int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
     }
 
     //return the optimal solution
-    z.create(c.cols,1,CV_64FC1);
+    Mat z(c.cols,1,CV_64FC1);
     MatIterator_<double> it=z.begin<double>();
     unsigned int nsize = (unsigned int)N.size();
     for(int i=1;i<=c.cols;i++,it++){
@@ -140,6 +142,7 @@ int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
         }
     }
 
+    z.copyTo(z_);
     return res;
 }
 
index 97f87f4..99829cb 100644 (file)
@@ -145,10 +145,10 @@ TEST(Core_LPSolver, issue_12337)
 {
     Mat A=(cv::Mat_<double>(3,1)<<3,1,2);
     Mat B=(cv::Mat_<double>(3,4)<<1,1,3,30,2,2,5,24,4,1,2,36);
-    EXPECT_ANY_THROW(Mat1f z_float; cv::solveLP(A, B, z_float));
-    EXPECT_NO_THROW(Mat1d z_double; cv::solveLP(A, B, z_double));
-    EXPECT_ANY_THROW(Mat1i z_int; cv::solveLP(A, B, z_int));
-    //need to update interface: EXPECT_ANY_THROW(Mat1b z_8u; cv::solveLP(A, B, z_8u));
+    Mat1f z_float; cv::solveLP(A, B, z_float);
+    Mat1d z_double; cv::solveLP(A, B, z_double);
+    Mat1i z_int; cv::solveLP(A, B, z_int);
+    EXPECT_ANY_THROW(Mat1b z_8u; cv::solveLP(A, B, z_8u));
 }
 
 }} // namespace