public static GaussLegendreCoefficients GaussLegendre(int N) { var beta = from i in 1.To(N - 1) select 0.5 / Math.Sqrt(1.0 - (2.0 * i).Pow(-2)); SymmetricMatrix T = new SymmetricMatrix(N); // how to use TridiagonalMatrix? beta.ForEach((b, i) => { T[i + 1, i] = b; T[i, i + 1] = b; }); var e = T.Eigendecomposition(); var indices = from i in 0.To(N - 1) orderby e.Eigenpairs[i].Eigenvalue select i; return(new GaussLegendreCoefficients { mu = indices.Select(i => e.Eigenpairs[i].Eigenvalue).ToArray(), wt = indices.Select(i => 2 * e.Eigenpairs[i].Eigenvector[0].Pow(2)).ToArray() }); }
public static void EigenvaluesAndEigenvectors() { SymmetricMatrix H = new SymmetricMatrix(3); for (int r = 0; r < H.Dimension; r++) { for (int c = 0; c <= r; c++) { H[r, c] = 1.0 / (r + c + 1); } } RealEigendecomposition ed = H.Eigendecomposition(); SquareMatrix V = ed.TransformMatrix; PrintMatrix("V^T V", V.Transpose * V); PrintMatrix("V D V^T", V * ed.DiagonalizedMatrix * V.Transpose); foreach (RealEigenpair pair in ed.Eigenpairs) { Console.WriteLine($"Eigenvalue {pair.Eigenvalue}"); PrintMatrix("Hv", H * pair.Eigenvector); PrintMatrix("ev", pair.Eigenvalue * pair.Eigenvector); } ed.Eigenpairs.Sort(OrderBy.MagnitudeDescending); Console.WriteLine($"Largest eigenvalue {ed.Eigenpairs[0].Eigenvalue}"); ed.Eigenpairs.Sort(OrderBy.ValueAscending); Console.WriteLine($"Least eigenvalue {ed.Eigenpairs[0].Eigenvalue}"); double[] eigenvalues = H.Eigenvalues(); double sum = 0.0; double product = 1.0; foreach (double eigenvalue in eigenvalues) { sum += eigenvalue; product *= eigenvalue; } Console.WriteLine($"sum(e) = {sum}, tr(H) = {H.Trace()}"); Console.WriteLine($"prod(e) = {product}, det(H) = {H.CholeskyDecomposition().Determinant()}"); SquareMatrix G1 = new SquareMatrix(4); G1[0, 3] = 1.0; G1[1, 2] = 1.0; G1[2, 1] = -1.0; G1[3, 0] = -1.0; ComplexEigendecomposition ced = G1.Eigendecomposition(); foreach (ComplexEigenpair pair in ced.Eigenpairs) { Console.WriteLine(pair.Eigenvalue); } }
public void RealEigenvalueOrdering() { int d = 10; Random rng = new Random(d + 1); SymmetricMatrix A = new SymmetricMatrix(d); A.Fill((int r, int c) => - 1.0 + 2.0 * rng.NextDouble()); RealEigendecomposition E = A.Eigendecomposition(); RealEigenpairCollection pairs = E.Eigenpairs; pairs.Sort(OrderBy.ValueAscending); for (int i = 1; i < pairs.Count; i++) { Assert.IsTrue(pairs[i - 1].Eigenvalue <= pairs[i].Eigenvalue); Assert.IsTrue(TestUtilities.IsNearlyEigenpair(A, pairs[i].Eigenvector, pairs[i].Eigenvalue)); } pairs.Sort(OrderBy.ValueDescending); for (int i = 1; i < pairs.Count; i++) { Assert.IsTrue(pairs[i - 1].Eigenvalue >= pairs[i].Eigenvalue); Assert.IsTrue(TestUtilities.IsNearlyEigenpair(A, pairs[i].Eigenvector, pairs[i].Eigenvalue)); } pairs.Sort(OrderBy.MagnitudeAscending); for (int i = 1; i < pairs.Count; i++) { Assert.IsTrue(Math.Abs(pairs[i - 1].Eigenvalue) <= Math.Abs(pairs[i].Eigenvalue)); Assert.IsTrue(TestUtilities.IsNearlyEigenpair(A, pairs[i].Eigenvector, pairs[i].Eigenvalue)); } pairs.Sort(OrderBy.MagnitudeDescending); for (int i = 1; i < pairs.Count; i++) { Assert.IsTrue(Math.Abs(pairs[i - 1].Eigenvalue) >= Math.Abs(pairs[i].Eigenvalue)); Assert.IsTrue(TestUtilities.IsNearlyEigenpair(A, pairs[i].Eigenvector, pairs[i].Eigenvalue)); } }
public void SymmetricRandomMatrixEigenvectors() { for (int d = 1; d <= 100; d = d + 11) { SymmetricMatrix M = CreateSymmetricRandomMatrix(d, 1); RealEigendecomposition E = M.Eigendecomposition(); Assert.IsTrue(E.Dimension == M.Dimension); double[] eigenvalues = new double[E.Dimension]; for (int i = 0; i < E.Dimension; i++) { double e = E.Eigenpairs[i].Eigenvalue; ColumnVector v = E.Eigenpairs[i].Eigenvector; // The eigenvector works Assert.IsTrue(TestUtilities.IsNearlyEigenpair(M, v, e)); // The eigenvalue is the corresponding diagonal value of D Assert.IsTrue(E.DiagonalizedMatrix[i, i] == e); // Remember eigenvalue to take sum in future eigenvalues[i] = e; } // The eigenvectors sum to trace double tr = M.Trace(); Assert.IsTrue(TestUtilities.IsSumNearlyEqual(eigenvalues, tr)); // The decomposition works Assert.IsTrue(TestUtilities.IsNearlyEqual( E.DiagonalizedMatrix, E.TransformMatrix.Transpose * M * E.TransformMatrix )); // Transform matrix is orthogonal Assert.IsTrue(TestUtilities.IsNearlyEqual( E.TransformMatrix.Transpose * E.TransformMatrix, UnitMatrix.OfDimension(d) )); } }