您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

remez-matrix.h 2.6 KiB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. //
  2. // Lol Engine - Sample math program: Chebyshev polynomials
  3. //
  4. // Copyright: (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if !defined __REMEZ_MATRIX_H__
  11. #define __REMEZ_MATRIX_H__
  12. template<int N> struct Matrix
  13. {
  14. inline Matrix() {}
  15. Matrix(real x)
  16. {
  17. for (int j = 0; j < N; j++)
  18. for (int i = 0; i < N; i++)
  19. if (i == j)
  20. m[i][j] = x;
  21. else
  22. m[i][j] = 0;
  23. }
  24. /* Naive matrix inversion */
  25. Matrix<N> inv() const
  26. {
  27. Matrix a = *this, b((real)1.0);
  28. /* Inversion method: iterate through all columns and make sure
  29. * all the terms are 1 on the diagonal and 0 everywhere else */
  30. for (int i = 0; i < N; i++)
  31. {
  32. /* If the expected coefficient is zero, add one of
  33. * the other lines. The first we meet will do. */
  34. if ((double)a.m[i][i] == 0.0)
  35. {
  36. for (int j = i + 1; j < N; j++)
  37. {
  38. if ((double)a.m[i][j] == 0.0)
  39. continue;
  40. /* Add row j to row i */
  41. for (int n = 0; n < N; n++)
  42. {
  43. a.m[n][i] += a.m[n][j];
  44. b.m[n][i] += b.m[n][j];
  45. }
  46. break;
  47. }
  48. }
  49. /* Now we know the diagonal term is non-zero. Get its inverse
  50. * and use that to nullify all other terms in the column */
  51. real x = (real)1.0 / a.m[i][i];
  52. for (int j = 0; j < N; j++)
  53. {
  54. if (j == i)
  55. continue;
  56. real mul = x * a.m[i][j];
  57. for (int n = 0; n < N; n++)
  58. {
  59. a.m[n][j] -= mul * a.m[n][i];
  60. b.m[n][j] -= mul * b.m[n][i];
  61. }
  62. }
  63. /* Finally, ensure the diagonal term is 1 */
  64. for (int n = 0; n < N; n++)
  65. {
  66. a.m[n][i] *= x;
  67. b.m[n][i] *= x;
  68. }
  69. }
  70. return b;
  71. }
  72. void print() const
  73. {
  74. using std::printf;
  75. for (int j = 0; j < N; j++)
  76. {
  77. for (int i = 0; i < N; i++)
  78. printf("%9.5f ", (double)m[j][i]);
  79. printf("\n");
  80. }
  81. }
  82. real m[N][N];
  83. };
  84. #endif /* __REMEZ_MATRIX_H__ */