我有一个稀疏矩阵,想要将区域划分为4个部分,将x和y分成2个等距的部分,并想要计算相应值的总和。
对于下面的示例,坐标x-y各自对应于[0,16],因此该区域是正方形。这个方块中有一个稀疏矩阵,它是对称的。我想将区域划分为较小的正方形并总结稀疏值。区域0:8,0:8有2个元素,它们的值都是(2,3)=(3,2)= 8所以总和是16.
第一个区域的总和应该是16
,第二个和第三个区域是36
,第四个区域是26
。
x = sparse(16,16);
x (3,2) = 8;
x (10,2) = 8;
x (13,2) = 8;
x (14,2) = 4;
x (15,2) = 4;
x (2,3) = 8;
x (10,3) = 4;
x (13,3) = 4;
x (14,3) = 2;
x (15,3) = 2;
x (2,10) = 8;
x (3,10) = 4;
x (13,10) = 4;
x (14,10) = 2;
x (15,10) = 2;
x (2,13) = 8;
x (3,13) = 4;
x (10,13) = 4;
x (14,13) = 2;
x (15,13) = 2;
x (2,14) = 4;
x (3,14) = 2;
x (10,14) = 2;
x (13,14) = 2;
x (15,14) = 1;
x (2,15) = 4;
x (3,15) = 2;
x (10,15) = 2;
x (13,15) = 2;
x (14,15) = 1;
我宁愿采用更短的方式,而不是为每个子广场写一条线。让我们说6000个子方块应该写6000行?
答案 0 :(得分:1)
让我们以更方便的方式定义输入:
X = sparse([...
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 8, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 4, 4
0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 2, 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 8, 4, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 2
0, 4, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 1
0, 4, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 1, 0]);
为方便起见,我们首先使阵列尺寸均匀。我们不会使用padarray()
,因为这会使稀疏矩阵变满!
sz = size(X);
newX = sparse(sz(1)+1,sz(2)+1);
padTopLeft = true; % < chosen arbitrarily
if padTopLeft
newX(2:end,2:end) = X;
else % bottom right
newX(1:sz(1),1:sz(2)) = X;
end
%% Preallocate results:
sums = zeros(2,2,2);
accumarray
我们创建了一个形式的掩码:
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
然后用它来汇总newX
:
sums(:,:,1) = reshape(...
accumarray(reshape(repelem([1,2;3,4], ceil(sz(1)/2), ceil(sz(2)/2)),[],1),...
reshape(newX, [],1),...
[],@sum) ,2,2);
blockproc
(需要图像处理工具箱)sums(:,:,2) = blockproc(full(newX), ceil(sz/2), @(x)sum(x.data(:)));
我也尝试了histcounts2
,它很短,但它只告诉你每个象限中金额的值,而不是它们的总和:
[r,c] = find(newX);
histcounts2(r,c,[2,2])
accumarray
解决方案过于复杂。答案 1 :(得分:0)
虽然你的问题不是很精确,而且你没有找到任何解决方案,但这就是你所要求的......
clear;clc;close;
Matrix=rand(20,20);
Acc=zeros(1,4);
Acc(1)=sum(sum( Matrix(1:size(Matrix,1)/2,1:size(Matrix,2)/2) ));
Acc(2)=sum(sum( Matrix((size(Matrix,1)/2)+1:end,1:size(Matrix,2)/2)));
Acc(3)=sum(sum( Matrix(1:size(Matrix,1)/2,((size(Matrix,2)/2)+1):end )));
Acc(4)=sum(sum( Matrix((size(Matrix,1)/2)+1:end,((size(Matrix,2)/2)+1):end)));
% Verification
sum(sum(Matrix)) % <- is the same with
sum(Acc) % <- this
答案 2 :(得分:0)
您可以通过定义矩阵的4个角来定义矩阵内的任何矩形。然后使用for
循环处理所有矩形。
regions = [
1 8 1 8
9 16 1 8
1 8 9 16
9 16 9 16
];
regionsum = zeros(size(regions,1),1);
for rr = 1:size(regions,1)
submat = x(regions(rr,1):regions(rr,2),regions(rr,3):regions(rr,4));
regionsum(rr) = sum(submat(:));
end
>> regionsum
regionsum =
16
36
36
26
如果您的意思是想要将方形矩阵划分为相同大小的2 ^ N(N> 2)个方格,则可以使用for循环编写regions
。
N = 1; % 2^N-by-2^N sub-squares
L = size(x,1);
dL = L/(2^N);
assert(dL==int32(dL),'Too many divisions')
segments = zeros(2^N,2);
for nn = 1:2^N
segments(nn,:) = [1,dL]+dL*(nn-1);
end
regions = zeros(2^(2*N),4);
for ss = 1:2^N
for tt = 1:2^N
regions((2^N)*(ss-1) + tt,:) = [segments(ss,:),segments(tt,:)];
end
end
示例输出,分为16个(N = 2)平方子矩阵:
>> regions
regions =
1 4 1 4
1 4 5 8
1 4 9 12
1 4 13 16
5 8 1 4
5 8 5 8
5 8 9 12
5 8 13 16
9 12 1 4
9 12 5 8
9 12 9 12
9 12 13 16
13 16 1 4
13 16 5 8
13 16 9 12
13 16 13 16
>> regionsum
regionsum =
16
0
12
24
0
0
0
0
12
0
0
8
24
0
8
10
>>