Используйте вектор в качестве индекса для матрицы
Я пишу функцию 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;