Sie sind auf Seite 1von 21

#include <iostream>

#include <cmath>
//#include <conio.h>
#include <stdlib.h>
#include <iomanip>
#include <fstream>
#include <sstream>
using namespace std;
//##############################################################################
###############
//######
FUNCIONES AUXILIARES
######
//##############################################################################
###############
//Funcin que recibe un arreglo y un numero entero (que especifica la longitud del
arreglo) y
//muestra el arreglo en la pantalla como [x1,x2,...,xn].
void mostrar(double v[], int n)
{
int i;
for(i=0;i<n;i++)
{
int p=7; //presicion con la que se muestra el resultado
int ancho_campo=12;
cout << setiosflags(ios::showpoint);
if(i>0 && i<n-1)
cout << setw(ancho_campo) << setprecision(p) << v[i] << ",";
else
{
if(i==0)
cout << "[" << setw(ancho_campo) << setprecision(p) << v[0] << "
,";
if(i==n-1)
cout << setw(ancho_campo) << setprecision(p) << v[i] << "]";
}
}
}
//Funcin que convierte un entero a un string
string convertir_int_str(int num)
{
stringstream flujo;
flujo << num;
return flujo.str();
}
//Funcion que depliega un mensaje de error para la clase vectores y para la clas
e matriz.
inline void mensaje_error(string nombre_funcion, string mensaje)
{
cout << nombre_funcion << ": " << mensaje << endl;
cout << "El programa no puede continuar." << endl;
//getch();
exit(1);
}
//Funcin que despliega un mensaje de error para la clase de vectores y para la

//clase matriz (renglones y columnas).


inline void mensaje_error(string nombre_funcion, string mensaje, int i)
{
int ind=mensaje.find("i");
mensaje.replace(ind,1,convertir_int_str(i));
cout << nombre_funcion << ": " << mensaje << endl;
cout << "El programa no puede continuar." << endl;
//getch();
exit(1);
}
//Funcion que despliega un mensaje de error para la clase matriz.
inline void mensaje_error(string nombre_funcion, string mensaje, int i, int j)
{
int ind1=mensaje.find("i");
mensaje.replace(ind1,1,convertir_int_str(i));
int ind2=mensaje.find("j");
mensaje.replace(ind2,1,convertir_int_str(j));
cout << nombre_funcion << ": " << mensaje << endl;
cout << "El programa no puede continuar." << endl;
//getch();
exit(1);
}
//Funcion para la clase matriz que intercambia el valor de a con b.
void intercambio(double& a,double& b)
{
double temp=a;
a=b;
b=temp;
}
//##############################################################################
###############

//##############################################################################
###############
//######
CLASE VECTOR
######
//##############################################################################
###############
class Vector
{
private:
double *v;
public:
int dimension;
Vector(int);
Vector(const Vector&);
void borrar_vector();
void llenar_vector();
void mostrar_vector();
void modificar_vector(int, double);
double obtener_componente(int);
double norma();
};
//Mensajes de error

string mens_error_v1="Error al acceder a la componente i del vector";


string mens_error_v2="Las columnas de la matriz deben coinicidir con la longitud
del vector";
//Funcin constructora
Vector::Vector(int longitud)
{
dimension=longitud;
v=new double[dimension];
}
//Funcion costructora de copia
Vector::Vector(const Vector &u)
{
*this=u;
}
//Funcin que elimina el vector
void Vector::borrar_vector()
{
delete[] v;
}
//Funcion que permite llenar las entradas del vector desde el teclado.
void Vector::llenar_vector()
{
int i;
for(i=0; i<dimension; i++)
{
cout << "Escribe la entrada " << i << " del vector: ";
cin >> v[i];
}
cout << "El vector se ha creado con exito." << endl;
}
//Funcion que imprime el vector en la pantalla
void Vector::mostrar_vector()
{
mostrar(v,dimension);
}
//Funcin que modifica la entrada i-sima del vector
void Vector::modificar_vector(int i,double num)
{
if(i<0 || i>=dimension)
{
mensaje_error("modificar_vector",mens_error_v1,i);
}
else
v[i]=num;
}
//Funcion que regresa la componenente i-sima del vector, si el valor de i
//excede la dimensin del vector entonces se manda un mendaje de error y
//se detiene el programa.
double Vector::obtener_componente(int i)
{
if(i<0 || i>=dimension)
{

mensaje_error("obtener_componente", mens_error_v1,i);
}
return v[i];
}
//Funcion que calcula la norma de un vector
double Vector::norma()
{
double cuadrado_norma;
int i;
for(i=0;i<dimension;i++)
{
cuadrado_norma+=v[i]*v[i];
}
return sqrt(cuadrado_norma);
}
/*
//Funcin amiga que tranpone un vector rengln y lo convierte en un vector columna,
//es decir, lo convierte en una matriz de nx1
Matriz transponer(Vector &v)
{
Matriz V(n,1);
int i;
int n=v.dimension;
for(i=0;i<n;i++)
{
V.modificar_matriz(i,1,v.obtener_componente(i));
}
return V;
}
*/
//##############################################################################
###############

