ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/solveur/src/matcreuse.cpp
Revision: 1158
Committed: Thu Jun 13 22:18:49 2024 UTC (11 months ago) by francois
File size: 10811 byte(s)
Error occurred while calculating annotation data.
Log Message:
compatibilité Ubuntu 22.04
Suppression des refeences à Windows
Ajout d'une banière

File Contents

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