本征矩阵智能指针移动构造

时间:2018-06-22 03:03:11

标签: eigen copy-constructor smart-pointers

代码如下:

// Generate the returns matrix
boost::shared_ptr<Eigen::MatrixXd> returns_m = boost::make_shared<Eigen::MatrixXd>(factor_size, num_of_obs_per_simulation);

//Generate covariance matrix
boost::shared_ptr<MatrixXd> corMatrix = boost::make_shared<MatrixXd>(factor_size, factor_size);
    (*corMatrix) = (*returns_m) * (*returns_m).transpose() / (num_of_obs_per_simulation - 1);

关键是我想将corMatrx作为指针而不是对象返回,以存储为结果类的成员以供以后使用。上面的代码似乎可以复制大型矩阵,还有更好的方法吗? 谢谢你,并祝你一切顺利...

2 个答案:

答案 0 :(得分:2)

对@ggael答案的改进很小,您可以直接从表达式构造corMatrix共享指针:

boost::shared_ptr<MatrixXd> corMatrix 
   = boost::make_shared<MatrixXd>((*returns_m) * (*returns_m).transpose() * (1./(num_of_obs_per_simulation - 1));

或者,您可以使用rankUpdate利用产品的对称性:

boost::shared_ptr<MatrixXd> corMatrix = boost::make_shared<MatrixXd>(MatrixXd::Zero(factor_size, factor_size));
corMatrix->selfadjointView<Eigen::Upper>().rankUpdate(*returns_m, 1.0 / (num_of_obs_per_simulation - 1));
// optionally copy upper half to lower half as well:
corMatrix->triangularView<Eigen::StrictlyLower>() = corMatrix->adjoint();

答案 1 :(得分:1)

我不明白您的问题,因为将corMatrix返回为shared_ptr可以完全满足您的要求,但是对于您的产品,您可以使用noalias* (1./x)保存一个临时文件:

(*corMatrix).noalias() = (*returns_m) * (*returns_m).transpose() * (1./(num_of_obs_per_simulation - 1));

整个表达式将变成对类似gemm例程的单个调用。

要完成说明,

回想一下Eigen是一个表达式模板库,因此当您对A,B,C矩阵进行A = 2*B + C.transpose();时,所有事情都发生在operator=中,这就是右侧表达式直接在A中评估。对于产品,情况略有不同,因为1)为了高效,它需要直接在某事物内进行评估,并且2)如果存在别名,例如A = A*B,则不可能直接写到目标。 noalias告诉Eigen,目的地不是别名,可以在其中直接评估产品。