用2个方阵模拟matlab的mrdivide [英] Simulating matlab's mrdivide with 2 square matrices

查看:391
本文介绍了用2个方阵模拟matlab的mrdivide的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个19x19方阵(a& b),我想使用斜线(mrdivide)运算符执行除法,使

  c = a / b 



我试图在OpenCV中实现。我发现有几个人建议使用 cv :: solve ,但到目前为止我一直无法找到任何给我一个结果任何接近matlab。



有没有人知道我如何用opencv实现mrdivide?

我试过下面的代码: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