docs: function rrefInPlace (M, TOL = 1e-14) {
    const me = M.elements;
    // iterate through all rows to get to REF
    for (let i = 0; i < 3; ++i) {
      // search for largest in col and swap
      const k = findLargestInCol(M, i, i);
      if (k !== i) {
        swapRowsInPlace(M, i, k);
      }
      // scale and add current row to all rows underneath
      const largestElem = me[(i * 3) + i];
      if (!Compare.isZero(largestElem, TOL)) {
        scaleRow(M, i, 1.0 / largestElem);
        for (let j = i + 1; j < 3; ++j) {
          const scaleElem = me[(i * 3) + j];
          if (!Compare.isZero(scaleElem, TOL)) {
            scaleAndAddRow(M, i, j, -scaleElem);
          }
        }
      }
    }
    // iterate back through to get RREF since everything on diagonals should be 1 or 0
    for (let i = 2; i >= 0; --i) {
      const val = me[(i * 3) + i];
      if (!Compare.isZero(val, TOL)) {
        for (let j = i - 1; j >= 0; --j) {
          const scaleElem = me[(i * 3) + j];
          if (!Compare.isZero(scaleElem, TOL)) {
            scaleAndAddRow(M, i, j, -scaleElem);
          }
        }
      }
    }
    return M;
  }