矩阵求逆c++实现

摘要:
使用namespacestd;#定义N 10//将方阵的最大阶定义为10//函数floatMatDet(flow*p;//定义矩阵flow[N][N];row;buffer=(flow*)calloc(num;i<row;“row;
矩阵求逆c++实现
http://www.2cto.com/kf/201405/297388.html
2014-05-02     我来说两句    来源:矩阵求逆c++实现  
收藏    我要投稿

高斯消元法可以用来找出一个可逆矩阵的逆矩阵。设A 为一个N * N的矩阵,其逆矩阵可被两个分块矩阵表示出来。将一个N * N单位矩阵 放在A 的右手边,形成一个N * 2N的分块矩阵B = [A,I] 。经过高斯消元法的计算程序后,矩阵B 的左手边会变成一个单位矩阵I ,而逆矩阵A ^(-1) 会出现在B 的右手边。假如高斯消元法不能将A 化为三角形的格式,那就代表A 是一个不可逆的矩阵。应用上,高斯消元法极少被用来求出逆矩阵。高斯消元法通常只为线性方程组求解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
//********************************
//*** 求任何一个实矩阵的逆***
//********************************
#include"stdafx.h"
#include <math.h>
#include <malloc.h>
#include <iostream>
#include <iomanip>
using namespace std;
#define  N 10                //定义方阵的最大阶数为10
//函数的声明部分
floatMatDet(float*p,intn);                   //求矩阵的行列式
floatCreat_M(float*p,intm,intn,intk);   //求矩阵元素A(m, n)的代数余之式
voidprint(float*p,intn);                   //输出矩阵n*n
bool Gauss(floatA[][N],floatB[][N],intn);   //采用部分主元的高斯消去法求方阵A的逆矩阵B
intmain()
{
    float*buffer, *p;           //定义数组首地址指针变量
    introw, num;               //定义矩阵的行数和矩阵元素个数
    inti, j;
    floatdeterm;               //定义矩阵的行列式
    floata[N][N], b[N][N];
    intn;
    cout <<"采用逆矩阵的定义法求矩阵的逆矩阵! ";
    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 ";
    }
    cout <<"The original matrix : ";
    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! ";
    }
    free(buffer);       //释放内存空间
    cout <<"采用部分主元的高斯消去法求方阵的逆矩阵! ";
    cout <<"请输入方阵的阶数: ";
    cin >> n;
    cout <<"请输入"<< n <<"阶方阵: ";
    //输入一个n阶方阵
    for(i =0; i < n; i++)
    {
        for(j =0; j < n; j++)
        {
            cin >> a[i][j];
        }
    }
    //运用高斯消去法求该矩阵的逆矩阵并输出
    if(Gauss(a, b, n))
    {
        cout <<"该方阵的逆矩阵为: ";
        for(i =0; i < n; i++)
        {
            cout << setw(4);
            for(j =0; j < n; j++)
            {
                cout << b[i][j] << setw(10);
            }
            cout << endl;
        }
    }   
    getchar();
    return0;
}
//-----------------------------------------------
//功能: 求矩阵(n*n)的行列式
//入口参数: 矩阵的首地址,矩阵的行数
//返回值: 矩阵的行列式值
//----------------------------------------------
floatMatDet(float*p,intn)
{
    intr, c, m;
    intlop =0;
    floatresult =0;
    floatmid =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;
    returnresult;
}
//----------------------------------------------------------------------------
//功能: 求k*k矩阵中元素A(m, n)的代数余之式
//入口参数: k*k矩阵的首地址,矩阵元素A的下标m,n,矩阵行数k
//返回值: k*k矩阵中元素A(m, n)的代数余之式
//----------------------------------------------------------------------------
floatCreat_M(float*p,intm,intn,intk)
{
    intlen;
    inti, j;
    floatmid_result =0;
    intsign =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);
    returnmid_result;
}
//-----------------------------------------------------
//功能: 打印n*n矩阵
//入口参数: n*n矩阵的首地址,矩阵的行数n
//返回值: 无返回值
//-----------------------------------------------------
voidprint(float*p,intn)
{
    inti, 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(floatA[][N],floatB[][N],intn)
{
    inti, j, k;
    floatmax, temp;
    floatt[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!";
            returnfalse;
        }
        //消去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();
    returntrue;
}</iomanip></iostream></malloc.h></math.h>
实验结果:
矩阵求逆c++实现第1张

免责声明:文章转载自《矩阵求逆c++实现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SQL 语句解析线程池:第三章:线程池的手写改造和拒绝策略以及线程池配置合理线程数下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

css hover伪类选择器与JQuery hover()方法

css hover伪类选择器 它属于anchor伪类 在支持 CSS 的浏览器中,<a>标签链接的不同状态都可以以不同的方式显示,常常用来改链接的颜色效果 实例 a:link{color:#FF0000;}/* 未访问的链接 */ a:visited{color:#00FF00;}/* 已访问的链接 */ a:hover{color:#FF...

《自拍教程45》Python adb实时监控Logcat日志

接上一篇:adb命令_一键截取logcat日志, 有一天, 系统稳定性开发负责人找到我,希望我能在跑android 系统monkey的时候, 实时监控logcat的输出,如果一旦发现“java.lang.NullPointerException"空指针异常, 则立刻用adb bugreport命令导出当时log压缩包出来。 准备阶段 adb logcat...

MSBuild 常用命令(Copy,Zip)

Copy 1.下面的示例将 MvcApplication2 项集合中的项复制到 c:MyProjectMvcApplication2 文件夹中。 所有文件放入一个文件夹中,无层级。 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemG...

多分类问题中混淆矩阵(Confusion Matrix)的Matlab画法 | 丕子

在多分类问题中,有一种很实用的分类问题结果统计图。比如说多类别文类问题,那么每一个类别分到其他类别都有一些数据,但是分到自己类别的毕竟多,这样计算百分比之后就形成了一个矩阵,如果分类正确率高的话,那么对角线上的元素的值,也就是自己到自己的那一部分,value就大。我最近也在做多分类问题,要画这样的图,但是发现确实很少有代码,自己画的确实不好看,还牵扯到值的...

Html辅助方法 之 Form表单标签

一、Html.BeginForm  <form>标签 //视图代码@using (Html.BeginForm("search", "home", FormMethod.Get),new { target="_black",@ }) { <input type="text" value="" /> }//生成的...

解决jQuery多个版本,与其他js库冲突方法

jQuery多个版本或和其他js库冲突主要是常用的$符号的问题,这个问题 jquery早早就有给我们预留处理方法了,下面一起来看看解决办法。 1.同一页面jQuery多个版本或冲突解决方法。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="...