欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#计算矩阵的逆矩阵方法实例分析

程序员文章站 2023-12-04 23:35:16
本文实例讲述了c#计算矩阵的逆矩阵方法。分享给大家供大家参考。具体如下: 1.代码思路 1)对矩阵进行合法性检查:矩阵必须为方阵 2)计算矩阵行列式的值(determ...

本文实例讲述了c#计算矩阵的逆矩阵方法。分享给大家供大家参考。具体如下:

1.代码思路

1)对矩阵进行合法性检查:矩阵必须为方阵
2)计算矩阵行列式的值(determinant函数)
3)只有满秩矩阵才有逆矩阵,因此如果行列式的值为0(在代码中以绝对值小于1e-6做判断),则终止函数,报出异常
4)求出伴随矩阵(adjointmatrix函数)
5)逆矩阵各元素即其伴随矩阵各元素除以矩阵行列式的商

2.函数代码

(注:本段代码只实现了一个思路,可能并不是该问题的最优解)

/// <summary>
/// 求矩阵的逆矩阵
/// </summary>
/// <param name="matrix"></param>
/// <returns></returns>
public static double[][] inversematrix(double[][] matrix)
{
 //matrix必须为非空
 if (matrix == null || matrix.length == 0)
 {
  return new double[][] { };
 }
 //matrix 必须为方阵
 int len = matrix.length;
 for (int counter = 0; counter < matrix.length; counter++)
 {
  if (matrix[counter].length != len)
  {
   throw new exception("matrix 必须为方阵");
  }
 }
 //计算矩阵行列式的值
 double ddeterminant = determinant(matrix);
 if (math.abs(ddeterminant) <= 1e-6)
 {
  throw new exception("矩阵不可逆");
 }
 //制作一个伴随矩阵大小的矩阵
 double[][] result = adjointmatrix(matrix);
 //矩阵的每项除以矩阵行列式的值,即为所求
 for (int i = 0; i < matrix.length; i++)
 {
  for (int j = 0; j < matrix.length; j++)
  {
   result[i][j] = result[i][j] / ddeterminant;
  }
 }
 return result;
}
/// <summary>
/// 递归计算行列式的值
/// </summary>
/// <param name="matrix">矩阵</param>
/// <returns></returns>
public static double determinant(double[][] matrix)
{
 //二阶及以下行列式直接计算
 if (matrix.length == 0) return 0;
 else if (matrix.length == 1) return matrix[0][0];
 else if (matrix.length == 2)
 {
  return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
 }
 //对第一行使用“加边法”递归计算行列式的值
 double dsum = 0, dsign = 1;
 for (int i = 0; i < matrix.length; i++)
 {
  double[][] matrixtemp = new double[matrix.length - 1][];
  for (int count = 0; count < matrix.length - 1; count++)
  {
   matrixtemp[count] = new double[matrix.length - 1];
  }
  for (int j = 0; j < matrixtemp.length; j++)
  {
   for (int k = 0; k < matrixtemp.length; k++)
   {
    matrixtemp[j][k] = matrix[j + 1][k >= i ? k + 1 : k];
   }
  }
  dsum += (matrix[0][i] * dsign * determinant(matrixtemp));
  dsign = dsign * -1;
 }
 return dsum;
}
/// <summary>
/// 计算方阵的伴随矩阵
/// </summary>
/// <param name="matrix">方阵</param>
/// <returns></returns>
public static double[][] adjointmatrix(double [][] matrix)
{
 //制作一个伴随矩阵大小的矩阵
 double[][] result = new double[matrix.length][];
 for (int i = 0; i < result.length; i++)
 {
  result[i] = new double[matrix[i].length];
 }
 //生成伴随矩阵
 for (int i = 0; i < result.length; i++)
 {
  for (int j = 0; j < result.length; j++)
  {
   //存储代数余子式的矩阵(行、列数都比原矩阵少1)
   double[][] temp = new double[result.length - 1][];
   for (int k = 0; k < result.length - 1; k++)
   {
    temp[k] = new double[result[k].length - 1];
   }
   //生成代数余子式
   for (int x = 0; x < temp.length; x++)
   {
    for (int y = 0; y < temp.length; y++)
    {
     temp[x][y] = matrix[x < i ? x : x + 1][y < j ? y : y + 1];
    }
   }
   //console.writeline("代数余子式:");
   //printmatrix(temp);
   result[j][i] = ((i + j) % 2 == 0 ? 1 : -1) * determinant(temp);
  }
 }
 //console.writeline("伴随矩阵:");
 //printmatrix(result);
 return result;
}
/// <summary>
/// 打印矩阵
/// </summary>
/// <param name="matrix">待打印矩阵</param>
private static void printmatrix(double[][] matrix, string title = "")
{
 //1.标题值为空则不显示标题
 if (!string.isnullorwhitespace(title))
 {
  console.writeline(title);
 }
 //2.打印矩阵
 for (int i = 0; i < matrix.length; i++)
 {
  for (int j = 0; j < matrix[i].length; j++)
  {
   console.write(matrix[i][j] + "\t");
   //注意不能写为:console.write(matrix[i][j] + '\t');
  }
  console.writeline();
 }
 //3.空行
 console.writeline();
}

3.main函数调用

static void main(string[] args)
{
 double[][] matrix = new double[][] 
 {
  new double[] { 1, 2, 3 }, 
  new double[] { 2, 2, 1 },
  new double[] { 3, 4, 3 } 
 };
 printmatrix(matrix, "原矩阵");
 printmatrix(adjointmatrix(matrix), "伴随矩阵");
 console.writeline("行列式的值为:" + determinant(matrix) + '\n');
 printmatrix(inversematrix(matrix), "逆矩阵");
 console.readline();
}

4.执行结果

C#计算矩阵的逆矩阵方法实例分析

希望本文所述对大家的c#程序设计有所帮助。