我想从矢量生成一个“stairsteppy”的矩阵。
示例输入向量:[8 12 17]
示例输出矩阵:
[1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1]
是否有比以下更容易(或内置)的方式?:
function M = stairstep(v)
M = zeros(length(v),max(v));
v2 = [0 v];
for i = 1:length(v)
M(i,(v2(i)+1):v2(i+1)) = 1;
end
答案 0 :(得分:4)
您可以通过编制索引来完成此操作。
A = eye(3);
B = A(:,[zeros(1,8)+1, zeros(1,4)+2, zeros(1,5)+3])
答案 1 :(得分:3)
这是一个没有显式循环的解决方案:
function M = stairstep(v)
L = length(v); % M will be
V = max(v); % an L x V matrix
M = zeros(L, V);
% create indices to set to one
idx = zeros(1, V);
idx(v + 1) = 1;
idx = cumsum(idx) + 1;
idx = sub2ind(size(M), idx(1:V), 1:V);
% update the output matrix
M(idx) = 1;
编辑:已修复错误:p
答案 2 :(得分:2)
我知道没有内置函数可以做到这一点,但这是一个矢量化解决方案:
v = [8 12 17];
N = numel(v);
M = zeros(N,max(v));
M([0 v(1:N-1)]*N+(1:N)) = 1;
M(v(1:N-1)*N+(1:N-1)) = -1;
M = cumsum(M,2);
编辑:我喜欢Jonas必须使用BLKDIAG的想法。在我进一步缩短它之前,我不禁玩了一下这个想法(使用MAT2CELL代替ARRAYFUN):
C = mat2cell(ones(1,max(v)),1,diff([0 v]));
M = blkdiag(C{:});
答案 3 :(得分:1)
您可以使用ones
来定义您拥有1的位置:
答案 4 :(得分:1)
矢量化解决方案的非常短版本
function out = stairstep(v)
% create lists of ones
oneCell = arrayfun(@(x)ones(1,x),diff([0,v]),'UniformOutput',false);
% create output
out = blkdiag(oneCell{:});