Вопрос

У меня есть строка кода в MATLAB, написанная кем-то другим:

c=a.'/b

Мне нужно перевести его на Python.a, b и c — все массивы.Размеры, которые я сейчас использую для тестирования кода:

а:18x1,
б:25х18,

что дает мне c размером 1x25.

Массивы не квадратные, но я бы не хотел, чтобы код давал сбой, если бы они были квадратными.Может ли кто-нибудь объяснить, что именно делает эта строка (математически) и как это сделать на Python?(т. е. эквивалент встроенной функции mrdivide в MATLAB, если она существует в Python?)

Это было полезно?

Решение

Линия

c = a.' / b

вычисляет решение уравнения c b = a T для c . У Numpy нет оператора, который делает это напрямую. Вместо этого вы должны решить b T c T = a для c T и транспонировать результат:

c = numpy.linalg.lstsq(b.T, a.T)[0].T

Другие советы

Символ / - это матричный оператор деления справа в MATLAB, который вызывает функция mrdivide . Согласно документации, матричное правое деление связано с матричным левым делением в следующим образом:

B/A = (A'\B')'

Если A является квадратной матрицей, B / A примерно равно B * inv (A) (хотя вычисляется в другой, более надежный способ). В противном случае x = B / A является решением в смысле наименьших квадратов недооцененной или переопределенной системы уравнений x * A = B . Более подробная информация об алгоритмах, используемых для решения системы уравнений, приводится в здесь . Обычно такие пакеты, как LAPACK или BLAS используются под капотом.

пакет NumPy для Python содержит подпрограмму lstsq для вычисления наименьших квадратов решение системы уравнений. Эта процедура, скорее всего, даст вам сопоставимые результаты с использованием функции mrdivide в MATLAB, но вряд ли она будет точной . Любые различия в базовых алгоритмах, используемых каждой функцией, вероятно, приведут к ответам, которые немного отличаются друг от друга (то есть один может возвращать значение 1,0, тогда как другой может возвращать значение 0,999). Относительный размер этой ошибки может в конечном итоге быть большим, в значительной степени зависящей от конкретной системы уравнений, которую вы решаете.

Чтобы использовать lstsq , вам, возможно, придется немного исправить свою проблему. Похоже, что вы хотите решить уравнение вида cB = a , где B равно 25 на 18, a равно 1- на 18, а с - 1 на 25. Применение transpose к обеим сторонам дает уравнение B T c T = a T , что является более стандартной формой (т. е. Ax = b ). Аргументами lstsq должны быть (в этом порядке) B T (массив 18 на 25) и a T (массив из 18 элементов). lstsq должен возвращать массив из 25 элементов ( c T ).

Примечание: хотя NumPy не делает различий между массивом 1 на N или N на 1, MATLAB, безусловно, делает, и будет кричать на вас, если вы не используете правильный.

В Матлабе A.' означает транспонирование матрицы A.Итак, математически то, что достигается в коде, это AТ/Б.


Как реализовать матричное деление в Python (или любом другом языке) (Примечание:Давайте рассмотрим простое деление формы A/B;для вашего примера вам нужно будет сделать AТ сначала, а потом АТ/B далее, и операцию транспонирования в Python довольно легко выполнить |оставлено как упражнение :)|)

У вас есть матричное уравнение C*b = a (вы хотите найти C как A/B)

ПРАВОЕ ДЕЛЕНИЕ (/) выглядит следующим образом:

С**БТ)=А*БТ

Затем вы изолируете C, инвертируя (B*БТ)

то есть,

С = А*БТ**БТ)' ----- [1]

Следовательно, чтобы реализовать деление матрицы в Python (или любом другом языке), используйте следующие три метода.

  • Умножение матрицы
  • Транспонирование матрицы
  • Матрица обратная

Затем примените их итеративно, чтобы добиться разделения, как в [1].

Только вам нужно сделать АТ/B, поэтому ваша последняя операция после реализации трех основных методов должна быть:

АТ*БТ**БТ)'

Примечание:Не забывайте основные правила приоритета операторов :)

[отредактировано] Как указывал Сувеш, я был совершенно неправ. тем не менее, numpy все еще может легко выполнить процедуру, которую он дает в своем посте:

A = numpy.matrix(numpy.random.random((18, 1))) # as noted by others, your dimensions are off
B = numpy.matrix(numpy.random.random((25, 18)))
C = A.T * B.T * (B * B.T).I

Вы также можете приблизиться к этому, используя псевдообратное значение B , а затем умножить полученный результат на A . Попробуйте использовать numpy.linalg.pinv , затем объедините это с умножением матрицы с помощью < код> numpy.dot :

c = numpy.dot(a, numpy.linalg.pinv(b))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top