Симметричные положительно определённые матрицы

Если в системе линейных уравнений матрица является симметричной и к тому же положительно определённой ( xAx > 0, если x != 0 ), то в этом случае можно использовать для решения специальные методы.

Одним из таких методов является разложение Холецкого. Он представляет исходную матрицу в виде произведения: A = LLT, где L - нижняя треугольная матрица. Для того, чтобы найти решение системы Ax = b, последовательно решаются системы Ly = b, LTx = y. Здесь разложение Холецкого реализовано в виде класса SM_Chol. Конструктор осуществляет разложение исходной матрицы и хранит результат в одномерном массиве. Для диагональных элементов матрицы L записаны обратные значения. Метод determinant вычисляет определитель матрицы, а метод solve решает систему уравнений. Заметим, что в качестве аргументов для метода solve могут быть указатели на один и тот же массив. В этом случае исходные данные заменятся на вектор решения. Для того, чтобы найти обратную матрицу нужно n раз применить метод solve к соответствующему столбцу единичной матрицы, при этом будет получаться столбец обратной матрицы.

class SM_Chol
{
    const nat n;
    DynArray<double> g;
// Запрет конструктора копии и оператора присваивания:
    SM_Chol ( SM_Chol & );
    void operator = ( SM_Chol & );
public:
    SM_Chol ( nat k, const double * const * a );
    bool solve ( const double * b, double * x ) const; // b[n], x[n]
    double determinant () const;
};

Другим методом является LDLT разложение, где L - нижняя треугольная матрица с единичной диагональю, а D - диагональная матрица. В отличии от разложения Холецкого этот метод не использует операцию извлечения квадратного корня. Класс SM_LDLt имеет интерфейс аналогичный интерфейсу класса SM_Chol.

class SM_LDLt
{
    const nat n;
    DynArray<double> g;
// Запрет конструктора копии и оператора присваивания:
    SM_LDLt ( SM_LDLt & );
    void operator = ( SM_LDLt & );
public:
    SM_LDLt ( nat k, const double * const * a );
    bool solve ( const double * b, double * x ) const; // b[n], x[n]
    double determinant () const;
};

Оба класса были написаны на основе соответствующих программ из книги "Справочник алгоритмов на языке Алгол" ( Уилкинсон, Райнш ).

Описание шаблона классов DynArray находится здесь.

Исходники находятся в файле mathem.cpp.

Наверх

Hosted by uCoz