//##############################################################################
###############
//######
CLASE MATRIZ
######
//##############################################################################
###############
class Matriz
{
friend Matriz multiplicar_matrices(Matriz&, Matriz&);
friend Vector mult_matriz_vector(Matriz&, Vector&);
friend Matriz matriz_aumentada(Matriz&, Vector&);
friend Vector sustitucion_atras(Matriz&);
friend Vector sustitucion_adelante(Matriz&);
friend Vector sustitucion_atras_crout(Matriz&);
friend Vector sustitucion_adelante_crout(Matriz&);
private:
double **A;
int num_renglones;
int num_columnas;
public:
Matriz(int, int);

Matriz(const Matriz&);
void operator==(const Matriz&);
void borrar_matriz();
void llenar_matriz();
void leer_matriz(ifstream&);
void mostrar_matriz();
void modificar_matriz(int, int, double);
double obtener_elemento(int,int);
void intercambiar_renglones(int, int);
void sumar_multiplo_renglon(int, int, int, double=1);
void eliminacion_gaussiana();
void metodo_dolittle(Matriz&, Matriz&);
void metodo_crout(Matriz&, Matriz&);
void metodo_crout_opt(Matriz&, Matriz&);
void metodo_cholesky(Matriz&);
void identidad();
void ceros();
bool es_cuadrada();
bool es_extendida();
bool es_simetrica();
bool es_tridiagonal();
};
//Mensaje de error
string mens_error_m1="Error al acceder al elemento [i,j] de la matriz.";
string mens_error_m2="Error al acceder al renglon i de la matriz.";
string mens_error_m3="Error al acceder a la columna j de la matriz.";
string mens_error_m4="Las matrices introducidas deben ser cuadradas.";//Dolittle
, Cholesky, Crout
string mens_error_m5="La dimension de las matrices debe ser la misma.";//Dolittl
e, Cholesky, Crout
string mens_error_m6="La matriz es singular."; //Eliminacion gaussiana, Sustituc
ion hacia atras,
// y Sustitucion hacia adelante, Crout,
Crout optimizado
string mens_error_m7="La matriz introducida debe ser del tipo extendida";
string mens_error_m8="La matriz no es simtrica."; //Cholesky
string mens_error_m9="La matriz no es definida positiva o es singular."; //Chole
sky
string mens_error_m10="La matriz no es tridiagonal."; //Crout
string mens_error_m11="Las matriz A debe ser de nx3, L de nx2 y U de nx1."; //Cr
out optimizado
string mens_error_m12="El nmero de renglones de las matrices debe ser el mismo.";
//Crout optimizado
string mens_error_m14="La matriz introducida no es del tamao adecuado."; //Sustit
ucin hacia atrs para Crout
//Funcin constructora
Matriz::Matriz(int m,int n)
{
int i;
num_renglones=m;
num_columnas=n;
A=new double*[m];
for(i=0;i<m;i++)
{
A[i]=new double[n];
}
}

//Funcin constructora de copia


