public static void QRDecomposition() { SquareMatrix A = new SquareMatrix(new double[, ] { { 1, -2, 3 }, { 2, -5, 12 }, { 0, 2, -10 } }); ColumnVector b = new ColumnVector(2, 8, -4); SquareQRDecomposition qrd = A.QRDecomposition(); ColumnVector x = qrd.Solve(b); PrintMatrix("x", x); SquareMatrix Q = qrd.QMatrix; SquareMatrix R = qrd.RMatrix; PrintMatrix("QR", Q * R); PrintMatrix("Q Q^T", Q.MultiplySelfByTranspose()); SquareMatrix AI = qrd.Inverse(); PrintMatrix("A^{-1}", AI); PrintMatrix("A^{-1} A", AI * A); }
public void SquareRandomMatrixQRDecomposition() { for (int d = 1; d <= 100; d += 11) { Console.WriteLine("d={0}", d); SquareMatrix M = CreateSquareRandomMatrix(d); // QR decompose the matrix. SquareQRDecomposition QRD = M.QRDecomposition(); // The dimension should be right. Assert.IsTrue(QRD.Dimension == M.Dimension); // Test that the decomposition works. SquareMatrix Q = QRD.QMatrix; SquareMatrix R = QRD.RMatrix; Assert.IsTrue(TestUtilities.IsNearlyEqual(Q * R, M)); // Check that the inverse works. SquareMatrix MI = QRD.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(M * MI, UnitMatrix.OfDimension(d))); // Test that a solution works. ColumnVector t = new ColumnVector(d); for (int i = 0; i < d; i++) { t[i] = i; } ColumnVector s = QRD.Solve(t); Assert.IsTrue(TestUtilities.IsNearlyEqual(M * s, t)); } }
public void CirculantEigenvalues() { // See https://en.wikipedia.org/wiki/Circulant_matrix // Definition is C_{ij} = c_{|i - j|} for any n-vector c. // jth eigenvector known to be (1, \omega_j, \omega_j^2, \cdots, \omega_j^{n-1}) where \omega_j = \exp(2 \pi i j / n) are nth roots of unity // jth eigenvalue known to be c_0 + c_{n-1} \omega_j + c_{n-2} \omega_j^2 + \cdots + c_1 \omega_j^{n-1} int n = 12; double[] x = new double[n]; for (int i = 0; i < x.Length; i++) { x[i] = 1.0 / (i + 1); } SquareMatrix A = CreateCirculantMatrix(x); Complex[] u = RootsOfUnity(n); Complex[] v = new Complex[n]; for (int i = 0; i < v.Length; i++) { for (int j = 0; j < n; j++) { v[i] += x[j] * u[(i * (n - j)) % n]; } } Complex[][] w = new Complex[n][]; for (int i = 0; i < n; i++) { w[i] = new Complex[n]; for (int j = 0; j < n; j++) { w[i][j] = u[i * j % n]; } } Complex[] eValues = A.Eigenvalues(); Complex eProduct = 1.0; foreach (Complex eValue in eValues) { eProduct *= eValue; } // v and eValues should be equal. By inspection they are, // but how to verify this given floating point jitter? // Verify that eigenvalue product equals determinant. SquareQRDecomposition QR = A.QRDecomposition(); double det = QR.Determinant(); Assert.IsTrue(TestUtilities.IsNearlyEqual(eProduct, det)); }
public void CirculantEigenvalues() { int n = 12; double[] x = new double[n]; for (int i = 0; i < x.Length; i++) { x[i] = 1.0 / (i + 1); } SquareMatrix A = CreateCirculantMatrix(x); Complex[] u = RootsOfUnity(n); Complex[] v = new Complex[n]; for (int i = 0; i < v.Length; i++) { for (int j = 0; j < n; j++) { v[i] += x[j] * u[(i * (n - j)) % n]; } } Complex[][] w = new Complex[n][]; for (int i = 0; i < n; i++) { w[i] = new Complex[n]; for (int j = 0; j < n; j++) { w[i][j] = u[i * j % n]; } } Complex[] eValues = A.Eigenvalues(); Complex eProduct = 1.0; foreach (Complex eValue in eValues) { eProduct *= eValue; } // v and eValues should be equal. By inspection they are, // but how to verify this given floating point jitter? // Verify that eigenvalue product equals determinant. SquareQRDecomposition QR = A.QRDecomposition(); double det = QR.Determinant(); Assert.IsTrue(TestUtilities.IsNearlyEqual(eProduct, det)); }
public void doWork() { matrix.Fill((j, i) => array[i, j]); SquareQRDecomposition qr = matrix.QRDecomposition(); SquareLUDecomposition lu = matrix.LUDecomposition(); ColumnVector qrresult = qr.Solve(vector); ColumnVector luresult = lu.Solve(vector); ColumnVector c6 = matrix.Column(6); RowVector r2 = matrix.Row(2); SquareMatrix inv = matrix.Inverse(); ColumnVector result = new ColumnVector(inv.Dimension); for (int i = 0; i < matrix.Dimension; ++i) { for (int j = 0; j < matrix.Dimension; ++j) { result[i] += matrix[i, j] * qrresult[j]; } } }
public static QuadraticInterpolationModel Construct(double[][] points, double[] values) { int m = points.Length; int d = points[0].Length; // find the minimum point, use it as the origin int iMin = 0; double fMin = values[0]; for (int i = 1; i < values.Length; i++) { if (values[i] < fMin) { iMin = i; fMin = values[i]; } } SquareMatrix A = new SquareMatrix(m); int c = 0; for (int r = 0; r < m; r++) { A[r, 0] = 1.0; } for (int i = 0; i < d; i++) { c++; for (int r = 0; r < m; r++) { A[r, c] = points[r][i] - points[iMin][i]; } } for (int i = 0; i < d; i++) { for (int j = 0; j <= i; j++) { c++; for (int r = 0; r < m; r++) { A[r, c] = (points[r][i] - points[iMin][i]) * (points[r][j] - points[iMin][j]); } } } ColumnVector b = new ColumnVector(values); SquareQRDecomposition QR = A.QRDecomposition(); ColumnVector a = QR.Solve(b); QuadraticInterpolationModel model = new QuadraticInterpolationModel(); model.d = d; model.origin = points[iMin]; model.f0 = a[0]; model.g = new double[d]; c = 0; for (int i = 0; i < d; i++) { c++; model.g[i] = a[c]; } model.h = new double[d][]; for (int i = 0; i < d; i++) { model.h[i] = new double[d]; } for (int i = 0; i < d; i++) { for (int j = 0; j <= i; j++) { c++; if (i == j) { model.h[i][j] = 2.0 * a[c]; } else { model.h[i][j] = a[c]; model.h[j][i] = a[c]; } } } return(model); }