From: Leandro Lucarella Date: Sun, 23 Mar 2003 07:10:16 +0000 (+0000) Subject: Import inicial después del "/var incident". :( X-Git-Tag: svn_import~1 X-Git-Url: https://git.llucax.com/z.facultad/75.12/ejercicios.git/commitdiff_plain/68017b9b54a74f52db0291ae88a610e9f353ad89 Import inicial después del "/var incident". :( --- 68017b9b54a74f52db0291ae88a610e9f353ad89 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6a7e1fa --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +# Makefile +#********************** +# Análisis Numérico I # +####################### + +HEADERS=lib_lineal.h tipos.h +CPP_OPTS=-g3 -Wall +LIBS=-lm + +ec_lineal: ec_lineal.o lib.o + gcc $(LIBS) -o ec_lineal lib.o ec_lineal.o +ec_lineal.o: ec_lineal.cpp $(HEADERS) + gcc $(CPP_OPTS) -c ec_lineal.cpp +lib.o: lib.cpp $(HEADERS) + gcc $(CPP_OPTS) -c lib.cpp + +clean: + rm -f *.o ec_lineal diff --git a/ec_lineal.cpp b/ec_lineal.cpp new file mode 100644 index 0000000..223b0c2 --- /dev/null +++ b/ec_lineal.cpp @@ -0,0 +1,114 @@ +/* ec_lineal.cpp + ********************** + * Análisis Numérico I + *--------------------- + * Para direccionar la salida a un archivo, ejecutelo con: + * + * ec_lineal > [archivo] + * + * Para compilar en *nix: + * + * gcc -lm -Wall -O3 -o ec_lienal ec_lineal.cpp + * + * Para debug: + * gcc -lm -Wall -g3 -o ec_lienal ec_lineal.cpp + * + */ + +#include +#include "lib.h" + +// Constantes de error +const int MATRIZ_SINGULAR = 1; + +// Variables +Matriz A; +Vector b; +VectorPermutaciones p; + +int main( int argc, char *argv[] ) { + + // Reinicio los numeros aleatorios + //srand( time( NULL ) ); + + // Genero matriz al azar + generar_matriz( A ); + // Genero vector al azar + generar_vector( b ); + // Genero vector de permutaciones + generar_vector_permutaciones( p ); + + // Imprimo matriz + printf( "Matriz A:\n=========\n" ); + imprimir_matriz( A ); + printf( "\n" ); + // Imprimo vector + printf( "Vector b:\n=========\n" ); + imprimir_vector( b ); + printf( "\n\n" ); + + // Recorro por columna (o diagonal). + for ( Indice j = 0; j < N; j++ ) { + // Busco máximo en la columna para usar de pivote + Indice maxi = j; + Numero max = fabs( A[j][j] ); + for ( Indice i = j + 1; i < N; i++ ) + if ( fabs( A[i][j] ) > max ) { + maxi = i; + max = fabs( A[i][j] ); + } + + // Nos fijamos si la matriz es singular + if ( max == 0 ) + return MATRIZ_SINGULAR; + + // Nos fijamos si hay permutación + if ( maxi != j ) { + // Intercambio vector de permutaciones + Indice aux = p[maxi]; + p[maxi] = p[j]; + p[j] = aux; + } + + // Reduzco las filas + for ( Indice i = j + 1; i < N; i++ ) { + // Calculo el m, almacenandolo en A + A[p[i]][j] /= A[p[j]][j]; + // Recorro columna por columna, operando + for ( Indice k = j + 1; i < N; i++ ) + A[p[i]][k] -= A[p[i]][j] * A[p[j]][k]; // Aij = Aij - m * Ajk + } + } + + // Imprimo la matriz modificada + printf( "Matriz A modificada:\n====================\n" ); + imprimir_matriz_permutada( A, p ); + printf( "\n" ); + // Imprimo la matriz L + printf( "Matriz L:\n========\n" ); + imprimir_matriz_L( A, p ); + printf( "\n" ); + // Imprimo la matriz U + printf( "Matriz U:\n========\n" ); + imprimir_matriz_U( A, p ); + printf( "\n" ); + + // Calcula solucion de Ly=b + sustitucion_directa( A, b, p ); + + // Imprimo el vector solucion y + printf( "y (Ly=b):\n=========\n" ); + imprimir_vector_permutado( b, p ); + printf( "\n" ); + + // Calcula solucion de Ux=y + sustitucion_inversa( A, b, p ); + + // Imprimo el vector solucion x + printf( "x (Ux=y):\n=========\n" ); + imprimir_vector_permutado( b, p ); + printf( "\n" ); + + return EXIT_SUCCESS; + +} diff --git a/gen_0.sh b/gen_0.sh new file mode 100755 index 0000000..1fb6696 --- /dev/null +++ b/gen_0.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +n=$1 + +# Genera -I para n. +for (( i=0; i < n; i++ )); do + for (( j=0; j < n; j++ )); do + echo -n " 0 " + done + echo +done diff --git a/gen_i.sh b/gen_i.sh new file mode 100755 index 0000000..83f2403 --- /dev/null +++ b/gen_i.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +n=$1 + +# Genera -I para n. +for (( i=0; i < n; i++ )); do + for (( j=0; j < n; j++ )); do + if (( i==j )); then + echo -n "-1 " + else + echo -n " 0 " + fi + done + echo +done diff --git a/gen_mat.sh b/gen_mat.sh new file mode 100755 index 0000000..11d637f --- /dev/null +++ b/gen_mat.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +n=$1 + +# Genera T para n. +for (( i=0; i < n; i++ )); do + for (( j=0; j < n; j++ )); do + if (( i==j )); then + ./gen_t.sh $n + else + if (( i==j-1 )); then + ./gen_i.sh $n + else + if (( j==i-1 )); then + ./gen_i.sh $n + else + ./gen_0.sh $n + fi + fi + fi + done + echo +done diff --git a/gen_t.sh b/gen_t.sh new file mode 100755 index 0000000..f307fe7 --- /dev/null +++ b/gen_t.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +n=$1 + +# Genera T para n. +for (( i=0; i < n; i++ )); do + for (( j=0; j < n; j++ )); do + if (( i==j )); then + echo -n " 4 " + else + if (( i==j-1 )); then + echo -n "-1 " + else + if (( j==i-1 )); then + echo -n "-1 " + else + echo -n " 0 " + fi + fi + fi + done + echo +done diff --git a/lib.cpp b/lib.cpp new file mode 100644 index 0000000..e49c754 --- /dev/null +++ b/lib.cpp @@ -0,0 +1,106 @@ +/* lib.h + ********************** + * Análisis Numérico I + *--------------------- + * Trabajo Práctico 1 + *--------------------- + * Para direccionar la salida a un archivo, ejecutelo con: + * + * c4xx > [archivo] + * + * Para compilar en *nix: + * + * gcc -lm -Wall -O3 -o ec_lienal ec_lineal.cpp + * + * Para debug: + * gcc -lm -Wall -g3 -o ec_lienal ec_lineal.cpp + * + */ + +#include "lib.h" + +extern void generar_matriz( Matriz& m ) { + for ( Indice i = 0; i < N; i++ ) + for ( Indice j = 0; j < N; j++ ) + m[i][j] = Numero( rand() ) * 3.0 / RAND_MAX; +} + +extern void generar_vector( Vector& v ) { + for ( Indice i = 0; i < N; i++ ) + v[i] = Numero( rand() ) * 3.0 / RAND_MAX; +} + +extern void generar_vector_permutaciones( VectorPermutaciones& v ) { + for ( Indice i = 0; i < N; i++ ) + v[i] = i; +} + +extern void imprimir_matriz( Matriz& m ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + printf( "%.02f ", m[i][j] ); + printf( "\n" ); + } +} + +extern void imprimir_vector( Vector& v ) { + for ( Indice i = 0; i < N; i++ ) + printf( "%.02f ", v[i] ); + printf( "\n" ); +} + +extern void imprimir_matriz_permutada( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +extern void imprimir_vector_permutado( Vector& v, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) + printf( "%.02f ", v[p[i]] ); + printf( "\n" ); +} + +extern void imprimir_matriz_L( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + if ( i < j ) + printf( "0.00 " ); + else if ( i == j ) + printf( "1.00 " ); + else + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +extern void imprimir_matriz_U( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + if ( i > j ) + printf( "0.00 " ); + else + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +extern void sustitucion_directa( Matriz& A, Vector& b, VectorPermutaciones& p ) { + for ( Indice i = 1; i < N; i++ ) { + Numero sum = 0; + for ( Indice j = 0; j < i; j++ ) + sum += A[p[i]][j] * b[p[j]]; + b[p[i]] -= sum; + } +} + +extern void sustitucion_inversa( Matriz& A, Vector& b, VectorPermutaciones& p ) { + for ( Indice i = N; i > 0; i-- ) { + Numero sum = 0; + for ( Indice j = i; j < N; j++ ) + sum += A[p[i-1]][j] * b[p[j]]; + b[p[i-1]] = ( b[p[i-1]] - sum ) / A[p[i-1]][i-1]; + } +} diff --git a/lib.h b/lib.h new file mode 100644 index 0000000..10da121 --- /dev/null +++ b/lib.h @@ -0,0 +1,23 @@ +/* ec_lineal.h + *********************** + * Análisis Numérico I * + *********************** + */ + +#include +#include +#include +#include "tipos.h" + +// Declaración de funciones +void generar_matriz( Matriz& ); +void generar_vector( Vector& ); +void generar_vector_permutaciones( VectorPermutaciones& ); +void imprimir_matriz( Matriz& ); +void imprimir_vector( Vector& ); +void imprimir_matriz_permutada( Matriz&, VectorPermutaciones& ); +void imprimir_vector_permutado( Vector&, VectorPermutaciones& ); +void imprimir_matriz_L( Matriz&, VectorPermutaciones& ); +void imprimir_matriz_U( Matriz&, VectorPermutaciones& ); +void sustitucion_directa( Matriz&, Vector&, VectorPermutaciones& ); +void sustitucion_inversa( Matriz&, Vector&, VectorPermutaciones& ); diff --git a/lib_lineal.h b/lib_lineal.h new file mode 100644 index 0000000..85cc838 --- /dev/null +++ b/lib_lineal.h @@ -0,0 +1,109 @@ +/* lib_lineal.h + *********************** + * Análisis Numérico I * + *********************** + */ + +#include +#include +#include +#include "tipos.h" + +// Declaración de funciones +inline void generar_matriz( Matriz& ); +inline void generar_vector( Vector& ); +inline void generar_vector_permutaciones( VectorPermutaciones& ); +inline void imprimir_matriz( Matriz& ); +inline void imprimir_vector( Vector& ); +inline void imprimir_matriz_permutada( Matriz&, VectorPermutaciones& ); +inline void imprimir_vector_permutado( Vector&, VectorPermutaciones& ); +inline void imprimir_matriz_L( Matriz&, VectorPermutaciones& ); +inline void imprimir_matriz_U( Matriz&, VectorPermutaciones& ); +inline void sustitucion_directa( Matriz&, Vector&, VectorPermutaciones& ); +inline void sustitucion_inversa( Matriz&, Vector&, VectorPermutaciones& ); + +inline void generar_matriz( Matriz& m ) { + for ( Indice i = 0; i < N; i++ ) + for ( Indice j = 0; j < N; j++ ) + m[i][j] = Numero( rand() ) * 3.0 / RAND_MAX; +} + +inline void generar_vector( Vector& v ) { + for ( Indice i = 0; i < N; i++ ) + v[i] = Numero( rand() ) * 3.0 / RAND_MAX; +} + +inline void generar_vector_permutaciones( VectorPermutaciones& v ) { + for ( Indice i = 0; i < N; i++ ) + v[i] = i; +} + +inline void imprimir_matriz( Matriz& m ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + printf( "%.02f ", m[i][j] ); + printf( "\n" ); + } +} + +inline void imprimir_vector( Vector& v ) { + for ( Indice i = 0; i < N; i++ ) + printf( "%.02f ", v[i] ); + printf( "\n" ); +} + +inline void imprimir_matriz_permutada( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +inline void imprimir_vector_permutado( Vector& v, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) + printf( "%.02f ", v[p[i]] ); + printf( "\n" ); +} + +inline void imprimir_matriz_L( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + if ( i < j ) + printf( "0.00 " ); + else if ( i == j ) + printf( "1.00 " ); + else + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +inline void imprimir_matriz_U( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + if ( i > j ) + printf( "0.00 " ); + else + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +inline void sustitucion_directa( Matriz& A, Vector& b, VectorPermutaciones& p ) { + for ( Indice i = 1; i < N; i++ ) { + Numero sum = 0; + for ( Indice j = 0; j < i - 1; j++ ) + sum += A[p[i]][j] * b[p[i]]; + b[p[i]] -= sum; + } +} + +inline void sustitucion_inversa( Matriz& A, Vector& b, VectorPermutaciones& p ) { + for ( Indice i = N; i > 0; i-- ) { + Numero sum = 0; + for ( Indice j = i; j < N; j++ ) + sum += A[p[i-1]][j] * b[p[j]]; + b[p[i-1]] = ( b[p[i-1]] - sum ) / A[p[i-1]][i]; + } +} diff --git a/lineal_iterativo.cpp b/lineal_iterativo.cpp new file mode 100644 index 0000000..1d9c0bf --- /dev/null +++ b/lineal_iterativo.cpp @@ -0,0 +1,131 @@ +/* lineal_iterativo.cpp + ********************** + * Análisis Numérico I + *--------------------- + * Para direccionar la salida a un archivo, ejecutelo con: + * + * lineal_iterativo > [archivo] + * + * Para compilar en *nix: + * + * gcc -lm -Wall -O3 -o lineal_iterativo lineal_iterativo.cpp + * + * Para debug: + * gcc -lm -Wall -g3 -o lineal_iterativo lineal_iterativo.cpp + * + */ + +#include +#include "lib.h" + +// Constantes de error +const int MATRIZ_SINGULAR = 1; +const int MAXIMO_ITERACIONES = 2; + +// Declaración de funciones +Numero* cargar_matriz( const char* ); + +// Variables +Matriz A; +Vector b; +VectorPermutaciones p; + +int main( int argc, char *argv[] ) { + + // Reinicio los numeros aleatorios + //srand( time( NULL ) ); + + // Genero matriz al azar + generar_matriz( A ); + // Genero vector al azar + generar_vector( b ); + // Genero vector de permutaciones + generar_vector_permutaciones( p ); + + // Imprimo matriz + printf( "Matriz A:\n=========\n" ); + imprimir_matriz( A ); + printf( "\n" ); + // Imprimo vector + printf( "Vector b:\n=========\n" ); + imprimir_vector( b ); + printf( "\n\n" ); + + // Recorro por columna (o diagonal). + for ( Indice j = 0; j < N; j++ ) { + // Busco máximo en la columna para usar de pivote + Indice maxi = j; + Numero max = fabs( A[j][j] ); + for ( Indice i = j + 1; i < N; i++ ) + if ( fabs( A[i][j] ) > max ) { + maxi = i; + max = fabs( A[i][j] ); + } + + // Nos fijamos si la matriz es singular + if ( max == 0 ) + return MATRIZ_SINGULAR; + + // Nos fijamos si hay permutación + if ( maxi != j ) { + // Intercambio vector de permutaciones + Indice aux = p[maxi]; + p[maxi] = p[j]; + p[j] = aux; + } + + // Reduzco las filas + for ( Indice i = j + 1; i < N; i++ ) { + // Calculo el m, almacenandolo en A + A[p[i]][j] /= A[p[j]][j]; + // Recorro columna por columna, operando + for ( Indice k = j + 1; i < N; i++ ) + A[p[i]][k] -= A[p[i]][j] * A[p[j]][k]; // Aij = Aij - m * Ajk + } + } + + // Imprimo la matriz modificada + printf( "Matriz A modificada:\n====================\n" ); + imprimir_matriz_permutada( A, p ); + printf( "\n" ); + // Imprimo la matriz L + printf( "Matriz L:\n========\n" ); + imprimir_matriz_L( A, p ); + printf( "\n" ); + // Imprimo la matriz U + printf( "Matriz U:\n========\n" ); + imprimir_matriz_U( A, p ); + printf( "\n" ); + + // Calcula solucion de Ly=b + sustitucion_directa( A, b, p ); + + // Imprimo el vector solucion y + printf( "y (Ly=b):\n=========\n" ); + imprimir_vector_permutado( b, p ); + printf( "\n" ); + + // Calcula solucion de Ux=y + sustitucion_inversa( A, b, p ); + + // Imprimo el vector solucion x + printf( "x (Ux=y):\n=========\n" ); + imprimir_vector_permutado( b, p ); + printf( "\n" ); + + return EXIT_SUCCESS; + +} + +Numero* cargar_matriz( const char* archivo ) { + + Indice n; + + FILE* f; + f = fopen( archivo, "r" ); + + char s[4096]; + n = Indice( atol( fgets( s, 4095, f ) ) ); + for ( Indice i = 0; !feof( f ) || ( i > n ); i++ ) { + fgets( s, 4095, f ); + diff --git a/mat.txt b/mat.txt new file mode 100644 index 0000000..f91dafb --- /dev/null +++ b/mat.txt @@ -0,0 +1,9 @@ + 4 -1 0 -1 0 0 0 0 0 +-1 4 -1 0 -1 0 0 0 0 + 0 -1 4 0 0 -1 0 0 0 +-1 0 0 4 -1 0 -1 0 0 + 0 -1 0 -1 4 -1 0 -1 0 + 0 0 -1 0 -1 4 0 0 -1 + 0 0 0 -1 0 0 4 -1 0 + 0 0 0 0 -1 0 -1 4 -1 + 0 0 0 0 0 -1 0 -1 4 diff --git a/tipos.h b/tipos.h new file mode 100644 index 0000000..ca3d002 --- /dev/null +++ b/tipos.h @@ -0,0 +1,17 @@ +/* ec_lineal.h + *********************** + * Análisis Numérico I * + *********************** + */ + +// Tipos básicos +typedef unsigned int Indice; +typedef float Numero; + +// Cantidad máxima de elementos +const Indice N = 4; + +// Tipos compuestos +typedef Indice VectorPermutaciones[N]; +typedef Numero Vector[N]; +typedef Numero Matriz[N][N]; diff --git a/todo.cpp b/todo.cpp new file mode 100644 index 0000000..c15532e --- /dev/null +++ b/todo.cpp @@ -0,0 +1,216 @@ +/* ec_lineal.h + *********************** + * Análisis Numérico I * + *********************** + */ + +// Tipos básicos +typedef unsigned int Indice; +typedef float Numero; + +// Cantidad máxima de elementos +const Indice N = 5000; + +// Tipos compuestos +typedef Indice VectorPermutaciones[N]; +typedef Numero Vector[N]; +typedef Numero Matriz[N][N]; + +#include +#include +#include + +// Declaración de funciones +void generar_matriz( Matriz& ); +void generar_vector( Vector& ); +void generar_vector_permutaciones( VectorPermutaciones& ); +void imprimir_matriz( Matriz& ); +void imprimir_vector( Vector& ); +void imprimir_matriz_permutada( Matriz&, VectorPermutaciones& ); +void imprimir_vector_permutado( Vector&, VectorPermutaciones& ); +void imprimir_matriz_L( Matriz&, VectorPermutaciones& ); +void imprimir_matriz_U( Matriz&, VectorPermutaciones& ); +void sustitucion_directa( Matriz&, Vector&, VectorPermutaciones& ); +void sustitucion_inversa( Matriz&, Vector&, VectorPermutaciones& ); + +#include + +// Constantes de error +const int MATRIZ_SINGULAR = 1; + +int main( int argc, char *argv[] ) { + + Matriz A; + Vector b; + VectorPermutaciones p; + + // Reinicio los numeros aleatorios + //srand( time( NULL ) ); + + // Genero matriz al azar + generar_matriz( A ); + // Genero vector al azar + generar_vector( b ); + // Genero vector de permutaciones + generar_vector_permutaciones( p ); + + // La imprimo + printf( "Matriz A:\n=========\n" ); + imprimir_matriz( A ); + printf( "\n" ); + // La imprimo + printf( "Vector b:\n=========\n" ); + imprimir_vector( b ); + printf( "\n\n" ); + + // Recorro por columna (o diagonal). + for ( Indice j = 0; j < N; j++ ) { + // Busco máximo en la columna para usar de pivote + Indice maxi = j; + Numero max = fabs( A[j][j] ); + for ( Indice i = j + 1; i < N; i++ ) + if ( fabs( A[i][j] ) > max ) { + maxi = i; + max = fabs( A[i][j] ); + } + + // Nos fijamos si la matriz es singular + if ( max == 0 ) + return MATRIZ_SINGULAR; + + // Nos fijamos si hay permutación + if ( maxi != j ) { + // Intercambio vector de permutaciones + Indice aux = p[maxi]; + p[maxi] = p[j]; + p[j] = aux; + } + + // Reduzco las filas + for ( Indice i = j + 1; i < N; i++ ) { + // Calculo el m, almacenandolo en A + A[p[i]][j] /= A[p[j]][j]; + // Recorro columna por columna, operando + for ( Indice k = j + 1; i < N; i++ ) + A[p[i]][j] -= A[p[i]][j] * A[p[j]][k]; // Aij = Aij - m * Ajk + } + } + + // Imprimo la matriz modificada + printf( "Matriz A modificada:\n====================\n" ); + imprimir_matriz_permutada( A, p ); + printf( "\n" ); + // Imprimo la matriz L + printf( "Matriz L:\n========\n" ); + imprimir_matriz_L( A, p ); + printf( "\n" ); + // Imprimo la matriz U + printf( "Matriz U:\n========\n" ); + imprimir_matriz_U( A, p ); + printf( "\n" ); + + // Calcula solucion de Ly=b + sustitucion_directa( A, b, p ); + + // Imprimo el vector solucion y + printf( "y (Ly=b):\n=========\n" ); + imprimir_vector_permutado( b, p ); + printf( "\n" ); + + // Calcula solucion de Ux=y + sustitucion_inversa( A, b, p ); + + // Imprimo el vector solucion x + printf( "x (Ux=y):\n=========\n" ); + imprimir_vector_permutado( b, p ); + printf( "\n" ); + + return EXIT_SUCCESS; + +} + +void generar_matriz( Matriz& m ) { + for ( Indice i = 0; i < N; i++ ) + for ( Indice j = 0; j < N; j++ ) + m[i][j] = Numero( rand() ) * 3.0 / RAND_MAX; +} + +void generar_vector( Vector& v ) { + for ( Indice i = 0; i < N; i++ ) + v[i] = Numero( rand() ) * 3.0 / RAND_MAX; +} + +void generar_vector_permutaciones( VectorPermutaciones& v ) { + for ( Indice i = 0; i < N; i++ ) + v[i] = i; +} + +void imprimir_matriz( Matriz& m ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + printf( "%.02f ", m[i][j] ); + printf( "\n" ); + } +} + +void imprimir_vector( Vector& v ) { + for ( Indice i = 0; i < N; i++ ) + printf( "%.02f ", v[i] ); + printf( "\n" ); +} + +void imprimir_matriz_permutada( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +void imprimir_vector_permutado( Vector& v, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) + printf( "%.02f ", v[p[i]] ); + printf( "\n" ); +} + +void imprimir_matriz_L( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + if ( i < j ) + printf( "0.00 " ); + else if ( i == j ) + printf( "1.00 " ); + else + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +void imprimir_matriz_U( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + if ( i > j ) + printf( "0.00 " ); + else + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +void sustitucion_directa( Matriz& A, Vector& b, VectorPermutaciones& p ) { + for ( Indice i = 1; i < N; i++ ) { + Numero sum = 0; + for ( Indice j = 0; j < i - 1; j++ ) + sum += A[p[i]][j] * b[p[i]]; + b[p[i]] -= sum; + } +} + +void sustitucion_inversa( Matriz& A, Vector& b, VectorPermutaciones& p ) { + for ( Indice i = N; i > 0; i-- ) { + Numero sum = 0; + for ( Indice j = i; j < N; j++ ) + sum += A[p[i-1]][j] * b[p[j]]; + b[p[i-1]] = ( b[p[i-1]] - sum ) / A[p[i-1]][i]; + } +} diff --git a/todo_inline.cpp b/todo_inline.cpp new file mode 100644 index 0000000..0dc8978 --- /dev/null +++ b/todo_inline.cpp @@ -0,0 +1,203 @@ +/* ec_lineal.h + *********************** + * Análisis Numérico I * + *********************** + */ + +// Tipos básicos +typedef unsigned int Indice; +typedef float Numero; + +// Cantidad máxima de elementos +const Indice N = 1000; + +// Tipos compuestos +typedef Indice VectorPermutaciones[N]; +typedef Numero Vector[N]; +typedef Numero Matriz[N][N]; + +#include +#include +#include +#include + +inline void generar_vector( Vector& v ) { + for ( Indice i = 0; i < N; i++ ) + v[i] = Numero( rand() ) * 3.0 / RAND_MAX; +} + +inline void generar_vector_permutaciones( VectorPermutaciones& v ) { + for ( Indice i = 0; i < N; i++ ) + v[i] = i; +} + +inline void imprimir_matriz( Matriz& m ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + printf( "%.02f ", m[i][j] ); + printf( "\n" ); + } +} + +inline void imprimir_vector( Vector& v ) { + for ( Indice i = 0; i < N; i++ ) + printf( "%.02f ", v[i] ); + printf( "\n" ); +} + +inline void imprimir_matriz_permutada( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +inline void imprimir_vector_permutado( Vector& v, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) + printf( "%.02f ", v[p[i]] ); + printf( "\n" ); +} + +inline void imprimir_matriz_L( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + if ( i < j ) + printf( "0.00 " ); + else if ( i == j ) + printf( "1.00 " ); + else + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +inline void imprimir_matriz_U( Matriz& m, VectorPermutaciones& p ) { + for ( Indice i = 0; i < N; i++ ) { + for ( Indice j = 0; j < N; j++ ) + if ( i > j ) + printf( "0.00 " ); + else + printf( "%.02f ", m[p[i]][j] ); + printf( "\n" ); + } +} + +inline void sustitucion_directa( Matriz& A, Vector& b, VectorPermutaciones& p ) { + for ( Indice i = 1; i < N; i++ ) { + Numero sum = 0; + for ( Indice j = 0; j < i - 1; j++ ) + sum += A[p[i]][j] * b[p[i]]; + b[p[i]] -= sum; + } +} + +inline void sustitucion_inversa( Matriz& A, Vector& b, VectorPermutaciones& p ) { + for ( Indice i = N; i > 0; i-- ) { + Numero sum = 0; + for ( Indice j = i; j < N; j++ ) + sum += A[p[i-1]][j] * b[p[j]]; + b[p[i-1]] = ( b[p[i-1]] - sum ) / A[p[i-1]][i]; + } +} +// Constantes de error +const int MATRIZ_SINGULAR = 1; + +int main( int argc, char *argv[] ) { + + Matriz A; + Vector b; + VectorPermutaciones p; + + // Reinicio los numeros aleatorios + //srand( time( NULL ) ); + + // Genero matriz al azar + generar_matriz( A ); + // Genero vector al azar + generar_vector( b ); + // Genero vector de permutaciones + generar_vector_permutaciones( p ); + + // La imprimo + printf( "Matriz A:\n=========\n" ); + imprimir_matriz( A ); + printf( "\n" ); + // La imprimo + printf( "Vector b:\n=========\n" ); + imprimir_vector( b ); + printf( "\n\n" ); + + // Recorro por columna (o diagonal). + for ( Indice j = 0; j < N; j++ ) { + // Busco máximo en la columna para usar de pivote + Indice maxi = j; + Numero max = fabs( A[j][j] ); + for ( Indice i = j + 1; i < N; i++ ) + if ( fabs( A[i][j] ) > max ) { + maxi = i; + max = fabs( A[i][j] ); + } + + // Nos fijamos si la matriz es singular + if ( max == 0 ) + return MATRIZ_SINGULAR; + + // Nos fijamos si hay permutación + if ( maxi != j ) { + // Intercambio vector de permutaciones + Indice aux = p[maxi]; + p[maxi] = p[j]; + p[j] = aux; + } + + // Reduzco las filas + for ( Indice i = j + 1; i < N; i++ ) { + // Calculo el m, almacenandolo en A + A[p[i]][j] /= A[p[j]][j]; + // Recorro columna por columna, operando + for ( Indice k = j + 1; i < N; i++ ) + A[p[i]][j] -= A[p[i]][j] * A[p[j]][k]; // Aij = Aij - m * Ajk + } + } + + // Imprimo la matriz modificada + printf( "Matriz A modificada:\n====================\n" ); + imprimir_matriz_permutada( A, p ); + printf( "\n" ); + // Imprimo la matriz L + printf( "Matriz L:\n========\n" ); + imprimir_matriz_L( A, p ); + printf( "\n" ); + // Imprimo la matriz U + printf( "Matriz U:\n========\n" ); + imprimir_matriz_U( A, p ); + printf( "\n" ); + + // Calcula solucion de Ly=b + sustitucion_directa( A, b, p ); + + // Imprimo el vector solucion y + printf( "y (Ly=b):\n=========\n" ); + imprimir_vector_permutado( b, p ); + printf( "\n" ); + + // Calcula solucion de Ux=y + sustitucion_inversa( A, b, p ); + + // Imprimo el vector solucion x + printf( "x (Ux=y):\n=========\n" ); + imprimir_vector_permutado( b, p ); + printf( "\n" ); + + return EXIT_SUCCESS; + +} + +inline void generar_matriz( Matriz& m ) { + for ( Indice i = 0; i < N; i++ ) + for ( Indice j = 0; j < N; j++ ) + m[i][j] = Numero( rand() ) * 3.0 / RAND_MAX; +} + +