c++ 如何计算浮点型的大型矩阵的逆?

c2e8gylq  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(161)

我使用高斯消元法来求逆矩阵,矩阵是12 x 12。
当找到一个小矩阵时,结果是正确的,但当矩阵变得更大时,结果是不正确的。
我想这是一个浮点小数精度问题。
有没有一种方法可以使用单精度浮点小数来计算精确的逆矩阵?

  1. template<typename T = float>
  2. inline bool inverse(const MATRIX<Mtx_Rt, Mtx_Rt, T>& matrix, MATRIX<Mtx_Rt, Mtx_Rt, T>& out, void* pTmp) {
  3. if (matrix.GetNumOfRow() != matrix.GetNumOfCol())
  4. return false;
  5. MATRIX<Mtx_Rt, Mtx_Rt, T> augmentedMatrix = MATRIX<Mtx_Rt, Mtx_Rt, T>(matrix.GetNumOfRow(), matrix.GetNumOfCol() * 2, (T*)pTmp);
  6. memset(pTmp, 0, augmentedMatrix._sizeof());
  7. //[matrix | identity]
  8. for (int i = 0; i < matrix.GetNumOfRow(); i++) {
  9. for (int j = 0; j < matrix.GetNumOfCol(); j++)
  10. augmentedMatrix(i, j) = matrix(i, j);
  11. augmentedMatrix(i, i + matrix.GetNumOfRow()) = 1.0;
  12. }
  13. for (int i = 0; i < matrix.GetNumOfRow(); i++) {
  14. int pivotRow = i;
  15. for (int j = i + 1; j < matrix.GetNumOfRow(); j++)
  16. if (augmentedMatrix(j, i) > augmentedMatrix(pivotRow, i))
  17. pivotRow = j;
  18. for (int k = 0; k < 2 * matrix.GetNumOfRow(); k++) {
  19. T tmp = augmentedMatrix(i, k);
  20. augmentedMatrix(i, k) = augmentedMatrix(pivotRow, k);
  21. augmentedMatrix(pivotRow, k) = tmp;
  22. }
  23. for (int j = 0; j < matrix.GetNumOfRow(); j++)
  24. if (j != i) {
  25. T ratio;
  26. if (augmentedMatrix(i, i) != 0.0)
  27. ratio = augmentedMatrix(j, i) / augmentedMatrix(i, i);
  28. else
  29. return false;
  30. for (int k = 0; k < 2 * matrix.GetNumOfRow(); k++)
  31. augmentedMatrix(j, k) -= ratio * augmentedMatrix(i, k);
  32. }
  33. }
  34. for (int i = 0; i < matrix.GetNumOfRow(); i++) {
  35. T diagonalElement = augmentedMatrix(i, i);
  36. for (int j = 0; j < 2 * matrix.GetNumOfRow(); j++)
  37. augmentedMatrix(i, j) /= diagonalElement;
  38. }
  39. for (int i = 0; i < matrix.GetNumOfRow(); i++)
  40. for (int j = 0; j < matrix.GetNumOfCol(); j++)
  41. out(i, j) = augmentedMatrix(i, j + matrix.GetNumOfRow());
  42. return true;
  43. }
  44. //The following is the test data
  45. 0x000001DEBFA44B70 0.00901737064 0.00851101335 0.00903018098 0.00852382369 1.71711508e-06 1.07878850e-05 1.07854212e-05 -5.71605915e-06 0.00000000 0.00000000 0.00000000 0.00000000
  46. 0x000001DEBFA44BA0 0.00851101428 0.00921893492 0.00835073180 0.00905865245 0.000142186589 6.97691357e-05 6.96772186e-05 0.000119451797 0.00000000 0.00000000 0.00000000 0.00000000
  47. 0x000001DEBFA44BD0 0.00903018005 0.00835073087 0.00916963257 0.00849018339 -0.000121859746 -5.83902292e-05 -5.83116416e-05 -0.000103386286 0.00000000 0.00000000 0.00000000 0.00000000
  48. 0x000001DEBFA44C00 0.00852382462 0.00905865245 0.00849018339 0.00902501121 1.86097168e-05 5.91026037e-07 5.80158485e-07 2.17815614e-05 0.00000000 0.00000000 0.00000000 0.00000000
  49. 0x000001DEBFA44C30 1.71710417e-06 0.000142186575 -0.000121859761 1.86097132e-05 0.141640529 0.00000000 0.00000000 0.00000000 0.00899084471 0.00772444298 -0.00682374742 -0.00809014961
  50. 0x000001DEBFA44C60 1.07878877e-05 6.97691430e-05 -5.83902220e-05 5.91027856e-07 0.00000000 0.122075945 0.122108623 0.0703755319 0.0109803220 0.00996958558 -0.00884070992 -0.00985144638
  51. 0x000001DEBFA44C90 1.07854303e-05 6.96772186e-05 -5.83116343e-05 5.80155756e-07 0.00000000 0.122108623 0.122141339 0.0704018399 0.0109902890 0.00998063106 -0.00885062385 -0.00986028183
  52. 0x000001DEBFA44CC0 -5.71606142e-06 0.000119451797 -0.000103386286 2.17815686e-05 0.00000000 0.0703755319 0.0704018399 0.110758379 0.00697547942 0.00992908329 -0.00901818927 -0.00606458541
  53. 0x000001DEBFA44CF0 0.00000000 0.00000000 0.00000000 0.00000000 0.00899084471 0.0109803220 0.0109902890 0.00697547942 0.157142207 0.148548171 0.145359069 0.136765048
  54. 0x000001DEBFA44D20 0.00000000 0.00000000 0.00000000 0.00000000 0.00772444159 0.00996958464 0.00998063106 0.00992908329 0.148548156 0.157674491 0.136261418 0.145387754
  55. 0x000001DEBFA44D50 0.00000000 0.00000000 0.00000000 0.00000000 -0.00682374695 -0.00884070992 -0.00885062385 -0.00901818834 0.145359069 0.136261433 0.156348825 0.147251189
  56. 0x000001DEBFA44D80 0.00000000 0.00000000 0.00000000 0.00000000 -0.00809014961 -0.00985144544 -0.00986028090 -0.00606458541 0.136765033 0.145387754 0.147251174 0.155873895

字符串

y3bcpkx1

y3bcpkx11#

使用模板数值工具包[TNT] https://math.nist.gov/tnt/只需要很少的包含(没有库来构建)和下面的行代码来使用LU分解计算逆。它是一个模板类,所以你可以使用它与浮点。我用它来从10多年的两倍矩阵大小到2000。TNT还包括QR,特征值求解器和SVD。

  1. #include <tnt/jama_lu.h>
  2. template <class T>
  3. TNT::Array2D<T> inverse(const TNT::Array2D<T>& M)
  4. {
  5. TNT::Array2D<T> LU(M);
  6. int nline = dim1();
  7. int ncol = dim2();
  8. TNT::Array2D<T> input(nline, ncol);
  9. for (int i = 0; i < nline; i++)
  10. {
  11. for (int j = 0; j < ncol; j++)
  12. {
  13. if (i == j) input[i][j] = 1.;
  14. else input[i][j] = 0.;
  15. }
  16. }
  17. return LU.solve(input);
  18. }

字符串

展开查看全部

相关问题