Я пытаюсь вставить несколько значений в массив с помощью массива 'значений' и 'встречного' массива. Например, если:
a=[1,3,2,5]
b=[2,2,1,3]
Я хочу вывод некоторой функции
c=somefunction(a,b)
быть
c=[1,1,3,3,2,5,5,5]
Где (1) повторяется b (1), количество раз, (2) повторяется b (2) времена и т.д...
Существует ли встроенная функция в MATLAB, который делает это? Я хотел бы избегать использования для цикла, если это возможно. Я попробовал изменения 'repmat ()' и 'kron ()' напрасно.
Это в основном Run-length encoding
.
Встроенной функции я не знаю, но вот одно решение:
index = zeros(1,sum(b));
index([1 cumsum(b(1:end-1))+1]) = 1;
c = a(cumsum(index));
Вектор нулей сначала создается такой же длины, как и выходной массив (т.е. сумма всех репликаций в b
). Затем нули помещаются в первый элемент и каждый последующий элемент, представляющий на выходе начало новой последовательности значений. Затем кумулятивная сумма векторного индекса
может быть использована для индексирования в a
, реплицируя каждое значение необходимое количество раз.
Для большей ясности, так выглядят различные векторы для значений a
и b
, приведенных в вопросе:
index = [1 0 1 0 1 1 0 0]
cumsum(index) = [1 1 2 2 3 4 4 4]
c = [1 1 3 3 2 5 5 5]
EDIT: Для полноты есть другая альтернатива, использующая ARRAYFUN, но это, кажется, занимает в 20-100 раз больше времени, чем вышеуказанное решение с векторами до 10,000 элементов длиной:
c = arrayfun(@(x,y) x.*ones(1,y),a,b,'UniformOutput',false);
c = [c{:}];