1 |
#include "gestionversion.h"
|
2 |
//---------------------------------------------------------------------------
|
3 |
#include "matcreuse.h"
|
4 |
|
5 |
#pragma hdrstop
|
6 |
|
7 |
|
8 |
//---------------------------------------------------------------------------
|
9 |
|
10 |
#pragma package(smart_init)
|
11 |
|
12 |
|
13 |
MatCr::MatCr(int dim) : dimension(dim) {
|
14 |
row = new Row[dim] ;
|
15 |
}
|
16 |
|
17 |
MatCr::~MatCr() { delete[] row; }
|
18 |
// aij <- aij + val
|
19 |
void MatCr::add(int i, int j, double val) {
|
20 |
if(j>=i)
|
21 |
row[i].add(j, val) ;
|
22 |
}
|
23 |
void MatCr::set(int i, int j, double val) {
|
24 |
row[i].set(j, val) ;
|
25 |
}
|
26 |
double MatCr::get(int i, int j) {
|
27 |
if(i>j){
|
28 |
int tmp=j;
|
29 |
j=i;
|
30 |
i=tmp;}
|
31 |
return row[i].get(j) ;
|
32 |
}
|
33 |
|
34 |
|
35 |
|
36 |
double MatCr:: get_max()
|
37 |
{
|
38 |
double max=0.;
|
39 |
for(int i=0;i<dimension;i++)
|
40 |
{
|
41 |
double maxi=row[i].row_max();
|
42 |
if (maxi>max) max=maxi;
|
43 |
}
|
44 |
return max;
|
45 |
}
|
46 |
void MatCr::diag(double* tmp_diag)
|
47 |
{
|
48 |
for(int i=0;i<dimension;i++)
|
49 |
{
|
50 |
tmp_diag[i]=get(i,i);
|
51 |
}
|
52 |
}
|
53 |
// A <- 0
|
54 |
void MatCr::clear() {
|
55 |
for(int i=0; i<dimension; i++) {
|
56 |
row[i].clear() ;
|
57 |
}
|
58 |
}
|
59 |
// number of non-zero coefficients
|
60 |
int MatCr::nnz() const {
|
61 |
int result = 0 ;
|
62 |
for(int i=0; i<dimension; i++) {
|
63 |
result += row[i].size() ;
|
64 |
}
|
65 |
return result ;
|
66 |
}
|
67 |
|
68 |
|
69 |
void MatCr::mul(double* y, const double* x)
|
70 |
{
|
71 |
for(int i=0; i<this->dimension; i++)
|
72 |
{
|
73 |
y[i] = 0 ;
|
74 |
const Row& R = this->row[i] ;
|
75 |
for(int jj=0; jj<this->dimension; jj++)
|
76 |
{
|
77 |
y[i] += this->get(i,jj)* x[jj] ;
|
78 |
}
|
79 |
/*
|
80 |
for(int jj=0; jj<R.size(); jj++)
|
81 |
{
|
82 |
y[i] += R[jj].a * x[ R[jj].index ] ;
|
83 |
} */
|
84 |
}
|
85 |
}
|
86 |
void MatCr::convert_to_CRS(const MatCr& M, CRSMatrix& M_CRS,int array_base) // 0 pour le C, 1 pour le Fortran
|
87 |
{
|
88 |
M_CRS.N = M.dimension ;
|
89 |
M_CRS.NNZ = M.nnz() ;
|
90 |
M_CRS.a = new double[M_CRS.NNZ] ;
|
91 |
M_CRS.col_ind = new int[M_CRS.NNZ] ;
|
92 |
M_CRS.row_ptr = new int[M_CRS.N+1] ;
|
93 |
int count = 0 ;
|
94 |
for(int i=0; i<M_CRS.N; i++)
|
95 |
{
|
96 |
const MatCr::Row& R = M.row[i] ;
|
97 |
M_CRS.row_ptr[i] = count + array_base ;
|
98 |
for(int jj=0; jj<R.size(); jj++)
|
99 |
{
|
100 |
M_CRS.a[count] = R[jj].a ;
|
101 |
M_CRS.col_ind[count] = R[jj].index + array_base ;
|
102 |
count++ ;
|
103 |
}
|
104 |
}
|
105 |
M_CRS.row_ptr[M_CRS.N] = M_CRS.NNZ + array_base ;
|
106 |
}
|
107 |
|
108 |
void MatCr::mult(double* y, CRSMatrix* M, double* x)
|
109 |
{
|
110 |
for(int i=0; i<M->N; i++) {
|
111 |
y[i] = 0.0 ;
|
112 |
for(int jj=M->row_ptr[i]; jj<M->row_ptr[i+1]; jj++) {
|
113 |
y[i] += M->a[jj] * x[M->col_ind[jj]] ;
|
114 |
}
|
115 |
}
|
116 |
}
|
117 |
|
118 |
|
119 |
void MatCr::pcg(double* b,double*x,double eps)
|
120 |
{
|
121 |
|
122 |
template < class Matrix, class Vector, class Preconditioner, class Real >
|
123 |
int
|
124 |
CGS(const Matrix &A, Vector &x, const Vector &b,
|
125 |
const Preconditioner &M, int &max_iter, Real &tol)
|
126 |
{
|
127 |
Real resid;
|
128 |
Vector rho_1(1), rho_2(1), alpha(1), beta(1);
|
129 |
Vector p, phat, q, qhat, vhat, u, uhat;
|
130 |
|
131 |
Real normb = norm(b);
|
132 |
Vector r = b - A*x;
|
133 |
Vector rtilde = r;
|
134 |
|
135 |
if (normb == 0.0)
|
136 |
normb = 1;
|
137 |
|
138 |
if ((resid = norm(r) / normb) <= tol) {
|
139 |
tol = resid;
|
140 |
max_iter = 0;
|
141 |
return 0;
|
142 |
}
|
143 |
|
144 |
for (int i = 1; i <= max_iter; i++) {
|
145 |
rho_1(0) = dot(rtilde, r);
|
146 |
if (rho_1(0) == 0) {
|
147 |
tol = norm(r) / normb;
|
148 |
return 2;
|
149 |
}
|
150 |
if (i == 1) {
|
151 |
u = r;
|
152 |
p = u;
|
153 |
} else {
|
154 |
beta(0) = rho_1(0) / rho_2(0);
|
155 |
u = r + beta(0) * q;
|
156 |
p = u + beta(0) * (q + beta(0) * p);
|
157 |
}
|
158 |
phat = M.solve(p);
|
159 |
vhat = A*phat;
|
160 |
alpha(0) = rho_1(0) / dot(rtilde, vhat);
|
161 |
q = u - alpha(0) * vhat;
|
162 |
uhat = M.solve(u + q);
|
163 |
x += alpha(0) * uhat;
|
164 |
qhat = A * uhat;
|
165 |
r -= alpha(0) * qhat;
|
166 |
rho_2(0) = rho_1(0);
|
167 |
if ((resid = norm(r) / normb) < tol) {
|
168 |
tol = resid;
|
169 |
max_iter = i;
|
170 |
return 0;
|
171 |
}
|
172 |
}
|
173 |
|
174 |
tol = resid;
|
175 |
return 1;
|
176 |
}
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 |
/*
|
185 |
double *r=new double[dimension];
|
186 |
double *d=new double[dimension];
|
187 |
double *z=new double[dimension];
|
188 |
double *Adk=new double[dimension];
|
189 |
double *s=new double[dimension];
|
190 |
double *dig=new double[dimension];
|
191 |
this->diag(dig);
|
192 |
double delta_zero;
|
193 |
double delta_new=0;
|
194 |
|
195 |
//mul(q,b);
|
196 |
for(int i=0;i<dimension;i++)
|
197 |
{
|
198 |
x[i]=0.;
|
199 |
r[i]=b[i]; //ro=b-A.xo i=0;
|
200 |
z[i]=(1./dig[i]) *r[i];
|
201 |
d[i]=z[i] ;
|
202 |
delta_new+=r[i]*d[i];
|
203 |
}
|
204 |
|
205 |
delta_zero=delta_new ;
|
206 |
|
207 |
while (fabs(delta_new)>eps)
|
208 |
{
|
209 |
double dkAdk=0.;
|
210 |
double zkrk= 0.;
|
211 |
mul(Adk,d);
|
212 |
for(int i=0;i<dimension;i++)
|
213 |
{
|
214 |
dkAdk+=d[i]*Adk[i];
|
215 |
zkrk+=z[i]*r[i];
|
216 |
}
|
217 |
double alpha=zkrk/ dkAdk;
|
218 |
for(int i=0;i<dimension;i++)
|
219 |
{
|
220 |
x[i]+=alpha*d[i];
|
221 |
r[i]-=alpha*Adk[i];
|
222 |
z[i]+=(1./dig[i]) *r[i];
|
223 |
}
|
224 |
|
225 |
double delta_old=zkrk;
|
226 |
delta_new=0.;
|
227 |
for(int i=0;i<dimension;i++)
|
228 |
{
|
229 |
delta_new+=z[i]*r[i];
|
230 |
}
|
231 |
|
232 |
|
233 |
double beta=delta_new/delta_old;
|
234 |
for(int i=0;i<dimension;i++)
|
235 |
{
|
236 |
d[i]=z[i]+beta*d[i];
|
237 |
}
|
238 |
|
239 |
}
|
240 |
delete [] r;
|
241 |
delete [] d;
|
242 |
//delete [] q;
|
243 |
delete [] s;
|
244 |
delete [] dig; */
|
245 |
}
|
246 |
|
247 |
|
248 |
|
249 |
|
250 |
MatCr& MatCr::Get_LU(int*perm,double&d)
|
251 |
{ |
252 |
static const double petit=double(1.0e-20); |
253 |
int taille=dimension; |
254 |
int imax,i,j,k; |
255 |
vector<double> v1(taille); |
256 |
double maxi,temp,som,dum; |
257 |
d=1; |
258 |
|
259 |
for(int i=0;i<taille;i++) |
260 |
{
|
261 |
maxi=row[i].row_max();
|
262 |
v1[i]=1./maxi;
|
263 |
} |
264 |
|
265 |
for(j=0;j<taille;j++) |
266 |
{ |
267 |
//cherche les colonnnes de lamatrice L (triangulaire inferieur |
268 |
for(i=0;i<j;i++) |
269 |
{ |
270 |
som=get(i,j);//[i][j]; |
271 |
for(k=0;k<i;k++) |
272 |
som-=get(i,k)*get(k,j); |
273 |
set(i,j,som); |
274 |
} |
275 |
maxi=0; |
276 |
|
277 |
//cherches les lignes de la matrice triangulaire superieur |
278 |
for(i=j;i<taille;i++) |
279 |
{ |
280 |
som=get(i,j); |
281 |
for(k=0;k<j;k++) |
282 |
som-=get(i,k)*get(k,j); |
283 |
set(i,j,som); |
284 |
//vèrificstion de pivot |
285 |
if((dum=v1[i]*fabs(som))>=maxi) |
286 |
{ |
287 |
maxi=dum; |
288 |
imax=i; |
289 |
} |
290 |
} |
291 |
//permuation des lignes imax et j |
292 |
if(j!=imax) |
293 |
{ |
294 |
for(k=0;k<taille;k++) |
295 |
{ |
296 |
dum=get(imax,k); |
297 |
set(imax,k,get(j,k)); |
298 |
set(j,k,dum); |
299 |
} |
300 |
d*=-1; |
301 |
v1[imax]=v1[j]; |
302 |
} |
303 |
// stoker dans perm la permuattion |
304 |
perm[j]=imax; |
305 |
// si le pivot est null |
306 |
if(get(j,j)==0.0)//Data[j][j]==0.0) |
307 |
set(j,j,petit);//[j][j]=petit; |
308 |
if(j!=taille-1) |
309 |
{ |
310 |
dum=1./get(j,j);//Data[j][j]; |
311 |
for(i=j+1;i<taille;i++) |
312 |
set(i,j,get(i,j)*dum);//Data[i][j]*=dum; |
313 |
} |
314 |
} |
315 |
|
316 |
return *this; |
317 |
}
|
318 |
|
319 |
|
320 |
void MatCr::Get_Solution(int*perm,const double* b,double* r1)
|
321 |
{ |
322 |
//Vecteur r1; |
323 |
int taille=dimension,i,j,ip,ii=-1; |
324 |
double som; |
325 |
|
326 |
// if(taille&&taille==NbCols&&taille==(int)b.Get_Size()) |
327 |
// { |
328 |
for(i=0;i<taille;i++) |
329 |
r1[i]=b[i]; |
330 |
for(i=0;i<taille;i++) |
331 |
{ |
332 |
ip=perm[i]; |
333 |
som=r1[ip]; |
334 |
r1[ip]=r1[i]; |
335 |
if(ii>=0) |
336 |
for(j=ii;j<=i-1;j++) |
337 |
som-=get(i,j)*r1[j]; |
338 |
else if(som) ii=i; |
339 |
r1[i]=som; |
340 |
} |
341 |
for(i=taille-1;i>=0;i--) |
342 |
{ |
343 |
som=r1[i]; |
344 |
for(j=i+1;j<taille;j++) |
345 |
som-=get(i,j)*r1[j]; |
346 |
r1[i]=som/get(i,i); |
347 |
} |
348 |
// } |
349 |
//return r1; |
350 |
} |
351 |
|
352 |
|
353 |
|
354 |
|