Solving a simple matrix in row-reduced form in C++

12,538

The main error in you code is that you are calculating the divisor or multiplier within the for loop. You should calculate them before iterating over the cells.

Hint: debugging is easier if the code is well formated and the variables have meaningful names.

See the implementation of 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);
    }
}

The output:

  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
Share:
12,538

Related videos on Youtube

user5179531
Author by

user5179531

Updated on July 29, 2022

Comments

  • user5179531
    user5179531 almost 2 years

    Okay, I am pulling out all my hair on this one, though, as a noob, I am sure there are several problems. I want to take a matrix and, by sing elementary row operations, reduced it to row-reduced echelon form. We assume (1) it is solvable and (2) a unique solution. There is no checking for zeros or anything; it just does row operations. Here is the code:

    #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;
    
        }
    
    }
    

    I tried doing it by hand, but what I get is, of course, the right answer, but this gets a diagonal matrix--which is great--but the wrong answer!

  • user5179531
    user5179531 almost 9 years
    Very nice, thanks. Not sure, however, what is wrong with mine. I also tried to do mine as I would have done by hand. Yours is a different means to get the same ends, but I am not sure still where I went wrong. Thanks for your effort though!
  • Jan Veselý
    Jan Veselý over 5 years
    Is there a way to make it work for : 1 2 3 4 / 0 0 1 1 / 0 0 1 1 /