ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/solveur/src/matcreuse.cpp
Revision: 108
Committed: Tue Jun 17 13:01:28 2008 UTC (16 years, 11 months ago) by souaissa
Original Path: magic/lib/solveur/solveur/src/matcreuse.cpp
File size: 8167 byte(s)
Error occurred while calculating annotation data.
Log Message:
solveur version du 17 juin 2008

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 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