ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/addin/vtkdisplay/src/linear_algebra.cc
Revision: 1156
Committed: Thu Jun 13 22:02:48 2024 UTC (14 months ago) by francois
File size: 7515 byte(s)
Log Message:
compatibilité Ubuntu 22.04
Suppression des refeences à Windows
Ajout d'une banière

File Contents

# User Rev Content
1 francois 1061 // nUtil - An utility Library for gnurbs
2     // Copyright (C) 2008-2019 Eric Bechet
3     //
4     // See the LICENSE file for contributions and license information.
5     // Please report all bugs and problems to <bechet@cadxfem.org>.
6     //
7    
8     #include <iostream>
9     #include <iomanip>
10 francois 1156 #include "linear_algebra.hxx"
11 francois 1061
12    
13     void Vector::Display(std::ostream& out) const
14     {
15     // out << std::setiosflags(std::ios::fixed);
16     // out << std::setprecision(8);
17     out << std::endl;
18     for (int j=0;j<Size();++j)
19     out << coord[j] << " ";
20     out << std::endl;
21     }
22    
23     void Matrix::Display(std::ostream& out) const
24     {
25     // out << std::setiosflags(std::ios::fixed);
26     // out << std::setprecision(8);
27     for (int i=0;i<this->SizeL();++i)
28     {
29     out << std::endl;
30     for (int j=0;j<this->SizeC();++j)
31     out << (*this)(i,j) << " ";
32     }
33     out << std::endl;
34     }
35    
36     #define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);\
37     a[k][l]=h+s*(g-h*tau);
38    
39     int Square_Matrix::Eigen_Vectors(Matrix &M,Vector &d)
40     {
41     int j,iq,ip,i;
42     double tresh,theta,tau,t,sm,s,h,g,c;
43    
44     std::vector<double> b(Size());
45     std::vector<double> z(Size());
46     std::vector<std::vector<double> > a(Size());
47     for (i=0;i<Size();i++)
48     {
49     a[i].resize(Size());
50     }
51    
52     int nrot=0;
53    
54     for (ip=0;ip<Size();ip++)
55     {
56     for (iq=0;iq<Size();iq++)
57     {
58     mat[ip][iq]=0.0;
59     a[ip][iq]=M(ip,iq);
60     }
61     mat[ip][ip]=1.0;
62     }
63     for (ip=0;ip<Size();ip++)
64     {
65     b[ip]=d[ip]=a[ip][ip];
66     z[ip]=0.0;
67     }
68     nrot=0;
69     for (i=0;i<100;i++)
70     {
71     sm=0.0;
72     for (ip=0;ip<Size()-1;ip++)
73     {
74     for (iq=ip+1;iq<Size();iq++)
75     sm += fabs(a[ip][iq]);
76     }
77     if (sm == 0.0)
78     {
79     break;
80     }
81     if (i < 3)
82     tresh=0.2*sm/ (Size() *Size());
83     else
84     tresh=0.0;
85     for (ip=0;ip<Size()-1;ip++)
86     {
87     for (iq=ip+1;iq<Size();iq++)
88     {
89     g=100.0*fabs(a[ip][iq]);
90     if ((i > 3) && ((fabs(d[ip]) +g) == fabs(d[ip])) && ((fabs(d[iq]) +g) == fabs(d[iq])))
91     a[ip][iq]=0.0;
92     else
93     {
94     if (fabs(a[ip][iq]) > tresh)
95     {
96     h=d[iq]-d[ip];
97     if ((fabs(h) +g) == fabs(h))
98     t= (a[ip][iq]) /h;
99     else
100     {
101     theta=0.5*h/ (a[ip][iq]);
102     t=1.0/ (fabs(theta) +sqrt(1.0+theta*theta));
103     if (theta < 0.0) t = -t;
104     }
105     c=1.0/sqrt(1+t*t);
106     s=t*c;
107     tau=s/ (1.0+c);
108     h=t*a[ip][iq];
109     z[ip] -= h;
110     z[iq] += h;
111     d[ip] -= h;
112     d[iq] += h;
113     a[ip][iq]=0.0;
114     for (j=0;j<=ip-1;j++)
115     {
116     ROTATE(a,j,ip,j,iq)
117     }
118     for (j=ip+1;j<=iq-1;j++)
119     {
120     ROTATE(a,ip,j,j,iq)
121     }
122     for (j=iq+1;j<Size();j++)
123     {
124     ROTATE(a,ip,j,iq,j)
125     }
126     for (j=0;j<Size();j++)
127     {
128     ROTATE(mat,j,ip,j,iq)
129     }
130     ++nrot;
131     }
132     }
133     }
134     }
135     for (ip=0;ip<Size();ip++)
136     {
137     b[ip] += z[ip];
138     d[ip]=b[ip];
139     z[ip]=0.0;
140     }
141     }
142     if (i==100)
143     {
144     return 1; // there was a problem.
145     }
146     return 0;
147     }
148    
149     #undef ROTATE
150    
151    
152     void Square_Matrix::Complete_Base(int num)
153     {
154     int i,j,k;
155     std::vector<Vector> Tab(Size());
156     for (i=0;i<Size();i++)
157     Tab[i].Resize(Size());
158    
159     double pscal,norm;
160     for (i=0;i<num;i++)
161     {
162     for (j=0;j<Size();j++)
163     Tab[i][j]=mat[i][j];
164     Tab[i].Normalize();
165     }
166    
167     for (i=num;i<Size();i++)
168     {
169     for (j=0;j<num;j++)
170     {
171     for (k=0;k<Size();k++)
172     Tab[i][k]=0;
173     Tab[i][(i+j) %Size()]=1.0;
174     for (k=0;k<i;k++)
175     {
176     pscal=Tab[i]*Tab[k];
177     Tab[i].Add(Tab[k],-pscal);
178     }
179     norm=Tab[i].Norm();
180     if (norm>1e-4)
181     break;
182    
183     }
184     Tab[i].Normalize();
185     }
186    
187     for (i=0;i<Size();i++)
188     for (j=0;j<Size();j++)
189     mat[i][j]=Tab[i][j];
190     }
191    
192    
193    
194    
195    
196     void Cholesky_Matrix::CholeskyDec_intern(void)
197     {
198     int k,i,p;
199     for (k=0;k<Size();++k)
200     {
201     double sumsqakp=0.;
202     for (p=0;p<k;++p)
203     {
204     double akp= (*this)(k,p);
205     sumsqakp+=akp*akp;
206     }
207     double& akk= (*this)(k,k);
208     if (akk<sumsqakp)
209     {
210     std::cerr << "Cholesky : (akk<sumsqakp) " << akk << " < " << sumsqakp << std::endl;
211     throw "Cholesky : (akk<sumsqakp)";
212     }
213     akk=sqrt(akk-sumsqakp);
214     // Display();
215     // cout << "a" << k << k << " " << akk << " sumsqakp " << sumsqakp << endl;
216     for (i=k+1;i<Size();++i)
217     {
218     double sumaipakp=0.0;
219     for (p=0;p<k;++p)
220     {
221     sumaipakp+= (*this)(i,p) * (*this)(k,p);
222     }
223     double& aik= (*this)(i,k);
224     aik= (aik-sumaipakp) /akk;
225     // Display();
226     // cout << "a" << i << k << " " << aik <<" sumaipakp " << sumaipakp << endl;
227     // cout << aik << " " ;
228     }
229     // cout << endl;
230     }
231     }
232    
233    
234     void LU_Matrix::LUDec_intern(void)
235     {
236    
237     int i,imax,j,k;
238     double big,dum,sum,temp;
239     std::vector<double> vv(Size());
240    
241    
242     d=1.;
243    
244     for (i=0;i<Size();++i)
245     {
246     big=0.0;
247     for (j=0;j<Size();++j)
248     if ((temp=fabs(mat[i][j])) > big) big=temp;
249    
250     if (big == 0.0)
251     {
252     d=0.0;
253     return;
254     }
255    
256     vv[i]=1.0/big;
257     }
258    
259    
260     for (j=0;j<Size();++j)
261     {
262     for (i=0;i<j;++i)
263     {
264     sum=mat[i][j];
265     for (k=0;k<i;++k) sum -= mat[i][k]*mat[k][j];
266     mat[i][j]=sum;
267     }
268    
269     big=0.0;
270     for (i=j;i<Size();++i)
271     {
272     sum=mat[i][j];
273     for (k=0;k<j;++k)
274     sum -= mat[i][k]*mat[k][j];
275     mat[i][j]=sum;
276     if ((dum=vv[i]*fabs(sum)) >= big)
277     {
278     big=dum;
279     imax=i;
280     }
281     }
282     if (j != imax)
283     {
284     for (k=0;k<Size();++k)
285     {
286     dum=mat[imax][k];
287     mat[imax][k]=mat[j][k];
288     mat[j][k]=dum;
289     }
290     d = - (d);
291     vv[imax]=vv[j];
292     }
293     tab[j]=imax;
294    
295     if (mat[j][j] == 0.0)
296     {
297     mat[j][j] = 1e-50;
298     }
299    
300     if (j != Size()-1)
301     {
302     dum=1.0/ (mat[j][j]);
303     for (i=j+1;i<Size();++i) mat[i][j] *= dum;
304     }
305     }
306     for (i=0;i<Size();++i)
307     d*=mat[i][i];
308     }
309    
310     void LU_Matrix::Solve_Linear_System(Vector &rhsv,Vector &sol)
311     {
312     int i,im1,ii=-1,ip,j;
313     double sum;
314    
315     if (d==0.0) return;
316    
317     sol=rhsv;
318    
319     for (i=0;i<Size();++i)
320     {
321     ip=tab[i];
322     sum=sol[ip];
323     sol[ip]=sol[i];
324     im1=i-1;
325     if (ii>=0)
326     for (j=ii;j<=im1;++j) sum -= mat[i][j]*sol[j];
327     else if (sum!=0.0) ii=i;
328     sol[i]=sum;
329     }
330    
331     for (i=Size()-1;i>=0;i--)
332     {
333     sum=sol[i];
334     for (j=i+1;j<Size();++j) sum -= mat[i][j]*sol[j];
335     sol[i]=sum/mat[i][i];
336     }
337     }
338    
339    
340    
341    
342     double det(double M[2][2])
343     {
344     return M[0][0]*M[1][1]-M[1][0]*M[0][1];
345     }
346    
347     double trace(double M[2][2])
348     {
349     return M[0][0]+M[1][1];
350     }
351    
352     double prodcc(double M1[2][2],double M2[2][2])
353     {
354     double p=0.;
355     for (int i=0;i<2;++i)
356     for (int j=0;j<2;++j)
357     p+=M1[i][j]*M2[i][j];
358     return p;
359     }
360    
361    
362     void inverse(double M[2][2],double I[2][2]) // I : inverse de la matrice M
363     {
364     double d = det(M);
365     I[0][0] = M[1][1]/d;
366     I[1][1] = M[0][0]/d;
367     I[0][1] = -M[0][1]/d;
368     I[1][0] = -M[1][0]/d;
369     }
370    
371    
372     void multi(double A[2][2],double B[2][2],double C[2][2]) // Effectue la multiplication de A et B et rentre le résultat dans la matrice C
373     {
374     for (int i=0;i<2;i++)
375     {
376     for (int j=0;j<2;j++)
377     {
378     C[i][j] = 0;
379     for (int k=0;k<2;k++)
380     {
381     C[i][j]+=A[i][k]*B[k][j];
382     }
383     }
384     }
385     }
386    
387     double multi(double V1[2],double M[2][2],double V2[2]) // Effectue la multiplication Ai Mij Cj
388     {
389     double res=0.;
390     for (int i=0;i<2;i++)
391     {
392     for (int j=0;j<2;j++)
393     {
394     res+=V1[i]*M[i][j]*V2[j];
395     }
396     }
397     return res;
398     }
399