Matriz::Matriz(const Matriz &B)
{
*this=B;
}
//Funcin que elimina la matriz creada para ahorrar espacio en la memoria
void Matriz::borrar_matriz()
{
int i;
for(i=0;i<num_renglones;i++)
{
delete[] A[i];
}
delete[] A;
}
//Funcin que permite llenar la matriz desde el teclado
void Matriz::llenar_matriz()
{
int i,j;
for(i=0;i<num_renglones;i++)
{
for(j=0;j<num_columnas;j++)
{
cout << "Escribe el elemento [" << i << "," << j << "]"
<< " de la matriz: ";
cin >> A[i][j];
}
}
cout << "La matriz se ha creado con exito." << endl;
}
/*
//Funcin que permite leer una matriz almacenada en un archivo
void Matriz::leer_matriz(ifstream &archivo)
{
archivo.open("Datos_prueba.txt");
if(archivo.fail())
{
cout << "El archivo Datos_prueba.txt no se encuentra.\n"
<< "Verifique que se encuentra en el directorio actual." << endl;
}
else
{
cout << "El archivo Datos_prueba.txt se abrio correctamente." << endl;
}
}
*/
//Funcion que imprime la matriz en pantalla
void Matriz::mostrar_matriz()
{
int i;
for(i=0;i<num_renglones;i++)
{
if(i>0 && i<num_renglones-1)

{
cout << " ";
mostrar(A[i],num_columnas);
cout << ",\n";
}
else
{
if(i==0)
{
cout << "[";
mostrar(A[i],num_columnas);
cout << ",\n";
}
if(i==num_renglones-1)
{
cout << " ";
mostrar(A[i],num_columnas);
cout << "]";
}
}
}
}
//Funcin que graba el valor de num en la posicin i,j de la matriz
void Matriz::modificar_matriz(int i,int j,double num)
{
if(i<0 || i>=num_renglones || j<0 || j>=num_columnas)
{
mensaje_error("modificar_matriz",mens_error_m1,i,j);
}
else
A[i][j]=num;
}
//Funcin que obtiene el elemento i,j de la matriz
double Matriz::obtener_elemento(int i, int j)
{
if(i<0 || i>=num_renglones || j<0 || j>=num_columnas)
{
mensaje_error("obtener_elemento",mens_error_m1,i,j);
}
return A[i][j];
}
//Funcin que intercambia dos renglones en la matriz
void Matriz::intercambiar_renglones(int k, int l)
{
if(k<0 || k>=num_renglones)
{
mensaje_error("intercambiar_renglones",mens_error_m2,k);
}
if(l<0 || l>=num_renglones)
{
mensaje_error("intercambiar_renglones",mens_error_m2,l);
}
else
{
int j;
for(j=0;j<num_columnas;j++)

intercambio(A[k][j],A[l][j]);
}
}
//Funcin que multiplica el rengln k por un esclar y suma ste rengln modificado
//al rengln l; el resultado se guarda en l. La suma se realiza a partir de
//la columna s.
void Matriz::sumar_multiplo_renglon(int k, int l, int s, double escalar)
{
if(k<0 || k>=num_renglones)
{
mensaje_error("sumar_multiplo_renglon",mens_error_m2,k);
}
if(l<0 || l>=num_renglones)
{
mensaje_error("sumar_multiplo_renglon",mens_error_m2,l);
}
if(s<0 || s>=num_columnas)
{
mensaje_error("sumar_multiplo_renglon",mens_error_m3,s);
}
else
{
int j;
for(j=s;j<num_columnas;j++)
{
A[l][j]=escalar*A[k][j]+A[l][j];
}
}
}
//Funcin amiga que multiplica dos matrices.
Matriz multiplicar_matrices(Matriz &A, Matriz &B)
{
int m=A.num_renglones;
int n=A.num_columnas;
int t=B.num_renglones;
int s=B.num_columnas;
if(t!=n)
{
mensaje_error("multiplicar_matrices", mens_error_m4);
}
int i,j,k;
double suma=0;
Matriz C(m,s);
for(i=0;i<m;i++)
{
for(j=0;j<s;j++)
{
for(k=0;k<n;k++)
{
suma+=A.obtener_elemento(i,k)*B.obtener_elemento(k,j);
}
C.modificar_matriz(i,j,suma);
suma=0;
}
}
return C;

}
//Funcin amiga que multiplica una matriz A por un vector rengln v, de la siguiente
//manera: Av^T=b. La funcin regresa como resultado b^T. (La notacin
// a^T significa el transpuesto del vector a)
Vector mult_matriz_vector(Matriz &A,Vector &v)
{
int n=A.num_columnas;
if(n!=v.dimension)
mensaje_error("mult_matriz_vector", mens_error_v2);
Vector resultado(n);
int i,j;
int m=A.num_renglones;
double suma=0;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
suma+=A.obtener_elemento(i,j)*v.obtener_componente(j);
}
resultado.modificar_vector(i,suma);
suma=0;
}
return resultado;
}
//Funcin amiga que crea la matriz aumentada. Esta funcin crea una matriz nueva y
//no modifica la matriz existente.
Matriz matriz_aumentada(Matriz &A, Vector &v)
{
int i,j;
int m=A.num_renglones;
int n=A.num_columnas;
Matriz B(m,n+1);
for(i=0;i<m;i++)
{
for(j=0;j<n+1;j++)
{
if(j<n)
B.modificar_matriz(i,j,A.obtener_elemento(i,j));
else
B.modificar_matriz(i,j,v.obtener_componente(i));
}
}
return B;
}
//Funcin que aplica el Mtodo de eliminacin Gaussiana a una matriz
//cuadrada o a una matriz aumentada.
void Matriz::eliminacion_gaussiana()
{
int k,i,s;
int n=num_renglones;
double akk;
for(k=0;k<n-1;k++)
{
//Primero se intercambia los renglones de manera adecuada.
if(A[k][k]==0)

{
for(s=k+1;s<n;s++)
{
if(A[s][k]!=0)
{
intercambiar_renglones(k,s);
break;
}
mensaje_error("eliminacion_gaussiana",mens_error_m6);
}
}
//Ahora se hacen cero los elementos debajos de la diagonal.
akk=A[k][k];
for(i=k+1;i<n;i++)
{
sumar_multiplo_renglon(k,i,k+1,-A[i][k]/akk);
A[i][k]=0;
}
}
}
//Funcin que aplica el metodo de Dolittles a la matriz A, la matriz superior
// y la matriz inferior resultantes se guardan en L y U respectivamente.
void Matriz::metodo_dolittle(Matriz &L, Matriz &U)
{
if(!es_cuadrada() || !(L.es_cuadrada()) || !(U.es_cuadrada()))
mensaje_error("metodo_dolittle", mens_error_m4);
int n=num_renglones;
int n1=L.num_renglones;
int n2=U.num_renglones;
if(n1!=n || n2!=n)
mensaje_error("metodo_dolittle", mens_error_m5);
int k,i,j,s;
double akk, mik;
L.identidad();
//Se crea una copia en U de los elementos de la matriz A.
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
U.modificar_matriz(i,j,A[i][j]);
}
}
for(k=0;k<n-1;k++)
{
//Primero se intercambia los renglones de manera adecuada.
if(U.obtener_elemento(k,k)==0)
{
for(s=k+1;s<n;s++)
{
if(U.obtener_elemento(s,k)!=0)
{
U.intercambiar_renglones(k,s);
break;
}
mensaje_error("metodo_dolittle",mens_error_m6);

}
}
//Ahora se hacen cero los elementos debajos de la diagonal.
//Adems los multiplicadores mik se guardan en L.
akk=U.obtener_elemento(k,k);
for(i=k+1;i<n;i++)
{
mik=U.obtener_elemento(i,k)/akk;
L.modificar_matriz(i,k,mik);
U.sumar_multiplo_renglon(k,i,k+1,-mik);
U.modificar_matriz(i,k,0);
}
}
}

