File: LUPDecomposition.cpp

package info (click to toggle)
ausaxs 1.1.8-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 72,592 kB
  • sloc: cpp: 49,853; ansic: 6,901; python: 730; makefile: 18
file content (62 lines) | stat: -rw-r--r-- 1,686 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// SPDX-License-Identifier: LGPL-3.0-or-later
// Author: Kristian Lytje

#include <math/LUPDecomposition.h>
#include <math/Matrix.h>
#include <math/Vector.h>

using namespace ausaxs;

LUPDecomposition::LUPDecomposition(const Matrix<double>& A) : Ap(::std::make_unique<Matrix<double>>(A.copy())) {decompose();}

void LUPDecomposition::decompose() {
    Matrix<double>& A = *Ap;

    Vector<double> row;
    P = Vector<double>(A.N); // enumerate our matrix rows so we can keep track of permutations.
    for (unsigned int i = 0; i < A.N; ++i) {P[i] = i;}
    permutations = 0;

    unsigned int j, k;
    for (unsigned int i = 0; i < A.N; ++i) {
        // find pivot point
        double A_max = 0, i_max = 0;
        for (k = i; k < A.N; ++k) {
            if (abs(A[k][i]) > A_max) {
                A_max = abs(A[k][i]);
                i_max = k;
            }
        }
        if (A_max < precision) {throw std::invalid_argument("LUDecomposition::decompose: Matrix is degenerate.");}
        if (i_max != i) {
            // pivot P
            j = P[i];
            P[i] = P[i_max];
            P[i_max] = j;

            // exchange rows of A
            row = A[i];
            A[i] = A[i_max];
            A[i_max] = row;

            permutations++;
        }

        for (j = i+1; j < A.N; ++j) {
            A[j][i] /= A[i][i];
            for (k = i+1; k < A.N; ++k) {
                A[j][k] -= A[j][i]*A[i][k];
            }
        }
    }
}

double LUPDecomposition::determinant() const {
    Matrix<double>& A = *Ap;

    double det = A[0][0];
    for (unsigned int i = 1; i < A.N; ++i) {
        det *= A[i][i];
    }
    return permutations % 2 == 0 ? det : -det;
}