c#矩阵求逆

2024-03-24 15:52
文章标签 c# 矩阵 .net netcore 求逆

本文主要是介绍c#矩阵求逆,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、矩阵求逆的数学方法

1、伴随矩阵法

2、初等变换法

3、分块矩阵法

4、定义法

二、矩阵求逆C#代码

1、伴随矩阵法求指定3*3阶数矩阵的逆矩阵

(1)伴随矩阵数学方法

(2)代码

(3)计算

2、对任意阶数矩阵求逆

(1)计算方法

(2)代码

(3)计算

(4)计算结果

三、工程下载连接


一、矩阵求逆的数学方法

1、伴随矩阵法

2、初等变换法

3、分块矩阵法

4、定义法

二、矩阵求逆C#代码

1、伴随矩阵法求指定3*3阶数矩阵的逆矩阵

(1)伴随矩阵数学方法

(2)代码

        /// <summary>/// 计算3*3矩阵的逆矩阵/// </summary>/// <param name="input">输入的3*3矩阵</param>/// <returns>计算得到的3*3逆矩阵</returns>public static double[,] inv3(double[,] input){double[,] output = new double[3, 3];//求出伴随矩阵output[0, 0] = input[2, 2] * input[1, 1] - input[2, 1] * input[1, 2];output[0, 1] = input[2, 1] * input[0, 2] - input[0, 1] * input[2, 2];output[0, 2] = input[0, 1] * input[1, 2] - input[0, 2] * input[1, 1];output[1, 0] = input[1, 2] * input[2, 0] - input[2, 2] * input[1, 0];output[1, 1] = input[2, 2] * input[0, 0] - input[0, 2] * input[2, 0];output[1, 2] = input[0, 2] * input[1, 0] - input[0, 0] * input[1, 2];output[2, 0] = input[1, 0] * input[2, 1] - input[2, 0] * input[1, 1];output[2, 1] = input[2, 0] * input[0, 1] - input[0, 0] * input[2, 1];output[2, 2] = input[0, 0] * input[1, 1] - input[1, 0] * input[0, 1];//求出行列式的值double Avalue = input[0, 0] * input[1, 1] * input[2, 2]+ input[0, 1] * input[1, 2] * input[2, 0]+ input[0, 2] * input[1, 0] * input[2, 1]- input[0, 2] * input[1, 1] * input[2, 0]- input[0, 1] * input[1, 0] * input[2, 2]- input[0, 0] * input[1, 2] * input[2, 1];//求出 逆矩阵 for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){output[i, j] = output[i, j] / Avalue;}}return output;}

(3)计算

计算代码

            计算3*3矩阵的逆矩阵double[,] input = new double[3, 3] {{ 0,    1,      3 }, { 1,    -1,     0 },{-1,    2,      1}};double[,] out1 = inv3(input);               //方法1——只能求3*3

程序计算结果

对应数学题目

2、对任意阶数矩阵求逆

(1)计算方法

Step1

1)利用初等行变换,那么要将单位矩阵E和n阶矩阵B合并(规定为EandB_normal[ n, 2 * n])

Step2

2)将EandB_normal[ n, 2 * n]转为右半部分为上三角的矩阵

>>>这一步转换比较复杂一点,具体实现就是:

>>>第一层循环,循环变量 j 从第n列开始到第2 * n - 1列结束,目的就是将该列值都转为1,方便后边变为上三角矩阵(需要注意的是,对于第n列,应该考虑把每个值都变为1;但是到第n + 1列时,就不考虑第一个值了;第n + 2列时,不考虑第一个和第二个值;类推);

>>>第二层循环,循环变量 i 从第j - n行开始到第n - 1行结束,目的是对每一行都进行除以EandB_normal[ i, j]值的运算,这样EandB_normal[ i, j]的值就变为了1(需要注意的是,如果EandB_normal[ i, j]的值为0的话,我们考虑将该行与最后一行调换,同时循环变量 i 到第n - 2行结束;如果调换之后,EandB_normal[ i, j]的值仍然为0,那么再将该行与此时的最后一行调换,类推;但是如果一直调换,直到发现始终为0,就说明矩阵B不满秩,退出计算;如果EandB_normal[ i, j]值为负数,该行同时变号);

