创建水平拉伸的上三角矩阵
Create a horizontically stretched upper triangular matrix
我想创建一个与上三角矩阵非常相似的 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
所以我的问题是。创建它的最有效方法是什么?没有循环,没有细胞乐趣。谢谢
一种vectorized
方法-
nrows = 4;
ncols = 12;
row_idx = repmat(1:nrows,ncols/nrows,1)
out = bsxfun(@le,[1:nrows]',row_idx(:).')
取决于您的 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]))
创建一个上三角矩阵,置换第二和第三维,沿第二维重复,并重塑为所需的形状:
m = 4;
n = 12;
result = reshape(repmat(permute(triu(ones(m,m)), [1 3 2]), [1 n/m 1]), [m n]);
Matlab R2015a 及更高版本 使用新引入的方法 repelem
:
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
总是最快的!有趣的是,其他两个完美对齐,可以猜测它们在内部几乎相同。
我想创建一个与上三角矩阵非常相似的 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
所以我的问题是。创建它的最有效方法是什么?没有循环,没有细胞乐趣。谢谢
一种vectorized
方法-
nrows = 4;
ncols = 12;
row_idx = repmat(1:nrows,ncols/nrows,1)
out = bsxfun(@le,[1:nrows]',row_idx(:).')
取决于您的 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]))
创建一个上三角矩阵,置换第二和第三维,沿第二维重复,并重塑为所需的形状:
m = 4;
n = 12;
result = reshape(repmat(permute(triu(ones(m,m)), [1 3 2]), [1 n/m 1]), [m n]);
Matlab R2015a 及更高版本 使用新引入的方法 repelem
:
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
总是最快的!有趣的是,其他两个完美对齐,可以猜测它们在内部几乎相同。