使用新引入的repelem
函数是Matlab R2015a及更高版本的做法:
n = 4;
m = 3;
out = repelem(triu(ones(n)),1,m);
out =
1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1
这个方法似乎比bsxfun
更快,尽管我不太敢相信 ;)
基准测试
不幸的是,由于它不完整且我没有完全理解,所以我不能考虑andrew的解决方案。
function [t] = bench()
n = 4;
m = 12;
t = zeros(3,15);
for ii = 1:15
fcns = {
@() thewaywewalk(ii*n,ii*m);
@() Divakar(ii*n,ii*m);
@() LuisMendo(ii*n,ii*m);
};
for jj = 1:100;
t(:,ii) = t(:,ii) + cellfun(@timeit, fcns);
end
end
plot(1:15,t(1,:)); hold on;
plot(1:15,t(2,:)); hold on;
plot(1:15,t(3,:)); hold on;
xlabel('Matrix size: n = x*4, m = x*12')
ylabel('timing')
legend({'thewaywewalk','Divakar','Luis Mendo'},'location','northwest')
end
function Z = thewaywewalk(n,m)
Z = repelem(triu(ones(n)),1,m/n);
end
function Z = Divakar(n,m)
row_idx = repmat(1:n,m/n,1);
Z = bsxfun(@le,[1:n]',row_idx(:).');
end
function Z = LuisMendo(n,m)
Z = reshape(repmat(permute(triu(ones(n,n)), [1 3 2]), [1 m/n 1]), [n m]);
end
第一结论 - 小矩阵:
新的repelem
表现很好,但reshape(repmat(permute...
也不错。对于某些中等大小的矩阵,bsxfun
方法稍逊一筹,但对于大矩阵,则成为领导者:
第二结论 - 大矩阵:
正如Divakar所预测的那样,对于较大的矩阵,bsxfun
是最快的,事实上,这是可以预料的,因为bsxfun
总是最快的!有趣的是,其他两个方法完全对齐,可以猜测它们在内部几乎是相同的。
![enter image description here](https://istack.dev59.com/u2sgJ.webp)