Проблема действительно в вашей математике.Предоставленная вами матрица не имеет полного ранга, поэтому она не является обратимой.Вы можете проверить это вручную (это не заняло времени), но MATLAB уже указывает на это, показывая это предупреждение.
Поскольку вы работаете с числами с плавающей запятой, это иногда вызывает другие тонкие проблемы,один из которых вы можете увидеть в результате det(A)
, который имеет порядок 1e-16
, то есть точность машины или 0 на практике.
Вы можете видеть, что эта матрица не имеет полного рангавыполнение функции rank
: rank(A) = 8
.Для матрицы 9x9
это действительно означает, что матрица не является обратимой для двойных чисел (поскольку функция rank
учитывает точность станка).
Если вы хотите использовать MATLAB для получения результата, который соответствуетВ ручном расчете вы можете использовать Symbolic Toolbox и его vpa
(арифметику с переменной точностью), чтобы обойти возможные числовые проблемы за счет более медленных вычислений.
B = [5 1 -2 0 0 -1 -1 0 0;
1 1 0 0 0 -1 -1 0 0;
-2 0 5 -1 -2 0 0 -1 1;
0 0 -1 1 0 0 0 1 -1;
0 0 -2 0 3 -1 1 0 0;
-1 -1 0 0 -1 4 0 -2 0;
-1 -1 0 0 1 0 2 0 0;
0 0 -1 1 0 -2 0 4 0;
0 0 1 -1 0 0 0 0 2];
A = B/2;
size(A) % = [9 9]
det(A) % = -1.38777878078145e-17
rank(A) % = 8
C = vpa(A);
det(C) % = 0.0
rank(C) % = 8
Как с VPA, так и с плавающей запятой выполучим, что ранг равен 8, размер равен [9 9], а определитель практически равен 0, то есть в единственном числе или не обратим.Изменение нескольких записей может сделать вашу матрицу регулярной (неособой), но она не гарантированно сработает и решит другую проблему.
Чтобы решить вашу актуальную проблему A*x=b
для x
, вамможно попытаться использовать mldivide
(он же оператор обратной косой черты) или псевдообратный код Мура-Пенроуза:
x1 = A\b;
x2 = pinv(A)*b;
Но помните, что такая система не имеет уникального решения, поэтому обе псевдооператор обратного слэша и оператор обратной косой черты могут (и в этом случае будут) возвращать очень разные решения, независимо от того, является ли любое из них приемлемым, действительно зависит от вашего приложения.