了解本征中的SolveInPlace操作 [英] Understanding solveInPlace operation in Eigen

查看:405
本文介绍了了解本征中的SolveInPlace操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Eigen3.3.7中使用LLT来加快应用程序中矩阵逆运算的速度时,我试图探索 solveInPlace()函数的选项。
我使用以下代码对其进行了测试。

I was trying to explore the option of "solveInPlace()" function while using LLT in Eigen3.3.7 to speed up the matrix inverse computation in my application. I used the following code to test it.

    int main()
    {
        const int M=3;

        Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic> R = Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic>::Zero(M,M);
        // to make sure full rank
        for(int i=0; i<M*2; i++)
        {
            const Eigen::Matrix<MyType, Eigen::Dynamic,1> tmp = Eigen::Matrix<MyType,Eigen::Dynamic,1>::Random(M);
            R += tmp*tmp.transpose();
        }

        std::cout<<"R \n";
        std::cout<<R<<std::endl;
        decltype (R) R0 =  R; // saving for later comparison



        Eigen::LLT<Eigen::Ref<Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic> > > myllt(R);
        const Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic> I = Eigen::Matrix<MyType,Eigen::Dynamic,Eigen::Dynamic>::Identity(R.rows(), R.cols());

        myllt.solveInPlace(I);

        std::cout<<"I: "<<I<<std::endl;
        std::cout<<"Prod InPlace: \n"<<R0*I<<std::endl;


        return 0;
}

在阅读了Eigen文档后,我认为输入矩阵(此处为 R )将在计算转换时进行修改。令我惊讶的是,我发现结果存储在 I中。因为我将 I定义为常量,所以这不是预期的。请为此行为提供一个解释。

After reading the Eigen documentation, I thought that the input matrix (here "R") will be modified while computing the transform. To my surprise, I found that the results is store in "I". This was not expected as I defined "I" as a constant. Please provide an explanation for this behaviour.

推荐答案

简单的非编译器回答是,您要让LLT进行操作。解决就地 (即在传递的参数中),那么您期望的结果是什么?显然,您希望它是编译器错误,因为就地意味着更改参数,但是您正在传递const对象。

The simple non-compiler answer would be that you're asking for the LLT to solve in-place (i.e. in the passed parameter) so what would you expect the result to be? Apparently, you would expect it to be a compiler error, as the "in-place" means change the parameter, but you're passing a const object.

因此,如果我们在Eigen文档中搜索solveInPlace,则会找到唯一带有const引用且具有以下注释

So, if we search the Eigen docs for solveInPlace, we find the only item that takes a const reference to have the following note:


TriangularView :: solve()的就地版本,将结果写入其中其他

"in-place" version of TriangularView::solve() where the result is written in other

警告

该参数仅标记为 const,以使C ++编译器在此处接受临时表达式。此函数将进行const_cast转换,因此此处不具备constness功能。

Warning
The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here. This function will const_cast it, so constness isn't honored here.

非就地选项将是:

R = myllt.solve(I);

但这不会真正加快计算速度。在任何情况下,都要先进行基准测试,然后再决定是否需要就地选择。

but that won't really speed up the calculation. In any case, benchmark before you decide that you need the in-place option.

您的问题就位了,因为 const_cast 的目的是在其基础变量不是const限定的情况下去除其常量的引用/指针的常量*( cppref )。如果您要编写一些示例

You're question is in place, as what const_cast is meant to do is strip references/pointers of their const-ness iff the underlying variable is not const qualified* (cppref). If you were to write some examples

const int i = 4;
int& iRef = const_cast<int&>(i); // UB, i is actually const
std::cout << i; // Prints "I want coffee", or it can as we like UB
int j = 4;
const int& jRef = j;
const_cast<int&>(jRef)++; // Legal. Underlying variable is not const.
std::cout << j; // Prints 5

i 的情况能否按预期运行,我们取决于每个实现/编译器。它可能适用于gcc,但不适用于clang或MSVC。没有保证。在您的示例中间接调用UB时,编译器可以选择执行您期望的操作或完全执行其他操作。

The case with i may well work as expected or not, we're dependent on each implementation/compiler. It may work with gcc but not with clang or MSVC. There are no guarantees. As you are indirectly invoking UB in your example, the compiler can choose to do what you expect or something else entirely.

*从技术上讲,修改是UB,而不是 const_cast 本身。

*Technically it's the modification that's UB, not the const_cast itself.

这篇关于了解本征中的SolveInPlace操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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