namespace internal
{
-template<typename _Tp, int m> struct Matx_FastInvOp
+template<typename _Tp, int m, int n> struct Matx_FastInvOp
+{
+ bool operator()(const Matx<_Tp, m, n>&, Matx<_Tp, n, m>&, int) const
+ {
+ CV_Assert(false);
+ return false;
+ }
+};
+
+template<typename _Tp, int m> struct Matx_FastInvOp<_Tp, m, m>
{
bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
{
}
};
-template<typename _Tp> struct Matx_FastInvOp<_Tp, 2>
+template<typename _Tp> struct Matx_FastInvOp<_Tp, 2, 2>
{
bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const
{
}
};
-template<typename _Tp> struct Matx_FastInvOp<_Tp, 3>
+template<typename _Tp> struct Matx_FastInvOp<_Tp, 3, 3>
{
bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const
{
};
-template<typename _Tp, int m, int n> struct Matx_FastSolveOp
+template<typename _Tp, int m, int l, int n> struct Matx_FastSolveOp
+{
+ bool operator()(const Matx<_Tp, m, l>&, const Matx<_Tp, m, n>&,
+ Matx<_Tp, l, n>&, int) const
+ {
+ CV_Assert(false);
+ return false;
+ }
+};
+
+template<typename _Tp, int m, int n> struct Matx_FastSolveOp<_Tp, m, m, n>
{
bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
Matx<_Tp, m, n>& x, int method) const
}
};
-template<typename _Tp> struct Matx_FastSolveOp<_Tp, 2, 1>
+template<typename _Tp> struct Matx_FastSolveOp<_Tp, 2, 2, 1>
{
bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
Matx<_Tp, 2, 1>& x, int) const
}
};
-template<typename _Tp> struct Matx_FastSolveOp<_Tp, 3, 1>
+template<typename _Tp> struct Matx_FastSolveOp<_Tp, 3, 3, 1>
{
bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
Matx<_Tp, 3, 1>& x, int) const
Matx<_Tp, n, m> b;
bool ok;
if( m == n && (method == DECOMP_LU || method == DECOMP_CHOLESKY) )
- ok = cv::internal::Matx_FastInvOp<_Tp, m>()(*reinterpret_cast<const Matx<_Tp, m, m>*>(this), reinterpret_cast<Matx<_Tp, m, m>&>(b), method);
+ ok = cv::internal::Matx_FastInvOp<_Tp, m, n>()(*this, b, method);
else
{
Mat A(*this, false), B(b, false);
{
Matx<_Tp, n, l> x;
bool ok;
- if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
- ok = cv::internal::Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method);
+ if( m == n && (method == DECOMP_LU || method == DECOMP_CHOLESKY) )
+ ok = cv::internal::Matx_FastSolveOp<_Tp, m, n, l>()(*this, rhs, x, method);
else
{
Mat A(*this, false), B(rhs, false), X(x, false);
ASSERT_FALSE(solve(A, B, solutionQR, DECOMP_QR));
}
+TEST(Core_Solve, regression_11888)
+{
+ cv::Matx<float, 3, 2> A(
+ 2, 1,
+ 3, 1,
+ 6, 1
+ );
+ cv::Vec<float, 3> b(4, 5, 7);
+ cv::Matx<float, 2, 1> xQR = A.solve(b, DECOMP_QR);
+ cv::Matx<float, 2, 1> xSVD = A.solve(b, DECOMP_SVD);
+ EXPECT_LE(cvtest::norm(xQR, xSVD, CV_RELATIVE_L2), FLT_EPSILON);
+ cv::Matx<float, 2, 3> iA = A.inv(DECOMP_SVD);
+ EXPECT_LE(cvtest::norm(A*iA, Matx<float, 3, 3>::eye(), CV_RELATIVE_L2), 0.6);
+}
+
softdouble naiveExp(softdouble x)
{
int exponent = x.getExp();