高斯消元法能够用来找出一个可逆矩阵的逆矩阵。设A 为一个N * N的矩阵,其逆矩阵可被两个分块矩阵表示出来。将一个N * N单位矩阵 放在A 的右手边,形成一个N * 2N的分块矩阵B = [A,I]
。经过高斯消元法的计算程序后,矩阵B 的左手边会变成一个单位矩阵I ,而逆矩阵A ^(-1) 会出如今B 的右手边。

假如高斯消元法不能将A 化为三角形的格式。那就代表A 是一个不可逆的矩阵。应用上。高斯消元法极少被用来求出逆矩阵。高斯消元法通常仅仅为线性方程组求解。

 //********************************
//*** 求不论什么一个实矩阵的逆***
//********************************
#include "stdafx.h"
#include <math.h>
#include <malloc.h>
#include <iostream>
#include <iomanip>
using namespace std;
#define N 10 //定义方阵的最大阶数为10
//函数的声明部分
float MatDet(float *p, int n); //求矩阵的行列式
float Creat_M(float *p, int m, int n, int k); //求矩阵元素A(m, n)的代数余之式
void print(float *p, int n); //输出矩阵n*n
bool Gauss(float A[][N], float B[][N], int n); //採用部分主元的高斯消去法求方阵A的逆矩阵B
int main()
{
float *buffer, *p; //定义数组首地址指针变量
int row, num; //定义矩阵的行数和矩阵元素个数
int i, j;
float determ; //定义矩阵的行列式
float a[N][N], b[N][N];
int n;
cout << "採用逆矩阵的定义法求矩阵的逆矩阵!\n";
cout << "请输入矩阵的行数: ";
cin >> row;
num = 2 * row * row;
buffer = (float *)calloc(num, sizeof(float)); //分配内存单元
p = buffer;
if (NULL != p)
{
for (i = 0; i < row; i++)
{
cout << "Please input the number of " << i+1 << " row: ";
for (j = 0; j < row; j++)
{
cin >> *p++;
}
}
}
else
{
cout << "Can't distribute memory\n";
}
cout << "The original matrix : \n";
print(buffer, row); //打印该矩阵 determ = MatDet(buffer, row); //求整个矩阵的行列式
p = buffer + row * row;
if (determ != 0)
{
cout << "The determinant of the matrix is " << determ << endl;
for (i = 0; i < row; i++) //求逆矩阵
{
for (j = 0; j < row; j++)
{
*(p+j*row+i) = Creat_M(buffer, i, j, row)/determ;
}
}
cout << "The inverse matrix is: " << endl;
print(p, row); //打印该矩阵
}
else
{
cout << "The determinant is 0, and there is no inverse matrix!\n";
}
free(buffer); //释放内存空间
cout << "採用部分主元的高斯消去法求方阵的逆矩阵!\n";
cout << "请输入方阵的阶数: ";
cin >> n;
cout << "请输入" << n << "阶方阵: \n";
//输入一个n阶方阵
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
cin >> a[i][j];
}
}
//运用高斯消去法求该矩阵的逆矩阵并输出
if (Gauss(a, b, n))
{
cout << "该方阵的逆矩阵为: \n";
for (i = 0; i < n; i++)
{
cout << setw(4);
for (j = 0; j < n; j++)
{
cout << b[i][j] << setw(10);
}
cout << endl;
}
}
getchar();
return 0;
}
//-----------------------------------------------
//功能: 求矩阵(n*n)的行列式
//入口參数: 矩阵的首地址。矩阵的行数
//返回值: 矩阵的行列式值
//----------------------------------------------
float MatDet(float *p, int n)
{
int r, c, m;
int lop = 0;
float result = 0;
float mid = 1;
if (n != 1)
{
lop = (n == 2) ? 1 : n; //控制求和循环次数,若为2阶,则循环1次,否则为n次
for (m = 0; m < lop; m++)
{
mid = 1; //顺序求和, 主对角线元素相乘之和
for (r = 0, c = m; r < n; r++, c++)
{
mid = mid * (*(p+r*n+c%n));
}
result += mid;
}
for (m = 0; m < lop; m++)
{
mid = 1; //逆序相减, 减去次对角线元素乘积
for (r = 0, c = n-1-m+n; r < n; r++, c--)
{
mid = mid * (*(p+r*n+c%n));
}
result -= mid;
}
}
else
result = *p;
return result;
}
//----------------------------------------------------------------------------
//功能: 求k*k矩阵中元素A(m, n)的代数余之式
//入口參数: k*k矩阵的首地址,矩阵元素A的下标m,n,矩阵行数k
//返回值: k*k矩阵中元素A(m, n)的代数余之式
//----------------------------------------------------------------------------
float Creat_M(float *p, int m, int n, int k)
{
int len;
int i, j;
float mid_result = 0;
int sign = 1;
float *p_creat, *p_mid;
len = (k-1)*(k-1); //k阶矩阵的代数余之式为k-1阶矩阵
p_creat = (float*)calloc(len, sizeof(float)); //分配内存单元
p_mid = p_creat;
for (i = 0; i < k; i++)
{
for (j = 0; j < k; j++)
{
if (i != m && j != n) //将除第i行和第j列外的全部元素存储到以p_mid为首地址的内存单元
{
*p_mid++ = *(p+i*k+j);
}
}
}
sign = (m+n)%2 == 0 ? 1 : -1; //代数余之式前面的正、负号
mid_result = (float)sign*MatDet(p_creat, k-1);
free(p_creat);
return mid_result;
}
//-----------------------------------------------------
//功能: 打印n*n矩阵
//入口參数: n*n矩阵的首地址,矩阵的行数n
//返回值: 无返回值
//-----------------------------------------------------
void print(float *p, int n)
{
int i, j;
for (i = 0; i < n; i++)
{
cout << setw(4);
for (j = 0; j < n; j++)
{
cout << setiosflags(ios::right) << *p++ << setw(10);
}
cout << endl;
}
}
//------------------------------------------------------------------
//功能: 採用部分主元的高斯消去法求方阵A的逆矩阵B
//入口參数: 输入方阵,输出方阵,方阵阶数
//返回值: true or false
//-------------------------------------------------------------------
bool Gauss(float A[][N], float B[][N], int n)
{
int i, j, k;
float max, temp;
float t[N][N]; //暂时矩阵
//将A矩阵存放在暂时矩阵t[n][n]中
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
t[i][j] = A[i][j];
}
}
//初始化B矩阵为单位阵
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
B[i][j] = (i == j) ? (float)1 : 0;
}
}
for (i = 0; i < n; i++)
{
//寻找主元
max = t[i][i];
k = i;
for (j = i+1; j < n; j++)
{
if (fabs(t[j][i]) > fabs(max))
{
max = t[j][i];
k = j;
}
}
//假设主元所在行不是第i行,进行行交换
if (k != i)
{
for (j = 0; j < n; j++)
{
temp = t[i][j];
t[i][j] = t[k][j];
t[k][j] = temp;
//B伴随交换
temp = B[i][j];
B[i][j] = B[k][j];
B[k][j] = temp;
}
}
//推断主元是否为0, 若是, 则矩阵A不是满秩矩阵,不存在逆矩阵
if (t[i][i] == 0)
{
cout << "There is no inverse matrix!";
return false;
}
//消去A的第i列除去i行以外的各行元素
temp = t[i][i];
for (j = 0; j < n; j++)
{
t[i][j] = t[i][j] / temp; //主对角线上的元素变为1
B[i][j] = B[i][j] / temp; //伴随计算
}
for (j = 0; j < n; j++) //第0行->第n行
{
if (j != i) //不是第i行
{
temp = t[j][i];
for (k = 0; k < n; k++) //第j行元素 - i行元素*j列i行元素
{
t[j][k] = t[j][k] - t[i][k]*temp;
B[j][k] = B[j][k] - B[i][k]*temp;
}
}
}
}
getchar();
return true;
}

