Decompose() публичный Метод

Performs Doolittle decomposition with partial pivoting and returns a combined LU matrix
public Decompose ( int &permutationArray, int &toggle ) : Matrix
permutationArray int Keeps track of how the matrices have been rearranged during the calculation
toggle int is +1 or -1 (even or odd)
Результат Matrix
        public void Matrix_DecomposeTest3_DifferentSigns()
        {
            Matrix matrixA = new Matrix(9,9);

            //Set up matrix A
            double[] row1OfMatrixA = { 3, 0, 0, -7, 0, 0, 0, 0, 0 };
            double[] row2OfMatrixA = { 0, 1, 8, 0, -4, 2, 0, 0, 0 };
            double[] row3OfMatrixA = { 0, 2, 8, 0, -9, 3, 0, 0, 0 };
            double[] row4OfMatrixA = { -5, 0, 0, 4, 0, 7, -1, 0, 3 };
            double[] row5OfMatrixA = { 0, -3, -7, 0, 7, -8, 0, -3, 0 };
            double[] row6OfMatrixA = { 0, 7, 2, 5, -3, 7, -2, 0, 4 };
            double[] row7OfMatrixA = { 0, 0, 0, -2, 0, -8, 4, 0, 7 };
            double[] row8OfMatrixA = { 0, 0, 0, 0, -9, 0, 0, 3, 0 };
            double[] row9OfMatrixA = { 0, 0, 0, 1, 0, 4, 7, 0, 6 };

            matrixA.SetRow(0, row1OfMatrixA);
            matrixA.SetRow(1, row2OfMatrixA);
            matrixA.SetRow(2, row3OfMatrixA);
            matrixA.SetRow(3, row4OfMatrixA);
            matrixA.SetRow(4, row5OfMatrixA);
            matrixA.SetRow(5, row6OfMatrixA);
            matrixA.SetRow(6, row7OfMatrixA);
            matrixA.SetRow(7, row8OfMatrixA);
            matrixA.SetRow(8, row9OfMatrixA);



            //The LUP Decomposition

            //Correct L Part
            Matrix correctLPartOfLUPDecomposition = new Matrix(9,9);

            double[] row1OfLMatrix = { 1, 0, 0, 0, 0, 0, 0, 0, 0 };
            double[] row2OfLMatrix = { 0, 1, 0, 0, 0, 0, 0, 0, 0 };
            double[] row3OfLMatrix = { 0, .143, 1, 0, 0, 0, 0, 0, 0 };
            double[] row4OfLMatrix = { -.6, 0, 0, 1, 0, 0, 0, 0, 0 };
            double[] row5OfLMatrix = { 0, 0, 0, 0, 1, 0, 0, 0, 0 };
            double[] row6OfLMatrix = { 0, 0, 0, .435, 0, 1, 0, 0, 0 };
            double[] row7OfLMatrix = { 0, 0, 0, -.217, 0, -.5, 1, 0, 0 };
            double[] row8OfLMatrix = { 0, -.429, -.796, -.342, -.319, .282, -.226, 1, 0 };
            double[] row9OfLMatrix = { 0.000, 0.286, 0.963, 0.161, 0.523, 0.065, 0.013, 0.767, 1.000 };

            correctLPartOfLUPDecomposition.SetRow(0, row1OfLMatrix);
            correctLPartOfLUPDecomposition.SetRow(1, row2OfLMatrix);
            correctLPartOfLUPDecomposition.SetRow(2, row3OfLMatrix);
            correctLPartOfLUPDecomposition.SetRow(3, row4OfLMatrix);
            correctLPartOfLUPDecomposition.SetRow(4, row5OfLMatrix);
            correctLPartOfLUPDecomposition.SetRow(5, row6OfLMatrix);
            correctLPartOfLUPDecomposition.SetRow(6, row7OfLMatrix);
            correctLPartOfLUPDecomposition.SetRow(7, row8OfLMatrix);
            correctLPartOfLUPDecomposition.SetRow(8, row9OfLMatrix);

            //Correct U Part
            Matrix correctUPartOfLUPDecomposition = new Matrix(9,9);

            double[] row1OfUMatrix = { -5.000, 0.000, 0.000, 4.000, 0.000, 7.000, -1.000, 0.000, 3.000 };
            double[] row2OfUMatrix = { 0.000, 7.000, 2.000, 5.000, -3.000, 7.000, -2.000, 0.000, 4.000 };
            double[] row3OfUMatrix = { 0.000, 0.000, 7.714, -0.714, -3.571, 1.000, 0.286, 0.000, -0.571 };
            double[] row4OfUMatrix = { 0.000, 0.000, 0.000, -4.600, 0.000, 4.200, -0.600, 0.000, 1.800 };
            double[] row5OfUMatrix = { 0.000, 0.000, 0.000, 0.000, -9.000, 0.000, 0.000, 3.000, 0.000 };
            double[] row6OfUMatrix = { 0.000, 0.000, 0.000, 0.000, 0.000, -9.826, 4.261, 0.000, 6.217 };
            double[] row7OfUMatrix = { 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 9.000, 0.000, 9.500 };
            double[] row8OfUMatrix = { 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -2.043, 2.272 };
            double[] row9OfUMatrix = { 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -3.153 };

            correctUPartOfLUPDecomposition.SetRow(0, row1OfUMatrix);
            correctUPartOfLUPDecomposition.SetRow(1, row2OfUMatrix);
            correctUPartOfLUPDecomposition.SetRow(2, row3OfUMatrix);
            correctUPartOfLUPDecomposition.SetRow(3, row4OfUMatrix);
            correctUPartOfLUPDecomposition.SetRow(4, row5OfUMatrix);
            correctUPartOfLUPDecomposition.SetRow(5, row6OfUMatrix);
            correctUPartOfLUPDecomposition.SetRow(6, row7OfUMatrix);
            correctUPartOfLUPDecomposition.SetRow(7, row8OfUMatrix);
            correctUPartOfLUPDecomposition.SetRow(8, row9OfUMatrix);

            //Calculate values for the above
            int[] permutationArray;
            int toggleValue;
            Matrix decomposeResult = matrixA.Decompose(out permutationArray, out toggleValue);

            Matrix calculatedLPartOfLUPDecomposition = decomposeResult.ExtractLower();
            Matrix calculatedUPartOfLUPDecomposition = decomposeResult.ExtractUpper();

            //Compare the two matrices
            double tolerance = .001;
            Matrix LDifferenceMatrix = calculatedLPartOfLUPDecomposition - correctLPartOfLUPDecomposition;
            Matrix UDifferenceMatrix = calculatedUPartOfLUPDecomposition - correctUPartOfLUPDecomposition;

            for (int i = 0; i < LDifferenceMatrix.NumberOfRows; i++)
            {
                for (int j = 0; j < LDifferenceMatrix.NumberOfColumns; j++)
                {
                    (Math.Abs(LDifferenceMatrix.GetElement(i, j)) < tolerance).Should().BeTrue();
                }
            }

            for (int i = 0; i < UDifferenceMatrix.NumberOfRows; i++)
            {
                for (int j = 0; j < UDifferenceMatrix.NumberOfColumns; j++)
                {
                    (Math.Abs(UDifferenceMatrix.GetElement(i, j)) < tolerance).Should().BeTrue();
                }
            }



        }
        public void Matrix_DecomposeComplicatedTest()
        {
            Matrix matrixA = new Matrix(4, 4);

            //Set up matrix A
            double[] columnOneOfMatrixA = { 3, 1, 2, 5 };
            double[] columnTwoOfMatrixA = { 7, 8, 1, 4 };
            double[] columnThreeOfMatrixA = { 2, 4, 9, 7 };
            double[] columnFourOfMatrixA = { 5, 2, 3, 1 };

            matrixA.SetColumn(0, columnOneOfMatrixA);
            matrixA.SetColumn(1, columnTwoOfMatrixA);
            matrixA.SetColumn(2, columnThreeOfMatrixA);
            matrixA.SetColumn(3, columnFourOfMatrixA);

            //The LUP Decomposition

            //Correct L Part
            Matrix correctLPartOfLUPDecomposition = new Matrix(4, 4);

            double[] columnOneOfLMatrix = { 1,0.2,0.4,0.6 };
            double[] columnTwoOfLMatrix = { 0, 1, -0.083, 0.639 };
            double[] columnThreeOfLMatrix = { 0, 0, 1, -0.602 };
            double[] columnFourOfLMatrix = { 0,0,0,1 };

            correctLPartOfLUPDecomposition.SetColumn(0, columnOneOfLMatrix);
            correctLPartOfLUPDecomposition.SetColumn(1, columnTwoOfLMatrix);
            correctLPartOfLUPDecomposition.SetColumn(2, columnThreeOfLMatrix);
            correctLPartOfLUPDecomposition.SetColumn(3, columnFourOfLMatrix);

            //Correct U Part
            Matrix correctUPartOfLUPDecomposition = new Matrix(4, 4);

            double[] columnOneOfUMatrix = { 5, 0,0,0 };
            double[] columnTwoOfUMatrix = { 4, 7.2, 0,0 };
            double[] columnThreeOfUMatrix = { 7, 2.6, 6.417, 0 };
            double[] columnFourOfUMatrix = { 1, 1.8, 2.75, 4.905 };

            correctUPartOfLUPDecomposition.SetColumn(0, columnOneOfUMatrix);
            correctUPartOfLUPDecomposition.SetColumn(1, columnTwoOfUMatrix);
            correctUPartOfLUPDecomposition.SetColumn(2, columnThreeOfUMatrix);
            correctUPartOfLUPDecomposition.SetColumn(3, columnFourOfUMatrix);

            //The other 2 output variables are a permutation array and the toggle value
            int[] correctPermutationArray = { 3, 1, 2, 0 };
            int correctToggleValue = -1;


            //Calculate values for the above
            int[] permutationArray;
            int toggleValue;

            Matrix decomposeResult = matrixA.Decompose(out permutationArray, out toggleValue);

            Matrix calculatedLPartOfLUPDecomposition = decomposeResult.ExtractLower();
            Matrix calculatedUPartOfLUPDecomposition = decomposeResult.ExtractUpper();
            
            //Check all the variables
            permutationArray.ShouldBeEquivalentTo(correctPermutationArray);
            toggleValue.ShouldBeEquivalentTo(correctToggleValue);

            //Compare the two matrices

            double tolerance = .001;
            Matrix LDifferenceMatrix = calculatedLPartOfLUPDecomposition - correctLPartOfLUPDecomposition;
            Matrix UDifferenceMatrix = calculatedUPartOfLUPDecomposition - correctUPartOfLUPDecomposition;

            for (int i = 0; i < LDifferenceMatrix.NumberOfRows; i++)
            {
                for (int j = 0; j < LDifferenceMatrix.NumberOfColumns; j++)
                {
                    (Math.Abs(LDifferenceMatrix.GetElement(i, j)) < tolerance).Should().BeTrue();
                }
            }

            for (int i = 0; i < UDifferenceMatrix.NumberOfRows; i++)
            {
                for (int j = 0; j < UDifferenceMatrix.NumberOfColumns; j++)
                {
                    (Math.Abs(UDifferenceMatrix.GetElement(i, j)) < tolerance).Should().BeTrue();
                }
            }
       
        }