|
5Qter豆
按照《计算机常用数值算法与程序(C++版)》书中写的,计算矩阵的秩,出现错误结果。
在VC60中运行的结果正确,与手算的结果相同。
以下是截图,(左边Qt,右边VC60)
出错matA矩阵为
const double dma[4][4 = { { 1.0, 2.0, 3.0, 4.0 }, { 5.0, 6.0, 7.0, 8.0 }, { 9.0, 10.0, 11.0, 12.0 }, { 13.0, 14.0, 15.0, 16.0 } };
手算的结果是2,所以Qt的结果(第一行)是错误的,VC60的结果是正确的。
算法是
//全选主元高斯(Gauss)消去法求一般矩阵的秩
template <typename T>//返回值为秩数
size_t matrank(const matrix<T>& mat)
{
size_t iSign, jSign;//主元的位置标志
size_t mrank = 0;//矩阵秩数
size_t nrow = mat.getrownum();//取矩阵行数
size_t ncol = mat.getcolnum();//取矩阵列数
size_t ColRowMin = Min(nrow, ncol); //取行或列最小值
matrix<T> m(mat);
//生成一matrix对象,用mat初始化
for(size_t k = 0; k < ColRowMin; k ++)
{ // 全选主元
long double MaxValue(0);
for(size_t i = k; i < nrow; i ++)
for(size_t j = k; j < ncol; j ++)
{
long double tmp(Abs(m(i, j))); //求m(i,j)绝对值
if(tmp > MaxValue)
{
MaxValue = tmp;
iSign = i; //记下主元位置
jSign = j;
}
}
//}
//子阵元素绝对值最大者为0,
// 注意浮点数与0相等的定义,见comm.h
if(FloatEqual(MaxValue, 0))
break; //return mrank;
else
mrank++;
//子阵元素绝对值最大者不为0,矩阵秩加1
if(k ==(ColRowMin - 1)) //已到最后一行(列)
break; //return mrank;
if(iSign != k) //主元不在当前行
{
for(size_t j = k; j < ncol; j ++) //交换行元素
swap(&m(k, j), &m(iSign, j));
}
if(jSign != k) //主元不在当前列
{
for(size_t i = k; i < nrow; i ++) //交换列元素
swap(&m(i, jSign), &m(i, k));
}
for(size_t i = k + 1; i < nrow; i ++)
{
const T d(m(i, k) / m(k, k)); //消元因子
for(size_t j = k + 1; j < ncol; j ++)
m(i, j) -= d * m(k, j);//当前主元右下阵元素作变换
}
}
return mrank;
}
我研究了好久,也没有弄明白是哪出了错。
以下是源文件,Qt和VC60工程文件,打开直接编译就可以用。
恳请大神指教!
|
最佳答案
查看完整内容
我这里运行结果是对的,见图。
注:我的Qt版本是5.1。
|