//Funcin que aplica el mtodo de Crout (versin particular del mtodo de Dolittle, que
//solo se aplica a matrices tridiagonales) para descomoponer una matriz tridiago
nal
//en el producto de una matriz superior U y una matriz inferior L.
void Matriz::metodo_crout(Matriz &L, Matriz &U)
{
if(!es_cuadrada() || !(L.es_cuadrada()) || !(U.es_cuadrada()))
mensaje_error("metodo_crout", mens_error_m4);
int n=num_renglones;
int n1=L.num_renglones;
int n2=U.num_renglones;
if(n1!=n || n2!=n)
mensaje_error("metodo_crout", mens_error_m5);
if(!es_tridiagonal())
mensaje_error("metodo_crout",mens_error_m10);
L.ceros();
U.identidad();
L.modificar_matriz(0,0,A[0][0]);
int i;
double temp;
for(i=1;i<n;i++)
{
L.modificar_matriz(i,i-1,A[i][i-1]);
}
for(i=1;i<n;i++)
{
temp=L.obtener_elemento(i-1,i-1);
if (temp==0)
mensaje_error("metodo_crout",mens_error_m6);
U.modificar_matriz(i-1,i,A[i-1][i]/temp);
temp=A[i][i]-L.obtener_elemento(i,i-1)*U.obtener_elemento(i-1,i);
L.modificar_matriz(i,i,temp);
}
}
//Se puede demostrar que las matrices de nxn tridiagonales tienen n^2-3n+2 ceros
.
//Para optimizar el mtodo de Crout se cre la siguiente funcin.
//Se ejecuta de la siguiente manera:
//A.metodo_crout_opt(L,U), donde A, es una matriz de nx3, L es una matriz de nx2
y
//U es una matriz de nx1 (es decir un vector columna de n entradas).
//El truco para hacer la optimizacin es crear

