特征保守,尺寸太贵
C++: Eigen conservativeResize too expensive?
我有一些特征矩阵,它们的维数我事先不知道,我只有一个上界。我有一个循环,在这个循环中,我一列一列地填充这些矩阵(我使用上界初始化它们),直到满足一个停止条件(假设在j次迭代之后)。
我现在的问题是:在循环之后,我需要这些矩阵进行矩阵乘法(显然只使用前j列)。直接的解决方案是使用Eigen的保守大小,然后直接执行矩阵乘法。由于矩阵往往非常大(100000+维),并且(据我所见,不确定)Eigen的conservativeResize为调整大小的矩阵重新分配内存并执行一次深度复制,因此该解决方案非常昂贵。
我正在考虑编写我自己的自定义矩阵乘法函数,它使用旧的(大)矩阵,使用参数指定要使用的列数。我担心尽管Eigen的矩阵乘法是如此的优化,最终这个解决方案比仅仅使用保守的调整大小和标准的Eigen乘法要慢…
我应该咬紧牙关使用保守尺寸还是有人有更好的主意?顺便说一句:我们正在谈论的矩阵在循环/resize
后用于3次乘法和1次转置。提前感谢!
编辑:这是代码的相关部分(其中X是MatrixXd, y是VectorXd, numComponents是PLS1应该使用的潜在变量的数量)。问题是:在开始时,numComponents将始终是X中的维数(X.cols()),但停止标准应该检查输出向量中解释方差的相对改进(我还没有实现)。如果相对改进太小,算法应该停止(因为我们对前j个分量很满意),然后计算回归系数。为此,我需要conservativersize:
using namespace Eigen;
MatrixXd W,P,T,B;
VectorXd c,xMean;
double xMean;
W.resize(X.cols(),numComponents);
P.resize(X.cols(),numComponents);
T.resize(X.rows(),numComponents);
c.resize(numComponents);
xMean.resize(X.cols());
xMean.setZero();
yMean=0;
VectorXd yCopy=y;
//perform PLS1
for(size_t j=0; j< numComponents; ++j){
VectorXd tmp=X.transpose()*y;
W.col(j)=(tmp)/tmp.norm();
T.col(j)=X*W.col(j);
double divisorTmp=T.col(j).transpose()*T.col(j);
c(j)=(T.col(j).transpose()*y);
c(j)/=divisorTmp;
P.col(j)=X.transpose()*T.col(j)/divisorTmp;
X=X-T.col(j)*P.col(j).transpose();
y=y-T.col(j)*c(j);
if(/*STOPPINGCRITERION(TODO)*/ && j<numComponents-1){
numComponents=j+1;
W.conservativeResize(X.cols(),numComponents);
P.conservativeResize(X.cols(),numComponents);
T.conservativeResize(X.rows(),numComponents);
c.conservativeResize(numComponents);
}
}
//store regression matrix
MatrixXd tmp=P.transpose()*W;
B=W*tmp.inverse()*c;
yCopy=yCopy-T*c;
mse=(yCopy.transpose()*yCopy);
mse/=y.size();//Mean Square Error
我认为您可以分配大矩阵一次,然后使用block
创建其部分的视图,其中包含有意义的数据。你可以重用一个大矩阵。这将节省重新分配。
下面的例子充分说明了这一点。
。/eigen_block_multiply.cpp:
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
Matrix<float, 2, 3> small;
small << 1,2,3,
4,5,6;
Matrix<float, 4, 4> big = Matrix<float, 4, 4>::Constant(0.6);
cout << "Big matrix:n";
cout << big << endl;
cout << "Block of big matrix:n";
cout << big.block(0,0,3,2) << endl;
cout << "Small matrix:n";
cout << small << endl;
cout << "Product:n";
cout << small * big.block(0,0,3,2) << endl;
Matrix<float, 3, 3> small2;
small2 << 1,2,3,
4,5,6,
7,8,9;
big = Matrix<float, 4, 4>::Constant(6.66);
cout << "Product2:n";
cout << small * big.block(0,0,3,3) << endl;
}
输出:Big matrix:
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6
Block of big matrix:
0.6 0.6
0.6 0.6
0.6 0.6
Small matrix:
1 2 3
4 5 6
Product:
3.6 3.6
9 9
Product2:
39.96 39.96 39.96
99.9 99.9 99.9
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 特征命名访问向量段
- 将特征矩阵的向量设置为0
- 特征:模板函数中矩阵的平面图
- basic_string的前导/尾部不区分空格的特征
- 特征 3 类的模板专用化
- 特征 c++:复矩阵的面积双曲正切(atanh)
- C++ 中的特征向量计算
- 根据C++标准的定义实现"is_similar"类型特征
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- 有没有办法找到特征矩阵系数的中值?
- 如何将高维数据映射到特征类型?
- 将平面阵列重塑为复杂的特征类型
- 特征 LLT 模块给出不正确的结果?
- 特征模板化函数和维度
- 特征稀疏向量:求最大系数
- 特征 3.3.x:如何在所有行中操作 lamba?
- 如何将向量断言到特征矩阵