public void QrDecompositionConstructorTest() { double[,] value = { { 2, -1, 0 }, { -1, 2, -1 }, { 0, -1, 2 } }; QrDecomposition target = new QrDecomposition(value); // Decomposition Identity var Q = target.OrthogonalFactor; var QQt = Q.Multiply(Q.Transpose()); Assert.IsTrue(Matrix.IsEqual(QQt, Matrix.Identity(3), 0.0000001)); // Linear system solving double[,] B = Matrix.ColumnVector(new double[] { 1, 2, 3 }); double[,] expected = Matrix.ColumnVector(new double[] { 2.5, 4.0, 3.5 }); double[,] actual = target.Solve(B); Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.0000000000001)); }
public void InverseTestNaN() { int n = 5; var I = Matrix.Identity(n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { double[,] value = Matrix.Magic(n); value[i, j] = double.NaN; var target = new QrDecomposition(value); var solution = target.Solve(I); var inverse = target.Inverse(); Assert.IsTrue(Matrix.IsEqual(solution, inverse)); } } }
/// <summary>QR decomposition.</summary> protected static void qr(double[,] m, out double[,] Q, out double[,] R, out double[] d) { var qr = new QrDecomposition(m); Q = qr.OrthogonalFactor; R = qr.UpperTriangularFactor; d = qr.Diagonal; }
public void SolveTransposeTest() { double[,] a = { { 2, 1, 4 }, { 6, 2, 2 }, { 0, 1, 6 }, }; double[,] b = { { 1, 0, 7 }, { 5, 2, 1 }, { 1, 5, 2 }, }; double[,] expected = { { 0.5062, 0.2813, 0.0875 }, { 0.1375, 1.1875, -0.0750 }, { 0.8063, -0.2188, 0.2875 }, }; double[,] actual = new QrDecomposition(b, true).SolveTranspose(a); Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.001)); }
public void SolveTest2() { // Example from Lecture notes for MATHS 370: Advanced Numerical Methods // http://www.math.auckland.ac.nz/~sharp/370/qr-solving.pdf double[,] value = { { 1, 0, 0 }, { 1, 7, 49 }, { 1, 14, 196 }, { 1, 21, 441 }, { 1, 28, 784 }, { 1, 35, 1225 }, }; // Matrices { double[,] b = { { 4 }, { 1 }, { 0 }, { 0 }, { 2 }, { 5 }, }; double[,] expected = { { 3.9286 }, { -0.5031 }, { 0.0153 }, }; QrDecomposition target = new QrDecomposition(value); double[,] actual = target.Solve(b); Assert.IsTrue(Matrix.IsEqual(expected, actual, 1e-4)); } // Vectors { double[] b = { 4, 1, 0, 0, 2, 5 }; double[] expected = { 3.9286, -0.5031, 0.0153 }; QrDecomposition target = new QrDecomposition(value); double[] actual = target.Solve(b); Assert.IsTrue(Matrix.IsEqual(expected, actual, 1e-4)); } }
public void SolveTest() { double[,] value = { { 2, -1, 0 }, { -1, 2, -1 }, { 0, -1, 2 } }; double[] b = { 1, 2, 3 }; double[] expected = { 2.5000, 4.0000, 3.5000 }; QrDecomposition target = new QrDecomposition(value); double[] actual = target.Solve(b); Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.0000000000001)); }
public void InverseTest() { double[,] value = { { 2, -1, 0 }, { -1, 2, -1 }, { 0, -1, 2 } }; double[,] expected = { { 0.7500, 0.5000, 0.2500}, { 0.5000, 1.0000, 0.5000}, { 0.2500, 0.5000, 0.7500}, }; QrDecomposition target = new QrDecomposition(value); double[,] actual = target.Inverse(); Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.0000000000001)); target = new QrDecomposition(value.Transpose(), true); actual = target.Inverse(); Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.0000000000001)); }
static void Main(string[] args) { Console.WriteLine("Please take a look at the source for examples!"); Console.ReadKey(); #region 1. Declaring matrices // 1.1 Using standard .NET declaration double[,] A = { {1, 2, 3}, {6, 2, 0}, {0, 0, 1} }; double[,] B = { {2, 0, 0}, {0, 2, 0}, {0, 0, 2} }; { // 1.2 Using Accord extension methods double[,] Bi = Matrix.Identity(3).Multiply(2); double[,] Bj = Matrix.Diagonal(3, 2.0); // both are equal to B // 1.2 Using Accord extension methods with implicit typing var I = Matrix.Identity(3); } #endregion #region 2. Matrix Operations { // 2.1 Addition var C = A.Add(B); // 2.2 Subtraction var D = A.Subtract(B); // 2.3 Multiplication { // 2.3.1 By a scalar var halfM = A.Multiply(0.5); // 2.3.2 By a vector double[] m = A.Multiply(new double[] { 1, 2, 3 }); // 2.3.3 By a matrix var M = A.Multiply(B); // 2.4 Transposing var At = A.Transpose(); } } // 2.5 Elementwise operations // 2.5.1 Elementwise multiplication A.ElementwiseMultiply(B); // A.*B // 2.5.1 Elementwise division A.ElementwiseDivide(B); // A./B #endregion #region 3. Matrix characteristics { // 3.1 Calculating the determinant double det = A.Determinant(); // 3.2 Calculating the trace double tr = A.Trace(); // 3.3 Computing the sum vector { double[] sumVector = A.Sum(); // 3.3.1 Computing the total sum of elements double sum = sumVector.Sum(); // 3.3.2 Computing the sum along the rows sumVector = A.Sum(0); // Equivalent to Octave's sum(A, 1) // 3.3.2 Computing the sum along the columns sumVector = A.Sum(1); // Equivalent to Octave's sum(A, 2) } } #endregion #region 4. Linear Algebra { // 4.1 Computing the inverse var invA = A.Inverse(); // 4.2 Computing the pseudo-inverse var pinvA = A.PseudoInverse(); // 4.3 Solving a linear system (Ax = B) var x = A.Solve(B); } #endregion #region 5. Special operators { // 5.1 Finding the indices of elements double[] v = { 5, 2, 2, 7, 1, 0 }; int[] idx = v.Find(e => e > 2); // finding the index of every element in v higher than 2. // 5.2 Selecting elements by index double[] u = v.Submatrix(idx); // u is { 5, 7 } // 5.3 Converting between different matrix representations double[][] jaggedA = A.ToArray(); // from multidimensional to jagged array // 5.4 Extracting a column or row from the matrix double[] a = A.GetColumn(0); // retrieves the first column double[] b = B.GetRow(1); // retrieves the second row // 5.5 Taking the absolute of a matrix var absA = A.Abs(); // 5.6 Applying some function to every element var newv = v.Apply(e => e + 1); } #endregion #region 7. Vector operations { double[] u = { 1, 2, 3 }; double[] v = { 4, 5, 6 }; var w1 = u.InnerProduct(v); var w2 = u.OuterProduct(v); var w3 = u.CartesianProduct(v); double[] m = { 1, 2, 3, 4 }; double[,] M = Matrix.Reshape(m, 2, 2); } #endregion #region Decompositions { // Singular value decomposition { SingularValueDecomposition svd = new SingularValueDecomposition(A); var U = svd.LeftSingularVectors; var S = svd.Diagonal; var V = svd.RightSingularVectors; } // or (please see documentation for details) { SingularValueDecomposition svd = new SingularValueDecomposition(A.Transpose()); var U = svd.RightSingularVectors; var S = svd.Diagonal; var V = svd.LeftSingularVectors; } // Eigenvalue decomposition { EigenvalueDecomposition eig = new EigenvalueDecomposition(A); var V = eig.Eigenvectors; var D = eig.DiagonalMatrix; } // QR decomposition { QrDecomposition qr = new QrDecomposition(A); var Q = qr.OrthogonalFactor; var R = qr.UpperTriangularFactor; } // Cholesky decomposition { CholeskyDecomposition chol = new CholeskyDecomposition(A); var R = chol.LeftTriangularFactor; } // LU decomposition { LuDecomposition lu = new LuDecomposition(A); var L = lu.LowerTriangularFactor; var U = lu.UpperTriangularFactor; } } #endregion }
/// <summary> /// Creates a new object that is a copy of the current instance. /// </summary> /// <returns> /// A new object that is a copy of this instance. /// </returns> public object Clone() { var clone = new QrDecomposition(); clone.qr = (double[,])qr.Clone(); clone.Rdiag = (double[])Rdiag.Clone(); return clone; }
private double regress(double[][] inputs, double[] outputs, out double[,] designMatrix, bool robust) { if (inputs.Length != outputs.Length) throw new ArgumentException("Number of input and output samples does not match", "outputs"); int parameters = Inputs; int rows = inputs.Length; // number of instance points int cols = Inputs; // dimension of each point for (int i = 0; i < inputs.Length; i++) { if (inputs[i].Length != parameters) { throw new DimensionMismatchException("inputs", String.Format( "Input vectors should have length {0}. The row at index {1} of the" + " inputs matrix has length {2}.", parameters, i, inputs[i].Length)); } } ISolverMatrixDecomposition<double> solver; // Create the problem's design matrix. If we // have to add an intercept term, add a new // extra column at the end and fill with 1s. if (!addIntercept) { // Just copy values over designMatrix = new double[rows, cols]; for (int i = 0; i < inputs.Length; i++) for (int j = 0; j < inputs[i].Length; j++) designMatrix[i, j] = inputs[i][j]; } else { // Add an intercept term designMatrix = new double[rows, cols + 1]; for (int i = 0; i < inputs.Length; i++) { for (int j = 0; j < inputs[i].Length; j++) designMatrix[i, j] = inputs[i][j]; designMatrix[i, cols] = 1; } } // Check if we have an overdetermined or underdetermined // system to select an appropriate matrix solver method. if (robust || cols >= rows) { // We have more variables than equations, an // underdetermined system. Solve using a SVD: solver = new SingularValueDecomposition(designMatrix, computeLeftSingularVectors: true, computeRightSingularVectors: true, autoTranspose: true); } else { // We have more equations than variables, an // overdetermined system. Solve using the QR: solver = new QrDecomposition(designMatrix); } // Solve V*C = B to find C (the coefficients) coefficients = solver.Solve(outputs); // Calculate Sum-Of-Squares error double error = 0.0; double e; for (int i = 0; i < outputs.Length; i++) { e = outputs[i] - Compute(inputs[i]); error += e * e; } return error; }
public void SolveTransposeTest() { double[][] a = { new double[] { 2, 1, 4 }, new double[] { 6, 2, 2 }, new double[] { 0, 1, 6 }, }; double[][] b = { new double[] { 1, 0, 7 }, new double[] { 5, 2, 1 }, new double[] { 1, 5, 2 }, }; double[][] expected = { new double[] { 0.5062, 0.2813, 0.0875 }, new double[] { 0.1375, 1.1875, -0.0750 }, new double[] { 0.8063, -0.2188, 0.2875 }, }; double[][] actual = new JaggedQrDecomposition(b, true).SolveTranspose(a); Assert.IsTrue(Matrix.IsEqual(expected, actual, 0.001)); var bX = b.Dot(expected); var Xb = expected.Dot(b); Assert.IsTrue(Matrix.IsEqual(Xb, a, atol: 1e-3)); Assert.IsFalse(Matrix.IsEqual(bX, a, atol: 1e-3)); double[,] actualMatrix = new QrDecomposition(b.ToMatrix(), true).SolveTranspose(a.ToMatrix()); Assert.IsTrue(Matrix.IsEqual(expected, actualMatrix, 0.001)); }
public void InverseTest1() { double[][] value = { new double[] { 41.9, 29.1, 1 }, new double[] { 43.4, 29.3, 1 }, new double[] { 43.9, 29.5, 0 }, new double[] { 44.5, 29.7, 0 }, new double[] { 47.3, 29.9, 0 }, new double[] { 47.5, 30.3, 0 }, new double[] { 47.9, 30.5, 0 }, new double[] { 50.2, 30.7, 0 }, new double[] { 52.8, 30.8, 0 }, new double[] { 53.2, 30.9, 0 }, new double[] { 56.7, 31.5, 0 }, new double[] { 57.0, 31.7, 0 }, new double[] { 63.5, 31.9, 0 }, new double[] { 65.3, 32.0, 0 }, new double[] { 71.1, 32.1, 0 }, new double[] { 77.0, 32.5, 0 }, new double[] { 77.8, 32.9, 0 } }; double[][] expected = new JaggedSingularValueDecomposition(value, computeLeftSingularVectors: true, computeRightSingularVectors: true, autoTranspose: true).Inverse(); var target = new JaggedQrDecomposition(value); double[][] actual = target.Inverse(); Assert.IsTrue(Matrix.IsEqual(expected, actual, atol: 1e-4)); var targetMat = new QrDecomposition(value.ToMatrix()); double[][] actualMat = target.Inverse(); Assert.IsTrue(Matrix.IsEqual(expected, actualMat, atol: 1e-4)); }
public void SolveTest3() { double[][] value = { new double[] { 41.9, 29.1, 1 }, new double[] { 43.4, 29.3, 1 }, new double[] { 43.9, 29.5, 0 }, new double[] { 44.5, 29.7, 0 }, new double[] { 47.3, 29.9, 0 }, new double[] { 47.5, 30.3, 0 }, new double[] { 47.9, 30.5, 0 }, new double[] { 50.2, 30.7, 0 }, new double[] { 52.8, 30.8, 0 }, new double[] { 53.2, 30.9, 0 }, new double[] { 56.7, 31.5, 0 }, new double[] { 57.0, 31.7, 0 }, new double[] { 63.5, 31.9, 0 }, new double[] { 65.3, 32.0, 0 }, new double[] { 71.1, 32.1, 0 }, new double[] { 77.0, 32.5, 0 }, new double[] { 77.8, 32.9, 0 } }; double[][] b = { new double[] { 251.3 }, new double[] { 251.3 }, new double[] { 248.3 }, new double[] { 267.5 }, new double[] { 273.0 }, new double[] { 276.5 }, new double[] { 270.3 }, new double[] { 274.9 }, new double[] { 285.0 }, new double[] { 290.0 }, new double[] { 297.0 }, new double[] { 302.5 }, new double[] { 304.5 }, new double[] { 309.3 }, new double[] { 321.7 }, new double[] { 330.7 }, new double[] { 349.0 } }; double[][] expected = { new double[] { 1.7315235669547167 }, new double[] { 6.25142110500275 }, new double[] { -5.0909763966987178 }, }; var target = new JaggedQrDecomposition(value); double[][] actual = target.Solve(b); Assert.IsTrue(Matrix.IsEqual(expected, actual, atol: 1e-4)); var reconstruct = value.Dot(expected); Assert.IsTrue(Matrix.IsEqual(reconstruct, b, rtol: 1e-1)); double[] b2 = b.GetColumn(0); double[] expected2 = expected.GetColumn(0); var target2 = new JaggedQrDecomposition(value); double[] actual2 = target2.Solve(b2); Assert.IsTrue(Matrix.IsEqual(expected2, actual2, atol: 1e-4)); var targetMat = new QrDecomposition(value.ToMatrix()); double[,] actualMat = targetMat.Solve(b.ToMatrix()); Assert.IsTrue(Matrix.IsEqual(expected, actualMat, atol: 1e-4)); var reconstructMat = value.ToMatrix().Dot(expected); Assert.IsTrue(Matrix.IsEqual(reconstruct, b, rtol: 1e-1)); var targetMat2 = new QrDecomposition(value.ToMatrix()); double[] actualMat2 = targetMat2.Solve(b2); Assert.IsTrue(Matrix.IsEqual(expected2, actualMat2, atol: 1e-4)); }