1 /* vim: set et ts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t:
3 * Taller de Programación (75.42).
6 * Graficador de la solución de una ecuación diferencial por el método
7 * de Euler (explícito).
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/).
13 * Creado: sáb ago 23 16:59:01 ART 2003
18 /* Cabecera del TP. */
21 void imprimir_uso(FILE* fh) {
23 fprintf(fh, "Modo de uso:\n");
24 fprintf(fh, " tp1 [paso [tf [f0]]]\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",
33 int argtod(const char* arg, Real* var, const char* nom) {
34 /* Puntero al último caracter bien interpretado por strtod. */
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
40 if ((char)*err == '\0') {
42 /* Si no, es que hubo error. */
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");
51 int cargar_datos(int argc, const char** argv, Real* paso, Real* tf, Real* f0) {
53 /* Si no tiene parámetros usa los valores por omisión. */
56 /* Si tiene de 1 a 3 parámetros, los lee y valida, saliendo con un
57 * mensaje de error en caso de haberlo. */
59 /* Hay 3 parámetros, lee el 3er parámetro. */
60 if (!argtod(argv[3], f0, "f0")) {
63 /* Continúa con el resto de los parámetros. */
65 /* Hay al menos 2 parámetros, lee el 2do parámetro. */
66 if (!argtod(argv[2], tf, "tf")) {
69 /* Continúa con el resto de los parámetros. */
71 /* Hay al menos 1 parámetro, lee el 1er parámetro. */
72 if (!argtod(argv[1], paso, "paso")) {
75 break; /* Finaliza el switch (no lee más parámetros). */
76 /* Hay demasiados parámetros, sale con mensaje de error. */
78 fprintf(stderr, "Error: Demasiados parámetros.\n");
81 /* TODO Verificar que el paso no sea cero y que tf > ti. */
85 size_t calcular(Resultados* res, Real paso, Real ti, Real tf, Real f0) {
86 /* Índice para iterar. */
88 /* Calculo la cantidad de pasos necesarios según el tiempo inicial, el
89 * tiempo final y el "tamaño" del paso. */
90 size_t pasos = (size_t)((tf - ti) / paso);
91 /* Respeto la cantidad máxima de pasos admitida. */
92 if (pasos > MAX_PASOS) {
95 /* Agrego el valor inicial de la función (para empezar a iterar). */
97 /* Itero paso a paso calculando el valor de la función. */
98 for (i = 1; i < pasos; i++) {
99 /* f(t+paso) = FUNCION(paso, f(t)) */
100 (*res)[i] = FUNCION(paso, (*res)[i-1]);
105 Real resultados_max(Resultados* res, size_t pasos) {
107 Real max = (*res)[0];
108 for (i = 1; i < pasos; i++) {
109 if ((*res)[i] > max) {
116 Real resultados_min(Resultados* res, size_t pasos) {
118 Real min = (*res)[0];
119 for (i = 1; i < pasos; i++) {
120 if ((*res)[i] < min) {
127 void inicializar_linea(char* linea, char caracter, size_t cant) {
129 for (j = 0; j < cant; j++) {
135 void resultados_graficar(Resultados* res, size_t pasos, char punto, char blanco) {
136 /* Máximo valor de la función. */
138 /* Mínimo valor de la función. */
140 /* Paso utilizado para la representación de las líneasMínimo valor de la función. */
145 min = resultados_min(res, pasos);
146 max = resultados_max(res, pasos);
147 pasoh = (max - min) / (ALTO);
148 printf("min: %f, max: %f, pasoh: %f\n", min, max, pasoh);
149 /* Inicializa la línea. */
150 inicializar_linea(linea, blanco, MAX_PASOS);
151 /* Por cada línea a dibujar. */
152 for (i = ALTO; i >= 0; i--) {
153 /* Se fija si hay algún punto que entre en el rango. */
154 for (j = 0; j < pasos; j++) {
155 /* Si está entre en el rango a imprimir, se agrega un punto. */
156 if (((min + pasoh * i) <= (*res)[j])
157 && ((*res)[j] < (min + pasoh * (i + 1)))) {
159 /* Si no, se lo deja en blanco. */
164 printf("%8.2f _%s\n", min + pasoh * i, linea);
168 int main(int argc, const char** argv) {
169 /* TODO: Declaración de variables. */
170 Resultados resultados;
172 Real paso = DEFAULT_PASO;
173 Real tf = DEFAULT_TF;
174 Real f0 = DEFAULT_F0;
178 /* Obtención de datos. */
179 if (!cargar_datos(argc, argv, &paso, &tf, &f0)) {
180 imprimir_uso(stderr);
184 /* Cálculo de la solución, dejando en un array los valores de cada paso. */
185 pasos = calcular(&resultados, paso, T0, tf, f0);
186 /* XXX - sacar o poner más lindo. */
187 printf("paso = %f, tf = %f, f0 = %f, pasos = %i\n", paso, tf, f0, pasos);
189 /* TODO: Barrido de pantalla de arriba hacia abajo consultando el array
190 * y dibujando los resultados pertinentes. */
191 resultados_graficar(&resultados, pasos, punto, blanco);