我有一个巨大的m * n矩阵A(其中行数m远大于列数n),它以armadillo
mat
类型存储在我的c ++程序中。现在我有一个向量w
我需要计算w=w-A*A^T*w
,其中A^T
表示矩阵A的转置。
由于矩阵A非常大并且消耗大量内存,因此犰狳w=w-A*A.t()*w
的常用快速方法不起作用,因为在这种情况下犰狳消耗大量内存(参见github )。他们解决这个问题的方法是引入函数inplace_trans( A, method )
,它可以使用方法" lowmem"它消耗的内存较少,但需要更多时间。
我现在的问题是,inplace_trans( A, method )
是一个void函数,所以我必须首先创建一个矩阵的副本,然后才能计算出新的w
:
mat Q = A;
inplace_trans(Q, 'lowmmem');
w=w-A*Q*w;
然而,这当然不是理想的结果,因为我需要我的矩阵的完整副本,我想首先避免(RAM问题!)。
那么,为了计算新的w
,我怎样才能以高效(快速且低内存要求)的方式对矩阵进行转置?
如果我像
那样按照元素进行mat A(m,n); //huge matrix, initialized before
vec temp(m);
temp.fill(0.0);
for (unsigned long int ii=0; ii<m; ii++){
for (unsigned long int ll=0; ll<m; ll++){
temp(ii)+=dot(A.row(ii),A.row(ll))*w(ll);
}
}
w=w-temp;
我必须在行数m上迭代两次,这是非常昂贵的。
修改 到目前为止,最快的方法如下:
vec temp(m);
inplace_trans(A, "lowmem");
temp = A * w;
inplace_trans(A, "lowmem");
temp = A * temp;
我必须将矩阵转置两次,因为我之后需要将其恢复到原始状态。我无法相信这应该是最快的方式,因为它会占用很多操作,imho。
答案 0 :(得分:1)
在你的编辑中,你已经正确地暗示从复杂的角度来看,当然最好先执行两次矩阵向量乘法,而不是首先计算A*A.t()
,然后将结果应用到{{1} }。然而,你的问题似乎是你必须将矩阵转置两次。
如果之后不需要以非转换形式返回矩阵,那么解决该问题的一个简单方法就是转换整个等式:
w
。在这种情况下,您可以先应用w = w - A A^T w <==> w^T = w^T - w^T A A^T
,然后再应用A
。如果你能以某种方式将A.t()
完全定义为行向量,那么这就等于
w
从概念上讲,行和列向量之间的存储应该没有区别,这些元素在内存中都应该是连续的。您将不得不看一下armadillo在行向量和列向量之间的明显区别,但是afaik向量只是一维设置为1的矩阵。无论如何,这些考虑因素对矢量水平的严格程度要低于矩阵水平。
答案 1 :(得分:0)
如果您逐个元素地执行此操作,则可以使用较少的工作和较少的缓存未命中直接计算A*A.t()*w
,并且只能A
的一个副本。我不知道犰狳会给你什么样的功能来帮助你快速完成。但是对矩阵行的简单访问应该足以使其实用而不使用过多的内存。