matrix.cc
上传用户:l56789
上传日期:2022-02-25
资源大小:2422k
文件大小:5k
源码类别:

图形图像处理

开发平台:

Matlab

  1. //-----------------------------------------------------------------------------
  2. // matrix.cc
  3. //-----------------------------------------------------------------------------
  4. #include "matrix.hh"
  5. #include <math.h>
  6. #include <iostream>
  7. #include <stdlib.h>
  8. using std::cerr;
  9. using std::endl;
  10. // Numerical Recipes functions (for matrix inversion and determinant)
  11. template <class T>
  12. void ludcmp(matrix<T>& a, int n, vector<int>& indx, T& d);
  13. template <class T>
  14. void lubksb(matrix<T>& a, int n, vector<int>& indx, vector<T>& b);
  15. //-----------------------------------------------------------------------------
  16. template <class T>
  17. matrix<T>::matrix(int nrow, int ncol, const T& value)
  18.     : data(nrow, vector<T>(ncol, value))
  19. {}
  20. //-----------------------------------------------------------------------------
  21. template <class T>
  22. matrix<T>::matrix(const matrix<T>& aMatrix)
  23.     :data(aMatrix.data.size()) 
  24. {
  25.     register int i, nrow = aMatrix.data.size();
  26.     // Copy data
  27.     for (i = 0; i < nrow; i++)
  28. data[i] = aMatrix.data[i];
  29. }
  30. //-----------------------------------------------------------------------------
  31. template <class T>
  32. matrix<T>& matrix<T>::operator = (const matrix<T>& aMatrix)
  33. {
  34.     register int i, nrow = aMatrix.data.size();
  35.   
  36.     if (this == &aMatrix)
  37. return *this;
  38.     if (data.size() != nrow)
  39. data = vector< vector<T> > (nrow);   // resize data
  40.   
  41.     // Copy data
  42.     for (i = 0; i < nrow; i++)
  43. data[i] = aMatrix.data[i];
  44.   
  45.     return *this;
  46. }
  47. //-----------------------------------------------------------------------------
  48. template <class T>
  49. matrix<T> matrix<T>::inv() const
  50. {
  51.     int n = data.size();
  52.     if ((n <= 0) || (n != data[0].size()))
  53.     {
  54. cerr << "Error: Non-square matrix in function matrix::inv()" 
  55.      << endl;
  56. exit(1);
  57.     }
  58.     matrix<T> tmp(*this);
  59.     matrix<T> res(n, n);
  60.     vector<T> col(n);
  61.     vector<int> indx(n);
  62.     T d;
  63.     // LU decompose
  64.     ludcmp(tmp, n, indx, d);
  65.     // Backsubstitution
  66.     for (int j = 0; j < n; j++)
  67.     {
  68. for (int i = 0; i < n; i++)
  69.     col[i] = 0.0;
  70. col[j] = 1.0;
  71. lubksb(tmp, n, indx, col);
  72. for (int i = 0; i < n; i++)
  73.     res[i][j] = col[i];
  74.     }
  75.     return res;
  76. }
  77. //-----------------------------------------------------------------------------
  78. template <class T>
  79. T matrix<T>::det() const
  80. {
  81.     int n = data.size();
  82.     if ((n <= 0) || (n != data[0].size()))
  83.     {
  84. cerr << "Error: Non-square matrix in function matrix::det()" 
  85.      << endl;
  86. exit(1);
  87.     }
  88.     matrix<T> tmp(*this);
  89.     vector<int> indx(n);
  90.     T d;
  91.     
  92.     ludcmp(tmp, n, indx, d); // LU decompose
  93.     for (int j = 0; j < n; j++)
  94. d *= tmp[j][j];
  95.     return d;
  96. }
  97. //-----------------------------------------------------------------------------
  98. // Numerical Recipes Routines (modified)
  99. //-----------------------------------------------------------------------------
  100. #define TINY 1.0e-20;
  101. // LU Decomposition
  102. template <class T>
  103. void ludcmp(matrix<T>& a, int n, vector<int>& indx, T& d)
  104. {
  105.     int i, imax, j, k;
  106.     T big, dum, sum, temp;
  107.     vector<T> vv(n);  // stores the implicit scaling of each row
  108.     d = 1.0;
  109.     for (i = 0; i < n; i++) 
  110.     {
  111. big = 0.0;
  112. for (j = 0; j < n; j++)
  113.     temp = (a[i][j] >= 0) ? a[i][j] : -a[i][j];
  114.     if (temp > big)
  115. big = temp;
  116. if (big == 0.0)
  117. {
  118.     cerr << "Error: Singular matrix in routine ludcmp" << endl;
  119.     return;
  120. }
  121. vv[i] = 1.0 / big;
  122.     }
  123.     for (j = 0; j < n; j++) 
  124.     {
  125. for (i = 0; i < j; i++) 
  126. {
  127.     sum = a[i][j];
  128.     for (k = 0; k < i; k++)
  129. sum -= a[i][k] * a[k][j];
  130.     a[i][j] = sum;
  131. }
  132. big = 0.0;
  133. for (i = j; i < n; i++) 
  134. {
  135.     sum = a[i][j];
  136.     for (k = 0; k < j; k++)
  137. sum -= a[i][k] * a[k][j];
  138.     a[i][j] = sum;
  139.     dum = (sum >= 0) ? sum : -sum;
  140.     dum *= vv[i];
  141.     if (dum >= big) 
  142.     {
  143. big = dum;
  144. imax = i;
  145.     }
  146. }
  147. if (j != imax) 
  148. {
  149.     for (k = 0; k < n; k++) 
  150.     {
  151. dum = a[imax][k];
  152. a[imax][k] = a[j][k];
  153. a[j][k] = dum;
  154.     }
  155.     d = -d;
  156.     vv[imax] = vv[j];
  157. }
  158. indx[j] = imax;
  159. if (a[j][j] == 0.0) a[j][j]=TINY;
  160. if (j != (n-1)) 
  161. {
  162.     dum = 1.0 / (a[j][j]);
  163.     for (i = j+1 ; i < n;i++) 
  164. a[i][j] *= dum;
  165. }
  166.     }
  167. }
  168. // LU forward substitution and backsubstitution
  169. template <class T>
  170. void lubksb(matrix<T>& a, int n, vector<int>& indx, vector<T>& b)
  171. {
  172.     int i, ii = -1, ip, j;
  173.     T sum;
  174.     for (i = 0; i < n; i++) 
  175.     {
  176. ip = indx[i];
  177. sum = b[ip];
  178. b[ip] = b[i];
  179. if (ii >= 0)
  180.     for (j = ii; j < i; j++)
  181. sum -= a[i][j] * b[j];
  182. else if (sum) ii = i;
  183. b[i] = sum;
  184.     }
  185.     for (i = n-1; i >= 0; i--) 
  186.     {
  187. sum = b[i];
  188. for (j = i+1; j < n; j++)
  189.     sum -= a[i][j] * b[j];
  190. b[i] = sum / a[i][i];
  191.     }
  192. }
  193. #undef TINY
  194. template class matrix<double>;