solve () вылетает при наведении на единичные матрицы

Я пытаюсь решить систему линейных уравнений в стиле наименьших квадратов.
Используя броненосец и его функцию решения, я хочу вычислить три коэффициента параболической посадки.

vec coeffs = solve(CtC, Ctb)

с CtC =

1.0e+009 *
+--------------------------------+
|     2.0878    0.0221    0.0002 |
|     0.0221    0.0002    0.0000 |
|     0.0002    0.0000    0.0000 |
+--------------------------------+

и Ctb =

+------------+
|    -0.6163 |
|    -0.0065 |
|    -0.0001 |
+------------+

По всей видимости, решать () не удается, даже Матлаб предупреждает:

Warning: Matrix is close to singular or badly scaled. Results may be inaccurate.
RCOND = 1.303968e-022.

Есть ли обходной путь или более мощный / сложный метод в броненосце или с ++ в целом?
Спасибо

2

Решение

Проблема, с которой вы сталкиваетесь, заключается в том, что номер условия вашей матрицы очень высока, что может сделать ваши результаты бессмысленными из-за ошибок округления.

Согласно предложению rhalbersma, вы можете попытаться лучше масштабировать различные записи, чтобы уменьшить эту проблему. Если у вас нет такого решения, то вы должны использовать переобусловливатель. Их много (некоторые очень сложные), поэтому вы должны найти тот, который соответствует вашей проблеме.

Тем не менее, для этой конкретной системы, которая у вас под рукой, я бы просто инвертировал уравнения (1) и (3), которые дали бы нижнюю треугольную систему, которую легко решить для Matlab (нет необходимости в итерационных методах, которые могут быть очень чувствителен к номеру условия. В вашем случае, поскольку матрица симметрична, Matlab может попытаться решить ее с помощью cg, который является итеративным методом).

Кстати, известно ли, что ваша проблема дает почти особые матрицы? Если нет, я бы проверил наличие проблемы (или ошибки) перед сборкой матрицы (матрица может быть неособой из-за ошибок округления).

редактировать: На моем Matlab 2009 я не получаю никаких предупреждений при попытке решить эту систему (используя \ команда). Однако, если я попытаюсь использовать команду pcgЯ их получаю!

2

Другие решения

Вы не можете инвертировать матрицу с определитель равен нулю. В вашем случае определитель равен -8e-12, который на самом деле не равен нулю, но который дает в качестве обратной матрицы (используя R)

1.0e-009 *
[,1]          [,2]    [,3]
[1,] -3.815763e-16  6.806617e-14    5000
[2,]  5.111864e-14  5.000000e+03 -552500
[3,]  5.000000e+03 -5.525000e+05 8856250

Обратите внимание, что эта обратная матрица имеет как очень большие, так и очень маленькие числа. Этим объясняется ваше предупреждение о «близких к единственному» и «плохо масштабируемых». В зависимости от базовой библиотеки с плавающей точкой, вы можете получить очень плохо ошибки округления.

Вы можете вернуться к своему приложению и посмотреть, есть ли какие-либо переменные, представляющие столбец или строку, которые на много порядков отличаются друг от друга. Если это так, вы можете изменить их. Например. если между ними есть коэффициент в 1 миллион, и они представляют собой длину, выразите одно в километрах, а другое — в миллиметрах.

2