--- /dev/null
+# 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
--- /dev/null
+/* 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 <time.h>
+#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;
+
+}
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+/* 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];
+ }
+}
--- /dev/null
+/* ec_lineal.h
+ ***********************
+ * Análisis Numérico I *
+ ***********************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#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& );
--- /dev/null
+/* lib_lineal.h
+ ***********************
+ * Análisis Numérico I *
+ ***********************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#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];
+ }
+}
--- /dev/null
+/* 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 <time.h>
+#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 );
+
--- /dev/null
+ 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
--- /dev/null
+/* 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];
--- /dev/null
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <math.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& );
+
+#include <time.h>
+
+// 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];
+ }
+}
--- /dev/null
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+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;
+}
+
+