假设我有一个稀疏的非矩形矩阵A:
>> A = round(rand(4,5))
A =
0 1 0 1 1
0 1 0 0 1
0 0 0 0 1
0 1 1 0 0
我想获得矩阵B
,其中A的非零项被行优先顺序中的线性索引替换:
B =
0 2 0 4 5
0 7 0 0 10
0 0 0 0 15
0 17 18 0 0
以及C
的非零条目被行优先搜索中的查找顺序替换的矩阵A
:
C =
0 1 0 2 3
0 4 0 0 5
0 0 0 0 6
0 7 8 0 0
我正在寻找可扩展到大型稀疏矩阵的此问题的矢量化解决方案。
答案 0 :(得分:3)
如果我明白你在问什么,那么几个转换应该可以解决问题。关键是find(A.')
将对A进行“行优先”索引,其中.'
是2D矩阵转置的简写。所以:
>> A = round(rand(4,5))
A =
0 1 0 1 1
0 1 0 0 1
0 0 0 0 1
0 1 1 0 0
然后
B=A.';
B(find(B)) = find(B);
B=B.';
给出
B =
0 2 0 4 5
0 7 0 0 10
0 0 0 0 15
0 17 18 0 0
答案 1 :(得分:1)
大纲(Matlab不在此机器上,因此验证被延迟):
find()
获取坐标列表。让T = A'; [r,c] = find(T)
valB = sub2ind([r,c],T)
和valC = 1:length(r)
sparse
命令创建B和C,例如B = sparse(r,c,valB)
,然后转置,例如B = B'
(或sparse(c,r,valB)
)。 或者,正如@IanHincks建议的那样,让B = A'; B(find(B)) = find(B)
。 (我不确定为什么建议使用.'
,但是,再次,我没有在前面检查Matlab。)对于C
,只需使用C(find(C)) = 1:nnz(A)
。并按照他的建议转而回归。
就个人而言,我一直在使用坐标列表,已经从稀疏矩阵表示中迁移出来,只是为了减少索引查找的成本。
答案 2 :(得分:1)
这是一个不需要来回转换的解决方案:
>> B = A; %# Initialize B
>> C = A; %# Initialize C
>> mask = logical(A); %# Create a logical mask using A
>> [r,c] = find(A); %# Find the row and column indices of non-zero values
>> index = c + (r - 1).*size(A,2); %# Compute the row-first linear index
>> [~,order] = sort(index); %# Compute the row-first order with
>> [~,order] = sort(order); %# two sorts
>> B(mask) = index %# Fill non-zero elements of B
B =
0 2 0 4 5
0 7 0 0 10
0 0 0 0 15
0 17 18 0 0
>> C(mask) = order %# Fill non-zero elements of C
C =
0 1 0 2 3
0 4 0 0 5
0 0 0 0 6
0 7 8 0 0