public void IRID90_CholeskySolve() { Matrix i = Matrix.Identity(3, 3); double[][] pvals1 = { new double[] { 1.0, 1.0, 1.0 }, new double[] { 1.0, 2.0, 3.0 }, new double[] { 1.0, 3.0, 6.0 } }; Matrix m1 = new Matrix(pvals1); CholeskyDecomposition cd1 = new CholeskyDecomposition(m1); Matrix inv1a = cd1.Solve(i); Matrix test1a = m1 * inv1a; NumericAssert.AreAlmostEqual(i, test1a, "1A"); Matrix inv1b = m1.Inverse(); NumericAssert.AreAlmostEqual(inv1a, inv1b, "1B"); double[][] pvals2 = { new double[] { 25, -5, 10 }, new double[] { -5, 17, 10 }, new double[] { 10, 10, 62 } }; Matrix m2 = new Matrix(pvals2); CholeskyDecomposition cd2 = new CholeskyDecomposition(m2); Matrix inv2a = cd2.Solve(i); Matrix test2a = m2 * inv2a; NumericAssert.AreAlmostEqual(i, test2a, "2A"); Matrix inv2b = m2.Inverse(); NumericAssert.AreAlmostEqual(inv2a, inv2b, "2B"); }
public double Distance(double[] x, double[] y) { double[] d = new double[x.Length]; for (int i = 0; i < x.Length; i++) { d[i] = x[i] - y[i]; } double[] z; if (svd != null) { z = svd.Solve(d); } else if (chol != null) { z = chol.Solve(d); } else { z = precision.Dot(d); } double sum = 0.0; for (int i = 0; i < d.Length; i++) { sum += d[i] * z[i]; } return(Math.Abs(sum)); }
/// <summary> /// Gets the probability density function (pdf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// <param name="x">A single point in the distribution range. For a /// univariate distribution, this should be a single /// double value. For a multivariate distribution, /// this should be a double array.</param> /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution. /// </returns> /// <remarks> /// The Probability Density Function (PDF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> public override double ProbabilityDensityFunction(params double[] x) { if (x.Length != Dimension) { throw new DimensionMismatchException("x", "The vector should have the same dimension as the distribution."); } double[] z = x.Subtract(mean); double[] a = chol.Solve(z); double b = a.InnerProduct(z); // Original code: // double r = constant * System.Math.Exp(-b/2); // Let lnconstant = log( constant ) // // r = constant * exp( b/2 ) // // r = exp(log(constant) * exp( b/2 ) // r = exp(lnconstant) * exp( b/2 ) // r = exp( lnconstant + b/2 ) // double r = Math.Exp(lnconstant - b / 2); return(r > 1.0 ? 1.0 : r); }
public void CholeskyDecomposition2() { double[][] pvals = { new double[] { 1.0, 1.0, 1.0 }, new double[] { 1.0, 2.0, 3.0 }, new double[] { 1.0, 3.0, 6.0 } }; GeneralMatrix A = new GeneralMatrix(pvals); CholeskyDecomposition chol = A.chol(); GeneralMatrix X = chol.Solve(GeneralMatrix.Identity(3, 3)); Assert.IsTrue(GeneralTests.Check(A.Multiply(X), GeneralMatrix.Identity(3, 3))); }
/// <summary> /// Gets the probability density function (pdf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="x">A single point in the distribution range. /// For a matrix distribution, such as the Wishart's, this /// should be a positive-definite matrix or a matrix written /// in flat vector form. /// </param> /// /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Density Function (PDF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// public double LogProbabilityDensityFunction(double[,] x) { var chol = new CholeskyDecomposition(x); double det = chol.Determinant; double[,] Vx = chol.Solve(inverseScaleMatrix); double z = -0.5 * Vx.Trace(); return(Math.Log(constant) + power * Math.Log(det) + z); }
/// <summary> /// Gets the probability density function (pdf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// <param name="x">A single point in the distribution range. For a /// univariate distribution, this should be a single /// double value. For a multivariate distribution, /// this should be a double array.</param> /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution. /// </returns> /// <remarks> /// The Probability Density Function (PDF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> public override double ProbabilityDensityFunction(params double[] x) { double[] z = x.Subtract(mean); double[] a = (svd == null) ? chol.Solve(z) : svd.Solve(z); double b = a.InnerProduct(z); double r = constant * System.Math.Exp(-0.5 * b); return(r > 1.0 ? 1.0 : r); }
/// <summary> /// Gets the probability density function (pdf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="x">A single point in the distribution range. For a /// univariate distribution, this should be a single /// double value. For a multivariate distribution, /// this should be a double array.</param> /// /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Density Function (PDF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// public override double ProbabilityDensityFunction(params double[] x) { if (x.Length != Dimension) { throw new DimensionMismatchException("x", "The vector should have the same dimension as the distribution."); } double[] z = new double[mean.Length]; for (int i = 0; i < x.Length; i++) { z[i] = x[i] - mean[i]; } double[] a = chol.Solve(z); double b = 0; for (int i = 0; i < z.Length; i++) { b += a[i] * z[i]; } // Original code: // double r = constant * System.Math.Exp(-b/2); // Let lnconstant = log( constant ) // // r = constant * exp( b/2 ) // // r = exp(log(constant) * exp( b/2 ) // r = exp(lnconstant) * exp( b/2 ) // r = exp( lnconstant + b/2 ) // double r = Math.Exp(lnconstant - b * 0.5); return(r > 1 ? 1 : r); }
/// <summary> /// Gets the probability density function (pdf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="x">A single point in the distribution range. /// For a matrix distribution, such as the Wishart's, this /// should be a positive-definite matrix or a matrix written /// in flat vector form. /// </param> /// /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Density Function (PDF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// public double ProbabilityDensityFunction(double[,] x) { var chol = new CholeskyDecomposition(x); double det = chol.Determinant; double[,] Vx = chol.Solve(inverseScaleMatrix); double z = -0.5 * Vx.Trace(); double a = Math.Pow(det, power); double b = Math.Exp(z); return(constant * a * b); }
public void CholeskySolveExample() { // This is a very simple 3 X 3 problem I just wrote down to test the Cholesky solver SymmetricMatrix S = new SymmetricMatrix(3); S[0, 0] = 4.0; S[1, 0] = -2.0; S[1, 1] = 5.0; S[2, 0] = 1.0; S[2, 1] = 3.0; S[2, 2] = 6.0; CholeskyDecomposition CD = S.CholeskyDecomposition(); ColumnVector b = new ColumnVector(9.0, 7.0, 15.0); ColumnVector x = CD.Solve(b); Assert.IsTrue(TestUtilities.IsNearlyEqual(S * x, b)); }
public void MatrixCholeskyDecomposition() { double[][] pvals = { new double[] { 25, -5, 10 }, new double[] { -5, 17, 10 }, new double[] { 10, 10, 62 } }; Matrix e = new Matrix(pvals); CholeskyDecomposition chol = e.CholeskyDecomposition; Matrix l = chol.TriangularFactor; Assert.That(l * Matrix.Transpose(l), NumericIs.AlmostEqualTo(e), "CholeskyDecomposition"); Matrix g = chol.Solve(Matrix.Identity(3, 3)); Assert.That(e * g, NumericIs.AlmostEqualTo(Matrix.Identity(3, 3)), "CholeskyDecomposition Solve"); }
/// <summary> /// Choleskies the solve. /// </summary> /// <param name="matrix1">The matrix1.</param> /// <param name="matrix2">The matrix2.</param> /// <param name="matrixResult">The matrix result.</param> /// <returns></returns> public static RelationalOperation CholeskySolve(NumericMatrixFactor matrix1, NumericMatrixFactor matrix2, out NumericMatrixFactor matrixResult) { var values1 = matrix1.Coefficients; var cMatrix1 = new NumericMatrixFactor(matrix1, new VariableFactor('C', 1), null); var values2 = matrix2.Coefficients; var cMatrix2 = new NumericMatrixFactor(matrix2, new VariableFactor('C', 1), null); var solver = new CholeskyDecomposition(values1.AsSpan2D()); var values3 = solver.Solve(values2).Items; matrixResult = new NumericMatrixFactor(values3, false); var equation = new RelationalOperation( ComparisonOperators.Equals, new NomialExpression( new ProductTerm(new NumericFactor(1), cMatrix1, cMatrix2) ), new ProductTerm(new NumericFactor(1), matrixResult) ); return(equation); }
/// <summary> /// Gets the probability density function (pdf) for /// this distribution evaluated at point <c>x</c>. /// </summary> /// /// <param name="x">A single point in the distribution range.</param> /// /// <returns> /// The probability of <c>x</c> occurring /// in the current distribution. /// </returns> /// /// <remarks> /// The Probability Density Function (PDF) describes the /// probability that a given value <c>x</c> will occur. /// </remarks> /// public override double ProbabilityDensityFunction(double[] x) { // http://www.buch-kromann.dk/tine/nonpar/Nonparametric_Density_Estimation_multidim.pdf // http://sfb649.wiwi.hu-berlin.de/fedc_homepage/xplore/ebooks/html/spm/spmhtmlnode18.html double sum = 0; CholeskyDecomposition chol = new CholeskyDecomposition(smoothing); double[] delta = new double[Dimension]; for (int i = 0; i < samples.Length; i++) { for (int j = 0; j < x.Length; j++) { delta[j] = (x[j] - samples[i][j]); } sum += kernel.Function(chol.Solve(delta)); } return(sum / (samples.Length * determinant)); }
public static Double[,] Inverse(Double[,] matrix) { var rows = matrix.GetLength(0); var cols = matrix.GetLength(1); var target = Helpers.One(cols); if (cols < 24) { var lu = new LUDecomposition(matrix); return(lu.Solve(target)); } else if (Helpers.IsSymmetric(matrix)) { var cho = new CholeskyDecomposition(matrix); return(cho.Solve(target)); } else { var qr = QRDecomposition.Create(matrix); return(qr.Solve(target)); } }
public double Mahalanobis(double[] x) { if (x.Length != Dimension) { throw new DimensionMismatchException("x", "The vector should have the same dimension as the distribution."); } var z = new double[mean.Length]; for (int i = 0; i < x.Length; i++) { z[i] = x[i] - mean[i]; } double[] a = (chol == null) ? svd.Solve(z) : chol.Solve(z); double b = 0; for (int i = 0; i < z.Length; i++) { b += a[i] * z[i]; } return(b); }
public void AllTests() { Matrix A, B, C, Z, O, I, R, S, X, SUB, M, T, SQ, DEF, SOL; double tmp; double[] columnwise = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 }; double[] rowwise = { 1.0, 4.0, 7.0, 10.0, 2.0, 5.0, 8.0, 11.0, 3.0, 6.0, 9.0, 12.0 }; double[][] avals = { new double[] { 1.0, 4.0, 7.0, 10.0 }, new double[] { 2.0, 5.0, 8.0, 11.0 }, new double[] { 3.0, 6.0, 9.0, 12.0 } }; double[][] rankdef = avals; double[][] tvals = { new double[] { 1.0, 2.0, 3.0 }, new double[] { 4.0, 5.0, 6.0 }, new double[] { 7.0, 8.0, 9.0 }, new double[] { 10.0, 11.0, 12.0 } }; double[][] subavals = { new double[] { 5.0, 8.0, 11.0 }, new double[] { 6.0, 9.0, 12.0 } }; double[][] pvals = { new double[] { 25, -5, 10 }, new double[] { -5, 17, 10 }, new double[] { 10, 10, 62 } }; double[][] ivals = { new double[] { 1.0, 0.0, 0.0, 0.0 }, new double[] { 0.0, 1.0, 0.0, 0.0 }, new double[] { 0.0, 0.0, 1.0, 0.0 } }; double[][] evals = { new double[] { 0.0, 1.0, 0.0, 0.0 }, new double[] { 1.0, 0.0, 2e-7, 0.0 }, new double[] { 0.0, -2e-7, 0.0, 1.0 }, new double[] { 0.0, 0.0, 1.0, 0.0 } }; double[][] square = { new double[] { 166.0, 188.0, 210.0 }, new double[] { 188.0, 214.0, 240.0 }, new double[] { 210.0, 240.0, 270.0 } }; double[][] sqSolution = { new double[] { 13.0 }, new double[] { 15.0 } }; double[][] condmat = { new double[] { 1.0, 3.0 }, new double[] { 7.0, 9.0 } }; int rows = 3, cols = 4; int invalidld = 5; /* should trigger bad shape for construction with val */ int validld = 3; /* leading dimension of intended test Matrices */ int nonconformld = 4; /* leading dimension which is valid, but nonconforming */ int ib = 1, ie = 2, jb = 1, je = 3; /* index ranges for sub Matrix */ int[] rowindexset = new int[] { 1, 2 }; int[] badrowindexset = new int[] { 1, 3 }; int[] columnindexset = new int[] { 1, 2, 3 }; int[] badcolumnindexset = new int[] { 1, 2, 4 }; double columnsummax = 33.0; double rowsummax = 30.0; double sumofdiagonals = 15; double sumofsquares = 650; #region Testing constructors and constructor-like methods // Constructors and constructor-like methods: // double[], int // double[,] // int, int // int, int, double // int, int, double[,] // Create(double[,]) // Random(int,int) // Identity(int) try { // check that exception is thrown in packed constructor with invalid length A = new Matrix(columnwise, invalidld); Assert.Fail("Catch invalid length in packed constructor: exception not thrown for invalid input"); } catch (ArgumentException) { } A = new Matrix(columnwise, validld); B = new Matrix(avals); tmp = B[0, 0]; avals[0][0] = 0.0; C = B - A; avals[0][0] = tmp; B = Matrix.Create(avals); tmp = B[0, 0]; avals[0][0] = 0.0; Assert.AreEqual((tmp - B[0, 0]), 0.0, "Create"); avals[0][0] = columnwise[0]; I = new Matrix(ivals); NumericAssert.AreAlmostEqual(I, Matrix.Identity(3, 4), "Identity"); #endregion #region Testing access methods // Access Methods: // getColumnDimension() // getRowDimension() // getArray() // getArrayCopy() // getColumnPackedCopy() // getRowPackedCopy() // get(int,int) // GetMatrix(int,int,int,int) // GetMatrix(int,int,int[]) // GetMatrix(int[],int,int) // GetMatrix(int[],int[]) // set(int,int,double) // SetMatrix(int,int,int,int,Matrix) // SetMatrix(int,int,int[],Matrix) // SetMatrix(int[],int,int,Matrix) // SetMatrix(int[],int[],Matrix) // Various get methods B = new Matrix(avals); Assert.AreEqual(B.RowCount, rows, "getRowDimension"); Assert.AreEqual(B.ColumnCount, cols, "getColumnDimension"); B = new Matrix(avals); double[][] barray = (Matrix)B; Assert.AreSame(barray, avals, "getArray"); barray = B.Clone(); Assert.AreNotSame(barray, avals, "getArrayCopy"); NumericAssert.AreAlmostEqual(new Matrix(barray), B, "getArrayCopy II"); // double[] bpacked = B.ColumnPackedCopy; // try // { // check(bpacked, columnwise); // try_success("getColumnPackedCopy... ", ""); // } // catch (System.SystemException e) // { // errorCount = try_failure(errorCount, "getColumnPackedCopy... ", "data not successfully (deep) copied by columns"); // System.Console.Out.WriteLine(e.Message); // } // bpacked = B.RowPackedCopy; // try // { // check(bpacked, rowwise); // try_success("getRowPackedCopy... ", ""); // } // catch (System.SystemException e) // { // errorCount = try_failure(errorCount, "getRowPackedCopy... ", "data not successfully (deep) copied by rows"); // System.Console.Out.WriteLine(e.Message); // } try { tmp = B[B.RowCount, B.ColumnCount - 1]; Assert.Fail("get(int,int): OutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { tmp = B[B.RowCount - 1, B.ColumnCount]; Assert.Fail("get(int,int): OutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } Assert.AreEqual(B[B.RowCount - 1, B.ColumnCount - 1], avals[B.RowCount - 1][B.ColumnCount - 1], "get(int,int)"); SUB = new Matrix(subavals); try { M = B.GetMatrix(ib, ie + B.RowCount + 1, jb, je); Assert.Fail("GetMatrix(int,int,int,int): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { M = B.GetMatrix(ib, ie, jb, je + B.ColumnCount + 1); Assert.Fail("GetMatrix(int,int,int,int): IndexOutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } M = B.GetMatrix(ib, ie, jb, je); NumericAssert.AreAlmostEqual(SUB, M, "GetMatrix(int,int,int,int)"); try { M = B.GetMatrix(ib, ie, badcolumnindexset); Assert.Fail("GetMatrix(int,int,int[]): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { M = B.GetMatrix(ib, ie + B.RowCount + 1, columnindexset); Assert.Fail("GetMatrix(int,int,int[]): IndexOutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } M = B.GetMatrix(ib, ie, columnindexset); NumericAssert.AreAlmostEqual(SUB, M, "GetMatrix(int,int,int[])"); try { M = B.GetMatrix(badrowindexset, jb, je); Assert.Fail("GetMatrix(int[],int,int): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { M = B.GetMatrix(rowindexset, jb, je + B.ColumnCount + 1); Assert.Fail("GetMatrix(int[],int,int): IndexOutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } M = B.GetMatrix(rowindexset, jb, je); NumericAssert.AreAlmostEqual(SUB, M, "GetMatrix(int[],int,int)"); try { M = B.GetMatrix(badrowindexset, columnindexset); Assert.Fail("GetMatrix(int[],int[]): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { M = B.GetMatrix(rowindexset, badcolumnindexset); Assert.Fail("GetMatrix(int[],int[]): IndexOutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } M = B.GetMatrix(rowindexset, columnindexset); NumericAssert.AreAlmostEqual(SUB, M, "GetMatrix(int[],int[])"); // Various set methods: try { B[B.RowCount, B.ColumnCount - 1] = 0.0; Assert.Fail("set(int,int,double): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { B[B.RowCount - 1, B.ColumnCount] = 0.0; Assert.Fail("set(int,int,double): IndexOutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } B[ib, jb] = 0.0; tmp = B[ib, jb]; NumericAssert.AreAlmostEqual(tmp, 0.0, "set(int,int,double)"); M = new Matrix(2, 3, 0.0); try { B.SetMatrix(ib, ie + B.RowCount + 1, jb, je, M); Assert.Fail("SetMatrix(int,int,int,int,Matrix): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { B.SetMatrix(ib, ie, jb, je + B.ColumnCount + 1, M); Assert.Fail("SetMatrix(int,int,int,int,Matrix): IndexOutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } B.SetMatrix(ib, ie, jb, je, M); NumericAssert.AreAlmostEqual(M - B.GetMatrix(ib, ie, jb, je), M, "SetMatrix(int,int,int,int,Matrix)"); B.SetMatrix(ib, ie, jb, je, SUB); try { B.SetMatrix(ib, ie + B.RowCount + 1, columnindexset, M); Assert.Fail("SetMatrix(int,int,int[],Matrix): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { B.SetMatrix(ib, ie, badcolumnindexset, M); Assert.Fail("SetMatrix(int,int,int[],Matrix): IndexOutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } B.SetMatrix(ib, ie, columnindexset, M); NumericAssert.AreAlmostEqual(M - B.GetMatrix(ib, ie, columnindexset), M, "SetMatrix(int,int,int[],Matrix)"); B.SetMatrix(ib, ie, jb, je, SUB); try { B.SetMatrix(rowindexset, jb, je + B.ColumnCount + 1, M); Assert.Fail("SetMatrix(int[],int,int,Matrix): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { B.SetMatrix(badrowindexset, jb, je, M); Assert.Fail("SetMatrix(int[],int,int,Matrix): IndexOutOfBoundsException expected but not thrown II"); } catch (IndexOutOfRangeException) { } B.SetMatrix(rowindexset, jb, je, M); NumericAssert.AreAlmostEqual(M - B.GetMatrix(rowindexset, jb, je), M, "SetMatrix(int[],int,int,Matrix)"); B.SetMatrix(ib, ie, jb, je, SUB); try { B.SetMatrix(rowindexset, badcolumnindexset, M); Assert.Fail("SetMatrix(int[],int[],Matrix): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } try { B.SetMatrix(badrowindexset, columnindexset, M); Assert.Fail("SetMatrix(int[],int[],Matrix): IndexOutOfBoundsException expected but not thrown"); } catch (IndexOutOfRangeException) { } B.SetMatrix(rowindexset, columnindexset, M); NumericAssert.AreAlmostEqual(M - B.GetMatrix(rowindexset, columnindexset), M, "SetMatrix(int[],int[],Matrix)"); #endregion #region Testing array-like methods // Array-like methods: // Subtract // SubtractEquals // Add // AddEquals // ArrayLeftDivide // ArrayLeftDivideEquals // ArrayRightDivide // ArrayRightDivideEquals // arrayTimes // ArrayMultiplyEquals // uminus S = new Matrix(columnwise, nonconformld); R = Matrix.Random(A.RowCount, A.ColumnCount); A = R; try { S = A - S; Assert.Fail("Subtract conformance check: nonconformance not raised"); } catch (ArgumentException) { } Assert.AreEqual((A - R).Norm1(), 0.0, "Subtract: difference of identical Matrices is nonzero,\nSubsequent use of Subtract should be suspect"); A = R.Clone(); A.Subtract(R); Z = new Matrix(A.RowCount, A.ColumnCount); try { A.Subtract(S); Assert.Fail("SubtractEquals conformance check: nonconformance not raised"); } catch (ArgumentException) { } Assert.AreEqual((A - Z).Norm1(), 0.0, "SubtractEquals: difference of identical Matrices is nonzero,\nSubsequent use of Subtract should be suspect"); A = R.Clone(); B = Matrix.Random(A.RowCount, A.ColumnCount); C = A - B; try { S = A + S; Assert.Fail("Add conformance check: nonconformance not raised"); } catch (ArgumentException) { } NumericAssert.AreAlmostEqual(C + B, A, "Add"); C = A - B; C.Add(B); try { A.Add(S); Assert.Fail("AddEquals conformance check: nonconformance not raised"); } catch (ArgumentException) { } NumericAssert.AreAlmostEqual(C, A, "AddEquals"); A = ((Matrix)R.Clone()); A.UnaryMinus(); NumericAssert.AreAlmostEqual(A + R, Z, "UnaryMinus"); A = (Matrix)R.Clone(); O = new Matrix(A.RowCount, A.ColumnCount, 1.0); try { Matrix.ArrayDivide(A, S); Assert.Fail("ArrayRightDivide conformance check: nonconformance not raised"); } catch (ArgumentException) { } C = Matrix.ArrayDivide(A, R); NumericAssert.AreAlmostEqual(C, O, "ArrayRightDivide"); try { A.ArrayDivide(S); Assert.Fail("ArrayRightDivideEquals conformance check: nonconformance not raised"); } catch (ArgumentException) { } A.ArrayDivide(R); NumericAssert.AreAlmostEqual(A, O, "ArrayRightDivideEquals"); A = (Matrix)R.Clone(); B = Matrix.Random(A.RowCount, A.ColumnCount); try { S = Matrix.ArrayMultiply(A, S); Assert.Fail("arrayTimes conformance check: nonconformance not raised"); } catch (ArgumentException) { } C = Matrix.ArrayMultiply(A, B); C.ArrayDivide(B); NumericAssert.AreAlmostEqual(C, A, "arrayTimes"); try { A.ArrayMultiply(S); Assert.Fail("ArrayMultiplyEquals conformance check: nonconformance not raised"); } catch (ArgumentException) { } A.ArrayMultiply(B); A.ArrayDivide(B); NumericAssert.AreAlmostEqual(A, R, "ArrayMultiplyEquals"); #endregion #region Testing linear algebra methods // LA methods: // Transpose // Multiply // Condition // Rank // Determinant // trace // Norm1 // norm2 // normF // normInf // Solve // solveTranspose // Inverse // chol // Eigen // lu // qr // svd A = new Matrix(columnwise, 3); T = new Matrix(tvals); T = Matrix.Transpose(A); NumericAssert.AreAlmostEqual(Matrix.Transpose(A), T, "Transpose"); NumericAssert.AreAlmostEqual(A.Norm1(), columnsummax, "Norm1"); NumericAssert.AreAlmostEqual(A.NormInf(), rowsummax, "NormInf"); NumericAssert.AreAlmostEqual(A.NormF(), Math.Sqrt(sumofsquares), "NormF"); NumericAssert.AreAlmostEqual(A.Trace(), sumofdiagonals, "Trace"); NumericAssert.AreAlmostEqual(A.GetMatrix(0, A.RowCount - 1, 0, A.RowCount - 1).Determinant(), 0.0, "Determinant"); SQ = new Matrix(square); NumericAssert.AreAlmostEqual(A * Matrix.Transpose(A), SQ, "Multiply(Matrix)"); NumericAssert.AreAlmostEqual(0.0 * A, Z, "Multiply(double)"); A = new Matrix(columnwise, 4); QRDecomposition QR = A.QRDecomposition; R = QR.R; NumericAssert.AreAlmostEqual(A, QR.Q * R, "QRDecomposition"); SingularValueDecomposition SVD = A.SingularValueDecomposition; NumericAssert.AreAlmostEqual(A, SVD.LeftSingularVectors * (SVD.S * Matrix.Transpose(SVD.RightSingularVectors)), "SingularValueDecomposition"); DEF = new Matrix(rankdef); NumericAssert.AreAlmostEqual(DEF.Rank(), Math.Min(DEF.RowCount, DEF.ColumnCount) - 1, "Rank"); B = new Matrix(condmat); SVD = B.SingularValueDecomposition; double[] singularvalues = SVD.SingularValues; NumericAssert.AreAlmostEqual(B.Condition(), singularvalues[0] / singularvalues[Math.Min(B.RowCount, B.ColumnCount) - 1], "Condition"); int n = A.ColumnCount; A = A.GetMatrix(0, n - 1, 0, n - 1); A[0, 0] = 0.0; LUDecomposition LU = A.LUDecomposition; NumericAssert.AreAlmostEqual(A.GetMatrix(LU.Pivot, 0, n - 1), LU.L * LU.U, "LUDecomposition"); X = A.Inverse(); NumericAssert.AreAlmostEqual(A * X, Matrix.Identity(3, 3), "Inverse"); O = new Matrix(SUB.RowCount, 1, 1.0); SOL = new Matrix(sqSolution); SQ = SUB.GetMatrix(0, SUB.RowCount - 1, 0, SUB.RowCount - 1); NumericAssert.AreAlmostEqual(SQ.Solve(SOL), O, "Solve"); A = new Matrix(pvals); CholeskyDecomposition Chol = A.CholeskyDecomposition; Matrix L = Chol.TriangularFactor; NumericAssert.AreAlmostEqual(A, L * Matrix.Transpose(L), "CholeskyDecomposition"); X = Chol.Solve(Matrix.Identity(3, 3)); NumericAssert.AreAlmostEqual(A * X, Matrix.Identity(3, 3), "CholeskyDecomposition Solve"); EigenvalueDecomposition Eig = A.EigenvalueDecomposition; Matrix D = Eig.BlockDiagonal; Matrix V = Eig.EigenVectors; NumericAssert.AreAlmostEqual(A * V, V * D, "EigenvalueDecomposition (symmetric)"); A = new Matrix(evals); Eig = A.EigenvalueDecomposition; D = Eig.BlockDiagonal; V = Eig.EigenVectors; NumericAssert.AreAlmostEqual(A * V, V * D, "EigenvalueDecomposition (nonsymmetric)"); #endregion }
public override IVector Apply(IMatrix A, IVector b, IVector x) { double[] xs = (double[])decomp.Solve( new Matrix(Blas.Default.GetArrayCopy(b), b.Length)); return(Blas.Default.SetVector(xs, x)); }
/// <summary>An exception is thrown at the end of the process, /// if any error is encountered.</summary> [Test] public void AllTests() { Matrix A, B, C, Z, O, I, R, S, X, SUB, M, T, SQ, DEF, SOL; int errorCount = 0; int warningCount = 0; double tmp; double[] columnwise = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 }; double[] rowwise = { 1.0, 4.0, 7.0, 10.0, 2.0, 5.0, 8.0, 11.0, 3.0, 6.0, 9.0, 12.0 }; double[,] avals = { { 1.0, 4.0, 7.0, 10.0 }, { 2.0, 5.0, 8.0, 11.0 }, { 3.0, 6.0, 9.0, 12.0 } }; double[,] rankdef = avals; double[,] tvals = { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 }, { 7.0, 8.0, 9.0 }, { 10.0, 11.0, 12.0 } }; double[,] subavals = { { 5.0, 8.0, 11.0 }, { 6.0, 9.0, 12.0 } }; double[,] pvals = { { 1.0, 1.0, 1.0 }, { 1.0, 2.0, 3.0 }, { 1.0, 3.0, 6.0 } }; double[,] ivals = { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 } }; double[,] evals = { { 0.0, 1.0, 0.0, 0.0 }, { 1.0, 0.0, 2e-7, 0.0 }, { 0.0, -2e-7, 0.0, 1.0 }, { 0.0, 0.0, 1.0, 0.0 } }; double[,] square = { { 166.0, 188.0, 210.0 }, { 188.0, 214.0, 240.0 }, { 210.0, 240.0, 270.0 } }; double[,] sqSolution = { { 13.0 }, { 15.0 } }; double[,] condmat = { { 1.0, 3.0 }, { 7.0, 9.0 } }; int rows = 3, cols = 4; int invalidld = 5; /* should trigger bad shape for construction with val */ int validld = 3; /* leading dimension of intended test Matrices */ int nonconformld = 4; /* leading dimension which is valid, but nonconforming */ int ib = 1, ie = 2, jb = 1, je = 3; /* index ranges for sub Matrix */ int[] rowindexset = new int[] { 1, 2 }; int[] badrowindexset = new int[] { 1, 3 }; int[] columnindexset = new int[] { 1, 2, 3 }; int[] badcolumnindexset = new int[] { 1, 2, 4 }; double columnsummax = 33.0; double rowsummax = 30.0; double sumofdiagonals = 15; double sumofsquares = 650; // Constructors and constructor-like methods: // double[], int // double[,] // int, int // int, int, double // int, int, double[,] // Create(double[,]) // Random(int,int) // Identity(int) print("\nTesting constructors and constructor-like methods...\n"); try { // check that exception is thrown in packed constructor with invalid length A = new Matrix(columnwise, invalidld); errorCount = try_failure(errorCount, "Catch invalid length in packed constructor... ", "exception not thrown for invalid input"); } catch (System.ArgumentException e) { try_success("Catch invalid length in packed constructor... ", e.Message); } A = new Matrix(columnwise, validld); B = new Matrix(avals); tmp = B[0, 0]; avals[0, 0] = 0.0; C = B - A; avals[0, 0] = tmp; B = Matrix.Create(avals); tmp = B[0, 0]; avals[0, 0] = 0.0; if ((tmp - B[0, 0]) != 0.0) { // check that Create behaves properly errorCount = try_failure(errorCount, "Create... ", "Copy not effected... data visible outside"); } else { try_success("Create... ", ""); } avals[0, 0] = columnwise[0]; I = new Matrix(ivals); try { check(I, Matrix.Identity(3, 4)); try_success("Identity... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Identity... ", "Identity Matrix not successfully created"); System.Console.Out.WriteLine(e.Message); } // Access Methods: // getColumnDimension() // getRowDimension() // getArray() // getArrayCopy() // getColumnPackedCopy() // getRowPackedCopy() // get(int,int) // GetMatrix(int,int,int,int) // GetMatrix(int,int,int[]) // GetMatrix(int[],int,int) // GetMatrix(int[],int[]) // set(int,int,double) // SetMatrix(int,int,int,int,Matrix) // SetMatrix(int,int,int[],Matrix) // SetMatrix(int[],int,int,Matrix) // SetMatrix(int[],int[],Matrix) print("\nTesting access methods...\n"); // Various get methods B = new Matrix(avals); if (B.RowCount != rows) { errorCount = try_failure(errorCount, "getRowDimension... ", ""); } else { try_success("getRowDimension... ", ""); } if (B.ColumnCount != cols) { errorCount = try_failure(errorCount, "getColumnDimension... ", ""); } else { try_success("getColumnDimension... ", ""); } B = new Matrix(avals); double[,] barray = (Matrix)B; if (barray != avals) { errorCount = try_failure(errorCount, "getArray... ", ""); } else { try_success("getArray... ", ""); } barray = (Matrix)B.Clone(); if (barray == avals) { errorCount = try_failure(errorCount, "getArrayCopy... ", "data not (deep) copied"); } try { check(barray, avals); try_success("getArrayCopy... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "getArrayCopy... ", "data not successfully (deep) copied"); System.Console.Out.WriteLine(e.Message); } // double[] bpacked = B.ColumnPackedCopy; // try // { // check(bpacked, columnwise); // try_success("getColumnPackedCopy... ", ""); // } // catch (System.SystemException e) // { // errorCount = try_failure(errorCount, "getColumnPackedCopy... ", "data not successfully (deep) copied by columns"); // System.Console.Out.WriteLine(e.Message); // } // bpacked = B.RowPackedCopy; // try // { // check(bpacked, rowwise); // try_success("getRowPackedCopy... ", ""); // } // catch (System.SystemException e) // { // errorCount = try_failure(errorCount, "getRowPackedCopy... ", "data not successfully (deep) copied by rows"); // System.Console.Out.WriteLine(e.Message); // } try { tmp = B[B.RowCount, B.ColumnCount - 1]; errorCount = try_failure(errorCount, "get(int,int)... ", "OutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { tmp = B[B.RowCount - 1, B.ColumnCount]; errorCount = try_failure(errorCount, "get(int,int)... ", "OutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("get(int,int)... OutofBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "get(int,int)... ", "OutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { if (B[B.RowCount - 1, B.ColumnCount - 1] != avals[B.RowCount - 1, B.ColumnCount - 1]) { errorCount = try_failure(errorCount, "get(int,int)... ", "Matrix entry (i,j) not successfully retreived"); } else { try_success("get(int,int)... ", ""); } } catch (System.IndexOutOfRangeException e) { errorCount = try_failure(errorCount, "get(int,int)... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e.Message); } SUB = new Matrix(subavals); try { M = B.GetMatrix(ib, ie + B.RowCount + 1, jb, je); errorCount = try_failure(errorCount, "GetMatrix(int,int,int,int)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { M = B.GetMatrix(ib, ie, jb, je + B.ColumnCount + 1); errorCount = try_failure(errorCount, "GetMatrix(int,int,int,int)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("GetMatrix(int,int,int,int)... ArrayIndexOutOfBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "GetMatrix(int,int,int,int)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { M = B.GetMatrix(ib, ie, jb, je); try { check(SUB, M); try_success("GetMatrix(int,int,int,int)... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "GetMatrix(int,int,int,int)... ", "submatrix not successfully retreived"); System.Console.Out.WriteLine(e.Message); } } catch (System.IndexOutOfRangeException e) { errorCount = try_failure(errorCount, "GetMatrix(int,int,int,int)... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e.Message); } try { M = B.GetMatrix(ib, ie, badcolumnindexset); errorCount = try_failure(errorCount, "GetMatrix(int,int,int[])... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { M = B.GetMatrix(ib, ie + B.RowCount + 1, columnindexset); errorCount = try_failure(errorCount, "GetMatrix(int,int,int[])... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("GetMatrix(int,int,int[])... ArrayIndexOutOfBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "GetMatrix(int,int,int[])... ", "ArrayIndexOutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { M = B.GetMatrix(ib, ie, columnindexset); try { check(SUB, M); try_success("GetMatrix(int,int,int[])... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "GetMatrix(int,int,int[])... ", "submatrix not successfully retreived"); System.Console.Out.WriteLine(e.Message); } } catch (System.IndexOutOfRangeException e) { errorCount = try_failure(errorCount, "GetMatrix(int,int,int[])... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e.Message); } try { M = B.GetMatrix(badrowindexset, jb, je); errorCount = try_failure(errorCount, "GetMatrix(int[],int,int)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { M = B.GetMatrix(rowindexset, jb, je + B.ColumnCount + 1); errorCount = try_failure(errorCount, "GetMatrix(int[],int,int)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("GetMatrix(int[],int,int)... ArrayIndexOutOfBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "GetMatrix(int[],int,int)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { M = B.GetMatrix(rowindexset, jb, je); try { check(SUB, M); try_success("GetMatrix(int[],int,int)... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "GetMatrix(int[],int,int)... ", "submatrix not successfully retreived"); System.Console.Out.WriteLine(e.Message); } } catch (System.IndexOutOfRangeException e) { errorCount = try_failure(errorCount, "GetMatrix(int[],int,int)... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e.Message); } try { M = B.GetMatrix(badrowindexset, columnindexset); errorCount = try_failure(errorCount, "GetMatrix(int[],int[])... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { M = B.GetMatrix(rowindexset, badcolumnindexset); errorCount = try_failure(errorCount, "GetMatrix(int[],int[])... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("GetMatrix(int[],int[])... ArrayIndexOutOfBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "GetMatrix(int[],int[])... ", "ArrayIndexOutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { M = B.GetMatrix(rowindexset, columnindexset); try { check(SUB, M); try_success("GetMatrix(int[],int[])... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "GetMatrix(int[],int[])... ", "submatrix not successfully retreived"); System.Console.Out.WriteLine(e.Message); } } catch (System.IndexOutOfRangeException e) { errorCount = try_failure(errorCount, "GetMatrix(int[],int[])... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e.Message); } // Various set methods: try { B[B.RowCount, B.ColumnCount - 1] = 0.0; errorCount = try_failure(errorCount, "set(int,int,double)... ", "OutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { B[B.RowCount - 1, B.ColumnCount] = 0.0; errorCount = try_failure(errorCount, "set(int,int,double)... ", "OutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("set(int,int,double)... OutofBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "set(int,int,double)... ", "OutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { B[ib, jb] = 0.0; tmp = B[ib, jb]; try { check(tmp, 0.0); try_success("set(int,int,double)... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "set(int,int,double)... ", "Matrix element not successfully set"); System.Console.Out.WriteLine(e.Message); } } catch (System.IndexOutOfRangeException e1) { errorCount = try_failure(errorCount, "set(int,int,double)... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e1.Message); } M = new Matrix(2, 3, 0.0); try { B.SetMatrix(ib, ie + B.RowCount + 1, jb, je, M); errorCount = try_failure(errorCount, "SetMatrix(int,int,int,int,Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { B.SetMatrix(ib, ie, jb, je + B.ColumnCount + 1, M); errorCount = try_failure(errorCount, "SetMatrix(int,int,int,int,Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("SetMatrix(int,int,int,int,Matrix)... ArrayIndexOutOfBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "SetMatrix(int,int,int,int,Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { B.SetMatrix(ib, ie, jb, je, M); try { check(M - B.GetMatrix(ib, ie, jb, je), M); try_success("SetMatrix(int,int,int,int,Matrix)... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "SetMatrix(int,int,int,int,Matrix)... ", "submatrix not successfully set"); System.Console.Out.WriteLine(e.Message); } B.SetMatrix(ib, ie, jb, je, SUB); } catch (System.IndexOutOfRangeException e1) { errorCount = try_failure(errorCount, "SetMatrix(int,int,int,int,Matrix)... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e1.Message); } try { B.SetMatrix(ib, ie + B.RowCount + 1, columnindexset, M); errorCount = try_failure(errorCount, "SetMatrix(int,int,int[],Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { B.SetMatrix(ib, ie, badcolumnindexset, M); errorCount = try_failure(errorCount, "SetMatrix(int,int,int[],Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("SetMatrix(int,int,int[],Matrix)... ArrayIndexOutOfBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "SetMatrix(int,int,int[],Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { B.SetMatrix(ib, ie, columnindexset, M); try { check(M - B.GetMatrix(ib, ie, columnindexset), M); try_success("SetMatrix(int,int,int[],Matrix)... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "SetMatrix(int,int,int[],Matrix)... ", "submatrix not successfully set"); System.Console.Out.WriteLine(e.Message); } B.SetMatrix(ib, ie, jb, je, SUB); } catch (System.IndexOutOfRangeException e1) { errorCount = try_failure(errorCount, "SetMatrix(int,int,int[],Matrix)... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e1.Message); } try { B.SetMatrix(rowindexset, jb, je + B.ColumnCount + 1, M); errorCount = try_failure(errorCount, "SetMatrix(int[],int,int,Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { B.SetMatrix(badrowindexset, jb, je, M); errorCount = try_failure(errorCount, "SetMatrix(int[],int,int,Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("SetMatrix(int[],int,int,Matrix)... ArrayIndexOutOfBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "SetMatrix(int[],int,int,Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { B.SetMatrix(rowindexset, jb, je, M); try { check(M - B.GetMatrix(rowindexset, jb, je), M); try_success("SetMatrix(int[],int,int,Matrix)... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "SetMatrix(int[],int,int,Matrix)... ", "submatrix not successfully set"); System.Console.Out.WriteLine(e.Message); } B.SetMatrix(ib, ie, jb, je, SUB); } catch (System.IndexOutOfRangeException e1) { errorCount = try_failure(errorCount, "SetMatrix(int[],int,int,Matrix)... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e1.Message); } try { B.SetMatrix(rowindexset, badcolumnindexset, M); errorCount = try_failure(errorCount, "SetMatrix(int[],int[],Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e) { System.Console.Out.WriteLine(e.Message); try { B.SetMatrix(badrowindexset, columnindexset, M); errorCount = try_failure(errorCount, "SetMatrix(int[],int[],Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); } catch (System.IndexOutOfRangeException e1) { try_success("SetMatrix(int[],int[],Matrix)... ArrayIndexOutOfBoundsException... ", ""); System.Console.Out.WriteLine(e1.Message); } } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "SetMatrix(int[],int[],Matrix)... ", "ArrayIndexOutOfBoundsException expected but not thrown"); System.Console.Out.WriteLine(e1.Message); } try { B.SetMatrix(rowindexset, columnindexset, M); try { check(M - B.GetMatrix(rowindexset, columnindexset), M); try_success("SetMatrix(int[],int[],Matrix)... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "SetMatrix(int[],int[],Matrix)... ", "submatrix not successfully set"); System.Console.Out.WriteLine(e.Message); } } catch (System.IndexOutOfRangeException e1) { errorCount = try_failure(errorCount, "SetMatrix(int[],int[],Matrix)... ", "Unexpected ArrayIndexOutOfBoundsException"); System.Console.Out.WriteLine(e1.Message); } // Array-like methods: // Subtract // SubtractEquals // Add // AddEquals // ArrayLeftDivide // ArrayLeftDivideEquals // ArrayRightDivide // ArrayRightDivideEquals // arrayTimes // ArrayMultiplyEquals // uminus print("\nTesting array-like methods...\n"); S = new Matrix(columnwise, nonconformld); R = Matrix.Random(A.RowCount, A.ColumnCount); A = R; try { S = A - S; errorCount = try_failure(errorCount, "Subtract conformance check... ", "nonconformance not raised"); } catch (System.ArgumentException e) { try_success("Subtract conformance check... ", ""); System.Console.Out.WriteLine(e.Message); } if ((A - R).Norm1() != 0.0) { errorCount = try_failure(errorCount, "Subtract... ", "(difference of identical Matrices is nonzero,\nSubsequent use of Subtract should be suspect)"); } else { try_success("Subtract... ", ""); } A = (Matrix)R.Clone(); A.Subtract(R); Z = new Matrix(A.RowCount, A.ColumnCount); try { A.Subtract(S); errorCount = try_failure(errorCount, "SubtractEquals conformance check... ", "nonconformance not raised"); } catch (System.ArgumentException e) { try_success("SubtractEquals conformance check... ", ""); System.Console.Out.WriteLine(e.Message); } if ((A - Z).Norm1() != 0.0) { errorCount = try_failure(errorCount, "SubtractEquals... ", "(difference of identical Matrices is nonzero,\nSubsequent use of Subtract should be suspect)"); } else { try_success("SubtractEquals... ", ""); } A = (Matrix)R.Clone(); B = Matrix.Random(A.RowCount, A.ColumnCount); C = A - B; try { S = A + S; errorCount = try_failure(errorCount, "Add conformance check... ", "nonconformance not raised"); } catch (System.ArgumentException e) { try_success("Add conformance check... ", ""); System.Console.Out.WriteLine(e.Message); } try { check(C + B, A); try_success("Add... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Add... ", "(C = A - B, but C + B != A)"); System.Console.Out.WriteLine(e.Message); } C = A - B; C.Add(B); try { A.Add(S); errorCount = try_failure(errorCount, "AddEquals conformance check... ", "nonconformance not raised"); } catch (System.ArgumentException e) { try_success("AddEquals conformance check... ", ""); System.Console.Out.WriteLine(e.Message); } try { check(C, A); try_success("AddEquals... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "AddEquals... ", "(C = A - B, but C = C + B != A)"); System.Console.Out.WriteLine(e.Message); } A = ((Matrix)R.Clone()); A.UnaryMinus(); try { check(A + R, Z); try_success("UnaryMinus... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "uminus... ", "(-A + A != zeros)"); System.Console.Out.WriteLine(e.Message); } A = (Matrix)R.Clone(); O = new Matrix(A.RowCount, A.ColumnCount, 1.0); try { Matrix.ArrayDivide(A, S); errorCount = try_failure(errorCount, "ArrayRightDivide conformance check... ", "nonconformance not raised"); } catch (System.ArgumentException e) { try_success("ArrayRightDivide conformance check... ", ""); System.Console.Out.WriteLine(e.Message); } C = Matrix.ArrayDivide(A, R); try { check(C, O); try_success("ArrayRightDivide... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "ArrayRightDivide... ", "(M./M != ones)"); System.Console.Out.WriteLine(e.Message); } try { A.ArrayDivide(S); errorCount = try_failure(errorCount, "ArrayRightDivideEquals conformance check... ", "nonconformance not raised"); } catch (System.ArgumentException e) { try_success("ArrayRightDivideEquals conformance check... ", ""); System.Console.Out.WriteLine(e.Message); } A.ArrayDivide(R); try { check(A, O); try_success("ArrayRightDivideEquals... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "ArrayRightDivideEquals... ", "(M./M != ones)"); System.Console.Out.WriteLine(e.Message); } A = (Matrix)R.Clone(); B = Matrix.Random(A.RowCount, A.ColumnCount); try { S = Matrix.ArrayMultiply(A, S); errorCount = try_failure(errorCount, "arrayTimes conformance check... ", "nonconformance not raised"); } catch (System.ArgumentException e) { try_success("arrayTimes conformance check... ", ""); System.Console.Out.WriteLine(e.Message); } C = Matrix.ArrayMultiply(A, B); try { C.ArrayDivide(B); check(C, A); try_success("arrayTimes... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "arrayTimes... ", "(A = R, C = A.*B, but C./B != A)"); System.Console.Out.WriteLine(e.Message); } try { A.ArrayMultiply(S); errorCount = try_failure(errorCount, "ArrayMultiplyEquals conformance check... ", "nonconformance not raised"); } catch (System.ArgumentException e) { try_success("ArrayMultiplyEquals conformance check... ", ""); System.Console.Out.WriteLine(e.Message); } A.ArrayMultiply(B); try { A.ArrayDivide(B); check(A, R); try_success("ArrayMultiplyEquals... ", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "ArrayMultiplyEquals... ", "(A = R, A = A.*B, but A./B != R)"); System.Console.Out.WriteLine(e.Message); } // LA methods: // Transpose // Multiply // Condition // Rank // Determinant // trace // Norm1 // norm2 // normF // normInf // Solve // solveTranspose // Inverse // chol // Eigen // lu // qr // svd print("\nTesting linear algebra methods...\n"); A = new Matrix(columnwise, 3); T = new Matrix(tvals); T = Matrix.Transpose(A); try { check(Matrix.Transpose(A), T); try_success("Transpose...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Transpose()...", "Transpose unsuccessful"); System.Console.Out.WriteLine(e.Message); } Matrix.Transpose(A); try { check(A.Norm1(), columnsummax); try_success("Norm1...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Norm1()...", "incorrect norm calculation"); System.Console.Out.WriteLine(e.Message); } try { check(A.NormInf(), rowsummax); try_success("normInf()...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "normInf()...", "incorrect norm calculation"); System.Console.Out.WriteLine(e.Message); } try { check(A.NormF(), System.Math.Sqrt(sumofsquares)); try_success("normF...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "normF()...", "incorrect norm calculation"); System.Console.Out.WriteLine(e.Message); } try { check(A.Trace(), sumofdiagonals); try_success("trace()...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "trace()...", "incorrect trace calculation"); System.Console.Out.WriteLine(e.Message); } try { check(A.GetMatrix(0, A.RowCount - 1, 0, A.RowCount - 1).Determinant(), 0.0); try_success("Determinant()...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Determinant()...", "incorrect determinant calculation"); System.Console.Out.WriteLine(e.Message); } SQ = new Matrix(square); try { check(A * Matrix.Transpose(A), SQ); try_success("Multiply(Matrix)...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Multiply(Matrix)...", "incorrect Matrix-Matrix product calculation"); System.Console.Out.WriteLine(e.Message); } try { check(0.0 * A, Z); try_success("Multiply(double)...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Multiply(double)...", "incorrect Matrix-scalar product calculation"); System.Console.Out.WriteLine(e.Message); } A = new Matrix(columnwise, 4); QRDecomposition QR = A.QRD(); R = QR.R; try { check(A, QR.Q * R); try_success("QRDecomposition...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "QRDecomposition...", "incorrect QR decomposition calculation"); System.Console.Out.WriteLine(e.Message); } SingularValueDecomposition SVD = A.SVD(); try { check(A, SVD.LeftSingularVectors * (SVD.S * Matrix.Transpose(SVD.RightSingularVectors))); try_success("SingularValueDecomposition...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "SingularValueDecomposition...", "incorrect singular value decomposition calculation"); System.Console.Out.WriteLine(e.Message); } DEF = new Matrix(rankdef); try { check(DEF.Rank(), System.Math.Min(DEF.RowCount, DEF.ColumnCount) - 1); try_success("Rank()...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Rank()...", "incorrect Rank calculation"); System.Console.Out.WriteLine(e.Message); } B = new Matrix(condmat); SVD = B.SVD(); double[] singularvalues = SVD.SingularValues; try { check(B.Condition(), singularvalues[0] / singularvalues[System.Math.Min(B.RowCount, B.ColumnCount) - 1]); try_success("Condition()...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Condition()...", "incorrect condition number calculation"); System.Console.Out.WriteLine(e.Message); } int n = A.ColumnCount; A = A.GetMatrix(0, n - 1, 0, n - 1); A[0, 0] = 0.0; LUDecomposition LU = A.LUD(); try { check(A.GetMatrix(LU.Pivot, 0, n - 1), LU.L * LU.U); try_success("LUDecomposition...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "LUDecomposition...", "incorrect LU decomposition calculation"); System.Console.Out.WriteLine(e.Message); } X = A.Inverse(); try { check(A * X, Matrix.Identity(3, 3)); try_success("Inverse()...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Inverse()...", "incorrect Inverse calculation"); System.Console.Out.WriteLine(e.Message); } O = new Matrix(SUB.RowCount, 1, 1.0); SOL = new Matrix(sqSolution); SQ = SUB.GetMatrix(0, SUB.RowCount - 1, 0, SUB.RowCount - 1); try { check(SQ.Solve(SOL), O); try_success("Solve()...", ""); } catch (System.ArgumentException e1) { errorCount = try_failure(errorCount, "Solve()...", e1.Message); System.Console.Out.WriteLine(e1.Message); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "Solve()...", e.Message); System.Console.Out.WriteLine(e.Message); } A = new Matrix(pvals); CholeskyDecomposition Chol = A.chol(); Matrix L = Chol.GetL(); try { check(A, L * Matrix.Transpose(L)); try_success("CholeskyDecomposition...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "CholeskyDecomposition...", "incorrect Cholesky decomposition calculation"); System.Console.Out.WriteLine(e.Message); } X = Chol.Solve(Matrix.Identity(3, 3)); try { check(A * X, Matrix.Identity(3, 3)); try_success("CholeskyDecomposition Solve()...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "CholeskyDecomposition Solve()...", "incorrect Choleskydecomposition Solve calculation"); System.Console.Out.WriteLine(e.Message); } EigenvalueDecomposition Eig = A.Eigen(); Matrix D = Eig.BlockDiagonal; Matrix V = Eig.EigenVectors; try { check(A * V, V * D); try_success("EigenvalueDecomposition (symmetric)...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "EigenvalueDecomposition (symmetric)...", "incorrect symmetric Eigenvalue decomposition calculation"); System.Console.Out.WriteLine(e.Message); } A = new Matrix(evals); Eig = A.Eigen(); D = Eig.BlockDiagonal; V = Eig.EigenVectors; try { check(A * V, V * D); try_success("EigenvalueDecomposition (nonsymmetric)...", ""); } catch (System.SystemException e) { errorCount = try_failure(errorCount, "EigenvalueDecomposition (nonsymmetric)...", "incorrect nonsymmetric Eigenvalue decomposition calculation"); System.Console.Out.WriteLine(e.Message); } print("\nTestMatrix completed.\n"); print("Total errors reported: " + System.Convert.ToString(errorCount) + "\n"); print("Total warnings reported: " + System.Convert.ToString(warningCount) + "\n"); if (errorCount > 0) { throw new Exception("Errors reported."); } }
public void Simple() { var matrixA = new Matrix(5, 5); // // [ 2, 1, 1, 3, 2 ] // // [ 1, 2, 2, 1, 1 ] // // [ 1, 2, 9, 1, 5 ] // // [ 3, 1, 1, 7, 1 ] // // [ 2, 1, 5, 1, 8 ] matrixA[0, 0] = 2; matrixA[0, 1] = 1; matrixA[0, 2] = 1; matrixA[0, 3] = 3; matrixA[0, 4] = 2; matrixA[1, 0] = 1; matrixA[1, 1] = 2; matrixA[1, 2] = 2; matrixA[1, 3] = 1; matrixA[1, 4] = 1; matrixA[2, 0] = 1; matrixA[2, 1] = 2; matrixA[2, 2] = 9; matrixA[2, 3] = 1; matrixA[2, 4] = 5; matrixA[3, 0] = 3; matrixA[3, 1] = 1; matrixA[3, 2] = 1; matrixA[3, 3] = 7; matrixA[3, 4] = 1; matrixA[4, 0] = 2; matrixA[4, 1] = 1; matrixA[4, 2] = 5; matrixA[4, 3] = 1; matrixA[4, 4] = 8; var matrixB = new Matrix(5, 1); matrixB[0, 0] = -2; matrixB[1, 0] = 4; matrixB[2, 0] = 3; matrixB[3, 0] = -5; matrixB[4, 0] = 1; var decomposition = new CholeskyDecomposition(matrixA); var solveMatrix = decomposition.Solve(matrixB); Assert.AreEqual(solveMatrix.Rows, 5); Assert.AreEqual(solveMatrix.Columns, 1); Assert.IsTrue(solveMatrix[0, 0].IsSimilarTo(-629.0 / 98.0)); Assert.IsTrue(solveMatrix[1, 0].IsSimilarTo(237.0 / 49.0)); Assert.IsTrue(solveMatrix[2, 0].IsSimilarTo(-53.0 / 49.0)); Assert.IsTrue(solveMatrix[3, 0].IsSimilarTo(62.0 / 49.0)); Assert.IsTrue(solveMatrix[4, 0].IsSimilarTo(23.0 / 14.0)); }
public static void test_Matrices() { int N = 200; //int N = 2500; DenseMatrix M1 = new DenseMatrix(N, N); SymmetricSparseMatrix M2 = new SymmetricSparseMatrix(); for (int i = 0; i < N; ++i) { for (int j = i; j < N; ++j) { if (i == j) { M1.Set(i, i, N); M2.Set(i, i, N); } else if (j % 2 != 0) { double d = 1.0 / Math.Sqrt(i + j); M1.Set(i, j, d); M1.Set(j, i, d); M2.Set(i, j, d); } } } double[] X = new double[N], b1 = new double[N], b2 = new double[N]; for (int i = 0; i < N; ++i) { X[i] = (double)i / (double)N; } M1.Multiply(X, b1); M2.Multiply(X, b2); for (int i = 0; i < N; ++i) { Debug.Assert(MathUtil.EpsilonEqual(b1[i], b2[i])); } Debug.Assert(M1.IsSymmetric()); Debug.Assert(M1.IsPositiveDefinite()); // test parallel cholesky decomposition LocalProfiler p = new LocalProfiler(); p.Start("chol"); CholeskyDecomposition decompM = new CholeskyDecomposition(M1); decompM.ComputeParallel(); p.Stop("chol"); //System.Console.WriteLine(p.AllTimes()); DenseMatrix LLT_M1 = decompM.L.Multiply(decompM.L.Transpose()); if (LLT_M1.EpsilonEquals(M1) == false) { System.Console.WriteLine("FAIL choleskyM1 did not reproduce input"); } // test cholesky-decomp backsubstitution Random r = new Random(31337); double[] RealX = TestUtil.RandomScalars(N, r, new Interval1d(-10, 10)); double[] B = new double[N], SolvedX = new double[N], TmpY = new double[N]; M1.Multiply(RealX, B); decompM.Solve(B, SolvedX, TmpY); if (BufferUtil.DistanceSquared(RealX, SolvedX) > MathUtil.ZeroTolerance) { System.Console.WriteLine("FAIL choleskyM1 backsubstution did not reproduce input vector"); } // test case from: https://people.cs.kuleuven.be/~karl.meerbergen/didactiek/h03g1a/ilu.pdf //DenseMatrix tmp = new DenseMatrix(6, 6); //tmp.Set(new double[] { // 3,0,-1,-1,0,-1, // 0,2,0,-1,0,0, // -1,0,3,0,-1,0, // -1,-1,0,2,0,-1, // 0,0,-1,0,3,-1, // -1,0,0,-1,-1,4}); //CholeskyDecomposition decompDense = new CholeskyDecomposition(tmp); //decompDense.Compute(); //PackedSparseMatrix M1_sparse = PackedSparseMatrix.FromDense(tmp, true); //M1_sparse.Sort(); //SparseCholeskyDecomposition decompM1_sparse = new SparseCholeskyDecomposition(M1_sparse); //decompM1_sparse.ComputeIncomplete(); // cholesky decomposition known-result test DenseMatrix MSym3x3 = new DenseMatrix(3, 3); MSym3x3.Set(new double[] { 25, 15, -5, 15, 18, 0, -5, 0, 11 }); DenseMatrix MSym3x3_Chol = new DenseMatrix(3, 3); MSym3x3_Chol.Set(new double[] { 5, 0, 0, 3, 3, 0, -1, 1, 3 }); CholeskyDecomposition decomp3x3 = new CholeskyDecomposition(MSym3x3); decomp3x3.Compute(); if (decomp3x3.L.EpsilonEquals(MSym3x3_Chol) == false) { System.Console.WriteLine("FAIL cholesky3x3 incorrect result"); } if (decomp3x3.L.Multiply(decomp3x3.L.Transpose()).EpsilonEquals(MSym3x3) == false) { System.Console.WriteLine("FAIL cholesky3x3 did not reproduce input"); } // cholesky decomposition known-result test DenseMatrix MSym4x4 = new DenseMatrix(4, 4); MSym4x4.Set(new double[] { 18, 22, 54, 42, 22, 70, 86, 62, 54, 86, 174, 134, 42, 62, 134, 106 }); DenseMatrix MSym4x4_Chol = new DenseMatrix(4, 4); MSym4x4_Chol.Set(new double[] { 4.24264, 0, 0, 0, 5.18545, 6.56591, 0, 0, 12.72792, 3.04604, 1.64974, 0, 9.89949, 1.62455, 1.84971, 1.39262 }); CholeskyDecomposition decomp4x4 = new CholeskyDecomposition(MSym4x4); decomp4x4.Compute(); if (decomp4x4.L.EpsilonEquals(MSym4x4_Chol, 0.0001) == false) { System.Console.WriteLine("FAIL cholesky4x4 incorrect result"); } if (decomp4x4.L.Multiply(decomp4x4.L.Transpose()).EpsilonEquals(MSym4x4) == false) { System.Console.WriteLine("FAIL cholesky4x4 did not reproduce input"); } }
// the internal linear regression routine, which assumes inputs are entirely valid private FitResult LinearRegression_Internal(int outputIndex) { // to do a fit, we need more data than parameters if (Count < Dimension) { throw new InsufficientDataException(); } // construct the design matrix SymmetricMatrix D = new SymmetricMatrix(Dimension); for (int i = 0; i < Dimension; i++) { for (int j = 0; j <= i; j++) { if (i == outputIndex) { if (j == outputIndex) { D[i, j] = Count; } else { D[i, j] = storage[j].Mean * Count; } } else { if (j == outputIndex) { D[i, j] = storage[i].Mean * Count; } else { double Dij = 0.0; for (int k = 0; k < Count; k++) { Dij += storage[i][k] * storage[j][k]; } D[i, j] = Dij; } } } } // construct the right hand side ColumnVector b = new ColumnVector(Dimension); for (int i = 0; i < Dimension; i++) { if (i == outputIndex) { b[i] = storage[i].Mean * Count; } else { double bi = 0.0; for (int k = 0; k < Count; k++) { bi += storage[outputIndex][k] * storage[i][k]; } b[i] = bi; } } // solve the system for the linear model parameters CholeskyDecomposition CD = D.CholeskyDecomposition(); ColumnVector parameters = CD.Solve(b); // find total sum of squares, with dof = # points - 1 (minus one for the variance-minimizing mean) double totalSumOfSquares = storage[outputIndex].Variance * Count; // find remaining unexplained sum of squares, with dof = # points - # parameters double unexplainedSumOfSquares = 0.0; for (int r = 0; r < Count; r++) { double y = 0.0; for (int c = 0; c < Dimension; c++) { if (c == outputIndex) { y += parameters[c]; } else { y += parameters[c] * storage[c][r]; } } unexplainedSumOfSquares += MoreMath.Sqr(y - storage[outputIndex][r]); } int unexplainedDegreesOfFreedom = Count - Dimension; double unexplainedVariance = unexplainedSumOfSquares / unexplainedDegreesOfFreedom; // find explained sum of squares, with dof = # parameters - 1 double explainedSumOfSquares = totalSumOfSquares - unexplainedSumOfSquares; int explainedDegreesOfFreedom = Dimension - 1; double explainedVariance = explainedSumOfSquares / explainedDegreesOfFreedom; // compute F statistic from sums of squares double F = explainedVariance / unexplainedVariance; Distribution fDistribution = new FisherDistribution(explainedDegreesOfFreedom, unexplainedDegreesOfFreedom); SymmetricMatrix covariance = unexplainedVariance * CD.Inverse(); return(new FitResult(parameters, covariance, new TestResult("F", F, TestType.RightTailed, fDistribution))); }