]> git.llucax.com Git - z.facultad/75.42/euler.git/blob - tp1.c
Se separa el TP en varios archivos.
[z.facultad/75.42/euler.git] / tp1.c
1 /* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t:
2  *
3  * Taller de Programación (75.42).
4  *
5  * Ejercicio Número 1:
6  * Graficador de la solución de una ecuación diferencial por el método
7  * de Euler (explícito).
8  *
9  * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
10  * Puede copiar, modificar y distribuir este programa bajo los términos de
11  * la licencia GPL (http://www.gnu.org/).
12  *
13  * Creado: sáb ago 23 16:59:01 ART 2003
14  *
15  * $Id$
16  */
17
18 /* Cabecera del TP. */
19 #include "tp1.h"
20
21 void imprimir_uso(FILE* fh) {
22     fprintf(fh, "\n");
23     fprintf(fh, "Modo de uso:\n");
24     fprintf(fh, "  tp1 [paso [tf [f0]]]\n");
25     fprintf(fh, "\n");
26     fprintf(fh, "Donde:\n");
27     fprintf(fh, "  paso: Paso a utilizar (%.2f por omisión).\n", DEFAULT_PASO);
28     fprintf(fh, "  tf:   Tiempo final (%.2f por omisión).\n", DEFAULT_TF);
29     fprintf(fh, "  f0:   Valor inicial de la función (%.2f por omisión).\n",
30             DEFAULT_F0);
31 }
32
33 int argtod(const char* arg, Real* var, const char* nom) {
34     /* Puntero al último caracter bien interpretado por strtod. */
35     char* err = NULL;
36     /* Realiza la conversión de un string a un Real */
37     *var = strtod(arg, &err);
38     /* Si el caracter donde apunta endptr es 0 es porque se interpretó toda la
39      * cadena bien */
40     if ((char)*err == '\0') {
41         return TRUE;
42     /* Si no, es que hubo error. */
43     } else {
44         fprintf(stderr, "Error: El parámetro '%s' debe ser un número ", nom);
45         fprintf(stderr, "real. Usted ingresó '%s' pero '%s' no ", arg, err);
46         fprintf(stderr, "pudo ser interpretado.\n");
47         return FALSE;
48     }
49 }
50
51 int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0) {
52     switch (argc) {
53         /* Si no tiene parámetros usa los valores por omisión. */
54         case 1:
55             break;
56         /* Si tiene de 1 a 3 parámetros, los lee y valida, saliendo con un
57          * mensaje de error en caso de haberlo. */
58         case 4:
59             /* Hay 3 parámetros, lee el 3er parámetro. */
60             if (!argtod(argv[3], f0, "f0")) {
61                 return FALSE;
62             }
63             /* Continúa con el resto de los parámetros. */
64         case 3:
65             /* Hay al menos 2 parámetros, lee el 2do parámetro. */
66             if (!argtod(argv[2], tf, "tf")) {
67                 return FALSE;
68             }
69             /* Continúa con el resto de los parámetros. */
70         case 2:
71             /* Hay al menos 1 parámetro, lee el 1er parámetro. */
72             if (!argtod(argv[1], paso, "paso")) {
73                 return FALSE;
74             }
75             break; /* Finaliza el switch (no lee más parámetros). */
76         /* Hay demasiados parámetros, sale con mensaje de error. */
77         default:
78             fprintf(stderr, "Error: Demasiados parámetros.\n");
79             return FALSE;
80     }
81     /* TODO Verificar que el paso no sea cero y que tf > ti. */
82     /* XXX - sacar */
83     printf("paso = %f, tf = %f, f0 = %f\n", *paso, *tf, *f0);
84     return TRUE;
85 }
86
87 size_t calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0) {
88     /* Índice para iterar. */
89     size_t i;
90     /* Calculo la cantidad de pasos necesarios según el tiempo inicial, el
91      * tiempo final y el "tamaño" del paso. */
92     size_t pasos = (size_t)((tf - ti) / paso);
93     /* Respeto la cantidad máxima de pasos admitida. */
94     if (pasos > MAX_PASOS) {
95         pasos = MAX_PASOS;
96     }
97     /* Agrego el valor inicial de la función (para empezar a iterar). */
98     (*res)[0] = f0;
99     /* Itero paso a paso calculando el valor de la función. */
100     for (i = 1; i < pasos; i++) {
101         /* f(t+paso) = FUNCION(paso, f(t)) */
102         (*res)[i]       = FUNCION(paso, (*res)[i-1]);
103         /* FIXME sacar!!!! */
104         printf("i = %i, t = %.2f, f(t) = %.2f\n", i, (Real)i * paso, (*res)[i]);
105     }
106     return pasos;
107 }
108
109 Real max(const Resultados* res, size_t pasos) {
110     size_t  i;
111     Real    max = (*res)[0];
112     for (i = 1; i < pasos; i++) {
113         if ((*res)[i] > max) {
114             max = (*res)[i];
115         }
116     }
117     return max;
118 }
119
120 Real min(const Resultados* res, size_t pasos) {
121     size_t  i;
122     Real    min = (*res)[0];
123     for (i = 1; i < pasos; i++) {
124         if ((*res)[i] < min) {
125             min = (*res)[i];
126         }
127     }
128     return min;
129 }
130
131 int main(int argc, const char** argv) {
132     /* TODO: Declaración de variables. */
133     Resultados  resultados;
134     size_t      pasos;
135     Real        paso  = DEFAULT_PASO;
136     Real        tf    = DEFAULT_TF;
137     Real        f0    = DEFAULT_F0;
138
139     /* Obtención de datos. */
140     if (!cargar_datos(argc, argv, &paso, &tf, &f0)) {
141         imprimir_uso(stderr);
142         return EXIT_FAILURE;
143     }
144
145     /* Cálculo de la solución, dejando en un array los valores de cada paso. */
146     pasos = calcular(&resultados, paso, T0, tf, f0);
147
148     /* TODO: Barrido de pantalla de arriba hacia abajo consultando el array
149      *       y dibujando los resultados pertinentes. */
150     /* TODO: Liberación de memoria y otras limpiezas, en caso de ser necesario. */
151     return EXIT_SUCCESS;
152 }
153