实验结果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1cnVpX2lkZWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

版权声明:本文博主原创文章,博客,未经同意不得转载。

矩阵求逆c++达到的更多相关文章

  1. 矩阵求逆算法及程序实现(C++)

    在做课题时,遇到了求多项式问题,利用了求逆方法.矩阵求逆一般使用简单的算法,还有快速算法 如全选主元高斯-约旦消元法,但本文程序主要写了简单的矩阵求逆算法定义法之伴随矩阵求逆公式如下,其中A可逆: , ...

  2. matrix矩阵求逆 与解方程模板 留做备用 (有bug,待补充)

    // // main.cpp // 矩阵求逆 // // Created by 唐 锐 on 13-6-20. // Copyright (c) 2013年 唐 锐. All rights reser ...

  3. 矩阵求逆的几种方法总结(C++)

    矩阵求逆运算有多种算法: 伴随矩阵的思想,分别算出其伴随矩阵和行列式,再算出逆矩阵: LU分解法(若选主元即为LUP分解法: Ax = b ==> PAx = Pb ==>LUx = Pb ...

  4. RLS自适应滤波器中用矩阵求逆引理来避免求逆运算

    在RLS自适应滤波器的实现过程中,难免不涉及矩阵的求逆运算.而求逆操作双是非常耗时的,一个很自然的想法就是尽可能的避免直接对矩阵进行求逆运算.那么,在RLS自适应滤波器的实现中,有没有一种方法能避免直 ...

  5. 矩阵求逆·学习笔记 $\times$ [$LuoguP4783$]矩阵求逆

    哦?今天在\(luogu\)上fa♂现了矩阵求逆的板子--于是就切了切. 那么我们考虑一个矩阵\(A\),它的逆矩阵记作\(A^{-1}\),其中对于矩阵这个群来讲,会有\(A \cdot A^{-1 ...

  6. 【题解】Matrix BZOJ 4128 矩阵求逆 离散对数 大步小步算法

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4128 大水题一道 使用大步小步算法,把数字的运算换成矩阵的运算就好了 矩阵求逆?这么基础的线 ...

  7. BZOJ 4128 Matrix BSGS+矩阵求逆

    题意:链接 方法: BSGS+矩阵求逆 解析: 这题就是把Ax=B(mod C)的A和B换成了矩阵. 然而别的地方并没有修改. 所以就涉及到矩阵的逆元这个问题. 矩阵的逆元怎么求呢? 先在原矩阵后接一 ...

  8. BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)

    题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...

  9. LG4783 【模板】矩阵求逆

    P4783 [模板]矩阵求逆 题目描述 求一个$N\times N$的矩阵的逆矩阵.答案对$10^9+7$取模. 输入输出格式 输入格式: 第一行有一个整数$N$,代表矩阵的大小: 从第$2$行到第$ ...

  10. LUOGU P4783 【模板】矩阵求逆(高斯消元)

    传送门 解题思路 用高斯消元对矩阵求逆,设\(A*B=C\),\(C\)为单位矩阵,则\(B\)为\(A\)的逆矩阵.做法是把\(B\)先设成单位矩阵,然后对\(A\)做高斯消元的过程,对\(B\)进 ...

随机推荐

  1. 解决vmware“二进制转换和长模式与此平台兼容.....”问题

    问题描述: 启动vmware显现:1.二进制转换和长模式与此平台兼容....字等.: 2.vmware启动一会,系统直接重新启动,这个现象出如今惠普电脑上 问题原因: 出现这种原因一般都是因为系统Vi ...

  2. svn rm --keep-local ./QueryParser_kill.logs

    svn rm --keep-local ./QueryParser_kill.logs

  3. 一起来开发Android的天气软件(四)——使用Gson解析数据

    离上一篇文章过去才4.5天,我们赶紧趁热打铁继续完毕该系列的天气软件的开发. 承接上一章的内容使用Volley实现网络的通信.返回给我们的是这一串Json数据{"weatherinfo&qu ...

  4. U10vim程序编辑器

    vim需要多加练习. 1.你可以将vim视为vi的高级版本.vi分成三种模式:一般模式,编辑模式和命令行模式. 一般模式:以vi打开一个文件就直接进入一般模式了(这也是默认的模式).在这个模式中,你可 ...

  5. 就这样CSDN账号被人盗了??

    和往常一样,来到公司后的第一件事情就是看看自己博客.没想到今天一看,小伙伴惊呆了. 莫名其妙地多了这个多不是神马的博文,还好几篇. 这说明CSDN账号也不怎么安全哦,以后小伙伴们要注意了.

  6. js实时监听input中值的变化

    $(function(){ $('#inputid').bind('input propertychange', function() { // input 中的值 var params = $(th ...

  7. [置顶] Codeforces Round #197 (Div. 2)(完全)

    http://codeforces.com/contest/339/ 这场正是水题大放送,在家晚上限制,赛后做了虚拟比赛 A,B 乱搞水题 C 我是贪心过的,枚举一下第一个拿的,然后选使差值最小的那个 ...

  8. Android在 Alertdialog对话框中点击消失?

    在开发的时候遇到一个问题.就是一触摸对话框边缘外部,对话框会自己主动消失.这个问题非常纠结啊,查找了一下发现从Android 4.0開始.AlertDialog有了变化.就是在触摸对话框边缘外部.对话 ...

  9. BestCoder Round#11div2 1003

    ----- 有时候如果枚举起点超时,那么试试枚举终点. 枚举每一个i为终点(0<= i < n),且维护起点下标startPos 对于终点i,cnt[str[i]] ++,   如果小于等 ...

  10. js中escape的用法----前端页面简单加密

    escape() 方法,它用于转义不能用明文正确发送的任何字符.比如,电话号码中的空格将被转换成字符 %20,从而能够在 URL 中传递这些字符. http://localhost:8080/a?na ...