标题:[求助]怎样求一个矩阵的逆
只看楼主
不是高手
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-6-11
 问题点数:0 回复次数:9 
[求助]怎样求一个矩阵的逆
以3*3矩阵为例,虽然知道线性代数的公式,但还是不知道怎么用C来实现

[此贴子已经被作者于2007-6-13 23:08:48编辑过]


搜索更多相关主题的帖子: 矩阵 线性代数 公式 
2007-06-12 00:05
不是高手
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-6-11
得分:0 

难道没有人会这个题吗?

2007-06-12 23:38
百年不亮
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:789
专家分:0
注 册:2006-4-14
得分:0 

是先算行列式的值吧,不过行列式很难算,用c实现可能还有很大近似误差.

2007-06-12 23:52
不是高手
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-6-11
得分:0 
如果要算行列式的话,好要算转制矩阵的......
2007-06-13 00:17
herbert_1987
Rank: 5Rank: 5
等 级:贵宾
威 望:15
帖 子:1314
专家分:0
注 册:2007-5-13
得分:0 
我只学过2维的矩阵,没学过3维的

人生重要的不是所站的位置,而是所朝的方向
2007-06-13 00:37
我是菜鸟哦
Rank: 6Rank: 6
等 级:贵宾
威 望:22
帖 子:921
专家分:209
注 册:2007-5-4
得分:0 
矩阵考完就忘了

偶是菜鸟鸟偶惧WHO?!!!!
2007-06-13 13:00
herbert_1987
Rank: 5Rank: 5
等 级:贵宾
威 望:15
帖 子:1314
专家分:0
注 册:2007-5-13
得分:0 

用这个公式吧:
A的逆 = adj A / det A;


人生重要的不是所站的位置,而是所朝的方向
2007-06-14 10:29
不是高手
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-6-11
得分:0 

这样还是不会写,有谁能写出代码来看一下

2007-06-15 21:20
百年不亮
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:789
专家分:0
注 册:2006-4-14
得分:0 

我今天去图书馆时特意看了一下,有一本经典好书,电子工业出版社的<<c数值算法>>,国外牛人写的有700多页
里面讲到LU分解算法是比较好的算法之一.还有一本c++版本<<c++数值算法>>,内容差不多.

你如果目的是解决实际问题,用专业的数学软件MATLAB,一个命令就算出来了.如果你目的就是想掌握算法,去找数值计算的书看,为了减小舍入误差,算法比较复杂,不是论坛里就能说清楚的.

2007-06-15 22:11
slv309
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2007-6-15
得分:0 

我来说吧,上学期学了线代,我粗心老算错作业题,就来了兴致写了个
思路是这样:先写个算行列式的函数 Det() ,算法是递归的那个,就是|A|= a[11]×|A[11]|+a[12]×|A[12]|+...+a[1n]×|A[1n]| 用第一行各项乘以各自代数余子式求和的那个公式,可以用递归写 Det(A)= a[11]×Det(A[11])+a[12]×Det(A[12])+...+a[1n]×Det(A[1n]),一直到2×2矩阵a[11]a[22]-a[12]a[21]

然后就好办了吧,把A的伴随阵A*算出来,那么逆矩阵A^(-1) = A* / |A|

部分代码

class CMat
{
public:
CMat();

~CMat(){}

friend float Det(CMat a); //计算行列式
friend void put_to_E(CMat& a); //转化为方阵(E)
friend unsigned _R_(CMat a); //秩的计算
friend CMat& _oppo_(CMat& a); // ---a^(-1)
friend CMat& _cpn_(CMat& a); // ---伴随阵
friend CMat& _Trn_(CMat& a); //---转置

friend CMat& operator+(CMat& a, CMat& b);
friend CMat& operator-(CMat& a, CMat& b);
friend CMat& operator*(CMat& a, CMat& b);

friend CMat& operator^(CMat& a, int b); //--------乘方
friend CMat& operator*(float a, CMat& b); //--------数乘(左)
friend CMat& operator*(CMat& b, float a); //--------数乘(右)
friend CMat& operator-(CMat& a); //--------取负


//-------------------------------------------//
private:
unsigned m,n;
char name;

float* p;
};

//...

float Det(CMat a) //*.-求行列式
{
unsigned _m = a.m, _n = a.n;
float* _p = a.p;

if(a.m != a.n)
printf("不能求行列式,此矩阵不是方阵");

if(a.m == 2)
{
float __1 = (*_p), __2 = (*(_p + 3)), __3 = (*(_p + 1)), __4 = (*(_p + 2));
return (*_p) * (*(_p + 3)) - (*(_p + 1)) * (*(_p + 2));
}

float tempResult = 0;

for(unsigned j = 0; j < _n; j++)
{
CMat cm_temp;
float* pCm_temp = new float[(_m - 1) * (_n - 1)];

for(unsigned i = 0, iTemp = 0; i < _m; i++)/*-------------确定余子式*/
for(unsigned q = 0; q < _n; q++)
if((i != 0)&&(q != j))
{
*(pCm_temp + iTemp) = *(_p + i * _m + q);
iTemp++;
}
/*------------------------------------------------确定余子式*/

cm_temp.p = pCm_temp;
cm_temp.m = _m -1; cm_temp.n = _n - 1;


_TEST(cm_temp.CMatrix_print();)

if(j % 2 == 0)
tempResult += Det(cm_temp) * (*(_p + j));
else
tempResult -= Det(cm_temp) * (*(_p + j));

_TEST(printf("tempResult = %g\n", tempResult);)
}

return tempResult;
}

CMat& _cpn_(CMat& a) // ---伴随阵
{
if(a.n != a.m)
printf("阵型不匹配,不是方阵!\n");

unsigned _m = a.m;
unsigned _k = _m, _l = _m; /*纪录行号*/
unsigned num1 = _m * _m;
unsigned num2 = (_m - 1) * (_m - 1);

CMat* p_result = new CMat;
float* p_f = new float[num1];
float* p_f_temp = new float[num2];
float* pf_temp = p_f_temp;

for(unsigned i = 0; i < _m; i++)
{
for(unsigned j = 0; j < _m; j++)
{
CMat* p_temp = new CMat;
p_temp->p = p_f_temp;
p_temp->m = p_temp->n = (_m - 1);
pf_temp = p_f_temp;

for(unsigned k = 0; k < num1; k++)
{
_l = get_line(k, _m);
_k = (k % _m);

if(((i == _l)||(j == _k)))
continue;

*pf_temp = *(a.p + _l * _m + _k);
pf_temp++;
}

if((i + j)%2 == 0)
*(p_f + j * _m + i) = Det(*p_temp);
else
*(p_f + j * _m + i) = -Det(*p_temp);
}
}

p_result->p = p_f;
p_result->m = p_result->n = _m;

return *p_result;
}

CMat& _oppo_(CMat& a) // ---a^(-1)
{
CMat* p_result = new CMat;

*p_result = _cpn_(a) *(1 / Det(a));

return *p_result;
}

//...

别的一些简单的实现就不写了,太长了~~

我知道这个程序写的有很多的不足,也写的相当的乱,难以解读。。。我自己看着都费力。。。但她确实可以运行的很好~~

如果你能耐着性子看完的一定是高手,请多指教吧~~

2007-06-15 23:08



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-146677-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.088472 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved