代码如下:
// 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作为指针而不是对象返回,以存储为结果类的成员以供以后使用。上面的代码似乎可以复制大型矩阵,还有更好的方法吗? 谢谢你,并祝你一切顺利...
答案 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,目的地不是别名,可以在其中直接评估产品。