Подтвердить что ты не робот

Получение индекса элемента в spfun, cellfun, arrayfun и т.д. В MATLAB

Есть ли способ получить индекс элемента, на котором действует функция, вызываемая cellfun, arrayfun или spfun? (т.е. получить индекс элемента в пределах объема функции).

Для простоты представьте, что у меня есть следующий пример игрушки:

S = spdiags([1:4]',0,4,4)
f = spfun(@(x) 2*x,S)

который строит 4x4 разреженную диагональную матрицу и затем умножает каждый элемент на 2.

И скажите, что теперь вместо того, чтобы умножать каждый элемент на постоянное число 2, я хотел бы умножить его на индекс, который элемент имеет в исходной матрице, т.е. предполагая, что linear_index содержит индекс для каждого элемента, это будет примерно так:

S = spdiags([1:4]',0,4,4)
f = spfun(@(x) linear_index*x,S)

Однако обратите внимание, что приведенный выше код не работает (linear_index не объявлен).

Этот вопрос частично мотивирован тем фактом, что blocproc дает вам доступ к block_struct.location, который можно аргументировать, ссылаясь на местоположение (~ index) текущего элемента в полном объекте (изображение в этом случае):

block_struct.location: Двухэлементный вектор, [строка col], который указывает положение первого пикселя (минимальная строка, минимальный столбец) блокировать данные во входном изображении.

4b9b3361

Ответ 1

Нет, но вы можете предоставить линейный индекс в качестве дополнительного аргумента.

Оба cellfun и arrayfun принимают несколько входных массивов. Таким образом, например, arrayfun, вы можете написать

a = [1 1 2 2];
lin_idx = 1:4;
out = arrayfun(@(x,y)x*y,a,lin_idx);

Это не работает с spfun, к сожалению, поскольку он принимает только один вход (разреженный массив).

Вместо этого вы можете использовать arrayfun, например:

S = spdiags([1:4]',0,4,4);
lin_idx = find(S);

out = spones(S);
out(lin_idx) = arrayfun(@(x,y)x*y,full(S(lin_idx)),lin_idx);
%# or
out(lin_idx) = S(lin_idx) .* lin_idx;

Обратите внимание, что вызов full не приведет к сбою памяти, так как S(lin_idx) 0% разрежен.

Ответ 2

Вы можете создать разреженную матрицу с заполнением linear_index вместо значений.

Создать A:

A(find(S))=find(S)

Затем используйте A и S без spfun, например: A.*S. Это выполняется очень быстро.

Ответ 3

Это просто. Просто сделайте ячейку вроде: C = num2cell (1: длина (S)); тогда: out = arrayfun (@(x, c) c * x, S, C)