2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008-2013 enGits GmbH +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26 struct LinSolveError
{
28 LinSolveError(double d
) { det
= d
; };
31 // Rainers full matrix solver
32 template <class M
, class V
>
33 void linsolve(const M
&Ain
, const V
&rsv
, V
&b
)
35 // Solve linear system Ax = rsv
36 // copy vec to protect it. b will be the return value
38 // copy yourself to protect matrix entries
46 // Find maximum element to get a relative value
47 for (int i
= 0; i
< A
.size(); ++i
) {
48 for (int j
= 0; j
< A
[i
].size(); ++j
) {
49 ele_max
= std::max(ele_max
,A
[i
][j
]);
53 // Get in matrix reduction
55 for (k
= 0; k
< n
-1; k
++) {
58 for(i
= k
; i
< n
; i
++) {
60 for(j
= k
; j
< n
; j
++) {
61 s
= s
+ fabs(A
[i
][j
]);
71 for(j
= 0; j
< n
; j
++) {
78 for(i
= k
+1; i
< n
; i
++) {
79 A
[i
][k
] = A
[i
][k
]/A
[k
][k
];
80 for(j
= k
+1; j
< n
; j
++) {
81 A
[i
][j
] = A
[i
][j
] - A
[i
][k
]*A
[k
][j
];
85 det
= det
*A
[n
-1][n
-1];
87 // Proceed with rest of system reduction
88 for(k
= 0; k
< n
-1; k
++) {
95 for(i
= 0; i
< n
; i
++) {
96 for(j
= 0; j
< i
; j
++) {
97 b
[i
] = b
[i
] - A
[i
][j
]*b
[j
];
100 for(i
= n
-1;i
>= 0; i
--) {
102 for(k
= i
+1; k
< n
; k
++)
103 s
= s
- A
[i
][k
]*b
[k
];
107 // Check Determinant and throw error, if needed
108 if (fabs(det
) < 1e-20) {
109 throw LinSolveError(det
);