首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NxN行列式函数(C++)的代码问题

NxN行列式函数(C++)的代码问题
EN

Stack Overflow用户
提问于 2019-02-27 06:23:36
回答 2查看 216关注 0票数 2

我正在尝试写一个矩阵求逆计算器(我在uni中为我的数学模块做了一些关于矩阵的工作,所以我认为这将是一个练习递归函数的好方法)。

目前,我正在研究用于计算函数行列式的函数,一个用于2x2,一个用于3x3,它调用2x2 (行列式的递归公式,我相信你知道这个步骤)。

然后第三个函数将矩阵作为输入,首先检查它是2x2还是3x3,如果是,则将其发送到前面提到的相应函数。接下来,我们按照行列式公式递归地消除行和列,直到得到行列式的值。

这段代码最多可以处理4x4个矩阵,但是任何大于这个值的矩阵都会导致错误的答案。

我是在uni的第一年,并且是编程的新手,这是我第一次尝试使用递归函数,任何建议都将不胜感激。我的数学讲师建议也许可以使用cramers规则,但如果我能让这种方法发挥作用,那将是一件有趣的事情。

如果我的格式不是最好的,我很抱歉,目前我还停留在旧笔记本电脑上。

代码语言:javascript
复制
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

double MatrixDet2By2(vector<vector<double>> matrix);
double MatrixDet3By3(vector<vector<double>> matrix);
double MatrixDet(vector<vector<double>> matrix);
//vector<vector<double>> CalcMinorMatrix(vector<vector<double>> matrix);
//vector<vector<double>> CalcCofactorMatrix(vector<vector<double>> matrix);

int main(int argc, char** argv)
{

    vector<vector<double>> testMatrix = {{1,4},{7,9}};
    vector<vector<double>> testMatrix2 = { {5,3,7},{6,-1,0},{4,-11,-2} };
    vector<vector<double>> testMatrix3 = 
    {
        {5,3,7,6},
        {6,-1,0,4},
        {4,-11,-2,3},
        {1,3,7,9},
    };
    vector<vector<double>> testMatrix4 = 
    {
        {1,2,-1,6,1},
        {6,-1,0,4,3},
        {4,0,-2,3,2},
        {1,3,7,2,3},
        {-2,7,0,2,5},
    };

    //cout << MatrixDet2By2(testMatrix) << endl;
    cout << MatrixDet(testMatrix4) << endl;

    cout << endl;
    return 0;
}

double MatrixDet2By2(vector<vector<double>> matrix)
{
    return (matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]);
}

