1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 struct LinSolveError
{
26 LinSolveError(double d
) { det
= d
; };
29 // Rainers full matrix solver
30 template <class M
, class V
>
31 void linsolve(const M
&Ain
, const V
&rsv
, V
&b
)
33 // Solve linear system Ax = rsv
34 // copy vec to protect it. b will be the return value
36 // copy yourself to protect matrix entries
44 // Find maximum element to get a relative value
45 for (int i
= 0; i
< A
.size(); ++i
) {
46 for (int j
= 0; j
< A
[i
].size(); ++j
) {
47 ele_max
= std::max(ele_max
,A
[i
][j
]);
51 // Get in matrix reduction
53 for (k
= 0; k
< n
-1; k
++) {
56 for(i
= k
; i
< n
; i
++) {
58 for(j
= k
; j
< n
; j
++) {
59 s
= s
+ fabs(A
[i
][j
]);
69 for(j
= 0; j
< n
; j
++) {
76 for(i
= k
+1; i
< n
; i
++) {
77 A
[i
][k
] = A
[i
][k
]/A
[k
][k
];
78 for(j
= k
+1; j
< n
; j
++) {
79 A
[i
][j
] = A
[i
][j
] - A
[i
][k
]*A
[k
][j
];
83 det
= det
*A
[n
-1][n
-1];
85 // Proceed with rest of system reduction
86 for(k
= 0; k
< n
-1; k
++) {
93 for(i
= 0; i
< n
; i
++) {
94 for(j
= 0; j
< i
; j
++) {
95 b
[i
] = b
[i
] - A
[i
][j
]*b
[j
];
98 for(i
= n
-1;i
>= 0; i
--) {
100 for(k
= i
+1; k
< n
; k
++)
101 s
= s
- A
[i
][k
]*b
[k
];
105 // Check Determinant and throw error, if needed
106 if (fabs(det
) < 1e-20) {
107 throw LinSolveError(det
);