Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

arrays

matrix

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!

like image 392
user5179531 Avatar asked Jul 31 '15 23:07

user5179531


People also ask

How do you reduce a matrix to a row reduced form?

To get the matrix in reduced row echelon form, process non-zero entries above each pivot. Identify the last row having a pivot equal to 1, and let this be the pivot row. Add multiples of the pivot row to each of the upper rows, until every element above the pivot equals 0.


1 Answers

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
like image 60
sergej Avatar answered Oct 25 '22 11:10

sergej