#include <iostream>
#include <cstdlib>

#define TAM 3

int main(){
    void escalona(double matriz[TAM][TAM]);
    
    double m[TAM][TAM];
    int i, j;
    
    cout << "entre com a matriz" << endl;
    /*
     * Faz a leitura de cada um dos elementos da matriz, 
     * linha a linha:
     */
    for (i = 0; i < TAM; i++)
        for (j = 0; j < TAM; j++)
            cin >> m[i][j];
    
    // Inicia o escalonamento da matriz:
    escalona(m);    
        
    // Imprime a matriz com o resultado do escalonamento:
    for (i = 0; i < TAM; i++){
        for (j = 0; j < TAM; j++)
            cout << m[i][j] << " "; 
        cout << endl;
    }
        
    return 0;
    
}
        
     
void escalona(double matriz[TAM][TAM]){
    int i, j, k;
    double r, m;
    double linha[TAM]; // para troca de linhas

    // Percorre cada uma das linhas da matriz, fazendo o escalonamento:
    for (i = 0; i < TAM; i++){
        // Verifica se o elemento da diagonal principal (a[i][i])
        // não eh igual a zero, para fazer pivoteamento. Se for nulo
        // deve ser aplicada uma troca de linha para que fique correto
        // o escalonamento:
        if (matriz[i][i] != 0) { // valor nao e zero, faz pivoteamento
            // A variavel _r_ vai armazenar o inverso do elemento pivo,
            // ou seja, 1/matriz[i][i]. Isso farah com que o elemento pivo
            // se iguale a 1 (ex.: 5 * (1/5) == 1) 
            // Essa eh uma operacao elementar em linha que nao vai alterar
            // o resultado final (multiplicar uma linha inteira por uma
            // constante r:
            r = 1 / matriz[i][i];
            // Multiplica cada coluna da linha em uso no momento pela 
            // constante r:
            for (j = 0; j < TAM; j++){
                matriz[i][j] = r * matriz[i][j];
            }               
            
            // Percorre toda a coluna em que o elemento pivo estah,
            // multiplicando pelo fator de correcao que vai anular
            // o valor da coluna. Isso vai garantir que em cada coluna
            // apenas o elemento da diagonal principal seja nao nulo.
            for (j = 0; j < TAM; j++){
                if (j != i) { // Se nao for o elemento da diagonal:
                    // m armazena o valor negativo do elemento que vai
                    // ser anulado:
                    m =  - matriz[j][i];                    
                    // Percorre todos os elementos da linha, somando seu
                    // valor ao valor de m multiplicado pelo valor do 
                    // elemento da linha pivo respectivo.
                    //
                    // Por exemplo, suponha que a j-esima linha seja:
                    // 0 3 4
                    // e a linha pivo (i) seja:
                    // 3 1 2
                    // O elemento pivo eh o da 2a coluna. Assim, temos a 
                    // seguinte operacao realizada:
                    //   0     3      4
                    //+  0    -3     -8  -- equivalente a (0*3) (-3*1) (-4*2)
                    //=================
                    //   0     0     -4
                    // Observe que a coluna pivo tem seu valor nulo e as outras
                    // colunas sao multiplicadas pelo fator de correcao.
                    // Note ainda que a primeira coluna, que jah havia sido 
                    // anulada antes, permaneceu inalterada.
                    for (k = 0; k < TAM; k++){
                        matriz[j][k] = matriz[j][k] + m * matriz[i][k];
                    }
                    
                }
                
            }
        }
            
        else {// valor é zero, tem que trocar as linhas abaixo
            k = -1;
            j = i+1;
            
            while (j < TAM) {
                if ( matriz[j][i] != 0 ) { // se achou um diferente, entao marca para trocar a linha
                    k = j;
                    j = TAM; // para terminar while
                } else j++; // se nao achou, continua procurando
            }
            
            if (k != -1) { // achou um valor, entao troca as linhas
                linha = matriz[i];
                matriz[i] = matriz[k];
                matriz[k] = linha;
                i--; //para repetir o processo na mesma linha 
            }
                 
        }
    
    }
}


 


