public void Determinant()
        {
            MatrixD a = new MatrixD(new double[, ] {
                { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 0, 1, 2, 0 }, { 1, 0, 1, 0 }
            });

            LUDecompositionD d = new LUDecompositionD(a);

            Assert.AreEqual(false, d.IsNumericallySingular);
            Assert.IsTrue(Numeric.AreEqual(-24, d.Determinant()));

            MatrixD aPermuted = d.L * d.U;

            Assert.IsTrue(MatrixD.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 3)));
        }
        public void TestRandomRegularA()
        {
            RandomHelper.Random = new Random(1);

            for (int i = 0; i < 100; i++)
            {
                VectorD column1 = new VectorD(3);
                RandomHelper.Random.NextVectorD(column1, 1, 2);

                VectorD column2 = new VectorD(3);
                RandomHelper.Random.NextVectorD(column2, 1, 2);

                // Make linearly independent.
                if (column1 / column1[0] == column2 / column2[0])
                {
                    column2[0]++;
                }

                // Create linearly independent third column.
                VectorD column3 = column1 + column2;
                column3[1]++;

                // Create A.
                MatrixD a = new MatrixD(3, 3);
                a.SetColumn(0, column1);
                a.SetColumn(1, column2);
                a.SetColumn(2, column3);

                LUDecompositionD d = new LUDecompositionD(a);

                MatrixD aPermuted = d.L * d.U;
                Assert.IsTrue(MatrixD.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2)));
                aPermuted = d.L * d.U; // Repeat with to test cached values.
                Assert.IsTrue(MatrixD.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2)));

                Assert.AreEqual(false, d.IsNumericallySingular);

                // Check solving of linear equations.
                MatrixD b = new MatrixD(3, 2);
                RandomHelper.Random.NextMatrixD(b, 0, 1);

                MatrixD x  = d.SolveLinearEquations(b);
                MatrixD b2 = a * x;
                Assert.IsTrue(MatrixD.AreNumericallyEqual(b, b2, 0.01f));
            }
        }
        public void TestRandomRegularA()
        {
            RandomHelper.Random = new Random(1);

            for (int i = 0; i < 100; i++)
            {
                VectorD column1 = new VectorD(3);
                RandomHelper.Random.NextVectorD(column1, 1, 2);

                VectorD column2 = new VectorD(3);
                RandomHelper.Random.NextVectorD(column2, 1, 2);

                // Make linearly independent.
                if (column1 / column1[0] == column2 / column2[0])
                {
                    column2[0]++;
                }

                // Create linearly independent third column.
                VectorD column3 = column1 + column2;
                column3[1]++;

                // Create A.
                MatrixD a = new MatrixD(3, 3);
                a.SetColumn(0, column1);
                a.SetColumn(1, column2);
                a.SetColumn(2, column3);

                QRDecompositionD d = new QRDecompositionD(a);
                Assert.IsTrue(MatrixD.AreNumericallyEqual(a, d.Q * d.R));
                Assert.IsTrue(MatrixD.AreNumericallyEqual(a, d.Q * d.R)); // Second time with the cached values.
                Assert.AreEqual(true, d.HasNumericallyFullRank);

                // Check solving of linear equations.
                MatrixD b = new MatrixD(3, 2);
                RandomHelper.Random.NextMatrixD(b, 0, 1);

                MatrixD x  = d.SolveLinearEquations(b);
                MatrixD b2 = a * x;
                Assert.IsTrue(MatrixD.AreNumericallyEqual(b, b2, 0.01f));

                MatrixD h = d.H; // Just call this one to see if it runs through.
                h = d.H;         // Call it secont time to cover code with internal caching.
            }
        }
        public void TestMatricesWithFullRank()
        {
            MatrixD a = new MatrixD(new double[, ] {
                { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, -9 }
            });
            QRDecompositionD qr = new QRDecompositionD(a);

            Assert.AreEqual(true, qr.HasNumericallyFullRank);
            Assert.IsTrue(MatrixD.AreNumericallyEqual(a, qr.Q * qr.R));
            qr = new QRDecompositionD(a.Transposed);
            Assert.AreEqual(true, qr.HasNumericallyFullRank);
            Assert.IsTrue(MatrixD.AreNumericallyEqual(a.Transposed, qr.Q * qr.R));

            a = new MatrixD(new double[, ] {
                { 1, 2 }, { 4, 5 }, { 4, 5 }
            });
            qr = new QRDecompositionD(a);
            Assert.AreEqual(true, qr.HasNumericallyFullRank);
            Assert.IsTrue(MatrixD.AreNumericallyEqual(a, qr.Q * qr.R));

            MatrixD h = qr.H; // Just call this one to see if it runs through.
        }