ARTS  2.0.49
lin_alg.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2008 Claudia Emde <claudia.emde@dlr.de>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA.
17 */
18 
30 #include "lin_alg.h"
31 
32 /*===========================================================================
33  === External declarations
34  ===========================================================================*/
35 
36 #include <stdexcept>
37 #include <cmath>
38 #include "arts.h"
39 #include "make_vector.h"
40 #include "array.h"
41 #include "logic.h"
42 
44 
52 void
54  ArrayOfIndex& indx,
55  ConstMatrixView A)
56 {
57  Index imax = 0;
58  const Numeric TINY=1.0e-20;
59  Numeric big, dum, sum, temp, d;
60 
61  LU = A;
62  const Index dim = A.nrows();
63  assert(is_size(A,dim,dim)); //check, if A is quadratic
64 
65  Vector vv(dim); //stores implicit scaling of each row
66  d = 1.0;
67  for (Index i=0; i<dim; i++)
68  {
69  indx[i]= i;
70  big = 0.0;
71  for (Index j=0; j<dim; j++)
72  {
73  if ((temp = abs(LU(i,j))) > big)
74  big = temp;
75  }
76  if (big == 0.)
77  throw runtime_error("ludcmp: Matrix is singular");
78  vv[i] = 1.0/big; // save scaling
79  }
80 
81  for (Index j=0; j<dim; j++)
82  {
83  for (Index i=0; i<j; i++)
84  {
85  sum = LU(i,j);
86  for (Index k=0; k<i; k++)
87  sum -= LU(i,k)*LU(k,j);
88  LU(i,j) = sum;
89  }
90  big = 0.0;
91  for( Index i=j; i<dim; i++)
92  {
93  sum = LU(i,j);
94  for (Index k=0; k<j; k++)
95  sum -= LU(i,k)*LU(k,j);
96  LU(i,j) = sum;
97  if( (dum = vv[i]*fabs(sum)) >= big)
98  {
99  big = dum;
100  imax = i;
101  }
102  }
103  if (j!=imax)
104  {
105  for(Index k=0; k<dim; k++)
106  {
107  dum = LU(imax,k);
108  LU(imax,k) = LU(j,k);
109  LU(j,k) = dum;
110  }
111  d = -d;
112  vv[imax] = vv[j];
113  indx[j] = imax;
114  indx[imax] =j;
115  }
116 
117  if(LU(j,j) == 0.0) LU(j,j) = TINY;
118 
119  if (j != dim)
120  {
121  dum=1.0/LU(j,j);
122  for (Index i=j+1; i<dim; i++)
123  LU(i,j) *=dum;
124  }
125  }
126 }
127 
128 
129 
130 
131 
133 
143 void
145  ConstMatrixView LU,
146  ConstVectorView b,
147  const ArrayOfIndex& indx)
148 {
149  Index dim = LU.nrows();
150 
151  /* Check if the dimensions of the input matrix and vectors agree and if LU is a quadratic matrix.*/
152  assert(is_size(LU, dim, dim));
153  assert(is_size(b, dim));
154  assert(is_size(indx, dim));
155 
156 
157  for(Index i=0; i<dim; i++)
158  {
159  x[indx[i]] = b[i];
160  }
161 
162  for (Index i=0; i<dim; i++)
163  {
164  Numeric sum = x[i];
165  for (Index j=0; j<=i-1; j++)
166  sum -= LU(i,j)*x[j];
167  x[i] = sum;
168  }
169 
170  for(Index i=dim-1; i>=0; i--)
171  {
172  Numeric sum = x[i];
173  for (Index j=i+1; j<dim; j++)
174  sum -= LU(i,j)*x[j];
175  x[i] = sum/LU(i,i);
176  }
177 }
178 
179 
181 
192 void
194  ConstMatrixView A,
195  const Index& q)
196 {
197  Numeric A_norm_inf, c;
198  Numeric j;
199  const Index n = A.ncols();
200  Matrix D(n,n), N(n,n), X(n,n), cX(n,n,0.0), B(n,n,0.0);
201  Vector N_col_vec(n,0.), F_col_vec(n,0.);
202 
203  /*Check if A and F are a quadratic and of the same dimension. */
204  assert(is_size(A,n,n));
205  assert(is_size(F,n,n));
206 
207  A_norm_inf = norm_inf(A);
208 
209  // This formular is derived in the book by Golub and Van Loan.
210  j = 1 + floor(1./log(2.)*log(A_norm_inf));
211 
212  if(j<0) j=0.;
213  Index j_index = (Index)(j);
214 
215  // Scale matrix
216  F = A;
217  F /= pow(2,j);
218 
219  /* The higher q the more accurate is the computation,
220  see user guide for accuracy */
221  // Index q = 8;
222  Numeric q_n = (Numeric)(q);
223  id_mat(D);
224  id_mat(N);
225  id_mat(X);
226  c = 1.;
227 
228  for(Index k=0; k<q; k++)
229  {
230  Numeric k_n = (Numeric)(k+1);
231  c *= (q_n-k_n+1)/((2*q_n-k_n+1)*k_n);
232  mult(B,F,X); // X = F * X
233  X = B;
234  cX = X;
235  cX *= c; // cX = X*c
236  N += cX; // N = N + X*c
237  cX *= pow(-1,k_n); // cX = (-1)^k*c*X
238  D += cX; // D = D + (-1)^k*c*X
239  }
240 
241  /*Solve the equation system DF=N for F using LU decomposition,
242  use the backsubstitution routine for columns of N*/
243 
244  /* Now use X for the LU decomposition matrix of D.*/
245  ArrayOfIndex indx(n);
246 
247  ludcmp(X, indx, D);
248 
249  for(Index i=0; i<n; i++)
250  {
251  N_col_vec = N(joker,i); // extract column vectors of N
252  lubacksub(F_col_vec, X, N_col_vec, indx);
253  F(joker,i) = F_col_vec; // construct F matrix from column vectors
254  }
255 
256  /* The square of F gives the result. */
257  for(Index k=0; k<j_index; k++)
258  {
259  mult(B,F,F); // F = F^2
260  F = B;
261  }
262 
263 }
264 
265 
267 
276 {
277  Numeric norm_inf = 0;
278 
279  for(Index j=0; j<A.nrows(); j++)
280  {
281  Numeric row_sum = 0;
282  //Calculate the row sum for all rows
283  for(Index i=0; i<A.ncols(); i++)
284  row_sum += abs(A(i,j));
285  //Pick out the row with the highest row sum
286  if( norm_inf < row_sum)
287  norm_inf = row_sum;
288  }
289  return norm_inf;
290 }
291 
292 
294 
297 void
299 {
300 
301  const Index n = I.ncols();
302  assert(n == I.nrows());
303 
304  I = 0;
305  for(Index i=0; i<n; i++)
306  I(i,i) = 1.;
307 }
308 
309 
Matrix
The Matrix class.
Definition: matpackI.h:767
MatrixView
The MatrixView class.
Definition: matpackI.h:668
id_mat
void id_mat(MatrixView I)
Identity Matrix.
Definition: lin_alg.cc:298
joker
const Joker joker
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:796
temp
#define temp
Definition: continua.cc:13409
array.h
This file contains the definition of Array.
matrix_exp
void matrix_exp(MatrixView F, ConstMatrixView A, const Index &q)
Exponential of a Matrix.
Definition: lin_alg.cc:193
q
#define q
Definition: continua.cc:14103
is_size
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
Definition: logic.cc:90
ludcmp
void ludcmp(MatrixView LU, ArrayOfIndex &indx, ConstMatrixView A)
LU decomposition.
Definition: lin_alg.cc:53
Array< Index >
mult
void mult(VectorView y, const ConstMatrixView &M, const ConstVectorView &x)
Matrix Vector multiplication.
Definition: matpackI.cc:1607
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:802
abs
#define abs(x)
Definition: continua.cc:13094
VectorView
The VectorView class.
Definition: matpackI.h:373
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
lin_alg.h
Linear algebra functions.
make_vector.h
The class MakeVector is a special kind of Vector that can be initialized explicitly from one or more ...
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:591
N
#define N
Definition: rng.cc:195
logic.h
Header file for logic.cc.
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
Vector
The Vector class.
Definition: matpackI.h:555
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:300
norm_inf
Numeric norm_inf(ConstMatrixView A)
Maximum absolute row sum norm.
Definition: lin_alg.cc:275
lubacksub
void lubacksub(VectorView x, ConstMatrixView LU, ConstVectorView b, const ArrayOfIndex &indx)
LU backsubstitution.
Definition: lin_alg.cc:144
arts.h
The global header file for ARTS.