From: Leandro Lucarella Date: Mon, 25 Aug 2003 07:22:40 +0000 (+0000) Subject: Se organiza mejor, separando el TP en varios archivos. X-Git-Tag: svn_import~11 X-Git-Url: https://git.llucax.com/z.facultad/75.42/euler.git/commitdiff_plain/b9c399a948a2dc3256e6a5c2059ae1ac748662ae Se organiza mejor, separando el TP en varios archivos. --- diff --git a/Makefile b/Makefile index 33d8e28..e7ef152 100644 --- a/Makefile +++ b/Makefile @@ -18,12 +18,14 @@ CFLAGS=-ansi -pedantic -Wall -g3 # Programa a compilar. -TARGETS=tp1 +TARGETS=carga.o calculo.o grafico.o # Regla por defecto. -all: $(TARGETS) +all: tp1 + +tp1: $(TARGETS) # Regla para borrar. clean: @echo "Limpiando..." - @rm -fv $(TARGETS) *.o core + @rm -fv $(TARGETS) *.o core tp1 diff --git a/calculo.c b/calculo.c new file mode 100644 index 0000000..09f7bd1 --- /dev/null +++ b/calculo.c @@ -0,0 +1,39 @@ +/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: + * + * Taller de Programación (75.42). + * + * Ejercicio Número 1: + * Graficador de la solución de una ecuación diferencial por el método + * de Euler (explícito). + * + * Copyleft 2003 - Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: sáb ago 23 16:59:01 ART 2003 + * + * $Id$ + */ + +#include "calculo.h" + +size_t resultados_calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0) { + /* Índice para iterar. */ + size_t i; + /* Calculo la cantidad de pasos necesarios según el tiempo inicial, el + * tiempo final y el "tamaño" del paso. */ + size_t pasos = (size_t)((tf - ti) / paso); + /* Respeto la cantidad máxima de pasos admitida. */ + if (pasos > ANCHO) { + pasos = ANCHO; + } + /* Agrego el valor inicial de la función (para empezar a iterar). */ + (*res)[0] = f0; + /* Itero paso a paso calculando el valor de la función. */ + for (i = 1; i < pasos; i++) { + /* f(t+paso) = FUNCION(paso, f(t)) */ + (*res)[i] = FUNCION(paso, (*res)[i-1]); + } + return pasos; +} + diff --git a/calculo.h b/calculo.h new file mode 100644 index 0000000..d243838 --- /dev/null +++ b/calculo.h @@ -0,0 +1,50 @@ +/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: + * + * Taller de Programación (75.42). + * + * Ejercicio Número 1: + * Graficador de la solución de una ecuación diferencial por el método + * de Euler (explícito). + * + * Copyleft 2003 - Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: sáb ago 23 16:59:01 ART 2003 + * + * $Id$ + */ + +#ifndef H_CALCULO +#define H_CALCULO + +#include "tipos.h" + +/** + * \ref integracion "Calcula" el siguiente paso de la función numérica. + * Obtiene el siguiente valor de \f$ f \f$, integrando numéricamente la \ref + * funcion "ecuación diferencial" por el \ref metodo "método de euler". + * \f[ + * f_{t + step} = f_{(step, f_t)} = f_t + \frac{500 - f_t}{30} \cdot step + * \f] + * + * \note Se pone en un macro para poder reemplazar fácilmente la función sin la + * pérdida de velocidad que agrega la indirección de un llamado a una + * función. + */ +#define FUNCION(paso, ft) ((ft) + ((500.0 - (ft)) / 30.0) * paso) + +/** + * \ref integracion "Calcula" todos los valores de la función. + * + * \param res Vector donde se guardan los resultados. + * \param paso Paso de iteración. + * \param ti Tiempo de inicio de la iteración. + * \param tf Tiempo final de la iteración. + * \param f0 Valor inicial de la función. + * + * \return Cantidad de pasos realizados. + */ +size_t resultados_calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0); + +#endif diff --git a/carga.c b/carga.c new file mode 100644 index 0000000..6747088 --- /dev/null +++ b/carga.c @@ -0,0 +1,75 @@ +/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: + * + * Taller de Programación (75.42). + * + * Ejercicio Número 1: + * Graficador de la solución de una ecuación diferencial por el método + * de Euler (explícito). + * + * Copyleft 2003 - Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: sáb ago 23 16:59:01 ART 2003 + * + * $Id$ + */ + +#include "carga.h" +/* Para utilizar fprintf() y stderr */ +#include +/* Para utilizar strtod() */ +#include + +int argtod(const char* arg, Real* var, const char* nom) { + /* Puntero al último caracter bien interpretado por strtod. */ + char* err = NULL; + /* Realiza la conversión de un string a un Real */ + *var = strtod(arg, &err); + /* Si el caracter donde apunta endptr es 0 es porque se interpretó toda la + * cadena bien */ + if ((char)*err == '\0') { + return TRUE; + /* Si no, es que hubo error. */ + } else { + fprintf(stderr, "Error: El parámetro '%s' debe ser un número ", nom); + fprintf(stderr, "real. Usted ingresó '%s' pero '%s' no ", arg, err); + fprintf(stderr, "pudo ser interpretado.\n"); + return FALSE; + } +} + +int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0) { + switch (argc) { + /* Si no tiene parámetros usa los valores por omisión. */ + case 1: + break; + /* Si tiene de 1 a 3 parámetros, los lee y valida, saliendo con un + * mensaje de error en caso de haberlo. */ + case 4: + /* Hay 3 parámetros, lee el 3er parámetro. */ + if (!argtod(argv[3], f0, "f0")) { + return FALSE; + } + /* Continúa con el resto de los parámetros. */ + case 3: + /* Hay al menos 2 parámetros, lee el 2do parámetro. */ + if (!argtod(argv[2], tf, "tf")) { + return FALSE; + } + /* Continúa con el resto de los parámetros. */ + case 2: + /* Hay al menos 1 parámetro, lee el 1er parámetro. */ + if (!argtod(argv[1], paso, "paso")) { + return FALSE; + } + break; /* Finaliza el switch (no lee más parámetros). */ + /* Hay demasiados parámetros, sale con mensaje de error. */ + default: + fprintf(stderr, "Error: Demasiados parámetros.\n"); + return FALSE; + } + /* TODO Verificar que el paso no sea cero y que tf > ti. */ + return TRUE; +} + diff --git a/carga.h b/carga.h new file mode 100644 index 0000000..3763642 --- /dev/null +++ b/carga.h @@ -0,0 +1,55 @@ +/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: + * + * Taller de Programación (75.42). + * + * Ejercicio Número 1: + * Graficador de la solución de una ecuación diferencial por el método + * de Euler (explícito). + * + * Copyleft 2003 - Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: sáb ago 23 16:59:01 ART 2003 + * + * $Id$ + */ + +#ifndef H_CARGA +#define H_CARGA + +#include "tipos.h" + +/** + * Carga (validando) un dato real en una variable. + * Si al validar hay algún error, muestra un mensaje por la salida de error y + * devuelve false. + * + * \param arg Argumento a cargar (y validar). + * \param var Variable en donde cargar el real. + * \param nom Nombre de la variable que se quiere cargar (para el mensaje de + * error, en caso de haberlo). + * + * \return TRUE si se cargó bien, FALSE si no. + */ +int argtod(const char* arg, Real* var, const char* nom); + +/** + * Carga los datos necesarios por el \ref main "programa". + * Obtiene los datos desde los parámetros de la línea de comandos, validándolos + * y mostrando un mensaje de error en caso de haberlo. + * + * \param argc Cantidad de parámetros de línea de comandos ingresados. + * \param argv Parámetros de línea de comandos. + * \param paso Paso utilizado para las iteraciones. + * \param tf Tiempo final. + * \param f0 Valor inicial de la función. + * + * \return TRUE si se cargaron bien, FALSE si no. + * \todo \b TODO: Verificar que el paso no sea cero y que tf > ti. + * \todo \b TODO: Agregar opciones para especificar caracter en blanco y de + * punto. + */ +int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0); + +#endif diff --git a/general.h b/general.h new file mode 100644 index 0000000..990144b --- /dev/null +++ b/general.h @@ -0,0 +1,28 @@ +/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: + * + * Taller de Programación (75.42). + * + * Ejercicio Número 1: + * Graficador de la solución de una ecuación diferencial por el método + * de Euler (explícito). + * + * Copyleft 2003 - Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: sáb ago 23 16:59:01 ART 2003 + * + * $Id$ + */ + +#ifndef H_GENERAL +#define H_GENERAL + +/** Altura (en líneas) utilizadas para dibujar el gráfico. */ +#define ALTO 20 + +/** Ancho (en líneas) utilizadas para dibujar el gráfico. */ +#define ANCHO 70 + +#endif + diff --git a/grafico.c b/grafico.c new file mode 100644 index 0000000..173c955 --- /dev/null +++ b/grafico.c @@ -0,0 +1,83 @@ +/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: + * + * Taller de Programación (75.42). + * + * Ejercicio Número 1: + * Graficador de la solución de una ecuación diferencial por el método + * de Euler (explícito). + * + * Copyleft 2003 - Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: sáb ago 23 16:59:01 ART 2003 + * + * $Id$ + */ + +#include "grafico.h" +#include + +void inicializar_linea(char* linea, char caracter, size_t cant) { + size_t j; + for (j = 0; j < cant; j++) { + linea[j] = caracter; + } + linea[cant] = '\0'; +} + +Real resultados_max(Resultados* res, size_t pasos) { + size_t i; + Real max = (*res)[0]; + for (i = 1; i < pasos; i++) { + if ((*res)[i] > max) { + max = (*res)[i]; + } + } + return max; +} + +Real resultados_min(Resultados* res, size_t pasos) { + size_t i; + Real min = (*res)[0]; + for (i = 1; i < pasos; i++) { + if ((*res)[i] < min) { + min = (*res)[i]; + } + } + return min; +} + +void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco) { + /* Máximo valor de la función. */ + Real min; + /* Mínimo valor de la función. */ + Real max; + /* Paso utilizado para la representación de las líneasMínimo valor de la función. */ + Real pasoh; + int i; + int j; + char linea[ANCHO]; + min = resultados_min(res, pasos); + max = resultados_max(res, pasos); + pasoh = (max - min) / (ALTO); + printf("min: %f, max: %f, pasoh: %f\n", min, max, pasoh); + /* Inicializa la línea. */ + inicializar_linea(linea, blanco, ANCHO); + /* Por cada línea a dibujar. */ + for (i = ALTO; i >= 0; i--) { + /* Se fija si hay algún punto que entre en el rango. */ + for (j = 0; j < pasos; j++) { + /* Si está entre en el rango a imprimir, se agrega un punto. */ + if (((min + pasoh * i) <= (*res)[j]) + && ((*res)[j] < (min + pasoh * (i + 1)))) { + linea[j] = punto; + /* Si no, se lo deja en blanco. */ + } else { + linea[j] = blanco; + } + } + printf("%8.2f _%s\n", min + pasoh * i, linea); + } +} + diff --git a/grafico.h b/grafico.h new file mode 100644 index 0000000..c3cea5b --- /dev/null +++ b/grafico.h @@ -0,0 +1,66 @@ +/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: + * + * Taller de Programación (75.42). + * + * Ejercicio Número 1: + * Graficador de la solución de una ecuación diferencial por el método + * de Euler (explícito). + * + * Copyleft 2003 - Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: sáb ago 23 16:59:01 ART 2003 + * + * $Id$ + */ + +#ifndef H_GRAFICO +#define H_GRAFICO + +#include "tipos.h" + +/** + * Rellena una cadena de caracteres con un caracter arbitrario. + * + * \param linea Cadena de caracteres. + * \param caracter Caracter utilizado para rellenar. + * \param cant Cantidad de caracteres a rellenar. + */ +void inicializar_linea(char* linea, char caracter, size_t cant); + +/** + * Devuelve el valor máximo de los resultados. + * + * \param res Vector de resultados. + * \param pasos Cantidad de pasos a iterar. + * + * \return Máximo resultado. + */ +Real resultados_max(Resultados* res, size_t pasos); + +/** + * Devuelve el valor mínimo de los resultados. + * + * \param res Vector de resultados. + * \param pasos Cantidad de pasos a iterar. + * + * \return Mínimo resultado. + */ +Real resultados_min(Resultados* res, size_t pasos); + +/** + * Imprime un gráfico de los resultados por pantalla. + * Realiza un gráfico de la función por pantalla, imprimiendo línea por línea. + * Cada línea representa un rango de valores. En cada línea se dibuja el + * caracter \e punto si la función en el tiempo evaluado está en el rango de esa + * línea. Si no lo está se dibuja el caracter \e blanco. + * + * \param res Vector de resultados a graficar. + * \param pasos Cantidad de pasos a graficar. + * \param punto Caracter utilizado para dibujar un punto de la función. + * \param blanco Caracter utilizado para dibujar un punto en blanco. + */ +void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco); + +#endif diff --git a/tipos.h b/tipos.h new file mode 100644 index 0000000..19555d3 --- /dev/null +++ b/tipos.h @@ -0,0 +1,44 @@ +/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: + * + * Taller de Programación (75.42). + * + * Ejercicio Número 1: + * Graficador de la solución de una ecuación diferencial por el método + * de Euler (explícito). + * + * Copyleft 2003 - Leandro Lucarella + * Puede copiar, modificar y distribuir este programa bajo los términos de + * la licencia GPL (http://www.gnu.org/). + * + * Creado: sáb ago 23 16:59:01 ART 2003 + * + * $Id$ + */ + +#ifndef H_TIPOS +#define H_TIPOS + +#include "general.h" +#include + +/** Indica un valor verdadero */ +#define TRUE 1 + +/** Indica un valor falso */ +#define FALSE 0 + +/** + * Tipo de dato utilizado para medir el tiempo y el valor de la función. + * Se define como un tipo de dato propio para cambiar fácilmente la precisión. + */ +typedef float Real; + +/** + * Vector que representa los resultados. + * El índice del vector representa el número de iteración (que multiplicado por + * el paso da el tiempo, o eje X). El contenido es el valor de la + * \ref funcion "función" en ese instante. + */ +typedef Real Resultados[ANCHO]; + +#endif diff --git a/tp1.c b/tp1.c index 7706605..c004b88 100644 --- a/tp1.c +++ b/tp1.c @@ -15,9 +15,37 @@ * $Id$ */ -/* Cabecera del TP. */ -#include "tp1.h" +#include "carga.h" +#include "calculo.h" +#include "grafico.h" +/* Para utilizar printf() y stderr */ +#include +/* Para utilizar EXIT_SUCCES y EXIT_FAILURE */ +#include +/** Tiempo inicial. */ +#define T0 0.0 + +/** Tiempo final por omisión. */ +#define DEFAULT_TF 70.0 + +/** Valor inicial de la función por omisión. */ +#define DEFAULT_F0 0.0 + +/** Valor del pas de iteración por omisión. */ +#define DEFAULT_PASO 1.0 + +/** Caracter usado para dibujar un punto por omisión. */ +#define DEFAULT_PUNTO '*' + +/** Caracter usado para dibujar un punto blanco por omisión. */ +#define DEFAULT_BLANCO ' ' + +/** + * Imprime una explicación de como usar el programa. + * + * \param fh Archivo en donde imprimir el mensaje (ej: stdout o stderr). + */ void imprimir_uso(FILE* fh) { fprintf(fh, "\n"); fprintf(fh, "Modo de uso:\n"); @@ -30,166 +58,37 @@ void imprimir_uso(FILE* fh) { DEFAULT_F0); } -int argtod(const char* arg, Real* var, const char* nom) { - /* Puntero al último caracter bien interpretado por strtod. */ - char* err = NULL; - /* Realiza la conversión de un string a un Real */ - *var = strtod(arg, &err); - /* Si el caracter donde apunta endptr es 0 es porque se interpretó toda la - * cadena bien */ - if ((char)*err == '\0') { - return TRUE; - /* Si no, es que hubo error. */ - } else { - fprintf(stderr, "Error: El parámetro '%s' debe ser un número ", nom); - fprintf(stderr, "real. Usted ingresó '%s' pero '%s' no ", arg, err); - fprintf(stderr, "pudo ser interpretado.\n"); - return FALSE; - } -} - -int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0) { - switch (argc) { - /* Si no tiene parámetros usa los valores por omisión. */ - case 1: - break; - /* Si tiene de 1 a 3 parámetros, los lee y valida, saliendo con un - * mensaje de error en caso de haberlo. */ - case 4: - /* Hay 3 parámetros, lee el 3er parámetro. */ - if (!argtod(argv[3], f0, "f0")) { - return FALSE; - } - /* Continúa con el resto de los parámetros. */ - case 3: - /* Hay al menos 2 parámetros, lee el 2do parámetro. */ - if (!argtod(argv[2], tf, "tf")) { - return FALSE; - } - /* Continúa con el resto de los parámetros. */ - case 2: - /* Hay al menos 1 parámetro, lee el 1er parámetro. */ - if (!argtod(argv[1], paso, "paso")) { - return FALSE; - } - break; /* Finaliza el switch (no lee más parámetros). */ - /* Hay demasiados parámetros, sale con mensaje de error. */ - default: - fprintf(stderr, "Error: Demasiados parámetros.\n"); - return FALSE; - } - /* TODO Verificar que el paso no sea cero y que tf > ti. */ - return TRUE; -} - -size_t calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0) { - /* Índice para iterar. */ - size_t i; - /* Calculo la cantidad de pasos necesarios según el tiempo inicial, el - * tiempo final y el "tamaño" del paso. */ - size_t pasos = (size_t)((tf - ti) / paso); - /* Respeto la cantidad máxima de pasos admitida. */ - if (pasos > MAX_PASOS) { - pasos = MAX_PASOS; - } - /* Agrego el valor inicial de la función (para empezar a iterar). */ - (*res)[0] = f0; - /* Itero paso a paso calculando el valor de la función. */ - for (i = 1; i < pasos; i++) { - /* f(t+paso) = FUNCION(paso, f(t)) */ - (*res)[i] = FUNCION(paso, (*res)[i-1]); - } - return pasos; -} - -Real resultados_max(Resultados* res, size_t pasos) { - size_t i; - Real max = (*res)[0]; - for (i = 1; i < pasos; i++) { - if ((*res)[i] > max) { - max = (*res)[i]; - } - } - return max; -} - -Real resultados_min(Resultados* res, size_t pasos) { - size_t i; - Real min = (*res)[0]; - for (i = 1; i < pasos; i++) { - if ((*res)[i] < min) { - min = (*res)[i]; - } - } - return min; -} - -void inicializar_linea(char* linea, char caracter, size_t cant) { - size_t j; - for (j = 0; j < cant; j++) { - linea[j] = caracter; - } - linea[cant] = '\0'; -} - -void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco) { - /* Máximo valor de la función. */ - Real min; - /* Mínimo valor de la función. */ - Real max; - /* Paso utilizado para la representación de las líneasMínimo valor de la función. */ - Real pasoh; - int i; - int j; - char linea[ANCHO]; - min = resultados_min(res, pasos); - max = resultados_max(res, pasos); - pasoh = (max - min) / (ALTO); - printf("min: %f, max: %f, pasoh: %f\n", min, max, pasoh); - /* Inicializa la línea. */ - inicializar_linea(linea, blanco, MAX_PASOS); - /* Por cada línea a dibujar. */ - for (i = ALTO; i >= 0; i--) { - /* Se fija si hay algún punto que entre en el rango. */ - for (j = 0; j < pasos; j++) { - /* Si está entre en el rango a imprimir, se agrega un punto. */ - if (((min + pasoh * i) <= (*res)[j]) - && ((*res)[j] < (min + pasoh * (i + 1)))) { - linea[j] = punto; - /* Si no, se lo deja en blanco. */ - } else { - linea[j] = blanco; - } - } - printf("%8.2f _%s\n", min + pasoh * i, linea); - } -} - +/** + * Programa principal. + * Este es el programa que se encarga de resolver el trabajo práctico. + * + * \param argc Cantidad de parámetros de línea de comandos ingresados. + * \param argv Parámetros de línea de comandos. + * + * \return EXIT_FAILURE si hubo un error, si no EXIT_SUCCESS. + */ int main(int argc, const char** argv) { - /* TODO: Declaración de variables. */ + /* Declaración de variables. (TODO: describir variables) */ Resultados resultados; size_t pasos; Real paso = DEFAULT_PASO; Real tf = DEFAULT_TF; Real f0 = DEFAULT_F0; - char punto = '*'; - char blanco = ' '; - + char punto = DEFAULT_PUNTO; + char blanco = DEFAULT_BLANCO; /* Obtención de datos. */ if (!cargar_datos(argc, argv, &paso, &tf, &f0)) { + /* Si hay error, imprime mensaje con modo de uso y sale con error. */ imprimir_uso(stderr); return EXIT_FAILURE; } - /* Cálculo de la solución, dejando en un array los valores de cada paso. */ - pasos = calcular(&resultados, paso, T0, tf, f0); + pasos = resultados_calcular(&resultados, paso, T0, tf, f0); /* XXX - sacar o poner más lindo. */ printf("paso = %f, tf = %f, f0 = %f, pasos = %i\n", paso, tf, f0, pasos); - /* TODO: Barrido de pantalla de arriba hacia abajo consultando el array * y dibujando los resultados pertinentes. */ resultados_graficar(&resultados, pasos, punto, blanco); - return EXIT_SUCCESS; } diff --git a/tp1.h b/tp1.h deleted file mode 100644 index eb00948..0000000 --- a/tp1.h +++ /dev/null @@ -1,200 +0,0 @@ -/* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t: - * - * Taller de Programación (75.42). - * - * Ejercicio Número 1: - * Graficador de la solución de una ecuación diferencial por el método - * de Euler (explícito). - * - * Copyleft 2003 - Leandro Lucarella - * Puede copiar, modificar y distribuir este programa bajo los términos de - * la licencia GPL (http://www.gnu.org/). - * - * Creado: sáb ago 23 16:59:01 ART 2003 - * - * $Id$ - */ - -/************************ BIBLIOTECAS USADAS *******************************/ - -/* Para utilizar printf(), fprintf() y stderr */ -#include -/* Para utilizar strtod(), EXIT_SUCCES y EXIT_FAILURE */ -#include - - - -/***************************** CONSTANTES **********************************/ - -/** Indica un valor verdadero */ -#define TRUE 1 - -/** Indica un valor falso */ -#define FALSE 0 - -/** Máxima cantidad de pasos a calcular. */ -#define MAX_PASOS 70 - -/** Altura (en líneas) utilizadas para dibujar el gráfico. */ -#define ALTO 20 - -/** Ancho (en líneas) utilizadas para dibujar el gráfico. */ -#define ANCHO 70 - -/** Tiempo inicial. */ -#define T0 0.0 - -/** Tiempo final por omisión. */ -#define DEFAULT_TF 70.0 - -/** Valor inicial de la función por omisión. */ -#define DEFAULT_F0 0.0 - -/** Valor del pas de iteración por omisión. */ -#define DEFAULT_PASO 1.0 - - - -/******************************* MACROS ************************************/ - -/** - * \ref integracion "Calcula" el siguiente paso de la función numérica. - * Obtiene el siguiente valor de \f$ f \f$, integrando numéricamente la \ref - * funcion "ecuación diferencial" por el \ref metodo "método de euler". - * \f[ - * f_{t + step} = f_{(step, f_t)} = f_t + \frac{500 - f_t}{30} \cdot step - * \f] - * - * \note Se pone en un macro para poder reemplazar fácilmente la función sin la - * pérdida de velocidad que agrega la indirección de un llamado a una - * función. - */ -#define FUNCION(paso, ft) ((ft) + ((500.0 - (ft)) / 30.0) * paso) - - - -/************************ TIPOS DE DATOS UTILIZADOS ************************/ - -/** - * Tipo de dato utilizado para medir el tiempo y el valor de la función. - * Se define como un tipo de dato propio para cambiar fácilmente la precisión. - */ -typedef float Real; - -/** - * Vector que representa los resultados. - * El índice del vector representa el número de iteración (que multiplicado por - * el paso da el tiempo, o eje X). El contenido es el valor de la - * \ref funcion "función" en ese instante. - */ -typedef Real Resultados[MAX_PASOS]; - - - -/********************************* FUNCIONES *******************************/ - -/** - * Imprime una explicación de como usar el programa. - * - * \param fh Archivo en donde imprimir el mensaje (ej: stdout o stderr). - */ -void imprimir_uso(FILE* fh); - -/** - * Carga (validando) un dato real en una variable. - * Si al validar hay algún error, muestra un mensaje por la salida de error y - * devuelve false. - * - * \param arg Argumento a cargar (y validar). - * \param var Variable en donde cargar el real. - * \param nom Nombre de la variable que se quiere cargar (para el mensaje de - * error, en caso de haberlo). - * - * \return TRUE si se cargó bien, FALSE si no. - */ -int argtod(const char* arg, Real* var, const char* nom); - -/** - * Carga los datos necesarios por el \ref main "programa". - * Obtiene los datos desde los parámetros de la línea de comandos, validándolos - * y mostrando un mensaje de error en caso de haberlo. - * - * \param argc Cantidad de parámetros de línea de comandos ingresados. - * \param argv Parámetros de línea de comandos. - * \param paso Paso utilizado para las iteraciones. - * \param tf Tiempo final. - * \param f0 Valor inicial de la función. - * - * \return TRUE si se cargaron bien, FALSE si no. - * \todo \b TODO Verificar que el paso no sea cero y que tf > ti. - * \todo \b TODO Agregar opciones para especificar caracter en blanco y de punto. - */ -int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0); - -/** - * \ref integracion "Calcula" todos los valores de la función. - * - * \param res Vector donde se guardan los resultados. - * \param paso Paso de iteración. - * \param ti Tiempo de inicio de la iteración. - * \param tf Tiempo final de la iteración. - * \param f0 Valor inicial de la función. - * - * \return Cantidad de pasos realizados. - */ -size_t calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0); - -/** - * Devuelve el valor máximo de los resultados. - * - * \param res Vector de resultados. - * \param pasos Cantidad de pasos a iterar. - * - * \return Máximo resultado. - */ -Real resultados_max(Resultados* res, size_t pasos); - -/** - * Devuelve el valor mínimo de los resultados. - * - * \param res Vector de resultados. - * \param pasos Cantidad de pasos a iterar. - * - * \return Mínimo resultado. - */ -Real resultados_min(Resultados* res, size_t pasos); - -/** - * Rellena una cadena de caracteres con un caracter arbitrario. - * - * \param linea Cadena de caracteres. - * \param caracter Caracter utilizado para rellenar. - * \param cant Cantidad de caracteres a rellenar. - */ -void inicializar_linea(char* linea, char caracter, size_t cant); - -/** - * Imprime un gráfico de los resultados por pantalla. - * Realiza un gráfico de la función por pantalla, imprimiendo línea por línea. - * Cada línea representa un rango de valores. En cada línea se dibuja el - * caracter \e punto si la función en el tiempo evaluado está en el rango de esa - * línea. Si no lo está se dibuja el caracter \e blanco. - * - * \param res Vector de resultados a graficar. - * \param pasos Cantidad de pasos a graficar. - * \param punto Caracter utilizado para dibujar un punto de la función. - * \param blanco Caracter utilizado para dibujar un punto en blanco. - */ -void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco); - -/** - * Programa principal. - * Este es el programa que se encarga de resolver el trabajo práctico. - * - * \param argc Cantidad de parámetros de línea de comandos ingresados. - * \param argv Parámetros de línea de comandos. - * - * \return EXIT_FAILURE si hubo un error, si no EXIT_SUCCESS. - */ -int main(int argc, const char** argv); -