Hello ,

I want to scan each row and find in each column the max element and the corresponding index.
Then , swap this column with the column which belongs to the main diagonal ( if a condition is valid ).

Finally , do the same for the rest rows.

In my code , I can't find the right index which corresponds to the max value!!!
Then,I can't figure how to use the column index in order to make the swap.
Finally , I can't figure how to continue with 1 row less.

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iomanip>

using namespace std;

void swapCols( const int ColIdx , const int N, double * const a, double * const b );

int main()
{
    const int N = 3;

    double * a = new double[ N * N ];
    double * b = new double[ N ];
    double * x = new double[ N ];

    a[ 0 ] = 9;
    a[ 1 ] = 3;
    a[ 2 ] = 1;
    a[ 3 ] = 0;
    a[ 4 ] = 4;
    a[ 5 ] = 5;
    a[ 6 ] = 8;
    a[ 7 ] = 1;
    a[ 8 ] = 4;

    b[ 0 ] = 7;
    b[ 1 ] = 8;
    b[ 2 ] = 9;

    //matrix before
    for ( int i = 0; i < N; i++ )
    {
        for ( int j = 0; j < N; j++ )
        {
            cout  << a[ i * N + j ] << setw(4);
        }

        cout << b[ i ] << endl;
    }


    //start the algorithm
    double Max;

    for ( int i = 0; i < N; i++ )
    {
        int ColIdx = 0;
        Max = fabs( a[ i * N ] );
        for ( int j = 1; j < N; j++ ) 
        {

            // Find the max element in a row and the index
            if ( fabs( a[ i * N + j ] ) > Max ) 
            {
                Max = fabs( a[ i * N + j ] );
                ColIdx = j;
            }
            else
            {
                Max = Max;
                ColIdx = j;

            }


        } // j

        cout << "max = " << Max << " idx = " << ColIdx << endl;

        // for this index ,compare to the element of the main diagonal
        // if it > main diagonal , then swap cols

        //I inserted a 3rd loop (k) because I can't figure how to use the column index
        for ( int k = 0; k < N; k++ )
        {
            if ( i == k )
            {              
                if ( fabs( a[ i * N + k ] ) < Max )  
                    swapCols( ColIdx ,N, a ,b );            
            }                    

        }

        // now we must go to the 2nd row and do the same but leave aside the first element of main diagonal!   
        // that's why the dimensions to be scanned now ,will be 1 row less


    } // i




    //matrix after
    for ( int i = 0; i < N; i++ )
    {
        for ( int j = 0; j < N; j++ )
        {
            cout  << a[ i * N + j ] << setw(4);
        }

        cout << b[ i ] << endl;
    }


    //free memory
    delete [] a;
    delete [] b;
    delete [] x;

    return 0;
}



void swapCols( 

const int ColIdx,
const int N,
double * const a,
double * const b )
{

    double tA , tB;

    for ( int i = 0; i < N; i++ )
    {
        for ( int j = 0; j < N; j++ ) 
        {

            tA = a[ i * N + 0 ];
            tB = b[ 0 ]; 


            a[ i * N + 0 ] = a[ i * N + ColIdx ];
            b[ 0 ] = b[ ColIdx ];

            a[ i * N + ColIdx ] = tA;
            b[ ColIdx ] = tB;

        }

   }


}

Thank you!

--------
Sorry , I uploaded in C ,but I don't have a problem using either ( I don't want to use libraries though)

Edited 1 Year Ago by glao

Not sure why you are switching values in the b array or why your swap function uses loops.

#include <iostream>
using namespace std;

int main()
{
    const int N = 3;
    double *a = new double[N*N];
    double *b = new double[N];
    double *x = new double[N];

    a[0] = 9;
    a[1] = 3;
    a[2] = 1;
    a[3] = 0;
    a[4] = 4;
    a[5] = 5;
    a[6] = 8;
    a[7] = 1;
    a[8] = 4;

    b[0] = 7;
    b[1] = 8;
    b[2] = 9;

    cout << "Before" << endl;
    for (int r = 0; r < N; r++)
    {
        for (int c = 0; c < N; c++)
            cout << a[r*N + c] << " ";
        cout << b[r] << endl;
    }

    cout << endl;

    for (int r = 0; r < N; r++)
    {
        //"Assume" maxIndex is the first element of the row
        int maxIndex = r*N;

        //Check to see if the rest of the elements are greater than current max index
        for (int c = 1; c < N; c++)
        {
            //If it is greater then set the max index to the current index
            if (fabs(a[r*N + c]) > fabs(a[maxIndex]))
                maxIndex = r*N + c;
        }

        cout << "Max = " << fabs(a[maxIndex]) << " idx = " << maxIndex - r*N << endl;

        //If the max index is not a diag then lets switch it
        if (maxIndex - r*N != r) //col != row aka diag
        {
            double tmp = a[maxIndex];
            a[maxIndex] = a[r*N + r];
            a[r*N + r] = tmp;
        }
    }

    cout << endl << "After" << endl;
    for (int r = 0; r < N; r++)
    {
        for (int c = 0; c < N; c++)
            cout << a[r*N + c] << " ";
        cout << b[r] << endl;
    }

    delete[] a;
    delete[] b;
    delete[] x;

    cin.get();
    return 0;
}

Great!
Thanks a lot !

Just a question.
Could you tell me how you thought this:

a[maxIndex] = a[r*N + r];

I mean the index r*N + r.
As I can see it gives the diagonal elements.
I didn't know about that!

Also, do you have a solution using the max value instead of the max index?

Because ,I can't figure why I couldn't get the proper max value.

Just a question.
Could you tell me how you thought this:

a[maxIndex] = a[r*N + r];

I mean the index r*N + r.
As I can see it gives the diagonal elements.
I didn't know about that!

The diagonal elements occur when the row index is equal to the column index. We use "r" in this case because we are iterating through the rows with the outer most for loop. If you write the matrix out on paper and try to come up with general solutions using only constants (N in this case) and variables that you are controling (r and c), you can come up with equations that you can input directly into your code.

Also, do you have a solution using the max value instead of the max index?

Because ,I can't figure why I couldn't get the proper max value.

You could use the max value but you will have to keep track of the column index of the max value (unless you want to scan through the columns after finding the max value to find it again and do the swap, which I think is a bad idea).

for (int r = 0; r < N; r++)
{
    //"Assume" maxValue is the first element of the row
    double maxValue = fabs(a[r*N]);
    int col = 0;

    //Check to see if the rest of the elements are greater than current max value
    for (int c = 1; c < N; c++)
    {
        //If it is greater then set the max value to the current index
        if (fabs(a[r*N + c]) > maxValue)
        {
            maxValue = fabs(a[r*N + c]);
            col = c;
        }
    }

    cout << "Max = " << maxValue << " idx = " << col << endl;

    //If the max index is not a diag then lets switch it
    if (col != r) //col != row aka diag
    {
        a[r*N + col] = a[r*N + r];
        a[r*N + r] = maxValue;
    }
}

So, my error was the else statement when checking for the max value..

Ok, thank you!

This question has already been answered. Start a new discussion instead.