Используйте вектор как индекс для матрицы - PullRequest
16 голосов
/ 06 мая 2011

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

В настоящее время у меня есть вектор current_point, который я повторяю, чтобы указать каждый индекс, и вектор max_points, который определяет размер массива.Так, если, например, я хотел 3-мерный массив размером 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] -> ...).То, что я хотел бы сделать, это указать current_point в качестве индекса матрицы следующим образом:

output_matrix(current_point) = val

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

Ответы [ 3 ]

20 голосов
/ 06 мая 2011

Использование функции 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), ....

10 голосов
/ 29 ноября 2012

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

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

4 голосов
/ 06 мая 2011

Вы можете использовать функцию 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...