[此贴子已经被作者于2007-6-13 23:08:48编辑过]
----------------解决方案--------------------------------------------------------
难道没有人会这个题吗?
----------------解决方案--------------------------------------------------------
是先算行列式的值吧,不过行列式很难算,用c实现可能还有很大近似误差.
----------------解决方案--------------------------------------------------------
如果要算行列式的话,好要算转制矩阵的......
----------------解决方案--------------------------------------------------------
我只学过2维的矩阵,没学过3维的
----------------解决方案--------------------------------------------------------
矩阵考完就忘了
----------------解决方案--------------------------------------------------------
用这个公式吧:
A的逆 = adj A / det A;
----------------解决方案--------------------------------------------------------
这样还是不会写,有谁能写出代码来看一下
----------------解决方案--------------------------------------------------------
我今天去图书馆时特意看了一下,有一本经典好书,电子工业出版社的<<c数值算法>>,国外牛人写的有700多页
里面讲到LU分解算法是比较好的算法之一.还有一本c++版本<<c++数值算法>>,内容差不多.
你如果目的是解决实际问题,用专业的数学软件MATLAB,一个命令就算出来了.如果你目的就是想掌握算法,去找数值计算的书看,为了减小舍入误差,算法比较复杂,不是论坛里就能说清楚的.
----------------解决方案--------------------------------------------------------
我来说吧,上学期学了线代,我粗心老算错作业题,就来了兴致写了个
思路是这样:先写个算行列式的函数 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;
}
//...
别的一些简单的实现就不写了,太长了~~
我知道这个程序写的有很多的不足,也写的相当的乱,难以解读。。。我自己看着都费力。。。但她确实可以运行的很好~~
如果你能耐着性子看完的一定是高手,请多指教吧~~
----------------解决方案--------------------------------------------------------