//implementa el metodo de eliminacion gaussiana con pivoteo
// maximo por columna
// m tiene filas y filas+1 columnas, la ultima es la extension
long double* Simulador :: resolver(long double **matriz) {
int filas = m->getTamanio()*m->getTamanio();
int n = filas;
//nrow va a actuar como diccionario para no tener que hacer
//intercambio real de los valores
int *nrow = new int [ filas ];
for(int i = 0; i < filas; i ++) {
nrow[ i ] = i;
}
int *ncol = new int [ filas ];
for(int i = 0; i < filas; i ++) {
ncol[ i ] = i;
}
int p;
for(int i = 0; i < filas - 1; i ++) {
p = buscarMaximo(matriz, i, filas, nrow, ncol);
if(matriz[ nrow[ p ] ][ ncol[i] ] == 0) {
int c =buscarMaxCol(matriz,p,nrow,i,ncol, filas);
if(c==i) {
break;
}
if(ncol[ i ] != ncol[ c ] ) {
int ncopy = ncol[ i ];
ncol[ i ] = ncol[ c ];
ncol[ c ] = ncopy;
}
p = buscarMaximo(matriz, i, filas, nrow, ncol);
}
if(nrow[ i ] != nrow[ p ] ) {
int ncopy = nrow[ i ];
nrow[ i ] = nrow[ p ];
nrow[ p ] = ncopy;
}
for(int j = i + 1; j < filas ; j ++) {
if(matriz[ nrow[ j ] ][ i ] != 0) {
long double multiplicador = matriz[ nrow[ j ] ][ i ] / matriz[ nrow[ i ]][ i ];
for(int k = i; k <= filas; k ++) {
matriz[ nrow[ j ] ][ k ] = matriz[ nrow[ j ] ][ k ] - multiplicador *
matriz[ nrow[ i ] ][ k];
}
}
}
}
long double *x = new long double [filas];
long double *y = new long double [filas];
if(matriz[ nrow[ n - 1 ] ][ncol [n - 1] ] == 0) {
if(matriz[nrow[n-1]][n] == 0) {
x[n-1] = 1;
cout<<"variable libre: ";
cout<<n-1<<endl;
} else {
cout<<"error"<<endl;
cout<<"ultimo nulo"<<endl;
}
} else {
x[n - 1]= matriz[ nrow[ n - 1 ] ][ n ] / matriz[ nrow[ n - 1 ] ][ncol[ n - 1]];
}
for(int i = n - 2; i >= 0; i --) {
long double acum = 0;
if( matriz[nrow[i]][ncol[i]] == 0) {
if(matriz[nrow[i]][n] == 0) {
x[i] = 1;
cout<<"variable libre: ";
cout<<i<<endl;
} else {
//se q el sistema esta determinado
//tonces vale igual, pero
x[i] = 1;
cout<<"variable libre: ";
cout<<i<<endl;
}
} else {
for(int k = i + 1; k < n; k ++) {
acum = acum + matriz[ nrow[ i ] ][ncol[ k] ] * x[ k ];
}
acum = matriz[ nrow[ i ] ][ n ] - acum;
acum = acum / matriz[ nrow[ i ] ][ ncol[i ]];
x[ i ] = acum;
}
}
for(int i = 0; i < n; i++) {
y[ncol[i]] = x[i];
}
delete[] nrow ;
delete[]ncol;
delete[] x;
return y;
}
int Simulador :: buscarMaxCol(long double **matriz,int p,int *nrow,int i,int *ncol, int filas) {
int res = i;
int j = i;
int filaActual = p;
//int filaMax = p;
while(filaActual < filas) {
while(j < filas) {
/* esta version busca el maximo, da menos es error en teoria, pero es bastante mas lento
* if(fabsl(m[nrow[filaMax]][ncol[res]]) < fabsl(m[nrow[filaActual]][ncol[j]])){
res=j;
filaMax = filaActual;
}*/
//se busca el primero no nulo
if(matriz[nrow[filaActual]][ncol[j]] != 0) {
res = j;
return res;
}
j++;
}
filaActual ++;
}
return res;
}
//permite buscar el pivote para triangular en la columna i
int Simulador :: buscarMaximo(long double **matriz, int i,int filas,int *nrow, int *ncol) {
int res=i;
int j = i;
while(j < filas) {
if(fabsl(matriz[nrow[res]][ncol[i]]) < fabsl(matriz[nrow[j]][ncol[i]]))
res=j;
j++;
}
return res;
}