MRDIVIDE или оператор /
фактически решает линейную систему xb = a
, в отличие от MLDIVIDE или оператора \
, который решит систему bx = a
.
Чтобы решить систему xb = a
с несимметричной, необратимой матрицей b
, вы можете либо положиться на mridivide()
, что выполняется посредством факторизации b
с исключением Гаусса, либо pinv()
, что делается через разложение по сингулярным значениям и обнуление сингулярных значений ниже (по умолчанию) уровня допуска.
Вот разница (для случая mldivide
): В чем разница между PINV и MLDIVIDE, когда я решаю A * x = b?
Когда система переопределена, оба алгоритма обеспечивают
тот же ответ. Когда система недоопределена, PINV вернет
решение x, которое имеет минимальную норму (min NORM (x)). MLDIVIDE будет
выберите решение с наименьшим количеством ненулевых элементов.
В вашем примере:
% solve xb = a
a = [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9];
b = ones(25, 18);
система недоопределена, и два разных решения будут:
x1 = a/b; % MRDIVIDE: sparsest solution (min L0 norm)
x2 = a*pinv(b); % PINV: minimum norm solution (min L2)
>> x1 = a/b
Warning: Rank deficient, rank = 1, tol = 2.3551e-014.
ans =
5.0000 0 0 ... 0
>> x2 = a*pinv(b)
ans =
0.2 0.2 0.2 ... 0.2
В обоих случаях ошибка аппроксимации xb-a
является пренебрежимо малой (неточное решение), и то же самое, т. Е. norm(x1*b-a)
и norm(x2*b-a)
будут возвращать один и тот же результат.
Что делает MATLAB?
Великолепная разбивка алгоритмов (и проверок свойств), вызываемых оператором '\', в зависимости от структуры матрицы b
приведена в этом посте в scicomp.stackexchange.com . Я предполагаю, что аналогичные параметры применяются для оператора /
.
В вашем примере, MATLAB, скорее всего, выполняет исключение по Гауссу, предоставляя самое разреженное решение среди бесконечности (отсюда и 5).
Что делает Python?
Python, в linalg.lstsq
используется псевдообратная / SVD, как показано выше (поэтому вы получаете вектор 0,2). По сути, следующее даст вам тот же результат, что и MATLAB pinv()
:
from numpy import *
a = array([1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9])
b = ones((25, 18))
# xb = a: solve b.T x.T = a.T instead
x2 = linalg.lstsq(b.T, a.T)[0]
x2 = dot(a, linalg.pinv(b))