-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathFullDirectSolver.cpp
108 lines (101 loc) · 1.98 KB
/
FullDirectSolver.cpp
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
106
107
108
#include "FullDirectSolver.h"
namespace Daetk
{
FullDirectSolver::FullDirectSolver(Mat& Min):
neq(Min.dim(0)),
x(this,Min.dim(0)),
b(this,Min.dim(0)),
scaleFactor(Min.dim(0)),
M(&Min)
{
permutationVector=new int[neq];
}
FullDirectSolver::~FullDirectSolver()
{
delete [] permutationVector;
}
bool FullDirectSolver::prepare()
{
scaleFactor=0.0;
real pivot,temp;
int i,j,k,pivotIndex(0);
for (i=0;i<neq;i++)
{
for(j=0;j<neq;j++)
{
temp = ::fabs((*M)(i,j));
if (temp > scaleFactor(i))
scaleFactor(i)=temp;
}
if (scaleFactor(i)==0.0)
return true;//matrix is singular
}
for (i=0;i<neq;i++)
{
pivot=0.0;
for (j=i;j<neq;j++)
{
temp=(*M)(j,i);
if (::fabs(temp/scaleFactor(j)) > ::fabs(pivot))
{
pivot=temp;
pivotIndex=j;
}
}
if (i!=pivotIndex)
{
for (k=0;k<neq;k++)
{
temp=(*M)(i,k);
(*M)(i,k)=(*M)(pivotIndex,k);
(*M)(pivotIndex,k)=temp;
}
}
permutationVector[i]=pivotIndex;
scaleFactor(pivotIndex)=scaleFactor(i);
for(j=i+1;j<neq;j++)
{
(*M)(j,i)=(*M)(j,i)/(*M)(i,i);
for (k=i+1;k<neq;k++)
{
(*M)(j,k)-=(*M)(j,i)*(*M)(i,k);
}
}
}
return false;
}
bool FullDirectSolver::solve(const Vec& bIn,Vec& xIn)
{
int i,j,indexOfFirstNonzeroInb;
real temp;
b.attachToTarget(bIn);
x.attachToTarget(xIn);
indexOfFirstNonzeroInb=-1; //exploit initial zeroes
for (i=0;i<neq;i++) //for rows $i=1,...,n:
{
temp=b.v_(permutationVector[i]);
b.v_(permutationVector[i])=b.v_(i);
if (indexOfFirstNonzeroInb!=-1)
{
for (j=indexOfFirstNonzeroInb;j<i;j++)
{
temp-=(*M)(i,j)*x.v_(j);
}
}
else if (temp!=0)
indexOfFirstNonzeroInb=i;
x.v_(i)=temp;
}
for (i=neq-1;i>=0;i--)
{
temp=x.v_(i);
for (j=i+1;j<neq;j++)
{
temp-=(*M)(i,j)*x.v_(j);
}
x.v_(i)=temp/(*M)(i,i);
}
x.restoreToTarget();
return false;
}
}//Daetk