用2个方阵模拟matlab的mrdivide [英] Simulating matlab's mrdivide with 2 square matrices
问题描述
我有2个19x19方阵(a& b),我想使用斜线(mrdivide)运算符执行除法,使
c = a / b
我试图在OpenCV中实现。我发现有几个人建议使用 cv :: solve
,但到目前为止我一直无法找到任何给我一个结果任何接近matlab。
有没有人知道我如何用opencv实现mrdivide? p>
我试过下面的代码: p>
cv :: Mat mldivide(const cv :: Mat& A,const cv :: Mat& B)
{
// return b * A.inv();
cv :: Mat a;
cv :: Mat b;
A.convertTo(a,CV_64FC1);
B.convertTo(b,CV_64FC1);
cv :: Mat ret;
cv :: solve(a,b,ret,cv :: DECOMP_NORMAL);
cv :: Mat ret2;
ret.convertTo(ret2,A.type());
return ret2;
}
然后我执行mrdivide如下:
cv :: Mat mrdivide(const cv :: Mat& A,const cv :: Mat& B)
{
return mldivide (At(),Bt()).t();
}
( 编辑 :
这给我一个错误的答案,即没有什么像matlab。根据我的意见,我也尝试了
cv :: Mat mrdivide(const cv :: Mat& A,const cv :: Mat& ; B)
{
return A * B.inv();
}
这给出了与上面相同的答案,但也是错误的。
在MATLAB中,使用 a / b 是等价的,因此可以使用rel =nofollow> mrdivide
到 a * b ^ { - 1}
其中 b ^ { - 1}
c> b 。因此,你可以做的是先反转矩阵 b
,然后预乘这个 a
。
一种方法是使用 >
,然后用 cv :: invert
a
。这可以通过以下函数定义来完成(从你上面的代码中借用):
cv :: Mat mrdivide const cv :: Mat& A,const cv :: Mat& B)
{
cv :: Mat bInvert;
cv :: invert(B,bInvert);
return A * bInvert;
}
另一种方法是使用 inv()
方法 cv :: Mat
接口,只需使用并乘以矩阵本身:
cv :: Mat mrdivide(const cv :: Mat& A,const cv :: Mat& B)
{
return A * B.inv();
}
我不知道哪一个更快,所以你可能要做一些测试,但两种方法都应该工作。然而,为了提供对可能的时序的一点洞察,有三种方式来反转OpenCV中的矩阵。您只需重写第三个参数 cv :: invert
或指定 cv :: Mat.inv()
以方便这一点。
这个StackOverflow文章使用以下三种方法来处理相对较大矩阵大小的矩阵的定时:与矩阵相反的最快方法
I have 2 19x19 square matrices (a & b) and I am trying to use the slash (mrdivide) operator to perform a division such that
c = a / b
I am trying to implement this in OpenCV. I've found a few people suggesting using cv::solve
but so far I've been unable to find anything that gives me a result anything close to matlab.
Does anyone have any idea how I could implement mrdivide with opencv?
I've tried the following code:
cv::Mat mldivide(const cv::Mat& A, const cv::Mat& B )
{
//return b * A.inv();
cv::Mat a;
cv::Mat b;
A.convertTo( a, CV_64FC1 );
B.convertTo( b, CV_64FC1 );
cv::Mat ret;
cv::solve( a, b, ret, cv::DECOMP_NORMAL );
cv::Mat ret2;
ret.convertTo( ret2, A.type() );
return ret2;
}
I've then implemented mrdivide as follows:
cv::Mat mrdivide(const cv::Mat& A, const cv::Mat& B )
{
return mldivide( A.t(), B.t() ).t();
}
(Edit: As per the answers this does actually give me the correct answer when I used it correctly!)
This gives me a wrong answer, ie nothing like matlab. As per the comments I also tried
cv::Mat mrdivide(const cv::Mat& A, const cv::Mat& B )
{
return A * B.inv();
}
This give the same answer as above but is also wrong.
In MATLAB, using mrdivide
on two matrices of compatible dimension such that a / b
is equivalent to a * b^{-1}
where b^{-1}
is the inverse of b
. As such, what you could do is perhaps invert the matrix b
first, then pre-multiply this a
.
One method is to use cv::invert
on the matrix b
then pre-multiplying with a
. This could be done with the following function definition (borrowing from your code in your post above):
cv::Mat mrdivide(const cv::Mat& A, const cv::Mat& B)
{
cv::Mat bInvert;
cv::invert(B, bInvert);
return A * bInvert;
}
Another way is to use the inv()
method that's builtin to the cv::Mat
interface and just use that and multiply the matrices themselves:
cv::Mat mrdivide(const cv::Mat& A, const cv::Mat& B)
{
return A * B.inv();
}
I'm not sure which one is faster, so you may have to do some tests, but either of the two methods should work. However, to provide a bit of insight in terms of possible timings, there are three ways to invert a matrix in OpenCV. You simply override the third parameter to cv::invert
or specify the method in cv::Mat.inv()
to facilitate this.
This StackOverflow post goes through the timings of inverting a matrix for a relatively large matrix size using the three methods: Fastest method in inverse of matrix
这篇关于用2个方阵模拟matlab的mrdivide的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!