如何在MATLAB中生成以下矩阵?

时间:2009-12-14 21:21:59

标签: matlab matrix

我想从矢量生成一个“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

5 个答案:

答案 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的位置:

http://www.mathworks.com/help/techdoc/ref/ones.html

答案 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{:});