我有N个方形矩阵,它们都是相同大小的MxM,必须在包含NxN矩阵的矩阵中复制,并以对称的方式排列。上半部分和下半部分包含相同矩阵的转置版本,如此方案中所示。
N = 4
m1 m2 m3 m4
m2'm1 m2 m3
m3'm2'm1 m2
m4'm3'm2'm1
生成数据的算法最初只填充上一行和第一列,其余部分为空。
m1 m2 m3 m4
m2'0 0 0
m3'0 0 0
m4'0 0 0
我想找到一个有效的索引方案,从已经填充的行的元素开始填充所有大矩阵。请记住,m1 ... mn是大小为MxM的方形矩阵,矩阵按列大顺序排列。矩阵不是那么大,所以不需要利用很多地方和缓存相关的东西。
琐碎的算法如下所示,其中X是矩阵。
int toX = 0, fromX = 0, toY = 0, fromY = 0;
for (int i = 1; i < N; ++i) {
for (int j = 1; j < N; ++j) {
for (int ii = 0; ii < M; ++ii) {
for (int jj = 0; jj < M; ++jj) {
fromX = (i - 1) * dim + ii;
fromY = (j - 1) * dim + jj;
toX = i * dim + ii;
toY = j * dim + jj;
X(toX, toY) = X(fromX, fromY);
}
}
}
}
你能找到更好的方法吗?
答案 0 :(得分:2)
根据您的应用程序,可能没有必要存储所有这些转置矩阵。如果m1是对称的,你甚至可以剔除m1矩阵的下半部分。
事实上,将所有这些矩阵单独留下并按块进行矩阵运算甚至可行(用标量加法和乘法很简单,用向量乘法会有点复杂)
如果你真的需要整个矩阵,你可以通过对角填充矩阵来获得略低的操作数,即通过这样的方式:
int toX = 0, fromX = 0, toY = 0, fromY = 0;
// m1 (note that this part can be sped up further if m1 is symmetric)
for (int ii = 0; ii<M; ii++){
for (int jj = 0; jj<M; jj++){
fromX = ii;
fromY = jj;
toX = fromX;
toY = fromY;
for (int k=1; k<N; k++){
toX += dim;
toY += dim;
X(toX, toY) = X(fromX, fromY);
}
}
}
// m2 to m(N-1)
for (int i = 2; i < N; i++){
for (int ii = 0; ii<M; ii++){
for (int jj = 0; jj<M; jj++){
fromX = i*dim+ii;
fromY = jj;
toX = fromX;
toY = fromY;
for (int k=i; k<N; k++){
toX += dim;
toY += dim;
X(toX, toY) = X(fromX, fromY);
X(toY, toX) = X(fromX, fromY);
}
}
}
}