|
- //
- // Lol Engine - Sample math program: Chebyshev polynomials
- //
- // Copyright: (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the Do What The Fuck You Want To
- // Public License, Version 2, as published by Sam Hocevar. See
- // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
- //
-
- #if !defined __REMEZ_MATRIX_H__
- #define __REMEZ_MATRIX_H__
-
- template<int N> struct Matrix
- {
- inline Matrix() {}
-
- Matrix(real x)
- {
- for (int j = 0; j < N; j++)
- for (int i = 0; i < N; i++)
- if (i == j)
- m[i][j] = x;
- else
- m[i][j] = 0;
- }
-
- /* Naive matrix inversion */
- Matrix<N> inv() const
- {
- Matrix a = *this, b((real)1.0);
-
- /* Inversion method: iterate through all columns and make sure
- * all the terms are 1 on the diagonal and 0 everywhere else */
- for (int i = 0; i < N; i++)
- {
- /* If the expected coefficient is zero, add one of
- * the other lines. The first we meet will do. */
- if ((double)a.m[i][i] == 0.0)
- {
- for (int j = i + 1; j < N; j++)
- {
- if ((double)a.m[i][j] == 0.0)
- continue;
- /* Add row j to row i */
- for (int n = 0; n < N; n++)
- {
- a.m[n][i] += a.m[n][j];
- b.m[n][i] += b.m[n][j];
- }
- break;
- }
- }
-
- /* Now we know the diagonal term is non-zero. Get its inverse
- * and use that to nullify all other terms in the column */
- real x = (real)1.0 / a.m[i][i];
- for (int j = 0; j < N; j++)
- {
- if (j == i)
- continue;
- real mul = x * a.m[i][j];
- for (int n = 0; n < N; n++)
- {
- a.m[n][j] -= mul * a.m[n][i];
- b.m[n][j] -= mul * b.m[n][i];
- }
- }
-
- /* Finally, ensure the diagonal term is 1 */
- for (int n = 0; n < N; n++)
- {
- a.m[n][i] *= x;
- b.m[n][i] *= x;
- }
- }
-
- return b;
- }
-
- void print() const
- {
- using std::printf;
-
- for (int j = 0; j < N; j++)
- {
- for (int i = 0; i < N; i++)
- printf("%9.5f ", (double)m[j][i]);
- printf("\n");
- }
- }
-
- real m[N][N];
- };
-
- #endif /* __REMEZ_MATRIX_H__ */
|