【问题标题】:Solving a simple matrix in row-reduced form in C++在 C++ 中以行缩减形式求解一个简单的矩阵
【发布时间】:2015-07-31 23:00:57
【问题描述】:

好的,我正在拔掉我所有的头发,不过,作为一个菜鸟,我确信有几个问题。我想采用一个矩阵,并通过执行基本的行操作,将其简化为行缩减梯形。我们假设(1)它是可解的,(2)一个唯一的解。没有检查零或任何东西;它只是进行行操作。代码如下:

#include <iostream>
#include <cstdlib>

using namespace std;

void printmatrix(float A[][4]);
void RowReduce (float A[][4]);

int main() {

    // answer should be { 2, 4, -3 }
    float A[3][4] = {
        { 5, -6, -7,   7 },
        { 3, -2,  5, -17 },
        { 2,  4, -3,  29 }
    };

    printmatrix(A);
    RowReduce(A);

}

// Outputs the matrix
void printmatrix(float A[][4]) { 

    int p = 3;
    int q = 4;

    for (int i = 0; i < p; i++) {
        for (int j = 0; j < q; j++) {
            cout << A[i][j] << " ";
        }
        cout << endl;
    } 

}

void RowReduce (float A[][4]){

    //rows
    int p = 3;  
    //columns
    int q = 4;  

    // the determines the column we are at which holds the diagonal,
    // the basis for all elimination above and below
    int lead = 0; 

    cout << endl;
    while ( lead < q - 1 ) {

        // for each row . . .
        for (int i = 0; i < p; i++)  {

            // ignore the diagonal, and we will not have a tree rref
            // as the diagonal will not be divided by itself. I can fix that.
            if ( i != lead )  {

                cout << A[lead][lead] << "  " << A[i][lead];

                for (int j = 0; j < q; j++) {

                    //here is the math . . . . probably where the problem is?
                    A[i][j]    = A[lead][lead] * A[i][j]; 
                    A[i][lead] = A[i][lead]    * A[lead][j];
                    A[i][j]    = A[i][j]       - A[i][lead];

                }

                cout << endl;

            }
        }

        // now go to the next pivot
        lead++;  
        cout << endl;

    }

}

我尝试用手做,但我得到的当然是正确的答案,但这得到了一个对角矩阵——这很好——但是错误的答案!

【问题讨论】:

  • 试着弄清楚你是如何手工完成的,然后在代码中复制这种行为。 (当然,如果我没记错线性代数,那么我是如何手工完成的主要是直观的,因此很难在代码中精确复制......但是,有一些简单的方法可以做到这一点,你可以用谷歌搜索。)
  • 如果它应该做你手工做的事情,那么我会在每个枢轴周期结束时插入一个printmatrix 调用。你会(希望很快)看到它是如何/哪里出了问题。
  • 如果这不是学校作业,Eigen 是一个很棒的 C++ 线性代数库。
  • “问题可能出在哪里?”你在使用调试器吗?单步执行代码?查看变量的值?
  • 是的,我做了一些中间打印,但无法缩小范围。我想我希望有人会帮我计算一下,看看我哪里出错了,他。 :-)

标签: c++ arrays matrix


【解决方案1】:

您的代码中的主要错误是您在 for 循环中计算除数或乘数。您应该在迭代单元格之前计算它们。

提示:如果代码格式正确且变量具有有意义的名称,则调试会更容易。

查看RowReduce()的实现:

#include <iostream>
#include <cstdlib>
#include <iomanip>

using namespace std;

void printmatrix(float A[][4]);
void RowReduce(float A[][4]);

int main()
{
    float A[3][4] = {{5, -6, -7,   7},
                     {3, -2,  5, -17},
                     {2,  4, -3,  29}}; //answer should be {2, 4, -3}

    printmatrix(A);
    RowReduce(A);
}

void printmatrix(float A[][4]) // Outputs the matrix
{
    int p=3;
    int q=4;

    for (int i=0; i<p; i++) {
            for (int j=0; j<q; j++) {
                    cout << setw(7) << setprecision(4) << A[i][j] << " ";
            }
            cout << endl;
    }

    cout << endl;
}

void RowReduce(float A[][4])
{
    const int nrows = 3; // number of rows
    const int ncols = 4; // number of columns

    int lead = 0; 

    while (lead < nrows) {
        float d, m;

        for (int r = 0; r < nrows; r++) { // for each row ...
            /* calculate divisor and multiplier */
            d = A[lead][lead];
            m = A[r][lead] / A[lead][lead];

            for (int c = 0; c < ncols; c++) { // for each column ...
                if (r == lead)
                    A[r][c] /= d;               // make pivot = 1
                else
                    A[r][c] -= A[lead][c] * m;  // make other = 0
            }
        }

        lead++;
        printmatrix(A);
    }
}

输出:

  5      -6      -7       7 
  3      -2       5     -17 
  2       4      -3      29 


  1    -1.2    -1.4     1.4 
  0     1.6     9.2   -21.2 
  0     6.4    -0.2    26.2 

  1       0     5.5   -14.5 
  0       1    5.75  -13.25 
  0       0     -37     111 

  1       0       0       2 
  0       1       0       4 
  0       0       1      -3

【讨论】:

  • 非常好,谢谢。但是,不确定我的有什么问题。我也试着做我的,因为我会用手做。你的方法是达到相同目的的不同方法,但我仍然不确定我哪里出错了。不过感谢您的努力!
  • 有没有办法让它适用于:1 2 3 4 / 0 0 1 1 / 0 0 1 1 /
猜你喜欢
  • 1970-01-01
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多