ReducedRowEchelonForm.cc 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. // Reduced row echelon form via Gauss-Jordan elimination
  2. // with partial pivoting. This can be used for computing
  3. // the rank of a matrix.
  4. // Running time: O(n^3)
  5. // INPUT: a[][] = an nxn matrix
  6. // OUTPUT: rref[][] = an nxm matrix (stored in a[][])
  7. // returns rank of a[][]
  8. typedef double T;
  9. typedef vector<T> VT;
  10. typedef vector<VT> VVT;
  11. int rref(VVT &a) {
  12. int n = a.size();
  13. int m = a[0].size();
  14. int r = 0;
  15. for (int c = 0; c < m; c++) {
  16. int j = r;
  17. for (int i = r+1; i < n; i++)
  18. if (fabs(a[i][c]) > fabs(a[j][c])) j = i;
  19. if (fabs(a[j][c]) < EPS) continue;
  20. swap(a[j], a[r]);
  21. T s = 1.0 / a[r][c];
  22. for (int j = 0; j < m; j++) a[r][j] *= s;
  23. for (int i = 0; i < n; i++) if (i != r) {
  24. T t = a[i][c];
  25. for (int j = 0; j < m; j++) a[i][j] -= t * a[r][j];
  26. }
  27. r++;
  28. }
  29. return r;
  30. }
  31. int main() {
  32. const int n = 5;
  33. const int m = 4;
  34. double A[n][m] = { {16,2,3,13},{5,11,10,8},{9,7,6,12},{4,14,15,1},{13,21,21,13} };
  35. VVT a(n);
  36. for (int i = 0; i < n; i++)
  37. a[i] = VT(A[i], A[i] + n);
  38. int rank = rref (a);
  39. // expected: 4
  40. cout << "Rank: " << rank << endl;
  41. // expected: 1 0 0 1
  42. // 0 1 0 3
  43. // 0 0 1 -3
  44. // 0 0 0 2.78206e-15
  45. // 0 0 0 3.22398e-15
  46. cout << "rref: " << endl;
  47. for (int i = 0; i < 5; i++){
  48. for (int j = 0; j < 4; j++)
  49. cout << a[i][j] << ' ';
  50. cout << endl;
  51. }
  52. }