>>>第三层循环,循环变量 k 从第0列开始到第2 * n - 1列结束,目的是将上一步中循环到的行中的每一个值都除以EandB_normal[ i, j]的值;

>>>循环全部完成之后,矩阵EandB_normal[ n, 2 * n]就变成了右半部分为上三角的矩阵。

Step3

3)接上一步,将该矩阵转为右半部分为单位矩阵的矩阵,此时即为矩阵B的逆矩阵与单位矩阵的合并(规定为B_inverse_andE[ n, 2 * n])

>>>这一步中的循环变量是递减的,具体实现就是:

>>>第一层循环,循环变量 j 从第2 * n - 1列开始到第n列结束,目的是将该列值只保留一个1,其余变为0;

>>>第二层循环,循环变量 i 从第 j - n行开始到第0行结束;

>>>第三层循环,循环变量 k 从第0列开始到第2 * n - 1列结束;拿 j = 2 * n - 1, i = n - 1举例,此时,我们希望第n - 2行的值都加上该行最后一个值的相反数与第n - 1行乘积的对应值,第n - 3行的值都加上该行最后一个值得相反数与第n - 1行乘积的对应值,类推;(需要注意的是,j = 2 * n - 2时,i从第n - 2行开始循环,j = 2 * n - 3时,i从第n - 2行开始循环,类推);

>>>当循环全部完成之后,B_inverse_andE[ n, 2 * n]的右半部分就变为了单位矩阵,左半部分为矩阵B的逆矩阵。

Step4

4)接上一步,将B的逆矩阵取出来(规定为B_inverse[n, n])

(2)代码

/// <summary>/// 任意矩阵求逆。(矩阵是2*2、3*3、4*4、5*5等类型)/// </summary>/// <param name="matrixB">输入的初始矩阵</param>/// <param name="orderNum">矩阵行和列的数</param>/// <returns>计算出的逆矩阵</returns>public static double[,] MatrixInverse(double[,] matrixB, int orderNum){//判断是否满秩bool IsFullRank = true;//n为阶级int n = orderNum;//####赋值####//矩阵B//矩阵B的逆矩阵//单位矩阵E和矩阵B组成的矩阵double[,] B_normal = matrixB;double[,] B_inverse = new double[n, n];double[,] EandB_normal = new double[n, 2 * n];for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){if (i == j)EandB_normal[i, j] = 1;elseEandB_normal[i, j] = 0;}for (int k = n; k < 2 * n; k++){EandB_normal[i, k] = B_normal[i, k - n];}}//####计算####//中间变量数组,用于临时盛装值double[] rowHaveZero = new double[2 * n];//EB矩阵右边的n*n变为上三角矩阵for (int j = n; j < 2 * n; j++){int firstRowN = j - n;int lastRowN = n;int colCount = 2 * n;//把EB中索引为j的列的值化为1for (int i = firstRowN; i < lastRowN; i++){//如果EBijNum值为0,就把0所在的行与此刻最后一行调换位置//并且循环变量i的终止值减去1,直到EBijNum值不为0//最多调换到0所在的行的下一行double EBijNum = EandB_normal[i, j];while (EBijNum == 0 && lastRowN > i + 1){for (int k = 0; k < colCount; k++){rowHaveZero[k] = EandB_normal[i, k];EandB_normal[i, k] = EandB_normal[lastRowN - 1, k];EandB_normal[lastRowN - 1, k] = rowHaveZero[k];}lastRowN -= 1;EBijNum = EandB_normal[i, j];}//如果while循环是由第二个判断跳出//即EBijNum始终为0if (EBijNum == 0){//循环变量i的终止值再减去1,然后跳出循环lastRowN -= 1;break;}//如果为负数,该行变号if (EBijNum < 0){for (int k = 0; k < colCount; k++){EandB_normal[i, k] = (-1) * EandB_normal[i, k];}EBijNum = EandB_normal[i, j];}//将该值变为1,则其余值都除以EBijNumfor (int k = 0; k < colCount; k++){EandB_normal[i, k] = EandB_normal[i, k] / EBijNum;}}//自n列起,每列只保留一个1,呈阶梯状int secondRowN = firstRowN + 1;for (int i = secondRowN; i < lastRowN; i++){for (int k = 0; k < colCount; k++){EandB_normal[i, k] = EandB_normal[i, k]- EandB_normal[firstRowN, k];}}if (lastRowN == firstRowN){//矩阵不满秩IsFullRank = false;break;}}//不满秩,结束运算if (!IsFullRank){double[,] error = new double[n, n];for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){error[i, j] = 0;}}//返还值均为0的矩阵return error;}//将上三角矩阵变为单位矩阵for (int j = 2 * n - 1; j > n; j--){//firstRowN为参考行//secondRowN为运算行int firstRowN = j - n;int secondRowN = firstRowN - 1;int colCount = j + 1;//从最后一列起,每列只保留一个1,其余减为0for (int i = secondRowN; i > -1; i--){double EBijNum = EandB_normal[i, j];for (int k = 0; k < colCount; k++){EandB_normal[i, k] = EandB_normal[i, k]- EandB_normal[firstRowN, k] * EBijNum;}}}//####提取逆矩阵####for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){B_inverse[i, j] = EandB_normal[i, j];}}return B_inverse;}

