【问题标题】:Problem with finding determinant of matrix 3x3 or larger in C在 C 中找到矩阵 3x3 或更大的行列式的问题
【发布时间】:2020-04-03 20:41:19
【问题描述】:

我已经用 1x1 和 2x2 矩阵运行它,但对于较大的矩阵,我没有得到正确的答案。我在代码中有一个示例 5x5 矩阵,它的行列式应该是 -30024。

我正在运行这段代码,但它不会给我正确的答案:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define rMax 5

double a[rMax][rMax] = {{-1,2,3,-6,7}, {-2,0,-1,4,2}, {1,-9,8,2,0}, {9,3,5,7,9}, {-5,3,2,-2,2}};
//determinant should be -30024

double matrix_determinant(size_t rowMax, const double z[][rMax])
{
    double final = 0;
    double w[rowMax][rowMax];

    for(size_t row = 0; row < rowMax; row++) //copies z into a new editable matrix
    {
        for(size_t column = 0; column < rowMax; column++)
            w[row][column] = z[row][column];
    }

    if(rowMax > 2) //checks for larger matrix
    {
        for(size_t mat = 0; mat < rowMax; mat++) //loops equal to the max width of the matrix
        {
            double new[rowMax - 1][rowMax - 1]; //new matrix is 1x1 smaller

            for(size_t cRow = 0; cRow < (rowMax - 1); cRow++) //initializing the new matrix
            {
                for(size_t cCol = 0; cCol < (rowMax - 1); cCol++)
                {
                    new[cRow][cCol] = w[cRow + 1][((cCol + mat) % (rowMax - 1)) + 1];
                }           
            }
            if(0 == (mat % 2)) //alternates adding and subtracting
                final += (w[0][mat] * matrix_determinant((rowMax - 1), new));
            else
                final += ((-1) * w[0][mat] * matrix_determinant((rowMax - 1), new));
        }

        return final;
    }

    if(rowMax == 1) //checks for 1x1 matrix
    {
        return w[0][0];
    }

    else //computes final 2x2 matrix (base case)
    {
        final = (w[0][0] * w[1][1]) - (w[0][1] * w[1][0]);
        return final;
    }
}

int main ( void )
{
    size_t s = rMax;
    double det = matrix_determinant(s, a);
    printf("The determinant of matrix a is: %lf\n", det);
}

【问题讨论】:

  • 为什么不先处理 3x3 行列式,让它发挥作用?有了这些,4x4 和 5x5 以及更大的 NxN 行列式应该是可以管理的。 1x1 和 2x2 值很简单; 3x3 案例是第一个真正需要对矩阵进行分区的工作。您可能希望不需要制作副本 - 或者您最好将其推迟到现有代码工作之后。
  • 您可能应该在制作副本之前处理 rowMax == 1rowMax == 2 案例 - 您可以直接使用 z 处理这两个案例。
  • 你有没有打印矩阵的代码,这样你就可以看到你的递归调用是否传递了正确的数据?
  • 至少这个问题:错误地将double new[rowMax - 1][rowMax - 1];传递给matrix_determinant(size_t rowMax, const double z[][rMax])
  • 拿起chuxcomment——你的函数double matrix_determinant(size_t rowMax, const double z[][rMax])应该是double matrix_determinant(size_t rowMax, const double z[][rowMax]),因为你分配new矩阵的方式——或者用new矩阵分配@987654333 @ 而不是 rowMax-1 作为维度。 (我避免使用 C++ 关键字作为 C 变量名——注意new。)

标签: c


【解决方案1】:

2 个变化。

类型错误

错误地将double new[rowMax - 1][rowMax - 1]; 传递给matrix_determinant(size_t rowMax, const double z[][rMax])。最后的[rowMax - 1] 肯定不匹配[rMax]

由于种种原因(这是一个side issue),我也拿出了const

// double matrix_determinant(size_t rowMax,   double z[][rMax])
double matrix_determinant(size_t rowMax,    double z[rowMax][rowMax])

计算错误

改进了new[cRow][cCol] 计算。 OP 的代码没有跳过w[][] 中的右列。

            size_t offset = 0;
            for(size_t cCol = 0; cCol < (rowMax - 1); cCol++) {
                //new[cRow][cCol] = w[cRow + 1][((cCol + mat) % (rowMax - 1)) + 1];
                if (cCol == mat) offset = 1;
                new[cRow][cCol] = w[cRow + 1][cCol + offset];
            }

结果

The determinant of matrix a is: -30024.000000

【讨论】:

  • 我认为整个“复制到w”操作是多余的。 “复制到new”操作可以来自z,也可以来自w,不是吗?
  • @JonathanLeffler 同意。没有w[] 可以重构代码。我怀疑是代码试图处理原始z[] 的不同维度。
猜你喜欢
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多