//una biyeccin entre las matrices tridiagonales de nxn y las


//las matrices de nx3.
void Matriz::metodo_crout_opt(Matriz &L, Matriz &U)
{
int m=num_columnas;
int m1=L.num_columnas;
int m2=U.num_columnas;
if(m!=3 || m1!=2 || m2!=1)
mensaje_error("metodo_crout_opt",mens_error_m11);
int n=num_renglones;
int n1=L.num_renglones;
int n2=U.num_renglones;
if(n1!=n || n2!=n)
mensaje_error("metodo_crout_opt", mens_error_m12);
U.modificar_matriz(n-1,0,1);
L.modificar_matriz(0,1,A[0][1]);
int i;
double temp;
for(i=1;i<n;i++)
{
L.modificar_matriz(i,0,A[i][0]);
}
for(i=1;i<n;i++)
{
temp=L.obtener_elemento(i-1,1);
if (temp==0)
{
cout << i << endl;
mensaje_error("metodo_crout_opt",mens_error_m6);
}
U.modificar_matriz(i-1,0,A[i-1][2]/temp);
temp=A[i][1]-L.obtener_elemento(i,0)*U.obtener_elemento(i-1,0);
L.modificar_matriz(i,1,temp);
}
}
//Funcin que aplica el mtodo de Cholesky a una matriz simtrica, la matriz
//superior resultante se guarda en L.
void Matriz::metodo_cholesky(Matriz &L)
{
//Se verifica que la matriz A sea simetrica y que L sea cuadrada con la mism
a dimension
//que A.
if(!es_simetrica())
mensaje_error("metodo_cholesky",mens_error_m8);
if(!L.es_cuadrada())
mensaje_error("metodo_cholesky",mens_error_m4);
int n=num_renglones;
int n1=L.num_renglones;
if(n!=n1)
mensaje_error("metodo_cholesky",mens_error_m5);
L.ceros();
double a00=A[0][0];
if(a00<=0)
mensaje_error("metodo_cholesky",mens_error_m9);
double l00=sqrt(a00);
L.modificar_matriz(0,0,l00);
L.mostrar_matriz();//*******************

cout << "\n";


int i,j,k;
double suma=0;
double temp;
for(i=1;i<n;i++)
{
L.modificar_matriz(i,0,A[i][0]/l00);
L.mostrar_matriz();//*******************
cout << "\n";
}
for(i=1;i<n-1;i++)
{
for(k=0;k<=i-1;k++)
{
suma+=L.obtener_elemento(i,k)*L.obtener_elemento(i,k);
}
temp=A[i][i]-suma;
cout << temp << endl;
if(temp<=0)
mensaje_error("metodo_cholesky",mens_error_m9);
L.modificar_matriz(i,i,sqrt(temp));
L.mostrar_matriz();//*******************
cout << "\n";
suma=0;
for(j=i+1;j<n;j++)
{
for(k=0;k<=i-1;k++)
{
suma+=L.obtener_elemento(i,k)*L.obtener_elemento(j,k);
}
temp=(A[j][i]-suma)/L.obtener_elemento(i,i);
L.modificar_matriz(j,i,temp);
L.mostrar_matriz();//*******************
cout << "\n";
suma=0;
}
}
for(k=0;k<n-1;k++)
{
suma+=L.obtener_elemento(n-1,k)*L.obtener_elemento(n-1,k);
}
temp=A[n-1][n-1]-suma;
if(temp<=0)
mensaje_error("metodo_cholesky",mens_error_m9);
L.modificar_matriz(n-1,n-1,sqrt(temp));
L.mostrar_matriz();//*******************
cout << "\n";
}
//Funcion que llena una matriz con unos en la diagonal y cero en todo lo dems.
//Si la matriz es cuadrada, entonces la matriz resultante es la identidad.
void Matriz::identidad()
{
int i,j;
for(i=0;i<num_renglones;i++)
{
for(j=0;j<num_columnas;j++)
{
A[i][j]=0;

if(i==j)
A[i][i]=1;
}
}
}
//Funcion que transforma una matriz en una matriz llena de ceros.
void Matriz::ceros()
{
int i,j;
for(i=0;i<num_renglones;i++)
{
for(j=0;j<num_columnas;j++)
{
A[i][j]=0;
}
}
}
//Funcin que determina si una matriz es cuadrada.
bool Matriz::es_cuadrada()
{
if(num_columnas!=num_renglones)
return false;
return true;
}
//Funcin que determina si una matriz es extendida.
bool Matriz::es_extendida()
{
if(num_columnas==num_renglones+1)
return true;
return false;
}
//Funcin que determina si una matriz es simtrica.
bool Matriz::es_simetrica()
{
if(!es_cuadrada())
return false;
int i,j;
for(i=0;i<num_renglones;i++)
{
for(j=0;j<num_columnas;j++)
{
if(i!=j)
if(A[i][j]!=A[j][i])
return false;
}
}
return true;
}
//Funcin que determina si una matriz es tridiagonal
bool Matriz::es_tridiagonal()
{
if(!es_cuadrada())
return false;
int n=num_renglones;

int i,j;
if(n==2)
return true;
else
{
for(i=0;i<n-2;i++)
{
for(j=i+2;j<n;j++)
{
if(A[i][j]!=0)
return false;
}
}
for(i=n-1;i>=2;i--)
{
for(j=i-2;j>=0;j--)
{
if(A[i][j]!=0)
return false;
}
}
}
return true;
}
//Funcin amiga que aplica el mtodo de sustitucin hacia a atrs a una matriz aumentada
,
//la funcin regresa el vector [x1,x2,..,xn] que da solucin al sistema de ecuacione
s
Vector sustitucion_atras(Matriz &A)
{
if(!(A.es_extendida()))
mensaje_error("sustitucion_atras", mens_error_m7);
int i,j;
int n=A.num_renglones;
Vector v(n);
double suma=0;
double a;
double xn_1;
if((a=A.obtener_elemento(n-1,n-1))==0)
{
mensaje_error("sustitucion_atras",mens_error_m6);
}
else
xn_1=A.obtener_elemento(n-1,n)/a;
v.modificar_vector(n-1,xn_1);
for(i=n-2;i>=0;i--)
{
for(j=i+1;j<n;j++)
{
suma+=A.obtener_elemento(i,j)*v.obtener_componente(j);
}
v.modificar_vector(i,(A.obtener_elemento(i,n)-suma)/A.obtener_elemento(i
,i));
suma=0;
}
return v;

}
//Funcin amiga que aplica el mtodo de sustitucin hacia a adelante a una matriz aume
ntada,
//la funcin regresa el vector [x1,x2,..,xn] que da solucin al sistema de ecuacione
s
Vector sustitucion_adelante(Matriz &A)
{
if(!(A.es_extendida()))
mensaje_error("sustitucion_atras", mens_error_m7);
int i,j;
int n=A.num_renglones;
Vector v(n);
double suma=0;
double a;
double x0;
if((a=A.obtener_elemento(0,0))==0)
{
mensaje_error("sustitucion_adelante",mens_error_m6);
}
else
x0=A.obtener_elemento(0,n)/a;
v.modificar_vector(0,x0);
for(i=1;i<n;i++)
{
for(j=0;j<i;j++)
{
suma+=A.obtener_elemento(i,j)*v.obtener_componente(j);
}
v.modificar_vector(i,(A.obtener_elemento(i,n)-suma)/A.obtener_elemento(i
,i));
suma=0;
}
return v;
}
//Funcin amiga que aplica el mtodo de sustitucin hacia atrs para las matrices
//aumentadas resultantes del mtodo de Crout optimizado junto con la funcin que
//crea matrices aumentadas. No intente utilizar este mtodo para matrices que
//no provienen del mtodo de Crout.
//Por ejemplo: Sean L y U las matrices que resultan del mtodo de Crout,
//sabemos que LUx=c. Tranformamos U en [U|b] y resolvemos para x.
Vector sustitucion_atras_crout(Matriz &A)
{
int m=A.num_columnas;
if(m!=2) //Se verifica que la matriz sea de 2 columnas.
mensaje_error("sustitucion_atras_crout", mens_error_m14);
int n=A.num_renglones;
Vector v(n);
int i;
v.modificar_vector(n-1,A.obtener_elemento(n-1,1));
double temp;
for(i=n-2;i>=0;i--)
{
temp=A.obtener_elemento(i,1)-A.obtener_elemento(i,0)*v.obtener_component
e(i+1);

v.modificar_vector(i,temp);
}
return v;
}
//Funcin amiga que aplica el mtodo de sustitucin hacia adelante para las matrices
//aumentadas resultantes del mtodo de Crout optimizado junto con las funcin que
//creas matrices aumentadas.
Vector sustitucion_adelante_crout(Matriz &A)
{
int m=A.num_columnas;
if(m!=3) //Se verifica que la matriz sea de 3 columnas
mensaje_error("sustitucion_adelante_crout", mens_error_m14);
int n=A.num_renglones;
Vector v(n);
int i;
double temp;
temp=A.obtener_elemento(0,1);
if(temp==0)
mensaje_error("sustitucion_adelante_crout",mens_error_m6);
v.modificar_vector(0,A.obtener_elemento(0,2)/temp);
for(i=1;i<n;i++)
{
temp=A.obtener_elemento(i,1);
if(temp==0)
mensaje_error("sustitucion_adelante_crout",mens_error_m6);
temp=(A.obtener_elemento(i,2)-A.obtener_elemento(i,0)*v.obtener_componen
te(i-1))/temp;
v.modificar_vector(i,temp);
}
return v;
}
//##############################################################################
###############

