docs: function() {
      if (!this.isSquare() || this.isSingular()) { return null; }
      var ni = this.elements.length, ki = ni, i, j;
      var M = this.augment(Matrix.I(ni)).toRightTriangular();
      var np, kp = M.elements[0].length, p, els, divisor;
      var inverse_elements = [], new_element;
      // Matrix is non-singular so there will be no zeros on the diagonal
      // Cycle through rows from last to first
      do { i = ni - 1;
        // First, normalise diagonal elements to 1
        els = []; np = kp;
        inverse_elements[i] = [];
        divisor = M.elements[i][i];
        do { p = kp - np;
          new_element = M.elements[i][p] / divisor;
          els.push(new_element);
          // Shuffle of the current row of the right hand side into the results
          // array as it will not be modified by later runs through this loop
          if (p >= ki) { inverse_elements[i].push(new_element); }
        } while (--np);
        M.elements[i] = els;
        // Then, subtract this row from those above it to
        // give the identity matrix on the left hand side
        for (j = 0; j < i; j++) {
          els = []; np = kp;
          do { p = kp - np;
            els.push(M.elements[j][p] - M.elements[i][p] * M.elements[j][i]);
          } while (--np);
          M.elements[j] = els;
        }
      } while (--ni);
      return Matrix.create(inverse_elements);
    }