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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/768217.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【微服务】详解弹性设计中各个模式的应用场景

目录 故障和微服务架构如何构建具有弹性的服务?隔舱模式何时使用此模式断路器模式何时使用此模式不适用断路器的情况速率限制器模式何时使用此模式重试模式何时使用此模式超时模式使用该模式的优势推荐超级课程: Docke

PyAV源码安装及基本使用

PyAV源码编译 PyAV是对 ffmpeg 库的 Python 绑定&#xff0c;本篇介绍PyAV的源码安装及基本使用。 文章目录 PyAV源码编译编译流程源码目录结构编译中遇到的问题 PyAV的使用nvidia 硬件编解码Python C debug 方式 编译流程 PyAV的源码地址为&#xff1a;https://github.com/…

政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(五)—— Dropout和批归一化

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; Dropout和批归一化是深度学习领域中常用的正则化技术…

stm32之GPIO寄存器

文章目录 1 背景2 GPIO寄存器的类型2.1 端口配置寄存器2.2 设置/清除寄存器和位清除寄存器 3 总结 1 背景 C51单片机在进行数据的输入输出时&#xff0c;是直接操作与外部引脚关联的内部寄存器&#xff0c;例如&#xff0c;当设置P2_1为0时&#xff0c;就是将外部引脚的P21引脚…

YOLOV5 部署:TensorRT的安装和使用

1、介绍 TensorRT 可以加速神经网络的推理时间,常常在工业生产中使用 因为TensorRT需要使用到cuda和cudnn加速,所以需要安装这两个,安装的具体步骤参考前文: YOLOV5 部署:cuda和cuDNN安装-CSDN博客 2、TensorRT 下载 TensorRT下载地址:NVIDIA TensorRT Download | NV…

6.windows ubuntu 子系统 测序数据质量控制。

上一个分享&#xff0c;我们对测序数据进行了质量评估&#xff0c;接下来我们需要对数据进行数据质量控制。 数据预处理&#xff08;Data Preprocessing&#xff09;&#xff1a;包括去除接头序列&#xff08;adapter trimming&#xff09;、去除低质量序列&#xff08;qualit…

Spark—GraphX实战 OneID

OneID 前面我们学习了ID Mapping&#xff0c;包括ID Mapping 的背景介绍和业务场景&#xff0c;以及如何使用Spark 实现ID Mapping&#xff0c;这个过程中涉及到了很多东西&#xff0c;当然我们都通过文章的形式介绍给大家了&#xff0c;所以你再学习今天这一节之前&#xff0…

FPGA时钟资源详解——时钟Buffer的选择

目录 一、概述 二、时钟Buffer的选择 2.1 BUFG 2.2 BUFR 和 BUFIO 2.2.1 源同步接口的支持 2.2.2 扩展时钟域转换功能 2.2.3 BUFR 作为简单的时钟分频器 2.3 BUFH 2.3.1 BUFH 的关键特性 2.3.2 应用场景 三、总结 3.1 BUFG&#xff08;全局时钟缓冲器&…

OpenCV4.9.0开源计算机视觉库核心功能(核心模块)

转到&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV 介绍使用 下一篇&#xff1a;如何使用OpenCV扫描图像、查找表和时间测量 ​ OpenCV核心功能主要有以下各个&#xff1a;本文将开始介绍下列内容&#xff1a; Mat - 基…

SpringBoot配置JWT拦截器

目录 1.背景介绍 2.前提工作 3.具体代码 &#xff08;1&#xff09;相关依赖 &#xff08;2&#xff09;相关配置文件 &#xff08;3&#xff09;JwtUtils类 &#xff08;4&#xff09;准备好登录逻辑代码&#xff08;Dao、Service、Controller&#xff09; &#xff0…

解决方案Please use Oracle(R) Java(TM) 11, OpenJDK(TM) 11 to run Neo4j.

文章目录 一、现象二、解决方案 一、现象 当安装好JDK跟neo4j&#xff0c;用neo4j.bat console来启动neo4却报错&#xff1a; 部分报错信息&#xff1a; Starting Neo4j. WARNING! You are using an unsupported Java runtime. Please use Oracle Java™ 11, OpenJDK™ 11 t…

大白话扩散模型(无公式版)

背景 传统的图像生成模型有GAN&#xff0c;VAE等&#xff0c;但是存在模式坍缩&#xff0c;即生成图片缺乏多样性&#xff0c;这是因为模型本身结构导致的。而扩散模型拥有训练稳定&#xff0c;保持图像多样性等特点&#xff0c;逐渐成为现在AIGC领域的主流。 扩散模型 正如…

设计模式学习笔记 - 设计模式与范式 - 创建型:6.建造者模式:详解构造函数、set方法、建造者三种对象创建方式

概述 本章学习一个比较常用的创建型设计模式&#xff0c;Builder 模式&#xff0c;中文翻译为建造者模式或构建者模式&#xff0c;也有人叫它生成器模式。 建造者模式的原理和代码实现非常简单&#xff0c;掌握起来并不难&#xff0c;难点在于应用场景。比如&#xff0c;你有…

Google ScreenAI代表了一款先进的视觉语言模型,专为用户界面(UI)和视觉情境下的语言理解而设计

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

华为od真题2023-C卷-三叉搜索树

题目描述&#xff1a; 定义构造三叉搜索树规则如下: 每个节点都存有一个数&#xff0c;当插入一个新的数时&#xff0c;从根节点向下寻找&#xff0c;直到找到一个合适的空节点插入。查找的规则是: 1.如果数小于节点的数减去500&#xff0c;则将数插入节点的左子树2.如果数大于…

政安晨:【深度学习部署】—— TensorFlow Extended(TFX)介绍

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 前言 TensorFlow Extended&#xff08;TFX&a…

深入了解Redis的过期策略和内存淘汰机制

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…

语言模型的原理、实战与评估

语言模型的原理、实战与评估是一个宽泛的话题,下面是对这三个方面简要概述: 语言模型的原理 语言模型(Language Model, LM)是一种统计模型,用于估计一段文本序列的概率分布。它的核心任务是给定一系列词语,计算出这些词语组合成一个完整句子或段落的概率。典型的语言模型…

mysql基础2多表查询

多表查询 多表关系: 一对多 案例: 部门 与 员工的关系 关系: 一个部门对应多个员工&#xff0c;一个员工对应一个部门 实现: 在多的一方建立外键&#xff0c;指向一的一方的主键 多对多 案例: 学生 与 课程的关系 关系: 一个学生可以选修多门课程&#xff0c;一门课程也可以…

MySQL基础复习

目录 一、简单的命令 二、SQL语句分类 三、简单查询 四、条件查询 五、排序 一、简单的命令 net start 服务名称 net stop 服务名称 mysql -uroot -p123456 显示密码形式 mysql -uroot -p 隐藏密码形式 exit 退出 show databases; 查看MySQL中的数据库有哪些 use test…