我想创建一个与上三角矩阵非常相似的4x12
矩阵,它看起来像这样:
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
所以我的问题是。创建它的最有效方法是什么?没有循环,没有cellfun。感谢。
答案 0 :(得分:2)
一种vectorized
方法 -
nrows = 4;
ncols = 12;
row_idx = repmat(1:nrows,ncols/nrows,1)
out = bsxfun(@le,[1:nrows]',row_idx(:).')
答案 1 :(得分:2)
创建一个上三角矩阵,置换第二维和第三维,沿第二维重复,然后重塑成所需的形状:
m = 4;
n = 12;
result = reshape(repmat(permute(triu(ones(m,m)), [1 3 2]), [1 n/m 1]), [m n]);
答案 2 :(得分:2)
使用新引入的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);
};
% timeit
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
总是最快的!有趣的是,其他两个完美对齐,可以猜测它们内部几乎一样。
答案 3 :(得分:0)
取决于您的matlab版本
m = 4;
n = 12;
dec2bin(bitshift(num,-1*[0:n/m:n-1])) %this prints out a string
这些应该是逻辑阵列(我没有其中任何一个,所以我不能测试它)
decimalToBinaryVector(bitshift(num,-1*[0:n/m:n-1]))
de2bi(bitshift(num,-1*[0:n/m:n-1]))