(3)计算

private void button1_Click(object sender, EventArgs e){计算3*3矩阵的逆矩阵double[,] input = new double[3, 3] {{ 0,    1,      3 }, { 1,    -1,     0 },{-1,    2,      1}};double[,] out1 = inv3(input);               //方法1——只能求3*3double[,] out2 = MatrixInverse(input, 3);   //方法2计算2*2矩阵的逆矩阵double[,] input2 = new double[2, 2] {{ 1, 2 }, { 3, 4 }};double[,] out3 = MatrixInverse(input2, 2); //计算4*4矩阵的逆矩阵double[,] input3 = new double[4, 4] {{ 2, 1,-1,2 }, { 1, 1,1,-1 },{0,0,2,5},{0,0,1,3}};double[,] out4 = MatrixInverse(input3, 4); }

(4)计算结果

以4*4矩阵说明

三、工程下载连接

https://download.csdn.net/download/panjinliang066333/89024543

这篇关于c#矩阵求逆的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/842065

相关文章

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

C# dateTimePicker 显示年月日,时分秒

dateTimePicker默认只显示日期,如果需要显示年月日,时分秒,只需要以下两步: 1.dateTimePicker1.Format = DateTimePickerFormat.Time 2.dateTimePicker1.CustomFormat = yyyy-MM-dd HH:mm:ss Tips:  a. dateTimePicker1.ShowUpDown = t

C#关闭指定时间段的Excel进程的方法

private DateTime beforeTime;            //Excel启动之前时间          private DateTime afterTime;               //Excel启动之后时间          //举例          beforeTime = DateTime.Now;          Excel.Applicat

C# 防止按钮botton重复“点击”的方法

在使用C#的按钮控件的时候,经常我们想如果出现了多次点击的时候只让其在执行的时候只响应一次。这个时候很多人可能会想到使用Enable=false, 但是实际情况是还是会被多次触发,因为C#采用的是消息队列机制,这个时候我们只需要在Enable = true 之前加一句 Application.DoEvents();就能达到防止重复点击的问题。 private void btnGenerateSh

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

C# Hash算法之MD5、SHA

MD5我们用的还是比较多的,一般用来加密存储密码。但是现在很多人觉MD5可能不太安全了,所以都用上了SHA256等来做加密(虽然我觉得都差不多,MD5还是能玩)。 还是跟上一篇说的一样,当一个算法的复杂度提高的同时肯定会带来效率的降低,所以SHA和MD5比较起来的话,SHA更安全,MD5更高效。 由于HASH算法的不可逆性,所以我认为MD5和SHA主要还是应用在字符串的"加密"上。 由于