-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathhelpers.c
105 lines (90 loc) · 2.89 KB
/
helpers.c
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
* Copyright (c) 1998-2007 Rainer Hegger, Holger Kantz, Thomas Schreiber
*
* TISEAN is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* TISEAN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with TISEAN; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*Author: Rainer Hegger, Last modified: Feb 6, 2006 */
/*Author: Federico Reghenzani, Last modified: Jun 20, 2017 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "helpers.h"
#include "global.h"
static double temp_swap[MAX_ARMADIM_POLES];
static double temp_mat[MAX_ARMADIM_POLES][MAX_ARMADIM_POLES];
extern double mat[MAX_ARMADIM_POLES][MAX_ARMADIM_POLES];
extern double inv[MAX_ARMADIM_POLES][MAX_ARMADIM_POLES];
extern double vec[MAX_ARMADIM_POLES];
static int solvele(unsigned int n)
{
double vswap,max,h,pivot,q;
int i,j,k,maxi;
for (i=0;i<n-1;i++) {
max=fabs(temp_mat[i][i]);
maxi=i;
for (j=i+1;j<n;j++)
if ((h=fabs(temp_mat[j][i])) > max) {
max=h;
maxi=j;
}
if (maxi != i) {
for (k=0; k<n; k++) {
temp_swap[k] = temp_mat[i][k];
temp_mat[i][k]=temp_mat[maxi][k];
temp_mat[maxi][k]=temp_swap[k];
}
vswap=vec[i];
vec[i]=vec[maxi];
vec[maxi]=vswap;
}
pivot=temp_mat[i][i];
if (fabs(pivot) == 0.0) {
return -1;
}
for (j=i+1;j<n;j++) {
q= -temp_mat[j][i]/pivot;
temp_mat[j][i]=0.0;
for (k=i+1;k<n;k++)
temp_mat[j][k] += q*temp_mat[i][k];
vec[j] += q*vec[i];
}
}
vec[n-1] /= temp_mat[n-1][n-1];
for (i=n-2;i>=0;i--) {
for (j=n-1;j>i;j--)
vec[i] -= temp_mat[i][j]*vec[j];
vec[i] /= temp_mat[i][i];
}
return 0;
}
int invert_matrix(unsigned int size)
{
int i,j,k;
for (i=0;i<size;i++) {
for (j=0;j<size;j++) {
vec[j]=(i==j)?1.0:0.0;
for (k=0;k<size;k++) {
temp_mat[j][k]=mat[j][k];
}
}
if (solvele(size)) {
return -1; // Singular matrix
}
for (j=0;j<size;j++) {
inv[j][i]=vec[j];
}
}
return 0;
}