| 287 | } |
| 288 | |
| 289 | bool InvertMatrix(const Matrix& input, Matrix& Minv) |
| 290 | { |
| 291 | // Very straightforward implementation of |
| 292 | // Gauss-Jordan elimination to invert a matrix. |
| 293 | // Returns true if successful |
| 294 | |
| 295 | wxASSERT(input.Rows() == input.Cols()); |
| 296 | auto N = input.Rows(); |
| 297 | |
| 298 | Matrix M = input; |
| 299 | Minv = IdentityMatrix(N); |
| 300 | |
| 301 | // Do the elimination one column at a time |
| 302 | for(unsigned i = 0; i < N; i++) { |
| 303 | // Pivot the row with the largest absolute value in |
| 304 | // column i, into row i |
| 305 | double absmax = 0.0; |
| 306 | unsigned int argmax = 0; |
| 307 | |
| 308 | for(unsigned j = i; j < N; j++) |
| 309 | if (fabs(M[j][i]) > absmax) { |
| 310 | absmax = fabs(M[j][i]); |
| 311 | argmax = j; |
| 312 | } |
| 313 | |
| 314 | // If no row has a nonzero value in that column, |
| 315 | // the matrix is singular and we have to give up. |
| 316 | if (absmax == 0) |
| 317 | return false; |
| 318 | |
| 319 | if (i != argmax) { |
| 320 | M.SwapRows(i, argmax); |
| 321 | Minv.SwapRows(i, argmax); |
| 322 | } |
| 323 | |
| 324 | // Divide this row by the value of M[i][i] |
| 325 | double factor = 1.0 / M[i][i]; |
| 326 | M[i] = M[i] * factor; |
| 327 | Minv[i] = Minv[i] * factor; |
| 328 | |
| 329 | // Eliminate the rest of the column |
| 330 | for(unsigned j = 0; j < N; j++) { |
| 331 | if (j == i) |
| 332 | continue; |
| 333 | if (fabs(M[j][i]) > 0) { |
| 334 | // Subtract a multiple of row i from row j |
| 335 | factor = M[j][i]; |
| 336 | for(unsigned k = 0; k < N; k++) { |
| 337 | M[j][k] -= (M[i][k] * factor); |
| 338 | Minv[j][k] -= (Minv[i][k] * factor); |
| 339 | } |
| 340 | } |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | return true; |
| 345 | } |
no test coverage detected