Ответ 1
Используйте linalg.lstsq(A,y)
, поскольку A
не является квадратным. Подробнее см. здесь. Вы можете использовать linalg.solve(A,y)
, если A
является квадратным, но не в вашем случае.
Я пытаюсь получить левый инверс неквадратной матрицы в 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 nump или scipy эквивалент левого инверсного оператора \
?
Используйте linalg.lstsq(A,y)
, поскольку A
не является квадратным. Подробнее см. здесь. Вы можете использовать linalg.solve(A,y)
, если A
является квадратным, но не в вашем случае.
Вы также можете найти эквивалент псевдоинверсивной функции pinv
в numpy/scipy
, в качестве альтернативы другому ответы.
Вот метод, который будет работать с разреженными матрицами (что из ваших комментариев - это то, что вы хотите), которое использует функцию lesssq из пакета оптимизации
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, но безрезультатно. Проблема в том, что все эти функции предназначены для обработки только квадратных функций. Если кто-то найдет способ сделать это таким образом, я тоже хотел бы знать.
Для тех, кто хочет решить проблемы с большими разреженными наименьшими квадратами:
Я добавил алгоритм 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
Я не тестировал его, но согласно этой веб-странице:
linalg.solve(A,y)
Вы можете использовать lsqr из scipy.sparse.linalg для решения разреженных матричных систем с наименьшими квадратами
Вы можете вычислить левое обратное, используя матричные вычисления:
import numpy as np
linv_A = np.linalg.solve(A.T.dot(A), A.T)
(Почему? Потому что:
)
Тест:
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.]]