我正在研究Matlab,并想知道如何在一个大矩阵中添加术语.具体来说,我有一个4914x4914
矩阵,并希望创建一个189x189
矩阵,其中每个项等于每个26x26
子集中的项的总和.
为了说明,我说魔法4x4
矩阵如下:
[16 2 3 13;
5 11 10 8;
9 7 6 12;
4 14 15 1]
Run Code Online (Sandbox Code Playgroud)
我想创建一个2x2
等于2x2
原始魔法中每个矩阵之和的矩阵4x4
,即:
[(16+2+5+11) (3+13+10+8);
(9+7+4+14) (6+12+15+1)]
Run Code Online (Sandbox Code Playgroud)
感谢任何建议!谢谢杰克
Div*_*kar 12
假设A
是输入4914x4914
矩阵,这可能是一种有效的(在运行时方面)方法 -
sublen = 26; %// subset length
squeeze(sum(reshape(sum(reshape(A,sublen,[])),size(A,1)/sublen,sublen,[]),2))
Run Code Online (Sandbox Code Playgroud)
对于通用块大小,让我们有一个功能 -
function out = sum_blocks(A,block_nrows, block_ncols)
out = squeeze(sum(reshape(sum(reshape(A,block_nrows,[])),...
size(A,1)/block_nrows,block_ncols,[]),2));
return
Run Code Online (Sandbox Code Playgroud)
样品运行 -
>> A = randi(9,4,6);
>> A
A =
8 2 4 9 4 5
3 3 8 3 6 8
9 6 6 7 1 9
4 5 5 7 1 2
>> sum_blocks(A,2,3)
ans =
28 35
35 27
>> sum(sum(A(1:2,1:3)))
ans =
28
>> sum(sum(A(1:2,4:6)))
ans =
35
>> sum(sum(A(3:4,1:3)))
ans =
35
>> sum(sum(A(3:4,4:6)))
ans =
27
Run Code Online (Sandbox Code Playgroud)
如果你想避免squeeze
-
sum(permute(reshape(sum(reshape(A,sublen,[])),size(A,1)/sublen,sublen,[]),[1 3 2]),3)
Run Code Online (Sandbox Code Playgroud)
希望您关心性能,以下是此处发布的所有解决方案的基准测试结果.我使用的基准代码 -
num_runs = 100; %// Number of iterations to run benchmarks
A = rand(4914);
for k = 1:50000
tic(); elapsed = toc(); %// Warm up tic/toc
end
disp('---------------------- With squeeze + reshape + sum')
tic
for iter = 1:num_runs
sublen = 26; %// subset length
out1 = squeeze(sum(reshape(sum(reshape(A,sublen,[])),...
size(A,1)/sublen,sublen,[]),2));
end
time1 = toc;
disp(['Avg. elapsed time = ' num2str(time1/num_runs) ' sec(s)']), clear out1 sublen
disp('---------------------- With kron + matrix multiplication')
tic
for iter = 1:num_runs
n = 189; k = 26;
B = kron(speye(k), ones(1,n));
result = B*A*B';
end
time2 = toc;
disp(['Avg. elapsed time = ' num2str(time2/num_runs) ' sec(s)']),clear result n k B
disp('---------------------- With accumarray')
tic
for iter = 1:num_runs
s = 26; n = size(A,1)/s;
subs = kron(reshape(1:(n^2), n, n),ones(s));
out2 = reshape(accumarray(subs(:), A(:)), n, n);
end
time2 = toc;
disp(['Avg. elapsed time = ' num2str(time2/num_runs) ' sec(s)']),clear s n subs out2
Run Code Online (Sandbox Code Playgroud)
基准测试结果我得到了我的系统 -
---------------------- With squeeze + reshape + sum
Avg. elapsed time = 0.050729 sec(s)
---------------------- With kron + matrix multiplication
Avg. elapsed time = 0.068293 sec(s)
---------------------- With accumarray
Avg. elapsed time = 0.64745 sec(s)
Run Code Online (Sandbox Code Playgroud)
如果您没有图像处理工具箱,那么您可以使用accumarray
以下方法执行此操作:
s = 26;
n = size(A,1)/s;
subs = kron(reshape(1:(n^2), n, n),ones(s));
reshape(accumarray(subs(:), A(:)), n, n)
Run Code Online (Sandbox Code Playgroud)
如果您决定聚合某种方式而不是简单的总和,例如中位数,则可以重复使用:
reshape(accumarray(subs(:), A(:), [], @median), n, n)
Run Code Online (Sandbox Code Playgroud)
你当然可以使用矩阵乘法:
n = 26;
k = 189;
B = kron(speye(k), ones(1,n));
result = B*A*B';
Run Code Online (Sandbox Code Playgroud)
另一种方法是将整个矩阵重新整形为4D矩阵,并在第一维和第三维上对元素求和:
result = squeeze(sum(sum(reshape(A,26,189,26,189),1),3));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2319 次 |
最近记录: |