function LuDecomposition(matrix) {
        if (!(this instanceof LuDecomposition)) {
            return new LuDecomposition(matrix);
        }

        matrix = Matrix.Matrix.checkMatrix(matrix);

        var lu = matrix.clone(),
            rows = lu.rows,
            columns = lu.columns,
            pivotVector = new Array(rows),
            pivotSign = 1,
            i, j, k, p, s, t, v,
            LUrowi, LUcolj, kmax;

        for (i = 0; i < rows; i++) {
            pivotVector[i] = i;
        }

        LUcolj = new Array(rows);

        for (j = 0; j < columns; j++) {

            for (i = 0; i < rows; i++) {
                LUcolj[i] = lu[i][j];
            }

            for (i = 0; i < rows; i++) {
                LUrowi = lu[i];
                kmax = Math.min(i, j);
                s = 0;
                for (k = 0; k < kmax; k++) {
                    s += LUrowi[k] * LUcolj[k];
                }
                LUrowi[j] = LUcolj[i] -= s;
            }

            p = j;
            for (i = j + 1; i < rows; i++) {
                if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {
                    p = i;
                }
            }

            if (p !== j) {
                for (k = 0; k < columns; k++) {
                    t = lu[p][k];
                    lu[p][k] = lu[j][k];
                    lu[j][k] = t;
                }

                v = pivotVector[p];
                pivotVector[p] = pivotVector[j];
                pivotVector[j] = v;

                pivotSign = -pivotSign;
            }

            if (j < rows && lu[j][j] !== 0) {
                for (i = j + 1; i < rows; i++) {
                    lu[i][j] /= lu[j][j];
                }
            }
        }

        this.LU = lu;
        this.pivotVector = pivotVector;
        this.pivotSign = pivotSign;
    }
@private
Check that the provided vector is an array with the right length
@param {Matrix} matrix
@param {Array|Matrix} vector
@return {Array}
@throws {RangeError}