double MatrixDet3By3(vector<vector<double>> matrix)
{
    vector<vector<double>> subMatrix1 = {
        {matrix[1][1], matrix[1][2]},
        {matrix[2][1], matrix[2][2]}
    };

    vector<vector<double>> subMatrix2 = {
        {matrix[1][0], matrix[1][2]},
        {matrix[2][0], matrix[2][2]}
    };

    vector<vector<double>> subMatrix3 = {
        {matrix[1][0], matrix[1][1]},
        {matrix[2][0], matrix[2][1]}
    };

    return ((matrix[0][0] * MatrixDet2By2(subMatrix1)) - (matrix[0][1] * MatrixDet2By2(subMatrix2)) + (matrix[0][2] * MatrixDet2By2(subMatrix3)));
}
/*
vector<vector<double>> CalcMinorMatrix(vector<vector<double>> matrix)
{
    vector<vector<double>> subMatrix1 = {
        {matrix[1][1], matrix[1][2]},
        {matrix[2][1], matrix[2][2]}
    };

    vector<vector<double>> subMatrix2 = {
        {matrix[1][0], matrix[1][2]},
        {matrix[2][0], matrix[2][2]}
    };

    vector<vector<double>> subMatrix3 = {
        {matrix[1][0], matrix[1][1]},
        {matrix[2][0], matrix[2][1]}
    };

    vector<vector<double>> subMatrix4 = {
    {matrix[0][1], matrix[0][2]},
    {matrix[2][1], matrix[2][2]}
    };

    vector<vector<double>> subMatrix5 = {
        {matrix[0][0], matrix[0][2]},
        {matrix[2][0], matrix[2][2]}
    };

    vector<vector<double>> subMatrix6 = {
        {matrix[0][0], matrix[0][1]},
        {matrix[2][0], matrix[2][1]}
    };

    vector<vector<double>> subMatrix7 = {
        {matrix[0][1], matrix[0][2]},
        {matrix[1][1], matrix[1][2]}
    };

    vector<vector<double>> subMatrix8 = {
        {matrix[0][0], matrix[0][2]},
        {matrix[1][0], matrix[1][2]}
    };

    vector<vector<double>> subMatrix9 = {
        {matrix[0][0], matrix[0][1]},
        {matrix[1][0], matrix[1][1]}
    };

    vector<vector<double>> matrixOfMinors = {
        {MatrixDet2By2(subMatrix1), MatrixDet2By2(subMatrix2), MatrixDet2By2(subMatrix3)},
        {MatrixDet2By2(subMatrix4), MatrixDet2By2(subMatrix5), MatrixDet2By2(subMatrix6)},
        {MatrixDet2By2(subMatrix7), MatrixDet2By2(subMatrix8), MatrixDet2By2(subMatrix9)},
    };

    return matrixOfMinors;
}

vector<vector<double>> CalcCofactorMatrix(vector<vector<double>> matrix)
{



    return matrix;
}
*/
double MatrixDet(vector<vector<double>> matrix)
{
    vector<vector<double>> tempMatrix{};

    static double totalDeterminant = 0;

    if (matrix.size() != matrix[0].size())
    {
        cout << "\r\nPlease enter a valid square matrix" << endl;
    }

    else if (matrix.size() == 2)
    {
        return MatrixDet2By2(matrix);
    }

    else if (matrix.size() == 3)
    {
        return MatrixDet3By3(matrix);
    }


    else
    {
        size_t pos = 0;


        for (auto value : matrix[0])
        {
            tempMatrix = matrix;
            tempMatrix.erase(tempMatrix.begin());

            for (size_t i = 0; i < tempMatrix.size(); i++)
            {
                if (tempMatrix[i].size() > pos)
                {
                    tempMatrix[i].erase(tempMatrix[i].begin() + pos);
                }
            }

            cout << "\r\n---------" << endl;
            for (auto vec : tempMatrix)
            {
                for (auto val : vec)
                {
                    cout << val << " ";
                }
                cout << endl;
            }
            cout << "\r\n---------" << endl;

            //totalDeterminant += MatrixDet(tempMatrix);


            if ((pos + 1) % 2 == 0)
            {
                totalDeterminant += (-value * MatrixDet(tempMatrix));
            }

            else
            {
                totalDeterminant += (value * MatrixDet(tempMatrix));
            }

            pos++;
        }



    }
    return totalDeterminant;

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-27 06:59:53

由于您在MatrixDet中使用关键字static定义了变量totalDeterminant,因此您的程序中永远只有一个totalDeterminant变量。并且= 0初始化器只在程序第一次到达那里时才会应用。因此,当计算第一个4x4次要矩阵的行列式时,这很好。然后将结果与matrix[0][0]相乘,并将其与totalDeterminant相加。第二个4x4次要矩阵的计算从那个奇怪的值(1+matrix[0][0])*detMinor1开始,并开始与之相加。

实际上,如果您只是在同一个程序中对两个4x4矩阵调用MatrixDet,那么第二个调用将返回两个行列式的总和。

每个主矩阵和子矩阵计算都需要一个单独的和(因为子矩阵行列式的结果需要乘以一个元素,然后才能添加到其他任何元素中)。所以totalDeterminant不能是static。当我从你的程序中删除static时,它给出了MatrixDet(testMatrix4) == -856的正确的最终结果。

请注意,一旦一般情况是正确的,您可以删除3x3甚至2x2情况的代码。不要忘记支持1x1矩阵:det [[x]] = x

票数 2
EN

Stack Overflow用户

发布于 2019-02-27 06:39:06

以下几行中有一个错误

代码语言:javascript
复制
for (size_t i = 0; i < tempMatrix.size(); i++)
{
    if (tempMatrix[i].size() > pos)
    {
        tempMatrix[i].erase(tempMatrix[i].begin() + pos);
    }
}

check if (tempMatrix[i].size() > pos)不是必需的。

要获得子矩阵,只需排除pos-th列。您需要使用:

代码语言:javascript
复制
// Remove the "pos" column of tempMatrix.
for (size_t i = 0; i < tempMatrix.size(); i++)
{
   tempMatrix[i].erase(tempMatrix[i].begin() + pos);
}

第二个错误是对totalDeterminant使用static变量,正如@aschepler所指出的那样。这条线

代码语言:javascript
复制
static double totalDeterminant = 0;

需要简单明了

代码语言:javascript
复制
double totalDeterminant = 0;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54895144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档