ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/solveur/src/matcreuse.cpp
Revision: 161
Committed: Thu Sep 18 16:04:06 2008 UTC (16 years, 8 months ago) by souaissa
Original Path: magic/lib/solveur/solveur/src/matcreuse.cpp
File size: 10039 byte(s)
Error occurred while calculating annotation data.
Log Message:
mise a jour du solveur

File Contents

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