Какую математическую функцию выполняет изменение формы?

Как в Python, так и в MATLAB вы можете использовать функцию reshape() для изменения размеров матрицы.

Что это за операция в линейной алгебре, это замена базиса, или более простое умножение матриц, или ни то, ни другое?


person Steven Alsheimer    schedule 08.04.2019    source источник
comment
Вы смотрели примеры в документации reshape (MATLAB)?   -  person SecretAgentMan    schedule 08.04.2019


Ответы (3)


Эта функция не имеет ничего общего с линейной алгеброй, это простой трюк с индексацией. Рассмотрим следующее (я буду использовать синтаксис MATLAB, но в Python, особенно используя NumPy/SciPy, он будет работать такой же):

A = [1 2 3; 4 5 6]; % 2-by-3 matrix
B = reshape(A,3,2); % B is 3-by-2
B =
     1     5
     4     3
     2     6

Итак, на самом деле у вас есть 6 индексов в A: от 1 до 6, в порядке столбцов. При изменении формы линейный стиль сохраняется, просто изменяется порядок. Линейно ваши элементы в порядке возрастания: 1 4 2 5 3 6, которые хранятся в непрерывной памяти. Своего рода «заголовок» сообщает программе, как формируются эти смежные элементы. Вот почему reshape почти бесплатна: она только изменяет заголовок.

Линейная алгебра не имеет к этому никакого отношения, это просто числовая уловка для облегчения некоторых задач программирования.

Для получения дополнительной информации о том, как работает индексирование в MATLAB, я рекомендую отличный вопрос/ответ.

Под капотом MATLAB преобразует A(2,2) в A(4), то есть четвертый линейный индекс, используя sub2ind() именно потому, что все хранится в виде линейного вектора. Все, что делает изменение формы, это сообщает заголовку, что элемент 3 больше не находится в A(1,2), а изменен на A(3,1), потому что его внешний вид изменился.

person Adriaan    schedule 08.04.2019
comment
Любая ссылка? То, что вы показываете, это просто транспонирование. Я не уверен, что в более сложной форме это будет то же самое. - person Karls; 08.04.2019
comment
@Karls просто бросьте это в MATLAB, транспонирование A будет [1 4; 2 5; 3 6], что является другой матрицей, чем транспонированная. Транспонирование изменяет порядок элементов, поэтому оно дороже, чем простое изменение формы. - person Adriaan; 08.04.2019
comment
Хорошо, правильно, это не эквивалентно транспонированию. Я все еще думаю, что это может быть сложнее, чем просто заголовок. Есть ли у вас какие-либо ссылки, которые могут поддержать ваше объяснение? - person Karls; 08.04.2019
comment
@Karls: ссылка — это документация к reshape, на которую ссылается Адриан, а также другая страница документации. - person Cris Luengo; 09.04.2019
comment
Вы можете создать действительно большой массив и определить, сколько времени потребуется на изменение формы и сколько времени потребуется на транспонирование. Вы увидите, что reshape тривиально, никакие данные не копируются, и что транспонирование занимает нетривиальное количество времени, оно копирует данные. - person Cris Luengo; 09.04.2019

Согласно документации Python 1,2, он просто распутывает массив (поэтому делает t линейным одномерным вектором. Затем, используя индексацию, он возвращается в новый массив определенного размера. Например:

start_array = 
[1,2,3,4;
5,6,7,8;
9,10,11,12]

i_a = [1,2,3,4,5,6,7,8,9,10,11,12] %implicit, not visible for user

result_array = 
[i_a(1), i_a(6), i_a(11); 
i_a(5), i_a(10), i_a(4); 
i_a(9), i_a(3), i_a(8); 
i_a(2), i_a(7), i_a(12)]
person Karls    schedule 08.04.2019
comment
Теперь вы считаете, что ваши элементы являются основными по строкам; это не так, вместо этого они хранятся (по крайней мере, в MATLAB, синтаксис которого вы используете) в порядке столбцов. - person Adriaan; 08.04.2019
comment
Порядок строк или столбцов здесь не имеет значения, он только показывает концепцию. Я основываюсь на официальной документации Python SciPy, в MATLAB это можно сделать по-другому. - person Karls; 08.04.2019
comment
под капотом массивы numpy похожи на MATLAB, 1D, всегда. Он просто меняет способ перевода 2D (в данном случае) индексов в этот 1D-массив и способ их отображения. - person Ander Biguri; 09.04.2019
comment
Цитата из документации You can think of reshaping as first raveling the array [...] then inserting [...] using the same kind of index. Так что, если они линейно сохранены, это звучит как тривиализация. - person Karls; 09.04.2019

Простейшая матрица, которую вы можете изменить, это 2x2, но вы поймете, что это такое. (Извините, StackOverflow не позволяет мне вставлять изображения или LaTex, так что вам придется немного помучаться, чтобы прочитать это.)

Мы начинаем с A=[[a,b],[c,d]] и хотим преобразовать его в массив 1x4: [[a,b,c,d]]. Вы можете сделать это алгебраически:

[[1,0]] * A * [[1,0,0,0],[0,0,0,0]] + 
[[1,0]] * A * [[0,0,0,0],[0,1,0,0]] + 
[[0,1]] * A * [[0,0,1,0],[0,0,0,0]] + 
[[0,1]] * A * [[0,0,0,0],[0,0,0,1]]

* обозначает умножение матриц.

Каждый термин является произведением соответствующих матриц: 1x2 * 2x2 * 2x4, что дает вам результат формы 1x4.

1-й термин дает вам [[a,0,0,0]], 2-й [[0,b,0,0]], 3-й [[0,0,c,0]] и 4-й [[0,0,0,d]].

Обобщить это на произвольный A формы nxm не должно быть слишком сложно. Вам понадобится n*m терминов вместо 4, так как ваша измененная матрица будет 1x(n*m). Каждый термин должен быть согласованным, поэтому вам понадобится матрица формы 1xn, чтобы попасть в A слева, и матрица формы mx(n*m), чтобы попасть в A справа.

Если вам нужно изменить форму A формы nxm в форму kxl, где k*l=n*m, вам нужно будет нажать A слева с матрицами kxn и справа с матрицами mx(k*l).

person gc1o1    schedule 21.04.2021