//##############################################################################
###############
//######
PRINCIPAL
######
//##############################################################################
###############
int main()
{
cout << "PROGRAMA QUE RESULEVE UN SISTEMA DE ECUACIONES POR\n"
<< "ELIMINACION GAUSSIANA CON SUSTITUICION HACIA ATRAS" << endl;
cout << "\n";
int n;
cout << "Escribe la dimension de la matriz cuadrada: ";
cin >> n;
if(n<=1)
{
cout << "Las dimension de la matriz deben ser mayor a uno."
<< endl;

cout << "El programa no puede continuar." << endl;


//getch();
exit(1);
}
/*
Matriz A(n,n);
Matriz L(n,n), Laum(n,n+1);
Matriz U(n,n), Uaum(n,n+1);
Vector c(n);
Vector b(n);
Vector x(n);
A.llenar_matriz();
cout << "La matriz creada es: " << endl;
A.mostrar_matriz();
cout << "\n";
c.llenar_vector();
cout << "El vector creado es: " << endl;
c.mostrar_vector();
cout << "\n";
cout << "Aplicamos el mtodo de Crout a la matriz introducida: " << endl;
A.metodo_crout(L,U);
cout << "La matriz triangular inferior resultante es: " << endl;
L.mostrar_matriz();
cout << "\n";
cout << "La matriz triangular superior resultante es: " << endl;
U.mostrar_matriz();
cout << "\n";
cout << "Resolvemos Lb=c. Encontramos b con sustitucin hacia adelante." << en
dl;
Laum=matriz_aumentada(L,c);
b=sustitucion_adelante(Laum);
b.mostrar_vector();
cout << "\n";
cout << "Resolvemos Ux=b. Encontramos x con sustitucin hacia atrs." << endl;
Uaum=matriz_aumentada(U,b);
x=sustitucion_atras(Uaum);
x.mostrar_vector();
cout << "\n";
cout << "Verifiquemos que la solucin es correcta: " << endl;
mult_matriz_vector(A,x).mostrar_vector();
*/
Matriz A(n,3);
Matriz L(n,2), Laum(n,3);
Matriz U(n,1), Uaum(n,2);
Vector c(n);
Vector y(n);
Vector x(n);
A.llenar_matriz();
cout << "La matriz creada es: " << endl;
A.mostrar_matriz();
cout << "\n";
c.llenar_vector();
cout << "El vector creado es: " << endl;
c.mostrar_vector();
cout << "\n";
cout << "Aplicamos el mtodo de Crout opt a la matriz introducida: " << endl;

A.metodo_crout_opt(L,U);
cout << "La matriz triangular inferior resultante es: " << endl;
L.mostrar_matriz();
cout << "\n";
cout << "La matriz triangular superior resultante es: " << endl;
U.mostrar_matriz();
cout << "\n";
cout << "Resolvemos Ly=c. Encontramos b con sustitucin hacia adelante." << en
dl;
Laum=matriz_aumentada(L,c);
y=sustitucion_adelante_crout(Laum);
y.mostrar_vector();
cout << "\n";
cout << "Resolvemos Ux=y. Encontramos x con sustitucin hacia atrs." << endl;
Uaum=matriz_aumentada(U,y);
x=sustitucion_atras_crout(Uaum);
x.mostrar_vector();
cout << "\n";
cout << "Verifiquemos que la solucin es correcta: " << endl;
mult_matriz_vector(A,x).mostrar_vector();
/*
Matriz D(n,3), E(n,2),F(n,1);
cout << "Ahora aplicamos el mtodo de Crout optimizado: " << endl;
D.llenar_matriz();
D.metodo_crout_opt(E,F);
cout << "El resultado es: " << endl;
E.mostrar_matriz();
cout << "\n";
F.mostrar_matriz();
cout << "\n";
*/
/*
Matriz A(n,n);
Matriz L(n,n);
A.llenar_matriz(); //Se pide al usuario que introduzca los elementos de la m
atriz
cout << "La matriz creada es: " << endl;
A.mostrar_matriz();
cout << "\n";
cout << "Aplicamos el mtodo de Cholesky a la matriz introducida: " << endl;
A.metodo_cholesky(L);
cout << "La matriz triangular inferior resultante es: " << endl;
L.mostrar_matriz();
cout << "\n";
*/
/*
Vector v(n); //Se crea un vector n-dimensional
Matriz A(n,n); //Se crea una matriz A de nxn
Matriz B(n,n+1); //Se crea una matriz B de nx(n+1)
v.llenar_vector(); //Se pide al usuario que introduzca las componentes del v
ector
cout << "El vector creado es: " << endl;
v.mostrar_vector();
cout << "\n";
A.llenar_matriz(); //Se pide al usuario que introduzca los elementos de la m

atriz
cout << "La matriz creada es: " << endl;
A.mostrar_matriz();
cout << "\n";
B=matriz_aumentada(A,v); //Se crea la matriz aumentada
cout << "La matriz aumentada es: " << endl;
B.mostrar_matriz();
cout << "\n";
cout << "\n";
cout << "Aplicamos el mtodo de eliminacion gaussiana a la matriz aumentada."
<< endl;
B.eliminacion_gaussiana();
cout << "La matriz triangular superior resultante es: " << endl;
B.mostrar_matriz();
cout << "\n";
cout << "Aplicamos sustitucion hacia atrs. El vector solucin es: " << endl;
sustitucion_atras(B).mostrar_vector();
cout << "\n";
cout << "\n";
cout << "Apliquemos el mtodo de Doolittle a la matriz A y guardamos los\n"
<< "resultados en L y U." << endl;
Matriz L(n,n);
Matriz U(n,n);
A.metodo_dolittle(L,U);
cout << "La matriz triangular inferior resultante es: " << endl;
L.mostrar_matriz();
cout << "\n";
cout << "La matriz triangular superior resultantes es:" << endl;
U.mostrar_matriz();
cout << "\n";
cout << "Creamos la matriz aumentada [L|b] para resolver LY=b." << endl;
Matriz C(n,n+1);
C=matriz_aumentada(L,v);
C.mostrar_matriz();
cout << "\n";
cout << "Encontramos Y usando sustitucion hacia adelante." << endl;
Vector Y(n);
Y=sustitucion_adelante(C);
Y.mostrar_vector();
cout << "\n";
cout << "Como UX=Y, entonces creamos la matriz aumentada [U|Y]" << endl;
Matriz D(n,n+1);
D=matriz_aumentada(U,Y);
D.mostrar_matriz();
cout << "\n";
cout << "Encontramos X usando sustitucion hacia atras." << endl;
sustitucion_atras(D).mostrar_vector();
cout << "\n";
*/

/*
cout << "Intercambiamos el renglon 1 por 2 en la matriz aumentada: " << endl
;
B.intercambiar_renglones(0,2);
B.mostrar_matriz();

cout << "\n";


int s=2;
cout << "Multiplicamos el rengln " << s << " por el escalar " << 3 << endl;
B.multiplicar_renglon(2,0);
B.mostrar_matriz();
cout <<"\n";
cout << "Sumamos el rengln 1 con el renglon 2: " << endl;
B.sumar_renglones(1,2,20);
cout << "\n";
B.mostrar_matriz();
cout << "\n";
*/
return 0;
}

Das könnte Ihnen auch gefallen