Memosa-FVM  0.2
MatrixOperation.h
Go to the documentation of this file.
1 // This file os part of FVM
2 // Copyright (c) 2012 FVM Authors
3 // See LICENSE file for terms.
4 
5 #ifndef _MATRIXOPERATION_H_
6 #define _MATRIXOPERATION_H_
7 
8 template <class T, int N>
10 {
11  public:
12  enum { NSQR = N*N };
13 
16 
18  for ( int i=0; i<NSQR; i++){
19  _data[i] = o._data[i];
20  }
21  }
22 
23  SquareMatrix(const T& s){
24  for ( int i=0; i<N; i++){
25  for ( int j=0; j<N; j++){
26  if (i==j)
27  (*this)(i,j) = s;
28  else
29  (*this)(i,j) = T(0);
30  }
31  }
32  }
33 
34  T& operator()(int i, int j) {return _data[i*N+j];}
35 
36  SquareMatrix& operator=(const T& s)
37  {
38  for(int i=0; i<N; i++)
39  for(int j=0; j<N; j++)
40  (*this)(i,j) = (i==j) ? s : T(0.);
41  return *this;
42  }
43 
45  {
46  for(int i=0;i<NSQR;i++)
47  _data[i] = o._data[i];
48  return *this;
49  }
50 
51  void print(){
52  for(int i=0; i<N; i++){
53  for (int j=0; j<N; j++)
54  cout << (*this)(i,j) << " ";
55  cout << endl;
56  }
57  }
58 
59 
60  private:
61 
62  T _data[NSQR];
63 
64 };
65 
66 template<class T>
68  T d = a(0,0)*a(1,1)-a(0,1)*a(1,0);
69  return d;
70 }
71 
72 template<class T>
74  T d = a(0,0)*(a(1,1)*a(2,2)-a(1,2)*a(2,1))
75  -a(0,1)*(a(1,0)*a(2,2) - a(1,2)*a(2,0))
76  +a(0,2)*(a(1,0)*a(2,1) - a(1,1)*a(2,0));
77  return d;
78 }
79 
80 template<class T,int N>
82 
83  T d(0.0);
84  T s(1.0);
85  int m, n;
87 
88  if (size == 1){
89  d = a(0,0);
90  return d;
91  }
92  else{
93  for(int k=0; k<size; k++){
94  m = 0;
95  n = 0;
96  for(int i=0; i<size; i++){
97  for(int j=0; j<size; j++){
98  b(i,j)=0.0;
99  if(i!=0&&j!=k){
100  b(m,n)=a(i,j);
101  if(n<(size-2))
102  n++;
103  else{
104  n=0;
105  m++;
106  }
107  }
108  }
109  }
110  d = d + s*(a(0,k)*determinant(b, size-1));
111  s=-1*s;
112  }
113  }
114  return d;
115 }
116 
117 template<class T>
119 
120  SquareMatrix<T,2> inv;
121  T d = determinant(a);
122  inv(0,0) = a(1,1) / d;
123  inv(0,1) = -a(0,1) / d;
124  inv(1,0) = -a(1,0) / d;
125  inv(1,1) = a(0,0) / d;
126 
127  return inv;
128 }
129 
130 
131 template<class T>
133 {
134  SquareMatrix<T,3> inv;
135  T d = determinant(a);
136 
137  inv(0,0) = (a(1,1)*a(2,2) - a(1,2)*a(2,1)) / d;
138  inv(0,1) = (a(0,2)*a(2,1) - a(0,1)*a(2,2)) / d;
139  inv(0,2) = (a(0,1)*a(1,2) - a(0,2)*a(1,1)) / d;
140  inv(1,0) = (a(1,2)*a(2,0) - a(1,0)*a(2,2)) / d;
141  inv(1,1) = (a(0,0)*a(2,2) - a(0,2)*a(2,0)) / d;
142  inv(1,2) = (a(0,2)*a(1,0) - a(0,0)*a(1,2)) / d;
143  inv(2,0) = (a(1,0)*a(2,1) - a(1,1)*a(2,0)) / d;
144  inv(2,1) = (a(0,1)*a(2,0) - a(0,0)*a(2,1)) / d;
145  inv(2,2) = (a(0,0)*a(1,1) - a(0,1)*a(1,0)) / d;
146 
147  return inv;
148 }
149 
150 template<class T, int N>
152 {
153  const T d = determinant(b, size);
154 
159 
160  int p, q, m, n, i, j;
161 
162  for(q=0; q<size; q++){
163  for(p=0; p<size; p++){
164  m=0;
165  n=0;
166  for(i=0; i<size; i++){
167  for(j=0; j<size; j++){
168  tmp(i,j)=0;
169  if(i!=q&&j!=p) {
170  tmp(m,n)=b(i,j);
171  if(n<(size-2))
172  n++;
173  else {
174  n=0;
175  m++;
176  }
177  }
178  }
179  }
180  fac(q,p)=pow(-1.0,q+p)*determinant(tmp,size-1);
181  }
182  }
183 
184  for(i=0; i<size; i++) {
185  for(j=0; j<size; j++){
186  trans(i,j)=fac(j,i);
187  }
188  }
189 
190  for(i=0; i<size; i++) {
191  for(j=0; j<size; j++){
192  a(i,j)=trans(i,j)/d;
193  }
194  }
195  return a;
196 }
197 /*
198 taken from http://www.physics.unlv.edu/~pang/cp_c.html 4.4
199 */
200 template<class T, int N>
202 {
203 
204  int indx[10];
205  T c[10];
208 
209  b = 1.0; //identity matrix
210  /*
211  for (int i = 0; i < size; i++)
212  cout <<i<<" a-matrix "<<a(i,0)<< " "<< a(i,1)<< " " <<a(i,2)<< " "<< a(i,3)<< " " <<a(i,4)<<endl;
213  */
214 
215  /* Initialize the index */
216  for (int i = 0; i < size; i++){indx[i] = i;}
217 
218  /* Find the rescaling factors, one from each row */
219  for (int i = 0; i < size; i++)
220  {
221  T c1 = 0;
222  for (int j = 0; j < size; j++)
223  {
224  if (fabs(a(i,j)) > c1)
225  c1 = fabs(a(i,j));
226  }
227  c[i] = c1;
228  }
229 
230 
231  /* Search the pivoting (largest) element from each column */
232  for (int j = 0; j < size-1; j++)
233  {
234  T pi1 = 0.0;
235  int pk=j;
236  int itmp;
237  T pi;
238  for (int i = j; i < size; i++)
239  {
240  pi = fabs(a(indx[i],j))/c[indx[i]];
241  if (pi > pi1)
242  {
243  pi1 = pi;
244  pk = i;
245  }
246  }
247  /* Interchange the rows via indx[] to record pivoting order */
248  itmp = indx[j];
249  indx[j] = indx[pk];
250  indx[pk] = itmp;
251  for (int i = j+1; i < size; i++)
252  {
253  T pj;
254  pj = a(indx[i],j)/a(indx[j],j);
255  /* Record pivoting ratios below the diagonal */
256  a(indx[i],j) = pj;
257  /* Modify other elements accordingly */
258  for (int k = j+1; k < size; k++)
259  {
260  a(indx[i],k) = a(indx[i],k)-pj*a(indx[j],k);
261  }
262  }
263  }
264 
265  /*
266  cout <<"indx "<< " re-scaling" <<endl;
267  for (int i = 0; i < size; i++)cout<< indx[i]<<" - "<<c[i] <<endl;
268  for (int i = 0; i < size; i++)
269  cout <<i<<" an-matrix "<<a(i,0)<< " "<< a(i,1)<< " " <<a(i,2)<< " "<< a(i,3)<< " " <<a(i,4)<<endl;
270  */
271 
272  for (int i = 0; i < size-1; i++)
273  {
274  for (int j = i+1; j < size; j++)
275  {
276  for (int k = 0; k < size; k++)
277  {
278  b(indx[j],k) = b(indx[j],k)-a(indx[j],i)*b(indx[i],k);
279  }
280  }
281  }
282  //backsubstitution
283  for (int col = 0; col < size; col++)
284  {
285  x(size-1,col) = b(indx[size-1],col)/a(indx[size-1],size-1);
286  for (int j = size-2; j >= 0; j = j-1)
287  {
288  x(j,col) = b(indx[j],col);
289  for (int k = j+1; k < size; k++)
290  {
291  x(j,col) = x(j,col)-a(indx[j],k)*x(k,col);
292  }
293  x(j,col) = x(j,col)/a(indx[j],j);
294  }
295  }
296  return x;
297 }
298 
299 #endif
SquareMatrix(const SquareMatrix &o)
SquareMatrix & operator=(const SquareMatrix &o)
SquareMatrix< T, N > inverseGauss(SquareMatrix< T, N > &a, int size)
T & operator()(int i, int j)
SquareMatrix< T, 2 > inverse(SquareMatrix< T, 2 > &a)
Tangent fabs(const Tangent &a)
Definition: Tangent.h:312
SquareMatrix(const T &s)
SquareMatrix & operator=(const T &s)
T determinant(SquareMatrix< T, 2 > &a)