Beispiel #1
0
        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);
        }
Beispiel #2
0
        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));
            }
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
        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);
        }