Как я могу сгенерировать следующую матрицу в MATLAB? - PullRequest
1 голос
/ 15 декабря 2009

Я хочу сгенерировать матрицу, которая является "лестничной" из вектора.

Пример входного вектора: [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 ]

4 голосов
/ 15 декабря 2009

Вы можете сделать это с помощью индексации.

A = eye(3);
B  = A(:,[zeros(1,8)+1, zeros(1,4)+2, zeros(1,5)+3])
3 голосов
/ 15 декабря 2009

Вот решение без явных циклов:

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 голосов
/ 15 декабря 2009

Я не знаю встроенной функции для этого, но вот одно векторизованное решение:

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);

РЕДАКТИРОВАТЬ: Мне нравится идея, что Джонас должен был использовать BLKDIAG . Я не мог не играть с этой идеей, пока не укоротил ее (используя MAT2CELL вместо ARRAYFUN ):

C = mat2cell(ones(1,max(v)),1,diff([0 v]));
M = blkdiag(C{:});
1 голос
/ 16 декабря 2009

Очень короткая версия векторизованного решения

function out = stairstep(v)

% create lists of ones
oneCell = arrayfun(@(x)ones(1,x),diff([0,v]),'UniformOutput',false);
% create output
out = blkdiag(oneCell{:});
1 голос
/ 15 декабря 2009

Вы можете использовать ones, чтобы определить места, где у вас есть 1:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...