HermesCommon  3.0
dense_matrix_operations.cpp
Go to the documentation of this file.
1 // This file is part of HermesCommon
2 //
3 // Copyright (c) 2009 hp-FEM group at the University of Nevada, Reno (UNR).
4 // Email: hpfem-group@unr.edu, home page: http://www.hpfem.org/.
5 //
6 // Hermes2D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published
8 // by the Free Software Foundation; either version 2 of the License,
9 // or (at your option) any later version.
10 //
11 // Hermes2D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with Hermes2D; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "exceptions.h"
24 #include "util/memory_handling.h"
25 
26 namespace Hermes
27 {
28  namespace Algebra
29  {
30  namespace DenseMatrixOperations
31  {
32  template<typename T, typename Int>
33  void ludcmp(T **a, Int n, Int *indx, double *d)
34  {
35  Int i, imax = 0, j, k;
36  T big, dum, sum, temp;
37  T *vv = malloc_with_check<T>(n);
38 
39  *d = 1.0;
40  for (i = 0; i < n; i++)
41  {
42  big = 0.0;
43  for (j = 0; j < n; j++)
44  {
45  temp = a[i][j];
46  if (std::abs(temp) > std::abs(big))
47  big = temp;
48  }
49  if (big == 0.0)
50  {
51  free_with_check(vv);
52  throw Exceptions::Exception("Singular matrix in routine LUDCMP!");
53  }
54  vv[i] = 1.0 / big;
55  }
56  for (j = 0; j < n; j++)
57  {
58  for (i = 0; i < j; i++)
59  {
60  sum = a[i][j];
61  for (k = 0; k < i; k++) sum -= a[i][k] * a[k][j];
62  a[i][j] = sum;
63  }
64  big = 0.0;
65  for (i = j; i < n; i++)
66  {
67  sum = a[i][j];
68  for (k = 0; k < j; k++) sum -= a[i][k] * a[k][j];
69  a[i][j] = sum;
70  dum = vv[i] * std::abs(sum);
71  if (std::abs(dum) >= std::abs(big))
72  {
73  big = dum;
74  imax = i;
75  }
76  }
77  if (j != imax)
78  {
79  for (k = 0; k < n; k++)
80  {
81  dum = a[imax][k];
82  a[imax][k] = a[j][k];
83  a[j][k] = dum;
84  }
85  *d = -(*d);
86  vv[imax] = vv[j];
87  }
88  indx[j] = imax;
89  if (a[j][j] == 0.0) a[j][j] = 1.0e-20;
90  if (j != n - 1)
91  {
92  dum = 1.0 / (a[j][j]);
93  for (i = j + 1; i < n; i++) a[i][j] *= dum;
94  }
95  }
96  free_with_check(vv);
97  }
98 
99  template<typename T, typename S, typename Int>
100  void lubksb(T **a, Int n, Int *indx, S *b)
101  {
102  Int ip, j;
103  int i;
104  S sum;
105 
106  for (i = 0; i < n; i++)
107  {
108  ip = indx[i];
109  sum = b[ip];
110  b[ip] = b[i];
111  for (j = 0; j < i; j++)
112  sum = sum - a[i][j] * b[j];
113  b[i] = sum;
114  }
115  for (i = n - 1; i >= 0; i--)
116  {
117  sum = b[i];
118  for (j = i + 1; j < n; j++)
119  sum -= a[i][j] * b[j];
120  b[i] = sum / a[i][i];
121  }
122  }
123 
124  template<typename T, typename Int>
125  void choldc(T **a, Int n, T p[])
126  {
127  Int i, j, k;
128  for (i = 0; i < n; i++)
129  {
130  for (j = i; j < n; j++)
131  {
132  T sum = a[i][j];
133  k = i;
134  while (k > 0)
135  {
136  sum -= a[i][k - 1] * a[j][k - 1];
137  k--;
138  }
139  if (i == j)
140  {
141  if ((std::complex<double>(sum)).real() <= 0.0)
142  throw Exceptions::Exception("CHOLDC failed!");
143  else p[i] = sqrt(sum);
144  }
145  else a[j][i] = sum / p[i];
146  }
147  }
148  }
149 
150  template HERMES_API void ludcmp<double, int>(double **a, int n, int *indx, double *d);
151  template HERMES_API void ludcmp<std::complex<double>, int>(std::complex<double> **a, int n, int *indx, double *d);
152 
153  template HERMES_API void ludcmp<double, unsigned short>(double **a, unsigned short n, unsigned short *indx, double *d);
154  template HERMES_API void ludcmp<std::complex<double>, unsigned short>(std::complex<double> **a, unsigned short n, unsigned short *indx, double *d);
155 
156  template HERMES_API void ludcmp<double, unsigned char>(double **a, unsigned char n, unsigned char *indx, double *d);
157  template HERMES_API void ludcmp<std::complex<double>, unsigned char>(std::complex<double> **a, unsigned char n, unsigned char *indx, double *d);
158 
159  template HERMES_API void lubksb<double, std::complex<double>, int>(double **a, int n, int *indx, std::complex<double> *d);
160  template HERMES_API void lubksb<double, double, int>(double **a, int n, int *indx, double *d);
161  template HERMES_API void lubksb<std::complex<double>, std::complex<double>, int>(std::complex<double> **a, int n, int *indx, std::complex<double> *d);
162 
163  template HERMES_API void lubksb<double, std::complex<double>, unsigned short>(double **a, unsigned short n, unsigned short *indx, std::complex<double> *d);
164  template HERMES_API void lubksb<double, double, unsigned short>(double **a, unsigned short n, unsigned short *indx, double *d);
165  template HERMES_API void lubksb<std::complex<double>, std::complex<double>, unsigned short>(std::complex<double> **a, unsigned short n, unsigned short *indx, std::complex<double> *d);
166 
167  template HERMES_API void lubksb<double, std::complex<double>, unsigned char>(double **a, unsigned char n, unsigned char *indx, std::complex<double> *d);
168  template HERMES_API void lubksb<double, double, unsigned char>(double **a, unsigned char n, unsigned char *indx, double *d);
169  template HERMES_API void lubksb<std::complex<double>, std::complex<double>, unsigned char>(std::complex<double> **a, unsigned char n, unsigned char *indx, std::complex<double> *d);
170 
171  template HERMES_API void choldc<double, int>(double **a, int n, double p[]);
172  template HERMES_API void choldc<std::complex<double>, int>(std::complex<double> **a, int n, std::complex<double> p[]);
173 
174  template HERMES_API void choldc<double, unsigned short>(double **a, unsigned short n, double p[]);
175  template HERMES_API void choldc<std::complex<double>, unsigned short>(std::complex<double> **a, unsigned short n, std::complex<double> p[]);
176 
177  template HERMES_API void choldc<double, unsigned char>(double **a, unsigned char n, double p[]);
178  template HERMES_API void choldc<std::complex<double>, unsigned char>(std::complex<double> **a, unsigned char n, std::complex<double> p[]);
179  }
180  }
181 }
HERMES_API void ludcmp(T **a, Int n, Int *indx, double *d)
General namespace for the Hermes library.
Exception interface Basically a std::exception, but with a constructor with string and with print_msg...
Definition: exceptions.h:49
File containing common definitions, and basic global enums etc. for HermesCommon. ...
File containing definition of exceptions classes.
HERMES_API void choldc(T **a, Int n, T p[])
Dense (small) simply stored matrix operations.
HERMES_API void lubksb(T **a, Int n, Int *indx, S *b)