犰狳矩阵转置

时间:2015-11-05 13:44:32

标签: c++ matrix transpose armadillo

我有一个巨大的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。

2 个答案:

答案 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的一个副本。我不知道犰狳会给你什么样的功能来帮助你快速完成。但是对矩阵行的简单访问应该足以使其实用而不使用过多的内存。