Левый обратный в numpy или scipy? - PullRequest
13 голосов
/ 12 февраля 2010

Я пытаюсь получить левую инверсию неквадратной матрицы в python, используя numpy или scipy. Как я могу перевести следующий код Matlab на Python?

>> A = [0,1; 0,1; 1,0]

A =

     0     1
     0     1
     1     0

>> y = [2;2;1]

y =

     2
     2
     1

>> A\y

ans =

    1.0000
    2.0000

Есть ли в Matlab эквивалентный или грубый эквивалент левого обратного оператора \?

Ответы [ 7 ]

9 голосов
/ 12 февраля 2010

Используйте linalg.lstsq(A,y), поскольку A не является квадратным.Смотрите здесь для деталей.Вы можете использовать linalg.solve(A,y), если A - квадрат, но не в вашем случае.

2 голосов
/ 02 марта 2010

Для тех, кто хочет решить большие разреженные задачи наименьших квадратов:

Я добавил алгоритм LSQR в SciPy. Со следующим выпуском вы сможете сделать:

from scipy.sparse import csr_matrix
from scipy.sparse.linalg import lsqr
import numpy as np

A = csr_matrix([[0., 1], [0, 1], [1, 0]])
b = np.array([[2.], [2.], [1.]])

lsqr(A, b)

, который возвращает ответ [1, 2].

Если вы хотите использовать эту новую функциональность без обновления SciPy, вы можете загрузить lsqr.py из репозитория кода на

http://projects.scipy.org/scipy/browser/trunk/scipy/sparse/linalg/isolve/lsqr.py

2 голосов
/ 12 февраля 2010

Вот метод, который будет работать с разреженными матрицами (который из ваших комментариев является тем, что вы хотите), который использует функцию leastsq из пакета оптимизации

from numpy import *
from scipy.sparse import csr_matrix
from scipy.optimize import leastsq
from numpy.random import rand

A=csr_matrix([[0.,1.],[0.,1.],[1.,0.]])
b=array([[2.],[2.],[1.]])

def myfunc(x):
    x.shape = (2,1)
    return (A*x - b)[:,0]

print leastsq(myfunc,rand(2))[0]

генерирует

[ 1.  2.]

Это немного уродливо из-за того, что я должен был подбирать формы, чтобы соответствовать тому, что хотел наименьший. Может быть, кто-то еще знает, как сделать это немного более аккуратным.

Я также пытался заставить что-то работать с функциями в scipy.sparse.linalg с помощью LinearOperators, но безрезультатно. Проблема в том, что все эти функции предназначены только для обработки квадратных функций. Если кто-нибудь найдет способ сделать это таким образом, я бы тоже хотел знать.

2 голосов
/ 12 февраля 2010

Вы также можете найти эквивалент псевдообратной функции pinv в numpy/scipy в качестве альтернативы другим ответам:

1 голос
/ 06 февраля 2017

Вы можете вычислить левое обратное, используя матричные вычисления:

import numpy as np

linv_A = np.linalg.solve(A.T.dot(A), A.T)

(Почему? Потому что:

enter image description here

)

Тест:

np.set_printoptions(suppress=True, precision=3)
np.random.seed(123)

A = np.random.randn(3, 2)
print('A\n', A)

A_linv = np.linalg.solve(A.T.dot(A), A.T)
print('A_linv.dot(A)\n', A_linv.dot(A))

Результат:

A
 [[-1.086  0.997]
 [ 0.283 -1.506]
 [-0.579  1.651]]
A_linv.dot(A)
 [[ 1. -0.]
 [ 0.  1.]]
0 голосов
/ 11 мая 2011

Вы можете использовать lsqr из scipy.sparse.linalg для решения разреженных матричных систем с наименьшими квадратами

0 голосов
/ 12 февраля 2010

Я не проверял это, но согласно этой веб-странице это:

linalg.solve(A,y)
...