Используйте вектор в качестве индекса для матрицы

Я пишу функцию MATLAB для считывания данных в n-мерный массив (размер переменной размерности). Мне нужно иметь доступ к определенной точке в матрице (например, писать или читать ее), но я заранее не знаю, сколько индексов указать.

В настоящее время у меня есть вектор current_point, который я повторяю, чтобы указать каждый индекс, и вектор max_points, который определяет размер массива. Итак, если, например, мне нужен трехмерный массив размером от 1000 до 15 на 3, max_points = [1000 15 3] и current_point итерации от [1, 1, 1] до [1000, 15, 3] ([1, 1, 1][1000, 1, 1][1, 2, 1][1000, 2, 1] → ...). То, что я хотел бы сделать, это feed current_point как индекс для матрицы:

output_matrix(current_point) = val

Но, похоже, что-то вроде output_matrix([1 2 3]) = val просто установит outputmatrix(1:3) = 30. Я не могу просто использовать фиктивные переменные, потому что иногда матрице потребуется 3 индекса, другие 4, другие 2 и т.д., Поэтому вектор переменной длины действительно то, что мне нужно здесь. Существует ли простой способ использования вектора в качестве точек в индексе?

Ответы

Ответ 1

Использование функции sub2ind для создания линейного индекса является типичным решением этой проблемы, как показано в этом тесно связанном вопросе. Вы также можете самостоятельно вычислить линейный индекс вместо вызова sub2ind.

Однако ваше дело может быть проще, чем в других вопросах, с которыми я связан. Если вы только индексируете одну точку с вашим вектором current_point (т.е. Это всего лишь вектор векторов n-элементов индексов в вашу n-мерную матрицу), вы можете использовать простое решение, в котором вы конвертируете current_point в ячеек массива индексов, используя функцию num2cell и использую ее для создания список разделенных запятыми индексов. Например:

current_point = [1 2 3 ...];        % A 1-by-n array of subscripts
subCell = num2cell(current_point);  % A 1-by-n cell array of subscripts
output_matrix(subCell{:}) = val;    % Update the matrix point

Операция subCell{:} создает эквивалент ввода subCell{1}, subCell{2}, ..., что эквивалентно типу current_point(1), current_point(2), ....

Ответ 2

Я знаю, что это слишком поздно, но для тех, кто найдет эту тему. самый простой способ, который работает для меня, - использовать: diag(A (x(:),y(:)) );

К сожалению, это работает, только если вам нужно получить значения из матрицы, а не для изменения значений

Ответ 3

Вы можете использовать функцию sub2ind, чтобы получить линейный индекс из индекса.

Пример:

A=magic(4)

A =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

selectElement={2,3}; %# get the element at position 2,3 in A.
indx=sub2ind(size(A),selectElement{:});
A(indx)

ans =

    10

В приведенном выше примере я сохранил индексы (может быть любое количество измерений) как cell. Если вы сохранили его как вектор, просто используйте num2cell(), чтобы преобразовать его в ячейку.

Теперь вы можете легко присвоить значение этому как A(indx)=value;. Я использовал разные переменные, чем ваши, чтобы сохранить общий ответ, но идея одинаков и вам просто нужно заменить имена переменных.

Вы также упомянули в своем посте, что вы зацикливаете от (1,1,1) до некоторого значения, (1000,15,3) и присваиваете значение каждой из этих точек. Если вы перебираете столбцы, вы можете заменить всю эту операцию на векторное решение.

Пусть finalElement={1000,15,3} - последний шаг цикла. Как и раньше, найдите линейный индекс как

index=sub2ind(size(A),finalElement{:});

Теперь, если у вас есть значения, которые вы назначаете в цикле, хранящемся как один вектор, values, вы можете просто назначить его за один шаг как

A(1:index)=values;