private Tuple<Vector, Matrix> doLUDecomposition(int which_matrix, Vector b) throws ArithmeticException
    {
        Double temp = 0d;
        Matrix U = clone();
        Matrix L = identity();
        
        // Reihenfolge der Vertauschung bei der Pivotstrategie(Permutationen)
        Vector lperm = new Vector();
        
        // Ergebnis ist [1, 2, 3, 4, ...] als Vektor
        for (int cellOfVector = 0; cellOfVector < rows; cellOfVector++)
        {
            lperm.set(cellOfVector, cellOfVector + 1d);
        }
        
        for (int row = 0; row < L.rows; row++)
        {
            // Pivotisierung + Gaussschritte, reduzierte Zeilenstufenform
            // if (MathLib.isPivotStrategy())
            // {
            // lperm = lperm.swapRows(row, pivotColumnStrategy(U, b, row ));
            // }
            
            for (int t = row; t < U.rows - 1; t++)
            {
                temp = U.values[t + 1][row] / U.values[row][row];
                
                for (int i = row; i < U.rows; i++)
                {
                    U.values[t + 1][i] = U.values[t + 1][i] - temp * U.values[row][i];
                }
                U.values[t + 1][row] = temp;
            }
        }
        
        for (int row = 0; row < L.rows; row++)
        { // Trenne Matizen U und L voneinander
            for (int col = 0; col < L.cols; col++)
            {
                if (row > col)
                {
                    L.values[row][col] = U.values[row][col];
                    U.values[row][col] = 0d;
                }
            }
        }
        
        if (which_matrix == 0)
        {
            return new Tuple<Vector, Matrix>(null, L);
        }
        if (which_matrix == 1)
        {
            return new Tuple<Vector, Matrix>(null, U);
        }
        else
        {
            return new Tuple<Vector, Matrix>(lperm, null);
        }
    }