CSharp 对称矩阵的实特征值和特征向量 源代码
时间: 2023-09-24 10:13:43 浏览: 45
以下是C#中对称矩阵的实特征值和特征向量的源代码:
```csharp
using System;
class Program
{
static void Main(string[] args)
{
// Define the symmetric matrix.
double[,] m = new double[,] { { 1, 2, 3 }, { 2, 4, 5 }, { 3, 5, 6 } };
// Get the eigenvalues and eigenvectors.
double[] eigenvalues;
double[,] eigenvectors;
SymmetricEigenSolver(m, out eigenvalues, out eigenvectors);
// Print the results.
Console.WriteLine("Eigenvalues:");
for (int i = 0; i < eigenvalues.Length; i++)
{
Console.WriteLine("{0:F4}", eigenvalues[i]);
}
Console.WriteLine("\nEigenvectors:");
for (int i = 0; i < eigenvectors.GetLength(0); i++)
{
for (int j = 0; j < eigenvectors.GetLength(1); j++)
{
Console.Write("{0:F4}\t", eigenvectors[i, j]);
}
Console.WriteLine();
}
Console.ReadKey();
}
static void SymmetricEigenSolver(double[,] m, out double[] eigenvalues, out double[,] eigenvectors)
{
int n = m.GetLength(0);
eigenvalues = new double[n];
eigenvectors = new double[n, n];
// Initialize the eigenvectors to the identity matrix.
for (int i = 0; i < n; i++)
{
eigenvectors[i, i] = 1;
}
double tolerance = 1e-10;
bool converged = false;
int maxIterations = 1000;
int iterations = 0;
while (!converged && iterations < maxIterations)
{
// Find the maximum off-diagonal element.
int p = 0;
int q = 0;
double maxOffDiagonal = 0;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (Math.Abs(m[i, j]) > maxOffDiagonal)
{
maxOffDiagonal = Math.Abs(m[i, j]);
p = i;
q = j;
}
}
}
// Compute the rotation angle.
double angle = 0;
if (m[p, p] == m[q, q])
{
angle = Math.PI / 4;
}
else
{
double a = 2 * m[p, q];
double b = m[p, p] - m[q, q];
double c = Math.Sqrt(a * a + b * b);
double cos = Math.Sqrt((c + b) / (2 * c));
double sin = a / (2 * c * cos);
angle = Math.Atan2(sin, cos);
}
// Compute the rotation matrix.
double[,] r = new double[n, n];
for (int i = 0; i < n; i++)
{
r[i, i] = 1;
}
r[p, p] = Math.Cos(angle);
r[p, q] = -Math.Sin(angle);
r[q, p] = Math.Sin(angle);
r[q, q] = Math.Cos(angle);
// Update the matrix and eigenvectors.
m = MatrixMultiply(MatrixMultiply(MatrixTranspose(r), m), r);
eigenvectors = MatrixMultiply(eigenvectors, r);
// Check for convergence.
double maxOffDiagonalAfter = 0;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (Math.Abs(m[i, j]) > maxOffDiagonalAfter)
{
maxOffDiagonalAfter = Math.Abs(m[i, j]);
}
}
}
if (maxOffDiagonalAfter < tolerance)
{
converged = true;
}
iterations++;
}
// Extract the eigenvalues and eigenvectors.
for (int i = 0; i < n; i++)
{
eigenvalues[i] = m[i, i];
for (int j = 0; j < n; j++)
{
eigenvectors[i, j] = eigenvectors[i, j] / eigenvectors[n - 1, j];
}
}
}
static double[,] MatrixMultiply(double[,] m1, double[,] m2)
{
int rows1 = m1.GetLength(0);
int cols1 = m1.GetLength(1);
int cols2 = m2.GetLength(1);
double[,] result = new double[rows1, cols2];
for (int i = 0; i < rows1; i++)
{
for (int j = 0; j < cols2; j++)
{
for (int k = 0; k < cols1; k++)
{
result[i, j] += m1[i, k] * m2[k, j];
}
}
}
return result;
}
static double[,] MatrixTranspose(double[,] m)
{
int rows = m.GetLength(0);
int cols = m.GetLength(1);
double[,] result = new double[cols, rows];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
result[j, i] = m[i, j];
}
}
return result;
}
}
```
该代码使用Jacobi迭代方法来计算对称矩阵的实特征值和特征向量。特别地,它使用正交变换将矩阵对角化,并且在每次迭代中找到最大的非对角元素,并通过一个旋转矩阵将其变为零。一旦所有非对角元素都足够小,迭代就会停止,并且对角线元素就是矩阵的实特征值,而正交变换的乘积就是特征向量。