找回密码
 立即注册
收起左侧

Qt做数值运算出错-计算矩阵的秩与VC不同,算法是正确的

2
回复
8398
查看
[复制链接]
累计签到:894 天
连续签到:1 天
来源: 2013-8-16 12:03:17 显示全部楼层 |阅读模式
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。
回复

使用道具 举报

累计签到:7 天
连续签到:1 天
2013-8-16 12:03:18 显示全部楼层
我这里运行结果是对的,见图。
注:我的Qt版本是5.1。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

累计签到:894 天
连续签到:1 天
2013-8-23 22:57:37 显示全部楼层
blacknightshade 发表于 2013-8-16 16:37
我这里运行结果是对的,见图。
注:我的Qt版本是5.1。

恩,谢谢你。问题解决了,我把size_t 改成int就行了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了