def gauss_jordan(self):
        """Reduce :py:obj:`self` to row echelon form.

        :return:    Returns :py:obj:`self` in row echelon form for convenience.
        :rtype:     Matrix
        :raise:     Raises an :py:exc:`ValueError` if:
                        - the matrix rows < columns
                        - the matrix is not invertible
                    In this case :py:obj:`self` is not changed.
        """

        mArray = self.get_array(rowBased=False)
        width = self.get_width()
        height = self.get_height()
        if not height < width:
            raise ValueError("""Not enough rows""")
        # Start with complete matrix and remove in each iteration
        # the first row and the first column
        for offset in xrange(height):
            # Switch lines, if current first value is 0
            if mArray[offset][offset] == 0:
                for i in xrange(offset + 1, height):
                    if mArray[offset][i] != 0:
                        tmp = []
                        for j in xrange(offset, width):
                            tmp.append(mArray[j][offset])
                        # tmp = mArray[offset][offset:]
                        for j in xrange(offset, width):
                            mArray[j][offset] = mArray[j][i]
                            mArray[j][i] = tmp[j]
                        # mArray[offset][offset:] = mArray[i][offset:]
                        # mArray[i] = tmp
                        break

            currentRow = [mArray[j][offset] for j in xrange(offset, width)]
            devider = float(currentRow[0])
            # If no line is found with an value != 0
            # the matrix is not invertible
            if devider == 0:
                raise ValueError("Matrix is not invertible")
            transformedRow = []
            # Devide current row by first element of current row
            for value in currentRow:
                transformedRow.append(value / devider)
            # put transformed row back into matrix
            for j in xrange(offset, width):
                mArray[j][offset] = transformedRow[j - offset]
            # subtract multiples of the current row, from all remaining rows
            # in order to become a 0 at the current first column
            for i in xrange(offset + 1, height):
                multi = mArray[offset][i]
                for j in xrange(offset, width):
                    mArray[j][i] = mArray[j][i] - mArray[j][offset] * multi
        for i in xrange(1, height):
            # subtract multiples of the i-the row from all above rows
            for j in xrange(0, i):
                multi = mArray[i][j]
                for col in xrange(i, width):
                    mArray[col][j] = mArray[col][j] - mArray[col][i] * multi
        self.matrix = mArray
        return self