Códigos de Programas en el lenguaje C++ Efraı́n Soto Apolinar Códigos de Programas en el lenguaje C++ Compilados por Efraı́n Soto Apolinar PISIS Monterrey, N.L., México. 2007 ÿ Índice 1 Introducción 1.1 1.2 Códigos en C++ 7 Conceptos básicos . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.1.1 Conceptos de programación . . . . . . . . . . . . . . . . . 8 1.1.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Sintaxis del lenguaje C++ . . . . . . . . . . . . . . . . . . . . . . 11 1.2.1 Palabras reservadas . . . . . . . . . . . . . . . . . . . . . 11 1.2.2 Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2.3 Tipos de constantes . . . . . . . . . . . . . . . . . . . . . 12 1.2.4 Caracteres especiales . . . . . . . . . . . . . . . . . . . . . 12 1.2.5 Declaración de variables . . . . . . . . . . . . . . . . . . . 12 1.2.6 Asignación . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.2.7 Operaciones matemáticas . . . . . . . . . . . . . . . . . . 14 1.2.8 Comparaciones . . . . . . . . . . . . . . . . . . . . . . . . 15 1.2.9 Ciclos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.2.10 Ejemplos de control de flujo . . . . . . . . . . . . . . . . . 17 Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 4 1.3 1.4 1.2.11 Operaciones lógicas . . . . . . . . . . . . . . . . . . . . . . 21 Funciones en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.3.1 Funciones predefinidas . . . . . . . . . . . . . . . . . . . . 22 1.3.2 Funciones definidas por el usuario . . . . . . . . . . . . . 23 Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2 Códigos 31 2.1 Mis primeros programas . . . . . . . . . . . . . . . . . . . . . . . 32 2.2 Programas con funciones . . . . . . . . . . . . . . . . . . . . . . . 38 2.3 Funciones cin, cout . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.4 if, for, while and the like... . . . . . . . . . . . . . . . . . . . . . . 46 2.5 Mis tareas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 2.5.1 Simulación 1 . . . . . . . . . . . . . . . . . . . . . . . . . 60 2.5.2 Cálculo analı́tico . . . . . . . . . . . . . . . . . . . . . . . 64 2.5.3 Simulación 2 . . . . . . . . . . . . . . . . . . . . . . . . . 65 2.5.4 Simulación 3 . . . . . . . . . . . . . . . . . . . . . . . . . 68 2.5.5 Simulación 4 . . . . . . . . . . . . . . . . . . . . . . . . . 70 2.5.6 Simulacion 5 . . . . . . . . . . . . . . . . . . . . . . . . . 72 2.5.7 Simulacion 6 . . . . . . . . . . . . . . . . . . . . . . . . . 74 2.5.8 Simulacion 7 . . . . . . . . . . . . . . . . . . . . . . . . . 78 2.5.9 Simulacion 8 . . . . . . . . . . . . . . . . . . . . . . . . . 80 2.5.10 Simulación de la distribución binomial . . . . . . . . . . . 84 2.5.11 Introducción a la dinámica de poblaciones . . . . . . . . . 87 Proyectos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 2.6.1 Regresión lineal . . . . . . . . . . . . . . . . . . . . . . . . 89 2.6.2 Regresión cuadrática . . . . . . . . . . . . . . . . . . . . . 91 Librerı́a Estadı́stica . . . . . . . . . . . . . . . . . . . . . . . . . . 96 2.6 2.7 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 5 2.8 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8.1 96 Ejemplos de uso . . . . . . . . . . . . . . . . . . . . . . . 139 2.8.1.1 funiforme(total, archivo) . . . . . . . . . . . . . 139 2.8.1.2 funiforme(total, archivo, A, B) . . . . . . . . . . 140 2.8.1.3 fnormal(total, archivo) . . . . . . . . . . . . . . 142 2.8.1.4 fnormal(total, archivo, media, SD) . . . . . . . . 143 2.8.1.5 fexponencial(total, lambda, archivo) . . . . . . . 144 2.8.1.6 fgeometrica(total, p, archivo) . . . . . . . . . . . 145 2.8.1.7 fpoisson(total, alpha, archivo) . . . . . . . . . . 145 2.8.1.8 fweibull(total, archivo, c, k) . . . . . . . . . . . . 146 2.8.1.9 frayleigh(total, archivo, media) . . . . . . . . . . 147 2.8.1.10 histograma(archivo, intervalos) . . . . . . . . . . 148 2.8.1.11 PchiUniforme(archivo, No Int) . . . . . . . . . . 154 2.8.1.12 PchiNormal(archivo, No Int) . . . . . . . . . . . 156 2.8.1.13 PchiExponencial(archivo, Num Int, lambda) . . 157 2.8.1.14 PchiWeibull(Archivo, Num Int, C, K) . . . . . . 159 2.8.1.15 PchiRayleigh(archivo, Num Int, media) . . . . . 161 2.8.1.16 RL(archivo) . . . . . . . . . . . . . . . . . . . . 162 2.8.1.17 RC(archivo) . . . . . . . . . . . . . . . . . . . . 163 2.8.2 Códigos en C++ Otras funciones . . . . . . . . . . . . . . . . . . . . . . . . 165 2.8.2.1 uniforme() . . . . . . . . . . . . . . . . . . . . . 165 2.8.2.2 uniforme(a,b) . . . . . . . . . . . . . . . . . . . . 166 2.8.2.3 weibull(c,k) . . . . . . . . . . . . . . . . . . . . . 167 2.8.2.4 rayleigh(media) . . . . . . . . . . . . . . . . . . 168 2.8.2.5 normal() . . . . . . . . . . . . . . . . . . . . . . 169 2.8.2.6 normal(media, desviacionStd) 2.8.2.7 exponencial(lambda) . . . . . . . . . . . . . . . . 171 . . . . . . . . . . 170 Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 2.8.2.8 geometrica(p) . . . . . . . . . . . . . . . . . . . 172 2.8.2.9 poisson(alpha) . . . . . . . . . . . . . . . . . . . 173 2.8.2.10 media(archivo), desviacionStd(archivo) . . . . . 174 2.8.3 Simulación del recurso eólico . . . . . . . . . . . . . . . . 176 2.8.3.1 2.8.4 2.9 Energı́a extraida del viento . . . . . . . . . . . . 176 Distribución del viento . . . . . . . . . . . . . . . . . . . . 178 2.8.4.1 Distribución Weibull . . . . . . . . . . . . . . . . 178 2.8.4.2 Distribución Rayleigh . . . . . . . . . . . . . . . 179 2.8.4.3 Distribución de energı́a . . . . . . . . . . . . . . 180 2.8.4.4 Anemómetros digitales . . . . . . . . . . . . . . 180 2.8.4.5 Predicción del recurso eólico . . . . . . . . . . . 180 2.8.5 Un caso especı́fico . . . . . . . . . . . . . . . . . . . . . . 181 2.8.6 Implementación . . . . . . . . . . . . . . . . . . . . . . . . 181 2.8.7 Resultados de la simulación . . . . . . . . . . . . . . . . . 186 Esqueletos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 2.10 Lecciones aprendidas . . . . . . . . . . . . . . . . . . . . . . . . . 193 3 End matter 195 3.1 Fuentes bibliográficas . . . . . . . . . . . . . . . . . . . . . . . . . 196 3.2 Términos de uso . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 3.3 Créditos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 3.4 Simbologı́a utilizada . . . . . . . . . . . . . . . . . . . . . . . . . 200 1 Introducción Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 8 Introducción 1.1 Conceptos básicos En este apartado se dan algunos conceptos que necesitas conocer para poder aprovechar la lectura de este material. Se presentan diversas secciones con contenidos igual de importantes. Los primeros tienen que ver con las bases de programación y después se incluyen los que conciernen al lenguaje C++ . 1.1.1 Conceptos de programación Los conceptos que debes entender para iniciarte en el arte de la programación son: Definición 1.1.1. Algoritmo Una sucesión ordenada de instrucciones para resolver un problema o una tarea. Puedes pensar en un algoritmo como si se tratara de una receta. Es el procedimiento que se debe realizar para resolver un problema especı́fico. Definición 1.1.2. Compilador Es el programa de computadora que traduce las instrucciones que nosotros le damos en un lenguaje especı́fico. Definición 1.1.3. Programa fuente Es el código que tú vas a escribir. En este texto encontrarás el programa fuente para resolver muchos problemas. El programa fuente también se conoce como código fuente. Definición 1.1.4. Código Es un conjunto de instrucciones en algún lenguaje de alto nivel. En este material solamente encontrarás código en C++ . El código no necesariamente es un programa completo, puede tratarse solamente de una parte del programa. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.1 Conceptos básicos 9 Definición 1.1.5. Sintaxis Son las reglas de acuerdo a las cuales debes escribir el programa fuente. Cada lenguaje de programación tiene su sintaxis. Puedes imaginar que la sintaxis son las reglas de gramática de ese lenguaje. Definición 1.1.6. Compilar Indicar a la computadora que verifique que el programa fuente no contenga errores. Esta tarea siempre la realizará un software (el compilador). Definición 1.1.7. Correr (un programa) Ordenar a la computadora que ejecute las instrucciones indicadas por el código de un programa. Evidementemente, un programa en C++ debe correrse en un compilador de ese lenguaje. (Yo utilizo el Dev-C++ , que es gratuito.) Nota 1.1.1. Algunas veces el compilador no encontrará errores, pero existe la posibilidad de que sı́ existan. Por ejemplo, en el caso de que tú hayas cometido el error de escribir un + en lugar de un *, el compilador no se da cuenta, porque no sabe realmente qué debe hacer el programa. En otras palabras, las computadoras todavı́a no pueden leer tu mente. Definición 1.1.8. Mensaje de error Es un mensaje que el compilador te dará cuando encuentre errores en el programa fuente. Estos mensajes te ayudan a corregir el código. Definición 1.1.9. Error de sintáxis Ocurre cuando el código no está completamente escrito de acuerdo a las reglas de sintaxis del mismo. Por ejemplo, si escribes, Go To en lugar de GOTO, cometiste un error de sintaxis (de acuerdo a la sintáxis del lenguaje GWBasic). Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 10 Introducción Definición 1.1.10. Errores lógicos Los que comete el programador cuando traduce el algoritmo al lenguaje C++ . El programa realmente no hace lo que el algoritmo indica. Tal vez no tenga errores de sintáxis... simplemente no realiza la tarea que debe realizar. Cuidado con esto. 1.1.2 Variables Definición 1.1.11. Identificador Es el nombre que el programador asigna a un valor dentro de un programa. En C++ , un identificador debe empezar con una letra o el sı́mbolo: ’ ’ y los demás caracteres deben ser letras, dı́gitos o el sı́mbolo ’ ’. Definición 1.1.12. Variable Es una herramienta de programación utilizada para asignar valores (no necesariamente numéricos) a letras o cadenas de letras. Las variables se clasifican de acuerdo al tipo de valor que almacenan. Definición 1.1.13. Constante Es un valor que no cambia durante la ejecución del programa. Una constante puede ser de cualquiera de los tipos de datos definidos en C++ . Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.2 Sintaxis del lenguaje C++ 1.2 1.2.1 11 Sintaxis del lenguaje C++ Palabras reservadas ! En C++ , las siguientes son consideradas reservadas: asm auto bool break case char catch class const const cast continue default delete do double dynamic cast else enum explicit extern false float for friend goto if inline return int short log signed long sizeof mutable static namespace static cast new struct operator switch private template protected this public throw register true reinterpret cast try typedef typeid typename union unsigned using virtual void volatile while esto significa que no se permite utilizar alguna de las palabras que se enlistaron antes como un identificador. 1.2.2 ! Tipos de datos En C++ hay varios tipos de datos que podemos definir para las variables y constantes que utilicemos en nuestros programas. ! Variable short int unsigned int float double long double char string bool Rango −32 767 a 32 767 −2 147 483 647 a 2 147 483 647 −2 147 483 647 a 2 147 483 647 10−38 a 1038 10−308 a 10308 10−4932 a 104932 No aplica No aplica False/True Precisión No Aplica No Aplica No Aplica 7 dı́gitos 15 dı́gitos 19 dı́gitos No aplica No aplica No aplica Ejemplo 23 −4 4 3.1416 3.141592654 2.718281828 ’a’ ’Hola Amigo.’ False Tipos de datos. Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 12 Introducción Decidir cómo definir una variable depende del uso que se le va a dar. Cuando vayas a definir una variable trata de pensar en qué le va a pasar durante la ejecución del programa. 1.2.3 Tipos de constantes Una variable, por definición, puede cambiar de valor durante la ejecución de un programa. Por el contrario una constante no cambia de valor durante la ejecución del programa. Bueno, muchos se preguntan, “si nunca cambia de valor, para qué utilizar un identificador y utilizar más memoria...” Ok. Acepto el argumento. Sin embargo, algunas veces un valor constante aparece en muchas partes del código de un programa, por ejemplo, la tasa de cambio. Si cambia de un dı́a para otro este valor, es una buena idea definirlo como constante, y cambiar su valor... porque si nos decidimos cambiar todos los lugares donde aparezca esta constante, existe la posibilidad de que omitamos uno o varios cambios. Además, existe también la posibilidad de que otra constante tenga el mismo valor y eso pueda ocasionar más errores todavı́a. i Cuando una variable del tipo bool toma el valor true, este resultado no es una cadena de caracteres, es decir, no es una variable del tipo string. De manera que si quieres engañar al compilador o a la computadora asignando a una constante del tipo bool la cadena ’true’, al compilar te dará el correspondiente mensaje de error. 1.2.4 ! Caracteres especiales En C++ se definen los siguientes caracteres especiales. Caracter especial Salto de lı́nea Tabulación Nulo Diagonal inversa Constante ’\n’ ’\t’ ’\0’ \\ Caracteres especiales. 1.2.5 Declaración de variables En C++ , estas obligado a declarar cualquier variable antes de poder utilizarla. La sintaxis para declarar una variable es la siguiente: Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.2 Sintaxis del lenguaje C++ 13 Tipo_de_variable variable1; También puedes declarar dos o más variables al mismo tiempo separándolas por comas: Tipo_de_variable variable1, variable2, variable3; Igual, podemos declarar una constante, anteponiendo la palabra const a la declaración. o Ejemplos: int contador, dia, mes, edad; // Variables tipo double promedio, precio, masa, volumen; // con char nombre[15], apellido_m[15], apellido_p[15]; const double e = 2.718281828; // Constante tipo 1.2.6 int (entero) punto decimal // Cadenas double Asignación En C++ , para hacer una asignación de un valor al identificador de una variable, necesariamente debemos escribir primero (i.e., a la izquierda) el valor del identificador que almacenará el valor y a la derecha el valor o una expresión matemática correctamente codificada en C++ . Como es costumbre, en medio debemos escribir el sı́mbolo ’=’. La sintáxis es la siguiente: variable = expresion; o Ejemplos: total = total + incremento; edad = year_actual - year_de_nac; area = 3.1416 * radio * radio; importe = precio_unitario * no_articulos; aceleracion = (v_f - v_i) / t; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 14 Introducción También podemos asignar un valor a un identificador a la hora de declarar la variable. Hay dos formas igualmente aceptables para hacer esto. La sintaxis es la siguiente: Tipo\_de\_variable variable1 = valor\_1, variable2 = valor\_2, var3 = valor\_3;\\ Tipo\_de\_variable variable4 (valor\_4), variable5 (valor\_5), var6 (valor\_6); o Ejemplos: int contador= 1, factor_de_conversion = 12; double alpha(0.32), delta_Cu(375.23); char respuesta = ’c’; 1.2.7 Operaciones matemáticas En C++ están definidas las operaciones aritméticas básicas: +, −, ×, ÷. Para la suma y la resta usamos los signos + y −, respectivamente. Para la multiplicación usamos el sı́mbolo ’*’ y para la división, el sı́mbolo: /. Es importante utilizar signos de agrupación para definir correctamente las operaciones. o Por ejemplo, supongamos que tenemos que realizar el siguiente cálculo: √ −b + b2 − 4 ac x1 = 2a En C++ esta misma expresión se codifica como sigue: x_1 = (- b + sqrt(b * b - 4 * a * c))/(2 * a); La función sqrt() está definida en una librerı́a de C++ (math.h)1 . En el caso de la fórmula: yf = o 1 2 a t + v0 t + yi 2 se codifica como: 1 Más sobre funciones y librerı́as en los siguientes temas. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.2 Sintaxis del lenguaje C++ 15 y_f = a * t * t / 2 + v_0 * t + y_i; En la programación es muy común utilizar la operación incremento. Es decir, incrementamos el valor de una variable en 1, digamos un contador. Debido a esto, en C++ hay varias operaciones matemáticas unitarias, en el sentido que se realizan con solamente una variable, no dos, en cuyo caso serı́an binarias. Ejemplo: contador++; reg −−; decenas += 10; p Neto −= desc; factor *= celcuis; residuo %= divisor; mejor *= calif1 + calif2; o Equivalente a: contador = contador + 1; reg = reg − 1 decenas = decenas + 10; p Neto = p Neto − desc; factor = factor * celcius; residuo = residuo % divisor; mejor = mejor * (calif1 + calif2); Operaciones unitarias 1.2.8 Comparaciones En la mayoria de los programas se requiere hacer comparaciones para controlar el flujo del procedimiento. En seguida se muestra la tabla que contiene los tipos de comparaciones. Sı́mbolo Matemático = 6= < ≤ > ≥ En Español Igual a Distinto a Menor a Menor o igual a Mayor a Mayor o igual a En C++ == != < <= > >= Ejemplo Práctico x == 0 x != 0 x < 0 x <= 0 x > 0 x >= 0 Equivalente a x=0 x 6= 1 x<0 x≤0 x>0 x≥0 Operadores de Comparación Las instrucciones que nos ayudan a realizar operaciones de comparación (booleanas) son las siguientes: If then else if (Expresión Booleana){ // Aquı́ van las instrucciones que Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. ! 16 Introducción // debe realizar en caso de que la // expresión Booleana sea verdadera } else{ // Aquı́ van las instrucciones que // debe realizar en caso de que la // expresión Booleana sea falsa } 1.2.9 Ciclos While while (Expresión Booleana){ // Algo debe ocurrir aquı́ // Varias veces para que el ciclo // cumpla con su función... } // Este ciclo no requiere punto y coma al final... do...while do{ // Algo debe ocurrir aquı́ // Varias veces para que el ciclo // cumpla con su función... } while (Expresión Booleana); // Nota el punto y coma al final... for for (incialización ; Expresión booleana ; Incremento){ // Algo debe ocurrir aquı́ // Varias veces para que el ciclo // cumpla con su función... } // Este ciclo tampoco requiere punto y coma al final... Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.2 Sintaxis del lenguaje C++ 1.2.10 17 Ejemplos de control de flujo if...then...else 1 2 #include <stdio.h> #include <iostream> 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 using namespace std; int main(void){ char respuesta; cout << "\n\n¿Te gusta el rock? [S/N] "; cin >> respuesta; if (respuesta == ’S’){ // dice que sı́... cout << "\n\nQue bien,"; cout << "\nIgual a mi..."; } else{ // dice que no... cout << "\n\nBueno, creo que hay mejor musica..."; cout << "\nPor ejemplo, el Jazz..."; } cout << "\n\n\n"; system ("PAUSE"); return 0; } for 1 2 #include <stdio.h> #include <iostream> 3 4 5 6 7 8 9 10 11 12 13 14 15 16 using namespace std; int main(void){ int total = 0,cuadrado; cout << "\n\nCuántos cuadrados deseas calcular?"; cin >> total; for (int i = 0 ; i <= total ; i++){ cuadrado = i * i; cout << "\nEl cuadrado de " << i << " es: " << i * i; } cout << "\n\n\n"; system ("PAUSE"); return 0; } while Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 18 Introducción 1 2 #include <stdio.h> #include <iostream> 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using namespace std; int main(void){ int total = 0, i = 0, cuadrado; cout << "\n\nCuántos cuadrados deseas calcular?"; cin >> total; while (i <= total){ cuadrado = i * i; cout << "\nEl cuadrado de " << i << " es: " << i * i; i++; } cout << "\n\n\n"; system ("PAUSE"); return 0; } do...while 1 2 #include <stdio.h> #include <iostream> 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using namespace std; int main(void){ int total = 0, i = 0, cuadrado; cout << "\n\nCuántos cuadrados deseas calcular?"; cin >> total; do{ cuadrado = i * i; cout << "\nEl cuadrado de " << i << " es: " << i * i; i++; }while (i <= total); cout << "\n\n\n"; system ("PAUSE"); return 0; } switch 1 2 #include <stdio.h> #include <iostream> 3 4 5 using namespace std; int main(void){ Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.2 Sintaxis del lenguaje C++ 19 int calificacion; cout << "\n\nQue calificacion obtuviste en tu examen? "; cout << "\n(Introduce un numero entero) "; cin >> calificacion; switch (calificacion){ case 0: cout << "\nCero!!!"; break; case 1: cout << "\n¿Por qué?"; break; case 2: cout << "\nQué te pasó?"; break; case 3: cout << "\nAy, no me digas!"; break; case 4: cout << "\nCaramba!!!!"; break; case 5: cout << "\nPor qué no estudiaste?"; break; case 6: cout << "\nDebes echarle más ganas..."; break; case 7: cout << "\nPasaste de panzaso"; break; case 8: cout << "\nQue bien..."; break; case 9: cout << "\nMuy bien..."; break; case 10: cout << "\nFelicidades!!!"; break; default: cout << "\nTe pedı́ tu calificación,"; cout << "\nno tu edad!!!\n"; } cout << "\n\n\n"; system ("PAUSE"); return 0; } 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 • Un ejemplo donde se generan las tablas de multiplicar: Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 20 Introducción 1 2 #include <stdio.h> #include <iostream> 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using namespace std; int main(void){ int i, j, k; // Empiezan las tablas de multiplicar... for (i = 1; i <= 12; i++){ cout << "Tabla del " << i << "\n"; for (j = 1 ; j <= 12 ; j++){ k = i * j; cout << i << " x " << j << " = " << k << "\n"; } cout <<"\n\n\n"; // Termino una tabla... voy con la siguiente... } cout << "\n\n\n"; system ("PAUSE"); return 0; } • El siguiente genera las tablas de multiplicar, pero el usuario decide hasta cuál. Se utiliza un ciclo for infinito para que el usuario pueda ingresar un número entero positivo. En caso de que ingrese un número negativo o cero, el programa envı́a un mensaje de error y le permite volver a ingresar el valor de la última tabla a imprimir. 1 2 #include <stdio.h> #include <iostream> 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using namespace std; int main(void){ int i, j, k; int total; for (;;){ // for infinito cout << "\n\nCuantas tablas desea que se impriman? "; cin >> total; if (total <= 0){ cout << "\n\nError en argumento..."; cout << "\nDebe introducir un numero entero positivo..."; } else{ // salir del for infinito... break; } } // end for infinito... cout << "\n\n\n"; // un poco de espacio Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.2 Sintaxis del lenguaje C++ 21 22 23 24 25 26 27 28 29 30 31 32 33 34 21 // Empiezan las tablas de multiplicar... for (i = 1; i <= total; i++){ cout << "Tabla del " << i << "\n"; for (j = 1 ; j <= 12 ; j++){ k = i * j; cout << i << " x " << j << " = " << k << "\n"; } cout <<"\n\n\n"; // Termino una tabla... voy con la siguiente... } cout << "\n\n\n"; system ("PAUSE"); return 0; } 1.2.11 Operaciones lógicas A las operaciones lógicas también se les conocen en programación como operaciones booleanas. AND: Se codifica con la instrucción: &&. Ejemplo: if ((x != 0) && (divisor == 3)) { // Aquı́ va a ocurrir algo... } //... OR: Se codifica con la instrucción: ||. Ejemplo: {if ((x > 0) || (divisor > 3)) { // Aquı́ va a ocurrir otra cosa... } ... Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 22 Introducción 1.3 1.3.1 Funciones en C++ Funciones predefinidas En C++ el truco de programar consiste en “desmenuzar” cada problema complejo en sus partes más elementales idependientes una de la otra. Es como si un ser pluricelular lo separaras en sus celulas y trabajaras con cada una de ellas. Cuando las juntes, todas van a trabajar como si fueran un ser completo, cada una realizando su tarea, sin preocuparse de las otras partes. En seguida se muestra una lista de las funciones predefinidas en C++ . Nombre sqrt pow abs labs fabs ceil floor exp log log10 Descripción raı́z cuadrada potencia valor absoluto valor absoluto valor absoluto cielo piso exp(x) ln(x) log10 (x) Argumento double double int long doule doule doule doule doule doule Retorno double double int long double double double double double double Librerı́a math.h math.h math.h stdlib.h math.h math.h math.h math.h math.h math.h Funciones predefinidas en C++ Las funciones trigonométricas e hiperbólicas están definidas en la librerı́a math.h. Nombre acos asin atan cos cosh sin sinh tan tanh Descripción arco coseno arco seno arco tangente coseno coseno hiperbólico seno seno hiperbólico tangente tangente hiperbólico Argumento double double double double double double double double double Retorno double double double double double double double double double Funciones trigonométricas en C++ Las funciones se invocan escribiendo primero el nombre de la función y después, entre paréntesis, los argumentos que requiera la misma. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.3 Funciones en C++ 23 La sintaxis es la siguiente. Funcion (Argumento 1,Argumento 2,· · · ,Argumento n); Ejemplo: pi = 3.1416; radio = sqrt(area /pi); edad = abs(year de nac - year actual); base = 5; exponente = 3; potencia = pow(base,exponente); 1.3.2 Funciones definidas por el usuario El programador de C++ puede crear sus propias funciones. Primero indicamos qué tipo de valor nos devolverá. Después indicamos el nombre de la función. Inmediatamente después se encierra entre paréntesis los argumentos de la función, los cuales deben ir precedidos del tipo de dato que le corresponde a cada uno. Finalmente, entre corchetes debemos incluir las instrucciones que debe realizar la función sobre la información que se le entregue. Recuerda que debes definir la función como si se tratara de otra variable. Es decir, debes definirla antes de hacer uso de ella en el cuerpo del programa. La sintaxis es la siguiente: Tipo devuelto Nombre funcion(Tipo 1 Arg 1,Tipo 2 Arg 2, · · · ,Tipo n Arg n) {// Aquı́ se incluyen las instrucciones de lo que debe // realizar la función sobre los argumentos... } Ejemplo: Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 24 Introducción // Esta función calcula el p porciento de una cantidad C. double porcentaje(double porciento,double cantidad) { double resultado; // defino una variable para almacenar ahı́ el resultado... resultado = porciento * cantidad / 100; return resultado; // la instrucción return devuelve el valor a la función que lo llamó... // generalmente, a la función main() } La misma función anterior pudo definirse de la siguiente manera: // Esta función calcula el p porciento de una cantidad C. double porcentaje(double porciento,double cantidad) { return (porciento * cantidad / 100); } • 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Funciones que he necesitado... /* Nombre del archivo: prueba.cpp Descripción: Este programa ayuda en la revisión de funciones definidas por el usuario... ------------------------------------------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] Fecha de última Modificación: 24 de enero de 2008 Lenguaje de Programación: C++ Compilador: Dev - C++ Versión 4.9.9.2. ------------------------------------------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output #include <stdlib.h> // para usar la función rand() #include <math.h> // funciones matemáticas (sin (double)) #include <conio.h> // para usar: getche, getch #include <ctime> // double difftime(time_t time2, time_t time1); 20 21 22 23 24 int int int int errores; // variable global factorial(int n); permuta(int n, int k); potencia(int e); 25 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.3 Funciones en C++ 26 27 28 29 30 31 32 33 25 using namespace std; int main(void) { char respuesta; int n,total; int i,j,k; // contadores double pBin, pBer; // probabilidades clock_t tiempo1,tiempo2; 34 35 36 37 38 39 40 41 42 43 44 45 46 cout << "\nEste programa sirve para verificar que"; cout << "\nlas funciones definidas más abajo (en el código)"; cout << "\nsean correctas......"; // for (;;) {tiempo1 = clock()/CLOCKS_PER_SEC; cout << "\n\nPrimero verificamos que la función "; cout << "\nfactorial no tenga errores: "; cout << "\n\n\nIngresa un número natural"; cout << "para calcular su factorial "; cin >> n; cout << "\n\n\nEl factorial de " << n << " es: " << factorial(n); 47 48 49 50 51 52 53 54 55 56 57 cout << "\n\nAhora verificamos que la función "; cout << "\nsubfactorial no tenga errores: "; cout << "\n\n\nIngresa un número natural n"; cout << "\npara calcular las permutaciones "; cin >> n; cout << "\n\n\nIngresa un número natural k"; cout << "\npara las permutaciones "; cin >> k; cout << "\n\n\nEl resultado de combinar " << k; cout << " de entre " << n << " es: " << permuta(n,k); 58 59 60 61 62 63 64 65 cout << "\n\nFinalmente verificamos que la función "; cout << "\npotencia no tenga errores: "; cout << "\n\n\nIngresa un número natural n"; cout << "\npara calcular 2ˆn: "; cin >> n; cout << "\n\n\nEl resultado de elevar 2ˆ" << n; cout << " es: " << potencia(n); 66 67 68 69 70 71 72 cout << cout << cout << cout << tiempo2 cout << "\n\nFinalmente verificamos el valor de "; "\nCLOCKS_PER_SECOND: "; CLOCKS_PER_SEC << endl; "\nTiempo 1 (inicio): " << tiempo1; = clock()/CLOCKS_PER_SEC; "\nTiempo 2 (actual): " << tiempo2; 73 74 75 cout << "\n\nTotal de errores: " << errores; // Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 26 Introducción 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)) { break; // Salir del ciclo for inicial... } cout <<"\n\n\n"; } return 0; } /************************************** Declaro la función factorial... ***************************************/ int factorial(int n) { int fi,i; fi = i = 1; while (i<=n) { fi *=i; if (fi <= 0){ // por si se rebasa la memoria... cout << "\n\n\nEl hecho de que sea computadora "; cout << "\nno implica que haga milagros...\n"; cout << "\nLo siento, se rebasó la memoria..."; fi = 1; errores++; break; } i++; } return fi; } /************************************** Declaro la función permuta... ***************************************/ int permuta(int n, int k) { int p,subfactorial,i; i = n - k + 1; // n - k + 1 para calcular el subfactorial // el subfactorial es el numerador de la fórmula para // calcular las combinaciones n en k //C(n,k) = (n-k+1)(n-k+2)...(n) / k! subfactorial = 1; // reinicio el subfactorial while (i<=n){ subfactorial *=i; i++; } p = subfactorial / factorial(k); // p siempre es entero... return p; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.3 Funciones en C++ 126 127 128 129 130 131 132 133 134 135 136 137 138 139 27 } /************************************** Declaro la función potencia... ***************************************/ int potencia(int e) {// para calcular la potencia 2ˆe int i,potencia; // contador y resultado potencia = 1; for (i=1; i <= e; i++) { potencia *=2; } return potencia; } Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 28 Introducción 1.4 Clases Yo me imagino las clases como tipos de datos que defino por comodidad. Por ejemplo, si necesito trabajar con números complejos, mejor defino un nuevo tipo de variable con una clase. ası́, podré definir números complejos como si se tratara de un tipo de variable que ya estuviera definido en C++ . La idea es que además de declarar tipos de datos también podré definir funciones y realizar operaciones con ellos, por ejemplo, sumarlos, multiplicarlos, etc. 1 2 3 4 5 6 /* Este programa crea una clase que se llama número complejo */ #include <iostream> // Funciones para input/output #include <cstdlib> // 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using namespace std; class complejo{ public: double real; // parte real del número complejo. double imaginary; // parte imaginaria del # complejo }; int main(void){ // defino una instancia de mi clase // se trata de un número complejo complejo z1; z1.real = 3.14159; // parte real z1.imaginary = 2.717281828; // parte imaginaria cout << "\n\n\n"; 21 cout << "\n\nParte real de z1 es z1.real = " << z1.real; cout << "\n\nParte compleja de z1 es z1.imaginary = " << z1.imaginary; cout << "\n\n"; system("PAUSE"); return 0; 22 23 24 25 26 27 28 29 } El siguiente código muestra funciones pertenecientes a una clase. 1 2 3 /* Este programa crea una clase que se llama número complejo. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 1.4 Clases 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 29 Se muestra además el uso de funciones definidas para las clases. */ #include <iostream> // Funciones para input/output #include <cstdlib> // using namespace std; class complejo{ public: // para asignar la parte real void DefinirReal(double r); // para asignar la parte imaginaria void DefinirImaginario(double i); // para leer la parte real double LeerReal(void); // para leer la parte imaginaria double LeerImaginario(void); private: double real; // parte real double imaginary; // parte imaginaria }; int main(void){ // defino una instancia de mi clase complejo z1; z1.DefinirReal(3.14159); z1.DefinirImaginario(2.717281828); cout << "\n\n\n"; 30 31 32 33 34 35 36 37 38 39 40 41 cout << "\n\nEste programa muestra el uso de funciones de clase."; cout << "\n\nParte real de z1 se obiente con z1.LeerReal(); = " << z1.LeerReal(); cout << "\n\nParte compleja de z1 se obtiene con z1.LeerImaginario(); = " << z1.LeerImaginario(); cout << "\n\n"; system("PAUSE"); return 0; } // Ahora defino las funciones de la clase. 42 43 44 45 46 // para asignar la parte real void complejo::DefinirReal(double r){ real = r; } 47 48 49 50 51 // para asignar la parte imaginaria void complejo::DefinirImaginario(double i){ imaginary = i; } 52 53 // para leer la parte real Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 30 Introducción 54 55 56 double complejo::LeerReal(void){ return(real); } 57 58 59 60 61 // para leer la parte imaginaria double complejo::LeerImaginario(void){ return(imaginary); } Debes notar que en el primer código se han definido las variables real e imaginary como variables públicas, pero en el segundo ejemplo se han definido como variables privadas. De esta forma, no se puede tener acceso a ellas, salvo a través de las funciones que se definen en la clase. En este ejemplo se trata de las funciones: LeerImaginario(), LeerReal(), DefinirImaginario(double i), y DefinirReal(double r). Observa también que las funciones de clase se definen con el siguiente código: 1 2 3 4 5 6 tipod clase::nombreFuncion(tipoa argumento){ // Instrucciones de la función... . . . } • tipod indica el tipo de valor que devolverá la función. • clase es el nombre de la clase a la que pertenece la función. • nombreFuncion es el nombre de la función. • tipoa es el tipo de variable que tendrá el argumento. • argumento es el identificador de la variable que será el argumento de la función. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2 Códigos Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 32 Códigos 2.1 Mis primeros programas En este apartado se muestra el código de algunos programas básicos. • Estructura básica del programa. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 /* Nombre del archivo: ProgramTemplate Template - Esta es una estructura de base para escribir programas en C++ ------------------------------------------------------------------Nombre del Archivo: ProgramTemplate Autor: Tu Nombre va aquı́... Email: [email protected] Descripción: Estructura para programa Fecha de última Modificación: 17 de Noviembre del 2007 ------------------------------------------------------------------∗/ #include <iostream> // Funciones básicas para input/output #include <math.h> // funciones matemáticas using namespace std; int main(int nNumberofArgs, char* pszArgs[]) { // El código del programa C++ debe estar encerrado entre llaves {} // después del la instrucción "main" // (Bueno, en realidad se trata de una función...) // La siguiente instrucción: system("PAUSE"); // permite que el usuario haya leı́do la información // que se obtuvo como resultado de la ejecución del programa... system("PAUSE"); return 0; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.1 Mis primeros programas • 33 Las reglas básicas del lenguaje C++ . #include <stdio.h> int main() { printf("\n Los paréntesis siempre aparecen en pares!"); printf("\n Los comentarios en una lı́nea se indican con //"); printf("\n O bien, se inician don /*"); printf("\n y se terminan con */"); printf("\n cuando abarcan varias lı́neas..."); printf("\n Las instrucciones terminan con un punto y coma (;)"); printf("\n Los espacios son opcionales"); printf("\n Puedes dejar lı́neas en blanco entre el código"); printf("\n para hacerlo más legible"); printf("\n Debe contener la función main()"); printf("\n C++ usa mayormente minúsculas."); printf("\n En C++ las letras mayúsculas y las minúsculas"); printf("\n no dan los mismos resultados en las instrucciones..."); return(0); } • Calcula el área de un triángulo. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> using namespace std; int main(void) { double area, base, altura; string unidad; cout << "¿Qué unidad de medida usarás? cin >> unidad; cout << "¿Cuántos " << unidad << "mide la base del triángulo? "; cin >> base; cout << "¿Cuántos " << unidad << "mide la altura del triángulo? "; cin >> altura; area = base*altura/2; cout << "El área del triángulo es: " << area << unidad << " cuadrados."; system("PAUSE"); return 0; } Códigos en C++ "; Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 34 Códigos • Una tonelada métrica equivale a 35,273.92 onzas. Escribe un programa que lea el peso de un paquete de cereal en onzas y la salida sea el peso en toneladas métricas ası́ como el número de cajas que se requieren para que pesen una tonelada métrica. El programa debe permitir al usuario realizar el cálculo tantas veces como lo desee.1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 /* Nombre del Archivo: proyecto1.cpp Descripción: En el encabezado... Fecha de última Modificación: 18 de Noviembre del 2007 */ #include <iostream> using namespace std; int main(void) { double pesoOnzas, pesoTon, n; double coef=35273.92; char respuesta = ’c’; for (;;) { cout << "¿Cuál es el peso de un paquete en onzas?: "; cin >> pesoOnzas; pesoTon = pesoOnzas / coef; n = coef / pesoTon; cout << "Un paquete pesa " << pesoTon << " Toneladas Métricas.\n\n"; cout << "Se requieren " << n << "cajas de cereal\n"; cout << "para que pesen una Tonelada Métrica,\n"; cout << "dado que 1 TM = 35,273.92 onzas.\n\n"; cout << "Presione < S > para salir o < C > para continuar...."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)) { break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; // Le indico que devuelva cero la función "main()" } 1 A partir de este programa se omiten el autor y el correo electrónico del mismo. En todos los casos se trata del autor de este material. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.1 Mis primeros programas 35 • Un laboratorio de investigación ha concluido que el azucar X, un endulzante artificial dietético, causará la muerte de ratones de laboratorio. Un paciente desea conocer cuánto refresco de cola endulzado con el azucar X puede tomar sin morir. Escribe un programa para encontrar la respuesta. La entrada es la cantidad (en gramos) de azucar X requerida para matar a un ratón, el peso del ratón y el peso del paciente. Para asegurar la integridad del paciente, indica el peso a cual el paciente dejará de controlar su dieta, en lugar de su peso actual. Suponga que el refresco de cola contiene un décimo de porciento de azúcar X. El programa debe repetirse tantas veces como el usuario requiera. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /* Nombre del Archivo: proyecto2.cpp Fecha de última Modificación: 18 de Noviembre del 2007 */ #include <iostream> using namespace std; int main(void) { double pesoPac, pesoRat, dosisRat, dosisPac; double ratio=0.001; char respuesta = ’c’; for (;;) { cout << "¿Cuál es el peso del ratón? [gr]: "; cin >> pesoRat; cout << "¿Cuál es la dosis mortal para el ratón?: "; cin >> dosisRat; cout << "¿Cuál es el peso deseado del paciente? [kg]: "; cin >> pesoPac; // Cálculos... dosisPac= 1000*dosisRat * pesoPac / pesoRat; // dosis de pura azucar X dosisPac = dosisPac / ratio; // dosis de refresco... cout << "El paciente no debe exceder de " << dosisPac << " gramos de refresco endulzado con Azucar X, \n"; cout << "para que su integridad fı́sica esté a salvo. \n"; cout << "Presione < S > para salir o < C > para continuar...."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)) { break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; // Le indico que devuelva cero la función "main()" } Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 36 Códigos • Los trabajadores de una compañı́a en particular han ganado un 7.6% de incremento retroactivo a seis meses. Escribe un programa que toma el salario promedio anual como entrada y da como salida el pago retroactivo al empleado, el nuevo salario anual y el nuevo salario mensual. Usa la declaración de variable con el modificador const para expresar el aumento en el salario. El programa debe permitir realizar el cálculo tantas veces como se requiera. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /* Nombre del Archivo: proyecto3.cpp Descripción: Ver el encabezado... Fecha de última Modificación: 20 de Noviembre del 2007 */ #include <iostream> using namespace std; int main(void) { double salarioInicial, salarioFinal, salarioMensual, retro; double aumento=0.076; int meses; char respuesta = ’c’; for (;;) { cout << "¿Cuál es el salario anual inicial del trabajador [en pesos]? "; cin >> salarioInicial; cout << "¿Cuántos meses se aplican de retroactivo [n<=6]? "; cin >> meses; retro = meses * aumento * salarioInicial; salarioFinal = salarioInicial * (1 + aumento); salarioMensual = salarioFinal/12; cout << "El monto del retroactivo es de: " << retro << " pesos.\n\n"; cout << "El nuevo salario anual es de: " << salarioFinal << " pesos,\n"; cout << "y equivale a: " << salarioMensual << " pesos mensuales.\n\n"; cout << "Presione < S > para salir o < C > para continuar...."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)) { break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.1 Mis primeros programas 37 • Elaborar un programa que calcule el factorial de un número entero positivo. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 /* Nombre del Archivo: factorial.cpp Autor: Efraı́n Soto Apolinar. Email: [email protected] Descripción: Ver el encabezado... Fecha de última Modificación: 22 de Noviembre del 2007 */ #include <iostream> using namespace std; int main(void) { int i,n,factorial; char respuesta = ’c’; for ( ; ; ){ cout << "Este programa calcula el valor del factorial \n"; cout << "de un número entero positivo\n"; cout << "Introduzca el valor de n: "; cin >> n; factorial=1; for (i = 1; i <= n ;i++) { factorial *=i;} cout << "El factorial del número " << n << " es: " << factorial << "\n\n\n"; cout << "Presione < S > para salir o < C > para continuar...."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)) { break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; } 31 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 38 Códigos 2.2 Programas con funciones En los siguientes ejemplos, los códigos incluyen programas que hacen llamadas a funciones que se definen en los mismos. • Generar un programa donde se defina una función que calcule el factorial de un número natural dado. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 /* Nombre del archivo: proyecto4.cpp Nombre del Archivo: proyecto4.cpp Descripción: Ver el encabezado... Fecha de última Modificación: 01 de Diciembre del 2007 */ #include <iostream> using namespace std; int main(void) { int f,n,i; int factorial(int n); // Declaro la función antes de usarla... char respuesta = ’c’; for ( ; ;) { cout << "Ingresa el número natural para el cual \n"; cout << "deseas calcular el factorial. "; cin >> n; f = factorial(n); // Aquı́ llamo la función factorial... cout << " \n\n\n"; cout << "El factorial del número " << n << " es: " << f << " \n\n\n"; cout << "Presione < S > para salir o < C > para continuar...."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)) { cout <<"\n\n\n\n"; break; } } return 0; } // Declaro la función factorial... int factorial(int n) { int fi,i; fi = i = 1; while (i<=n) { fi *=i; i++; } return fi; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.3 Funciones cin, cout 2.3 39 Funciones cin, cout En esta sección se enumeran programas sencillos que servirán de ejemplo para otros ejercicios. • 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 • 2 3 4 5 6 7 8 9 10 11 o /* Nombre del archivo: UnoUno.cpp Descripción: Escribir un programa que calcule la media real de 3 números enteros dados por el usuario. Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ int a,b,c; double promedio; cout << "\nEscribe el primer número entero: "; cin >> a; cout << "\nEscribe el segundo número entero: "; cin >> b; cout << "\nEscribe el tercer número entero: "; cin >> c; promedio = double(a + b + c)/3.0; cout << "\nEl promedio de estos valores es: " << promedio << endl; system("PAUSE"); return 0; } 1 1 Calcular el promedio. o Calcular la suma de dos números. /* Nombre del archivo: UnoDos.cpp Descripción: Escribir un programa que calcule la suma de 2 números enteros dados por el usuario. Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 40 Códigos int a,b; cout << "\nEscribe el primer número entero: "; cin >> a; cout << "\nEscribe el segundo número entero: "; cin >> b; cout << (a + b) << endl; system("PAUSE"); return 0; } 12 13 14 15 16 17 18 19 20 o • Calcular la diferencia de dos números. /* Nombre del archivo: UnoTres.Cpp Descripción: Escribir un programa que pida dos números y muestre la diferencia de ambos. Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ int a,b; cout << "\nEscribe el minuendo: "; cin >> a; cout << "\nEscribe el sustraendo: "; cin >> b; cout << (a - b) << endl; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 system("PAUSE"); return 0; } 19 20 21 o • 1 2 3 4 5 6 7 8 9 10 Intercambiar el valor de dos variables. /* Nombre del archivo: UnoCuatro.cpp Descripción: Dados dos números que introducirá el usuario, escribir un programa que intercambie sus valores. Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.3 Funciones cin, cout int main(void){ double a,b,temp; cout << "\nEscribe el primer valor: "; cin >> a; cout << "\nEscribe el segundo valor: "; cin >> b; temp = a; a = b; b = temp; cout << "\nLos valores intercambiados de orden son: " << a << " y " << b << endl; system("PAUSE"); return 0; } 11 12 13 14 15 16 17 18 19 20 21 22 23 24 • 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 • 2 o Insertar un dato tipo string. /* Nombre del archivo: UnoCinco.cpp Descripción: Escribir un programa que pida el nombre y el apellido paterno de una persona y lo muestre en pantalla de la forma apellido paterno, nombre. Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ char nombre[15], aPaterno[15], aMaterno[15]; cout << "Escribe tu nombre: "; gets(nombre); cout << "\nEscribe tu apellido paterno: "; gets(aPaterno); cout << "\nEscribe tu apellido materno: "; gets(aMaterno); cout << "\n\nTu nombre es: \n" << aPaterno << " " << aMaterno << ", " << nombre << "\n"; system("PAUSE"); return 0; } 1 1 41 o Convertir grados sexagesimales a radianes. /* Nombre del archivo: UnoSeis.cpp Descripción: Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 42 Códigos Escribir un programa que acepte el valor de un ángulo medido en grados sexagesimales e imprima su valor en radianes. Nota: Utiliza Pi = 3.141592654 Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ const double pi = 3.141592654; double grados, rad; cout << "\nEscribe la medida del ángulo en grados sexagesimales: "; cin >> grados; rad = grados * pi / 180; cout << "\nLa medida del ángulo en radianes es: " << rad << endl; system("PAUSE"); return 0; } 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 o • 1 2 3 4 5 6 Calcular el volumen de una esfera. /* Nombre del archivo: UnoSiete.cpp Descripción: El volumen de una esfera puede calcularse con V = 4 * Pi * rˆ3 / 3. Escribir un programa que solicite el radio de una esfera e imprima su volumen. 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ double r, volumen; const double pi = 3.141592654; cout << "\nEscribe el radio de la esfera: "; cin >> r; volumen = 4 * pi * r * r * r / 3; cout << "\nEl volumen de esa esfera es: " << volumen << endl; system("PAUSE"); return 0; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.3 Funciones cin, cout 43 } 24 • o Calcular área del cı́rculo y perı́metro de circunferencia. /* Nombre del archivo: UnoOcho.cpp Descripción: El área de un cı́rculo es : A = Pi * rˆ2 La longitud de la circunferencia es: P = 2 * Pi * r Escribir un programa que solicite el radio de un cı́rculo e imprima en pantalla su perı́metro y su área. 1 2 3 4 5 6 7 8 9 Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ double r, perimetro, area; const double pi = 3.141592654; cout << "\nEscribe el radio del cı́rculo: "; cin >> r; perimetro = 2 * pi * r; area = pi * r * r; cout << "\nEl area del cı́rculo es: " << area; cout << "\nEl perimetro de la circunferenca es: " << perimetro << endl; system("PAUSE"); return 0; } 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 • 1 2 3 4 5 6 7 8 9 10 11 o Realizar cálculos relacionados con un viaje. /* Nombre del archivo: UnoNueve.cpp Descripción: Escribir un programa que pida el total de kilómetros recorridos, el precio de la gasolina (por litro), el dinero de gasolina gastado en el viaje (en pesos) y el tiempo que se ha tardado (en horas y minutos) en ese viaje. Calcular, además: - Consumo de gasolina por cada 100 Km - Consumo de gasolina por cada Km - Velocidad media Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 44 Códigos 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ int KmR, Hrs, Min; double PrecioGas, ImporteGas, Tiempo, VelKmH, VelMS; double ConsumoGasPC, ConsumoGasP, ConsumoGasLC, ConsumoGasL; cout << "\nEscribe la distancia recorrida en kilómetros: "; cin >> KmR; cout << "\nEscribe el precio de un litro de gasolina: "; cin >> PrecioGas; cout << "\nEscribe el importe gastado en gasolina: "; cin >> ImporteGas; cout << "\n\nEscribe el tiempo que tardó el viaje. "; cout << "\nPrimero indica los minutos y después los segundos... "; cout << "\nHoras: "; cin >> Hrs; cout << "\nMinutos: "; cin >> Min; // Aquuı́ van los cálculos... Tiempo = Hrs + Min / 60; // Tiempo en formato double... VelKmH = KmR / Tiempo; VelMS = VelKmH * 1000 / 3600; ConsumoGasL = ImporteGas / PrecioGas; ConsumoGasP = ConsumoGasL * PrecioGas; ConsumoGasLC =ConsumoGasL * 100; ConsumoGasPC =ConsumoGasP * 100; cout << "\n\nLa velocidad promedio de ese viaje es: \n" << VelKmH << " Kilómetros por hora " ; cout << "\no bien..."; cout << "\n\nLa velocidad promedio de ese viaje es: \n" << VelMS << " metros por segundo" ; cout << "\nSe consumieron: " << ConsumoGasL << " litros de gasolina por cada kilómetro recorrido" ; cout << "\nSe consumieron: " << ConsumoGasLC << " litros de gasolina por cada cien kilómetros" ; cout << "\n\no bien..."; cout << "\nSe consumieron: " << ConsumoGasP << " pesos de gasolina por cada kilómetro recorrido" ; cout << "\nSe consumieron: " << ConsumoGasPC << " pesos de gasolina por cada cien kilómetros" << endl; system("PAUSE"); return 0; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.3 Funciones cin, cout • 1 2 3 4 5 6 7 45 o Calcular pendiente y ecuación de una recta. /* Nombre del archivo: UnoDiez.cpp Descripción: Escribir un programa que encuentre la ecuación de la recta que pasa por los dos puntos dados por el usuario A(x_a, y_a), y B(x_b, y_b). Indicar además sus intersecciones con los ejes coordenados. 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 Fecha de última Modificación: 03 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output using namespace std; int main(void){ int x_a, x_b, y_a, y_b, Dx, Dy, b; double m; cout << "\nEste programa calcula la pendiente de una recta "; cout << "\na partir de las coordenadas de dos puntos por los cuales pasa... "; cout << "\nEscriba las coordenadas de acuerdo a como se piden: "; cout << "\nCoordenada ’x’ del punto A: "; cin >> x_a; cout << "\nCoordenada ’y’ del punto A: "; cin >> y_a; cout << "\nCoordenada ’x’ del punto B: "; cin >> x_b; cout << "\nCoordenada ’y’ del punto B: "; cin >> y_b; // Cálculos... Dx = x_b - x_a; Dy = y_b - y_a; m = Dy / Dx; b = Dx * y_a - Dy * x_a; cout << "\nLa pendiente de la recta que pasa por esos dos puntos es: " << m; cout << "\ny su ecuación es: \n\n" << Dy << "x + " << -Dx << "y +" << b << "= 0."; cout << endl; system("PAUSE"); return 0; } Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 46 Códigos 2.4 if, for, while and the like... Las operaciones booleanas (comparaciones) y los ciclos nos permiten controlar el flujo del programa. o • Decidir si el usuario es mayor de edad. /* Nombre del archivo: DosUno.cpp Descripción: Escribir un programa que solicite la edad del usuario y decida si es o no mayor de edad. Considera a una persona mayor de edad si tiene al menos 18 años cumplidos. 1 2 3 4 5 6 7 8 Fecha de última Modificación: 04 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ int edad; cout << "\nEste programa decide si el usuario es mayor de edad o no "; cout << "\na partir de su edad... "; cout << "\n\n¿Cuál es tu edad? "; cin >> edad; if (edad > 17) { cout << "\n\nEl usuario es mayor de edad \n"; } else{ cout << "\n\nEl usuario es menor de edad \n"; } system("PAUSE"); return 0; } 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 o • 1 2 3 4 5 Indicar el nombre del mes a partir de un número. /* Nombre del archivo: DosDos.cpp Descripción: Escribir un programa que pida un número del 1 al 12 (inclusive) e imprima a qué mes del año corresponde ese valor. 6 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.4 if, for, while and the like... 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 47 Fecha de última Modificación: 04 de enero del 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ int mes; cout << "\nEste programa imprime el nombre del mes "; cout << "\na partir del número que le corresponde... "; cout << "\nIndique el número del mes "; cin >> mes; cout << endl; if (mes == 1){ cout << "El mes " << mes << " corresponde a Enero."; } if (mes == 2){ cout << "El mes " << mes << " corresponde a Febrero."; } if (mes == 3){ cout << "El mes " << mes << " corresponde a Marzo."; } if (mes == 4){ cout << "El mes " << mes << " corresponde a Abril."; } if (mes == 5){ cout << "El mes " << mes << " corresponde a Mayo."; } if (mes == 6){ cout << "El mes " << mes << " corresponde a Junio."; } if (mes == 7){ cout << "El mes " << mes << " corresponde a Julio."; } if (mes == 8){ cout << "El mes " << mes << " corresponde a Agosto."; } if (mes == 9){ cout << "El mes " << mes << " corresponde a Septiembre."; } if (mes == 10){ cout << "El mes " << mes << " corresponde a Octubre."; } if (mes == 11){ cout << "El mes " << mes << " corresponde a Noviembre."; } if (mes == 12){ cout << "El mes " << mes << " corresponde a Diciembre."; } // por si el usuario es medio güey... Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 48 Códigos 57 58 59 60 61 62 63 if ((mes > 12) || (mes < 1)){ cout << "El mes " << mes << " no existe." ; } cout << endl; system("PAUSE"); return 0; } • El mismo programa que el anterior, pero ahora utilizando la sentencia switch o 1 2 3 4 5 6 7 8 /************************************************** Nombre del Archivo: DosDosSwitch.cpp Autor: Efraı́n Soto Apolinar Email: [email protected] Descripción: Escribir un programa que pida un número del 1 al 12 (inclusive) e imprima a qué mes del año corresponde ese valor. 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Fecha de última Modificación: 23 de marzo de 2008 *****************************************************/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ int mes; cout << "\nEste programa imprime el nombre del mes "; cout << "\na partir del número que le corresponde... "; cout << "\nIndique el número del mes "; cin >> mes; switch (mes){ case 1: cout << "\nEl mes " << mes << " corresponde a Enero.\n" ; break; case 2: cout << "\nEl mes " << mes << " corresponde a Febrero.\n" ; break; case 3: cout << "\nEl mes " << mes << " corresponde a Marzo.\n" ; break; case 4: cout << "\nEl mes " << mes << " corresponde a Abril.\n" ; break; case 5: cout << "\nEl mes " << mes << " corresponde a Mayo.\n" ; break; case 6: cout << "\nEl mes " << mes << " corresponde a Junio.\n" ; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.4 if, for, while and the like... break; case 7: cout << "\nEl mes " << mes << break; case 8: cout << "\nEl mes " << mes << break; case 9: cout << "\nEl mes " << mes << break; case 10: cout << "\nEl mes " << mes << break; case 11: cout << "\nEl mes " << mes << break; case 12: cout << "\nEl mes " << mes << break; default: // Error en argumento... cout << "\nEl mes " << mes } // end switch cout << "\n\n\n"; system("PAUSE"); return 0; } 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 • 1 2 3 49 " corresponde a Julio.\n" ; " corresponde a Agosto.\n" ; " corresponde a Septiembre.\n" ; " corresponde a Octubreo.\n" ; " corresponde a Noviembre.\n" ; " corresponde a Diciembre.\n" ; << " no existe.\n" ; o Calcular una potencia. /* Nombre del archivo: DosTres.cpp Descripción: Calcular a elevado a la potencia b. 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Fecha de última Modificación: 05 Enero 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ int i, exponente, base; double potencia; cout << "\nEste programa calcula la potencia de un número "; cout << "\nsiendo la base y el exponente números enteros "; cout << "\nIngresa el valor de la base: "; cin >> base; cout << "\nIngresa el valor del exponente: "; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 50 Códigos cin >> exponente; potencia = 1; if (exponente == 0){ potencia = 1; } if (exponente > 0){ for (i=1 ; i<=exponente ; i++){ potencia *= base; } } if (exponente < 0){ for (i=-1 ; i>=exponente ; i--){ potencia /= double(base); // la instrucción double(var) // convierte un entero a tipo double... } } cout << "\nEl resultado de elevar el número: " << base << " a la potencia " << exponente << " es: " << potencia << endl; system("PAUSE"); return 0; } 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 o • 1 2 3 4 5 6 7 Pedir dos números y su suma. /*************************************************** Nombre del archivo: DosCuatro.cpp Descripción: Escribir un programa que pida dos números a, b y después solicite la suma de ambos. En caso de que la suma sea incorrecta indicarlo y dar oportunidad para que escriba de nuevo el resultado. 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Fecha de última Modificación: 04 Enero 2008 ****************************************************/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ int a,b,suma; char respuesta; cout << "\nEste pide dos números enteros "; cout << "\ny solicita su suma "; cout << "\nEn caso de error te permite volver a intentar."; cout << "\nIntroduce el primer número entero: "; cin >> a; cout << "\nIntroduce el segundo número entero: "; cin >> b; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.4 if, for, while and the like... for (;;){ cout << "\nIntroduce la suma de los números: "; cin >> suma; if (suma == (a+b)){ cout << "\nCorrecto!!!\n\n "; break; // sale del ciclo for } else{ cout << "\nIncorrecto!!!"; } cout << "Presione < S > para salir o < C > para continuar..."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo... } cout <<"\n\n\n"; } system("PAUSE"); return 0; } 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 • 1 2 3 4 5 51 o Pedir dos números y un operador para realizar el cálculo. /* Nombre del archivo: DosCinco.cpp Descripción: Escribir un programa que solicite al usuario dos números y una operación y mostrar el resultado de esa operación con esos dos números. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Fecha de última Modificación: 05 Enero 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ double a,b,resultado; char operacion; cout << "\nEste pide dos números enteros "; cout << "\ny solicita un operador "; cout << "\nDespués te muestra el resultado... "; cout << "\nIntroduce el primer número entero: "; cin >> a; cout << "\nIntroduce el segundo número entero: "; cin >> b; cout << "\nIntroduce el operador: "; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 52 Códigos cin >> operacion; if (operacion == ’+’){ resultado = a + b; } if (operacion == ’-’){ resultado = a - b; } if (operacion == ’*’){ resultado = a * b; } if (operacion == ’/’){ resultado = a / b; } cout << endl << "\t" << a << " " << operacion << " " << b << " = " << resultado << endl; system("PAUSE"); return 0; } 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 o • 1 2 3 4 5 6 7 8 9 Calcular el valor absoluto de un número. /* Nombre del archivo: DosSeis.cpp ------------------------------------------------------------------Nombre del Archivo: DosSeis.cpp Autor: Efraı́n Soto Apolinar Email: [email protected] Descripción: Escribir un programa que calcule el valor absoluto de un número introducido por el usuario. 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 Fecha de última Modificación: 05 Enero 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ double a, absa; cout << "\nEste pide un número real "; cout << "\ny calcula su valor absoluto "; cout << "\nIntroduce un número real: "; cin >> a; if (a>=0){ absa = a; } else{ absa = -a; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.4 if, for, while and the like... } cout << "\nEl valor absoluto del número real: " << a << " es: " << "\t" << absa << endl; system("PAUSE"); return 0; } 28 29 30 31 32 33 • 1 2 3 4 5 6 7 8 9 10 53 Calcular el área de un triángulo a partir de la medida de sus lados2 . /* Nombre del archivo: DosSiete.cpp Descripción: Escribir un programa que calcule el área de un triángulo conocidos las longitudes de sus tres lados. Sugerencia: Aplica la fórmula de Herón: A = sqrt(p*(p-a)*(p-b)*(p-c)) donde: a,b,c son las longitudes de los lados del triángulo, y p es el semiperı́metro del triángulo, es decir, p = (a + b + c) / 2 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Fecha de última Modificación: 05 Enero 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output #include <math.h> // Funciones matemáticas using namespace std; int main(void){ double a,b,c,p,area; cout << "\nEste programa calcula el área de un "; cout << "\ntriángulo a partir de la medida de sus lados."; cout << "\nIntroduce la medida del primer lado: "; cin >> a; cout << "\nIntroduce la medida del segundo lado: "; cin >> b; cout << "\nIntroduce la medida del tercer lado: "; cin >> c; if (((a + b) > c) && ((b + c) > a) && ((a + c) > b)){ // verifico que cumpla la desigualdad del triángulo... // la suma de dos lados siempre es mayor al tercero... p = (a + b + c)/2; // Semiperı́metro area = sqrt(p*(p-a)*(p-b)*(p-c)); cout << "\nEl área de el triángulo es:" << area << endl; } else{ 2 Observe Códigos en C++ se aplica la desigualdad del triángulo en la condición If. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. o 54 Códigos // por ejemplo, si ingresó: // primer lado = 100, segundo lado = 1, tercer lado = 1 cout << "\nEs imposible construir un triángulo "; cout << "\ncon esas longitudes para sus lados. " // i.e., pareces güey!!! << endl; } system("PAUSE"); return 0; } 38 39 40 41 42 43 44 45 46 47 o • 1 2 3 4 5 Calcular la distancia de un punto a una recta. /* Nombre del archivo: DosOcho.cpp Descripción: Escribir un programa que calcule la distancia desde el punto P(x_0, y_0) a la recta Ax+By+C=0. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 Fecha de última Modificación: 05 de enero de 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output #include <math.h> // Funciones matemáticas using namespace std; int main(void){ double A,B,C,x_0,y_0,d; cout << "\nEste programa calcula la distancia desde el "; cout << "\npunto P(x_0, y_0) hasta la recta: Ax + By + C = 0"; cout << "\nIntroduce el coeficiente A: "; cin >> A; cout << "\nIntroduce el coeficiente B: "; cin >> B; cout << "\nIntroduce el coeficiente C: "; cin >> C; cout << "\nIntroduce la coordenada x_0 del punto P: "; cin >> x_0; cout << "\nIntroduce la coordenada y_0 del punto P: "; cin >> y_0; d = fabs(A*x_0 + B*y_0 + C)/sqrt(A*A + B*B); cout << "\nLa distancia desde el punto P(" << x_0 << " , " << y_0 << "), es:" << d << endl; system("PAUSE"); return 0; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.4 if, for, while and the like... • 55 o Decidir si un número entero positivo dado es par o impar. /* Nombre del archivo: DosNueve.cpp Descripción: Escribir un programa que determine si el número positivo introducido por el usuario es par o impar. 1 2 3 4 5 Fecha de última Modificación: 05 de enero de 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ int ent,residuo; char respuesta; cout << "\nEste programa pide un número entero positivo"; cout << "\ny decide si es par o impar..."; for (;;){ cout << "\nIntroduce un número entero positivo:"; cin >> ent; // Encuentro el residuo de la división por 2 // para saber si es par o impar... residuo = ent % 2; if (ent <= 0) { cout << "\nSolo acepto números enteros positivos." << endl; } else{ if (residuo == 0){ cout << "\nEl número es par." << endl; } else{ cout << "\nEl número es impar." << endl; } } cout << "\nPresione < S > para salir..."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; } 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 • Convertir temperaturas de la escala Farenheit a la escala centı́grada. Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. o 56 Códigos /* Nombre del archivo: DosDiez.cpp Descripción: Escribir un programa que convierta una temperatura dada por el usuario en grados Farenheit a grados Celsius. El usuario debe poder realizar el cálculo tantas veces como lo desee. 1 2 3 4 5 6 7 8 Fecha de última Modificación: 05 enero de 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output using namespace std; int main(void){ double C, F; char respuesta; cout << "\nEste programa convierte una temperatura "; cout << "\nde la escala Farenheit a Centı́grada..."; for (;;){ cout << "\nIntroduce la temperatura en escala Farenheit: "; cin >> F; C = (F - 32) / 1.8; cout << endl << F << " grados Farenheit equivalen a " << C << " grados Centı́grados" << endl ; // cout << "Presione < S > para salir..."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; } 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 o • 1 2 3 4 Encontrar el mayor de 3 números enteros dados. /* Nombre del archivo: DosOnce.cpp Descripción: Escribir un programa que lea tres números e imprima el mayor valor de los 3. 5 6 7 8 9 Fecha de última Modificación: 05 enero de 2008 ------------------------------------------------------------------*/ Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.4 if, for, while and the like... #include <iostream> using namespace std; int main(void){ int a,b,c,max; char respuesta; cout << "\nEste programa pide tres números enteros"; cout << "\ne indica el mayor de los tres."; // for (;;){ cout << "\nIntroduce el primer número "; cin >> a; cout << "\nIntroduce el segundo número "; cin >> b; cout << "\nIntroduce el tercer número "; cin >> c; if (a > b){ max = a; } else{ max = b; } if (c > max){ max = c; } cout << "\nEl mayor de los números es: " << max << endl; // cout << "Presione < S > para salir..."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; } 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 • 1 2 3 4 57 o Encontrar el mayor y el menor de 3 números enteros dados. /* Nombre del archivo: DosDoce.cpp Descripción: Escribir un programa que lea tres números enteros e indique el mayor de los 3 y el menor de los 3. 5 6 7 8 9 10 Fecha de última Modificación: 05 enero de 2008 ------------------------------------------------------------------*/ #include <iostream> // Funciones básicas input/output Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 58 Códigos using namespace std; int main(void){ int a,b,c,min,max; char respuesta; cout << "\nEste programa pide tres números enteros,"; cout << "\nindica el mayor de los tres y "; cout << "\nel menor de los tres..."; // for (;;){ cout << "\nIntroduce el primer número "; cin >> a; cout << "\nIntroduce el segundo número "; cin >> b; cout << "\nIntroduce el tercer número "; cin >> c; if (a > b){ max = a; min = b; } else{ max = b; min = a; } if (c > max){ max = c; } if (c < min){ min = c; } cout << "\nEl menor de los números es: " << min << endl; cout << "\ny el mayor de los números es: " << max << endl; // cout << "Presione < S > para salir..."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; } 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 o • 1 2 3 4 Identificar el mayor y el menor de una lista de números. /* Nombre del archivo: DosTrece.cpp Descripción: Escribir un programa que lea una lista de números positivos y escriba el valor máximo y el valor Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.4 if, for, while and the like... 5 6 59 mı́nimo. La lista finalizará cuando se introduzca el número cero (0). 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 Fecha de última Modificación: 05 enero de 2008 ------------------------------------------------------------------*/ #include <iostream> using namespace std; int main(void){ double inicial, actual, max, min; char respuesta; cout << "\nEste programa pide números positivos,"; cout << "\nindica el mayor de todos y "; cout << "\nel menor de ellos..." << endl; cout << "\nPara terminar de ingresar los números"; cout << "\nintroduce el número 0" << endl; // for (;;){ cout << "\nIntroduce el primer número positivo: "; cin >> actual; min = actual; // Asigno valor inicial min max = actual; // Asigno valor inicial max while (actual !=0){ // mientras no presione cero... if (actual > max){ max = actual; } if (actual < min){ min = actual; } cout << "\nIntroduce otro número positivo: "; cin >> actual; } cout << "\nEl mayor de todos los números introducidos es: " << max << endl; cout << "\nEl menor de todos los números introducidos es: " << min << endl; // cout << "Presione < S > para salir o < C > para continuar..."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo... } cout <<"\n\n\n"; } return 0; } Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 60 Códigos 2.5 Mis tareas En esta sección encontrarás el código de las tareas que voy entregando en mis clases de Simulación de Sistemas. 2.5.1 Simulación 1 Se lanza un alfiler de longitud L a una mesa que tiene dibujadas lı́neas paralelas equidistantes separadas a L unidades una de la otra. Calcular la probabilidad de que el alfiler toque lı́nea. Consideraciones Se realizaron las siguientes suposiciones: 1. La longitud del alfiler es 1. 2. El alfiler siempre cae dentro de la mesa. 3. La distancia (medida verticalmente) de una recta a la cabeza del alfiler es una variable aleatoria que presenta distribución uniforme. 4. El ángulo que forma el alfiler con las rectas dibujadas sobre la mesa es una variable aleatoria que presenta distribución uniforme. Con base en estas suposiciones, podemos definir como x la distancia (medida verticalmente) de una recta a la cabeza del alfiler, y θ como el ángulo que forma una de las rectas dibujadas sobre la mesa y el alfiler. 1 `i+1 θ x 0 `i Ahora definimos y como la posición de la punta del alfiler (el extremo opuesto a la cabeza del alfiler). Dado que el alfiler mide 1, la coordenada y puede calcularse con: y = x + sin (2 π θ) Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 61 donde π = 3.141592654 · · · , es la constante geométrica3 , y θ es el ángulo como se definió anteriormente. El alfiler tocará lı́nea siempre y cuando se cumpla alguna de las siguientes condiciones: i. y > 1, ó ii. y < 0 Geométricamente, de la figura podemos ver que en estos casos, la punta del alfiler estará fuera del área encerrada por las lı́neas paralelas `i y `i+1 . Simulación por computadora En seguida se muestra el código del programa que simula este experimento. /* Nombre del archivo: simulacion01.cpp Descripción: Este programa simula el siguiente experimento: Se lanza un alfiler de longitud L a una mesa que tiene dibujadas lı́neas paralelas equidistantes separadas a L unidades una de la otra. El usuario debe ingresar el número total de experimentos (entero) que se deben realizar, entendiendo por experimento la simulación de un lanzamiento del alfiler sobre la mesa. El resultado indica la probabilidad de que el alfiler toque una de las lı́neas dibujadas sobre la mesa. ------------------------------------------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] Fecha de última Modificación: 24 de enero de 2008 Lenguaje de Programación: C++ Compilador: Dev - C++ Versión 4.9.9.2. ------------------------------------------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output #include <stdlib.h> // para usar la función rand() #include <math.h> // funciones matemáticas (sin (double)) #include <conio.h> // para usar: getche, getch using namespace std; int main(void) 3 Al multiplicar θ por 2 π convertimos la variable aleatoria θ, cuyos valores van desde 0 hasta 1 a radianes. Se trata de un simple mapeo uno a uno. Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 62 Códigos { char respuesta; int si, no, i, j, total; double p, x, y, a; const double pi = 3.141592654; /* x --> representa la distancia de una recta paralela de referencia al punto donde cayó la cabeza del alfiler. y = x + sin (2 * pi * a) a --> es el ángulo que forma el alfiler con las rectas paralelas dibujadas sobre la mesa si --> es el número de veces que el alfiler toca lı́nea no --> es el número de veces que el alfiler NO toca lı́nea p --> es la probabilidad de que toque... total --> es el número de experimentos que realizará el programa... */ cout << "\nEste programa calcula la probabilidad de que"; cout << "\nal lanzar un alfiler de una longitud dada "; cout << "\nsobre una mesa que tiene dibujadas lı́neas "; cout << "\nparalelas separadas por una distancia igual "; cout << "\na la longitud del alfiler, toque lı́nea... "; // for (;;) { cout << "\n\n\nIngrese el número de experimentos: "; cin >> total; si = no = 0; p = 0; for (i = 1 ; i <= total ; i++) { // realizo los experimentos x = double(rand()) / double(RAND_MAX); a = double(rand()) / double(RAND_MAX); y = x + sin(2*pi*a); if ((y < 0) || (y > 1)) {si++;} else {no++;} } // end del ciclo for () p = double(si) / double(total); cout << "\n\n\nDe los " << total << " experimentos "; cout << si << " tocaron lı́nea, \nmientras que " << no ; cout << " no tocaron lı́nea.\n"; cout << "\nDe aquı́ que la probabilidad de que el alfiler"; cout << "\ntoque lı́nea es: " << p; cout << "\n\n\n"; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 63 // cout << "Presione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)) { break; // Salir del ciclo for inicial... } cout <<"\n\n\n"; } return 0; } Como los resultados generados con este programa son aleatorios, los resultados varı́an ligeramente. En la siguiente tabla se muestran algunos resultados obtenidos con el mismo. No. Experimentos 100 200 300 400 500 600 700 800 900 1 000 10 000 106 108 Probabilidad 0.66 0.62 0.613333 0.63 0.644 0.646667 0.624173 0.64 0.647778 0.623 0.6437 0.636592 0.636612 De hecho, aún si se dan los mismos valores al programa, éste arrojará diferentes resultados cada vez, dado que los valores que van tomando las variables x (que representa la distancia desde la recta `i a la cabeza del alfiler) y θ (que representa el ángulo que forma el alfiler con cualquiera de las lı́neas dibujadas sobre la mesa) son variables aleatorias con distribución contı́nua. Esto se puede verificar realizando los cálculos de nuevo con el programa alimentándolo con los mismos valores. Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 64 Códigos 2.5.2 Cálculo analı́tico Para hacer el cálculo analı́tico podemos definir las siguientes coordenadas: Sea d la distancia del centro del alfiler a la recta más cercana. Sea ` esta recta, y sea α como el menor ángulo formado entre ` y el alfiler. De aquı́ se deduce que: 0≤d≤ 1 , 2 0≤α≤ y π 2 También es claro que el alfiler tocará la recta ` si la hipotenusa del triángulo es menor a 0.5, es decir: d 1 < sin α 2 Entonces, al lanzar el alfiler, las coordenadas (d, α) tienen distribución uniforme en los intervalos antes definidos, que se pueden representar mediante el siguiente rectángulo: 1 2 π 2 La probabilidad de que el alfiler toque lı́nea es igual a la fracción del área del 1 rectángulo que yace debajo de la gráfica de la función: d = sin α. 2 El área del rectángulo es: π/4 y el área debajo de la gráfica de la función en cuestión es: Zπ/2 1 1 sin α dα = 2 2 0 y ası́ obtenemos: 1 2 = 2 ≈ 0.6366197724 p(A) = π π 4 Ası́ que la simulación codificada en C++ es correcta. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 2.5.3 65 Simulación 2 Desarrollar una simulación por computadora que simule experimentos de Bernoulli. El programa debe repetir los intentos hasta que se supere un valor fijo p de éxito, definido por el usuario. Este mismo experimento debe realizarse con el método binomial. Se debe ir calculando el valor de la probabilidad binomial P (n, k) para k = 0, 1, 2 · · · i, hasta que se rebase el valor de p. El programa debe indicar al usuario cuántos intentos de Bernoulli se requierieron para superar el valor de p y cuántas iteraciones binomiales se requirieron para alcanzar el mismo objetivo. Se elaboró un programa que requiere de la siguiente información: 3 Máximo de intentos de Bernoulli, que corresponde al número máximo de experimentos de Bernoulli que se simularán. 3 El valor de la probabilidad de éxito, que corresponde al valor de p del evento a simular. El código en el lenguaje C++ se enlista en seguida. /* Nombre del archivo: simulacion02.cpp Descripción: Este programa simula experimentos de Bernoulli y probabilidad binomial. ------------------------------------------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Webpage: http://yalma.fime.uanl.mx/˜efrain/ Fecha de última Modificación: 03 de febrero de 2008 Lenguaje de Programación: C++ Compilador: Dev - C++ Versión 4.9.9.2. ------------------------------------------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output #include <stdlib.h> // para usar la función rand() #include <math.h> // funciones matemáticas (pow (double)) #include <conio.h> // para usar: getche, getch #include <ctime> // clock_t = clock(); int errores; // variable global... Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 66 Códigos int factorial(int n); int permuta(int n, int k); // using namespace std; int main(void){ char respuesta; int i, j, kBer, kBin, n; double p, q, prob, x; // cout << "\nEste programa simula experimentos binomiales"; cout << "\ny repeticiones de experimentos de Bernoulli..."; // // // for (;;){ errores = 0; kBer = 0; kBin = 0; cout << "\n\n\nMáximo de intentos de Bernoulli: "; cin >> n; if((n < 0) || (n > 20)) { cout << "\nn debe estar entre 1 y 20 (inclusive)..."; cout << "\n\n"; continue; } for (;;) { // para que pueda ingresar el valor de p... cout << "\nIngrese el valor de la probabilidad de éxito: "; cin >> p; if ((p < 0) || (p > 1)) { cout << "\np está entre cero y uno (inclusive)..."; cout << "\n\n\n"; continue; } q = 1 - p; // probabilidad de fracaso... break; } // termina el for... // // // // realizo el cálculo de acuerdo a Bernoulli... for (i=1 ; i <= n ; i++) { x = double(rand()) / double(RAND_MAX); if (p >= x){ kBer++; } // endif } // end for // // // realizo el cálculo por Binomial... Efraı́n Soto A. // genero x Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 67 x = double(rand())/ double(RAND_MAX); // genero x prob = 0; // inicio la probabilidad acumulada de Bernoulli kBin = 0; // inicio el número de intentos... for(;;){ // for infinito... prob += double(permuta(n,kBin)) * pow(p,double(kBin)) * pow(q,double(n-kBin)); if (prob >= x) { break; } kBin++; } // // Muestro los resultados... cout << "\n\n\nIntentos con Bernoulli: " << kBer; cout << "\n\nIntentos con Binomial: " << kBin; cout << "\n\n\nTotal de errores: " << errores; // cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; } return 0; } /************************************** Declaro la función factorial... ***************************************/ int factorial(int n){ long fi,i; fi = i = 1; while (i <= n){ fi *=i; if (fi <= 0){ // por si se pasa la memoria... cout << "\nLo siento, se rebasó la memoria..."; fi = 1; errores++; break; } i++; } return fi; } /************************************** Declaro la función permuta... ***************************************/ int permuta(int n, int k){ int perm,subfactorial,i; i = n - k + 1; // n - k + 1 para calcular el subfactorial Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 68 Códigos subfactorial = 1; // reinicio el subfactorial while (i <= n){ subfactorial *= i; i++; } perm = subfactorial / factorial(k); return perm; } 2.5.4 Simulación 3 Desarrollar un programa por computadora que simule experimentos con distribución de Poisson. El programa debe repetir los intentos hasta que se supere un valor fijo p de éxito, definido por el usuario. El programa debe indicar al usuario cuántos intentos del experimento se requierieron para superar el valor de p. Se elaboró un programa que requiere de la siguiente información: 3 Valor de Lambda, que corresponde al promedio de la muestra. 3 El valor de la probabilidad de éxito, que corresponde al valor de p del evento a simular. El código en el lenguaje C++ se enlista en seguida. /* Nombre del archivo: simulacion03.cpp Descripción: Este programa simula experimentos con distribución de Poisson y probabilidad binomial. ------------------------------------------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Webpage: http://yalma.fime.uanl.mx/˜efrain/ Fecha de última Modificación: 03 de febrero de 2008 Lenguaje de Programación: C++ Compilador: Dev - C++ Versión 4.9.9.2. ------------------------------------------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output #include <stdlib.h> // para usar la función rand() Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 69 #include <math.h> // funciones matemáticas (pow (double)) #include <conio.h> // para usar: getche, getch #include <ctime> // clock_t = clock(); int errores; // variable global... int factorial(int n); int permuta(int n, int k); // using namespace std; int main(void){ char respuesta; int i, k; double p, prob, x, lambda; // cout << "\nEste programa simula experimentos con"; cout << "\ndistribucion de Poisson..."; // // // for (;;){ errores = 0; cout << "\n\n\nValor de Lambda (Promedio): "; cin >> lambda; if((lambda < 0)) { cout << "\nLambda debe ser un valor positivo...\n\n"; continue; } for (;;) { // para que pueda ingresar el valor de p... cout << "\nIngrese el valor de la probabilidad de éxito: "; cin >> p; if ((p < 0) || (p > 1)) { cout << "\np está entre cero y uno (inclusive)..."; cout << "\n\n\n"; continue; } break; } // termina el for... // // // realizo el cálculo de la probabilidad... srand(unsigned(time(0)));// Semilla para el aleatorio... x = double(rand())/ double(RAND_MAX); // genero x prob = 0; // inicio la probabilidad acumulada for(i = 0 ; prob <= x ; i++){ prob += exp(-lambda) * pow(lambda,i) / factorial(i); // } Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 70 Códigos // // Muestro los resultados... cout << "\n\n\nIntentos con Poisson: " << i-1; cout << "\n\n\nTotal de errores: " << errores; // cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; } return 0; } /************************************** Declaro la función factorial... ***************************************/ int factorial(int n){ long fi,i; fi = i = 1; while (i <= n){ fi *=i; if (fi <= 0){ // por si se pasa la memoria... cout << "\nLo siento, se rebasó la memoria..."; fi = 1; errores++; break; } i++; } return fi; } 2.5.5 Simulación 4 Desarrollar un programa por computadora que simule el lanzamiento de dos dados. El programa debe permitir al usuario indicar cuántos experimentos realizar y si desea o no ver los resultados de cada experimento. El programa debe imprimir en pantalla el promedio de la suma de todos los experimentos realizados. El código en el lenguaje C++ se enlista en seguida. /* Nombre del archivo: simulacion04.cpp Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 71 Descripción: Este programa simula el lanzamiento de dos dados... ------------------------------------------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Webpage: http://yalma.fime.uanl.mx/˜efrain/ Fecha de última Modificación: 08 de febrero de 2008 Lenguaje de Programación: C++ Compilador: Dev - C++ Versión 4.9.9.2. ------------------------------------------------------------------------------------------------------*/ #include <iostream> // Funciones básicas para input/output #include <stdlib.h> // para usar la función rand() #include <conio.h> // para usar: getche, getch #include <ctime> // clock_t = clock(); using namespace std; int main(void){ char respuesta,resp; int i, x, y, n; // variables aleatorias... int suma; double promedio; // cout << "\nEste programa simula el lanzamiento"; cout << "\nde dos dados..."; // // // for (;;){ // realizo el cálculo de la probabilidad... cout << "\n\n\n¿Cuántos lanzamientos deseas simular? "; cin >> n; cout << "\n\n\n¿Deseas ver los resultados? "; cin >> resp; srand(unsigned(time(0)));// Semilla para el aleatorio... suma = 0; // reinicio la suma de resultados... if ((resp == ’S’)||(resp == ’s’)){ cout << "\n\nSimulación "; cout << "\t\tDADO 1: "; cout << "\tDADO 2: "; cout << "\tSUMA: \n"; } for (i = 1 ; i <= n ; i++ ){ // x = (rand() % 6) + 1; y = (rand() % 6) + 1; // Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 72 Códigos suma += x+y; if ((resp == ’S’)||(resp == ’s’)){ // Muestro los resultados... cout << "\t" << i << "\t"; cout << "\t " << x << "\t"; cout << "\t " << y << "\t"; cout << "\t " << x+y << "\n\n"; } } promedio = double(suma) / double(i-1); cout << "\n\n\n Suma Promedio: " << promedio; // cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; } return 0; } 2.5.6 Simulacion 5 Elaborar un programa para simular experimentos con distribución de Poisson. La variable de dominio tiene una distribución exponencial y se compara con la distribución de Poisson con dominio en una variable aleatoria que presenta distribución uniforme. /* Nombre del archivo: simulacion05.cpp Descripción: Este programa simula experimentos con distribución de Poisson cuya variable de dominio tiene una distribución exponencial y compararla con la distribución de Poisson con dominio en una variable aleatoria con distribución uniforme. ------------------------------------------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Fecha de última Modificación: 03 de febrero de 2008 Lenguaje de Programación: C++ Compilador: Dev - C++ Versión 4.9.9.2. ------------------------------------------------------------------------------------------------------- Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas */ #include #include #include #include #include 73 <iostream> // Funciones básicas input/output <stdlib.h> // para la función rand() <math.h> // funciones matemáticas <conio.h> // para usar getche, getch <ctime> // clock(); int errores; // variable global... int factorial(int n); // función... using namespace std; int main(void){ char respuesta; int i, ipe, ip; double prob, probe, u, lambda, x; // for (;;){ cout << "\nEste programa simula experimentos con"; cout << "\ndistribucion de Poisson a partir de una"; cout << "\nvariable aleatoria con distribución exponencial..."; // // srand(unsigned(time(0)));// Semilla para el aleatorio... // Con distribución Poisson - Exponencial probe = 0; // inicio la probabilidad acumulada for(i = 0 ; probe <= 1 ; i++){ // calculo la probabilidad... u = double(rand())/ double(RAND_MAX); // genero x x = - log(1 - u) / u; // probe += exp(-x) * pow(x,i) / factorial(i); ipe = i; } // // Ahora realizo el cálculo con distribución uniforme... prob = 0; // inicio la probabilidad acumulada for(i = 0 ; prob <= 1 ; i++){ prob += exp(-lambda) * pow(lambda,i) / factorial(i); // } // // Muestro los resultados... cout << "\n\n\nIntentos con poisson exponencial: " << ipe; cout << "\n\n\nIntentos con poisson uniforme: " << i; cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; } Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 74 Códigos return 0; } /************************************** Declaro la función factorial... ***************************************/ int factorial(int n){ long fi,i; fi = i = 1; while (i <= n){ fi *=i; if (fi <= 0){ // por si se pasa la memoria... cout << "\nLo siento, se rebasó la memoria..."; fi = 1; errores++; break; } i++; } return fi; } 2.5.7 Simulacion 6 Elaborar un programa para simular la transformación inversa de la distribución normal, esto es, a partir del valor de u = Φ(x) calcula de manera aproximada x. El usuario indica el valor u que está en el intervalo (0,1) /* Nombre del archivo: simulacion06.cpp Descripción: Este programa simula transformación inversa de la distribución normal, esto es, a partir del valor de u = Phi(x) calcula de manera aproximada x. El usuario indica el valor u que está en el intervalo (0,1) ------------------------------------------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Fecha de última Modificación: 18 de febrero de 2008 Lenguaje de Programación: C++ Compilador: Dev - C++ Versión 4.9.9.2. ------------------------------------------------------------------------------------------------------*/ Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas #include #include #include #include #include 75 <iostream> // Funciones básicas input/output <stdlib.h> // para usar rand() <math.h> // funciones matemáticas <conio.h> // para usar getche, getch <ctime> // clock(); int errores; // variable global... double rfactorial(int n); // función... double normal(double x); // función... double intnormal(double x); const double pi = 3.141592653589; // global using namespace std; int main(void){ char respuesta; double x, xa, u, approx, approxa; double step, error, errorx; int j, total, cont, z; char signo; // para los dı́gitos... cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(8); // for (;;){ cout << "\nEste programa simula la generación de números"; cout << "\ncon distribucion normal a partir de un"; cout << "\nvalor dado por el usuario entre cero y uno..."; for (;;){ cout << "\n\n\ningresa un valor entre cero y 1: "; cin >> u; if (u < 0 && u > 1){ cout << "\nError en argumento..."; cout << "\n\n"; continue; } break; } // end for para pedir u // x = 0; // valor inicial supuesto (media) z = 0; if (u < 0.01){ step = u / 2; } else{ step = 0.25; } for (;;){ // xa = x; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 76 Códigos approx = normal(x); // Decido si incremento o decremento x while (approx < u){ x += step; approx = normal(x); z++; } step /= 1.5; while (approx > u){ x -= step; approx = normal(x); z++; } step /= 1.5; if (approx < 0.0001 && fabs(x) > 3.999){ x = u / 2; approx = normal(u); } // calculo el error relativo para x if (fabs(xa - x) < 0.0001){ // Criterio para salir del ciclo... cout << "\tu = " << u << "\tApprox = " << intnormal(x) << "\t x = " << x; break; } } // end for que hace las iteraciones... // cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir... } cout << "\n\n\n"; } // end for infinito... return 0; // Salir... } /************************************** Declaro la función normal... ***************************************/ double normal(double x){ double u = 0; double un, ua, temp; int i; if (x < -4){ return 0; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 77 if (x > 4){ return 1; } for (i = 0 ; i < 40 ; i++){ ua = u; u += pow(-0.5 * x * x,i) * rfactorial(i) / (2*i+1); un = u; } // endfor if (x < 0 ){ u = 0.5 - u * x / sqrt(2*pi); } else{ u = 0.5 + u * x / sqrt(2*pi); } return u; } /************************************** Declaro la función normal... ***************************************/ double intnormal(double x){ double u = 0; double ua, up, ac; double xi, step; // xi es la iteracion actual // step es el tamaño del paso... int i; step = 0.00000001; // El paso es 1 / 10ˆ7 xi = 0; // empieza a integrar desde cero... while (xi <= fabs(x)){ u += exp(- xi * xi / 2) * step; xi += step; } // endfor u = u / sqrt(2 * pi) + 0.5; if (x < 0 ){ return (u - 0.5); } else{ return u; } } /************************************** Declaro la función rfactorial... ***************************************/ double rfactorial(int n){ double fi, i; int j; fi = i = 1.0; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 78 Códigos j = 1; // while (j <= n){ fi /=i; i = i + 1; j++; } return fi; } 2.5.8 Simulacion 7 Programar un generador de números pseudoaleatorios con distribución normal por el método de aceptación - rechazo. /* Nombre del archivo: simulacion08.cpp Este programa simula la generación de números aleatorios con distribución normal por el método de aceptación - rechazo. ------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Fecha de última Modificación: 01 de marzo de 2008 ------------------------------------------------------------------*/ #include <cstdio> // #include <cstdlib> // #include <iostream> // Funciones básicas input/output #include <math.h> // funciones matemáticas #include <conio.h> // para usar getche, getch // Defino las funciones que voy a usar... double f(double y); double g(double y); // using namespace std; int main(void){ int i, total; char respuesta; double x, y, z, u; // el valor de c = 1.315489247, se calculó con: // const double c = sqrt(2 * 2.718281828 / 3.141592653); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 79 const double c = 1.315489247; // for (;;){ // for infinito... cout << "\nEste programa simula la generacion de numeros"; cout << "\ncon distribucion normal con el metodo de "; cout << "\naceptacion y rechazo..."; cout << "\n\nCuantos numeros desea generar... "; cin >> total; cout << "\n\n\n"; // un poco de espacio... for (i = 1; i<= total ; i++){ x = double(rand()) / double(RAND_MAX); // aleatorio z = double(rand()) / double(RAND_MAX); // aleatorio if (z < 0.5){ // genero el valor de y y = log(2 * z); } else{ y = - log(2 - 2 * z); } // x es el valor a comparar... // y es el argumento de las funciones... u = f(y) / (c * g(y)); if (u >= x){ // aceptar el valor... cout << "\n" << i << "\t----->\t" << y; } } cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; } // end for infinito... return 0; } /************************************* Defino la función f(y) **************************************/ double f(double y){ return 0.39894228 * exp(- y * y / 2) ; // el factor // 0.39894228 = 1 / sqrt(2 * 3.141592653); } /************************************* Defino la función g(y) **************************************/ double g(double y){ return exp(-fabs(y)) / 2; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 80 Códigos } 2.5.9 Simulacion 8 Elaborar un programa para simular un movimiento browniano • Puede encontrar un PDF con una animación de los resultados generados por este programa en: http://yalma.fime.uanl.mx/~efrain/project.html /* Nombre del archivo: simulacion08.cpp Este programa simula un movimiento browniano. ------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Fecha de última Modificación: 01 de marzo de 2008 ------------------------------------------------------------------*/ #include <cstdio> // #include <cstdlib> // #include <iostream> // Funciones básicas input/output #include <math.h> // funciones matemáticas #include <conio.h> // para usar getche, getch #include <fstream> // para grabar los datos generados... // const double PI = 3.141592653; double step; // función para generar los números pseudoaleatorios // con distribución normal... double dnormal(double media, double sigma); double dnormal(void); // Función para generar un número pseudoaleatorio // con distribución uniforme en el intervalo (0,1) double uniforme(void); using namespace std; int main(void){ char respuesta, semilla; double t, tiempo; // escala de tiempo. double xn, x = 0; // posición de la partı́cula. double media, sigma; // parámetros de dist. Normal. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 81 int i = 0; // for (;;){ // for infinito... cout << "\nEste programa simula un "; cout << "movimiento browniano "; cout << "\n\nTiempo en segundos a simular: "; cin >> tiempo; for (;;){ cout << "\nIntervalo entre dos posiciones consecutivas (seg): "; cin >> step; if (step <= 0){ cout << "\n\nEl intervalo debe ser positivo..."; cout << "\nPreferentemente menor a un segundo."; cout << "\nValor sugerido: 0.05"; } else{ // ingresó un step positivo... break; cout << "\n\n\n"; } } // end for... // No requiero los siguientes renglones porque // se definió el problema con media cero... cout << "\nMedia de la posicion de la partı́cula: (sobre el eje x)"; cout << "\n(Presione 0 (cero) si la desconoce): "; cin >> media; cout << "\n\nDesviacion estandar de la posicion..."; cout << "\n(Presione 0 si la desconoce): "; cin >> sigma; if (sigma == 0){ sigma = 1; } for (;;){ // hasta que presione S ó N cout << "\n\nDesea iniciar la semilla?"; cout << "\n(del generador de numeros aleatorios) [S/N]"; cin >> semilla; if (semilla == ’S’ || semilla == ’s’){ srand(unsigned(time(0))); cout << "\n\nSe reinicia la semilla..."; break; // salir del for infinito } if (semilla == ’N’ || semilla == ’n’){ cout << "\n\nNo se reinicia la semilla..."; break; // salir del for infinito } cout << "\n\nError en argumento..."; } // end for infinito para la semilla cout << "\n\n\n"; // un poco de espacio... t = 0; // reinicio el tiempo del experimento... Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 82 Códigos ofstream out_stream; // creo canal p/escritura de datos... out_stream.open("brown.txt"); // creo y abro el archivo... if (out_stream.fail()){ // si no puede abrir el archivo... cout << "\n\nNo se pudo abrir el archivo..."; cout << "\nPor favor, reinicie el programa..."; exit(1); // Termina el programa } out_stream << "\n"; out_stream << "# Simulacion de un movimiento Browniano" << "\n"; out_stream << "# el eje t representa al tiempo" << "\n"; out_stream << "# y el eje x (vertical) representa la posicion..." << "\n"; out_stream << "# Los datos van desde t = 0 hasta t = " << tiempo << ".\n"; out_stream << "0 0 i\n"; // Primer dato... for (t = step; t <= tiempo ; t += step){ x += dnormal(); out_stream << t << " " << x << " i\n"; i++; } cout << "\n\n\nSe han grabado " << i << " datos en el archivo"; cout << "\nbrown.txt\n"; out_stream << "# Este archivo contiene " << i << " datos."; // pregunto si desea salir... cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; } // end for infinito... return 0; } /************************************** Declaro la función DNORMAL... ***************************************/ double dnormal(double media, double sigma){ /* Esta función genera números pseudoaleatorios con distribución uniforme a partir de su media y su desviación estándar. */ double u, v, x, y, z; u = uniforme(); y = uniforme(); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 83 x = sqrt(-2 * log(u)) * cos(2 * PI * y); if (u >= 0.5){ z = media + sigma * step * x; } else{ z = media - sigma * step * x; } return z; // step se utiliza porque el problema define // que la varianza es proporcional al intervalo de tiempo. } /************************************** Declaro la función DNORMAL... ***************************************/ double dnormal(void){ /* Esta función genera números pseudoaleatorios con distribución uniforme. */ double u, x, y, z; // Defino la media y desviación estándar... double media = 0, sigma = 1; u = uniforme(); y = uniforme(); x = sqrt(-2 * log(u)) * cos(2 * PI * y); if (u >= 0.5){ z = media + sigma * step * x; } else{ z = media - sigma * step * x; } return z; // step se utiliza porque el problema define // que la varianza es proporcional al intervalo de tiempo. } /************************************** Declaro la función UNIFORME... ***************************************/ double uniforme(void){ // Esta función genera un número pseudoaleatorio // con distribución uniforme en el intervalo (0,1). return (double(rand())/double(RAND_MAX)); } Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 84 Códigos 2.5.10 Simulación de la distribución binomial Utilizando ANSI-C y las funciones de generación de números pseudoaleatorios, escribe un programa que por simulación y la ley de grandes números aproxima la distribución binomial con n y p para todos los valores de k = 0, 1, 2, · · · , n. Incluye en tu respuesta el código que escribiste junto con un dibujo preparado con gnuplot de la distribucion Bin(n, p) con los valores definidos para n y p. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 /* Tarea 3. Nombre del archivo: tres.c Utilizando ANSI-C y las funciones de generacion de numeros pseudoaleatorios, escribe un programa que por simulacion y la ley de numeros grandes aproxima la distribucion binomial con n y p para todos los valores de k = 0, 1, 2, . . . , n. Incluye en tu respuesta el codigo que escribiste junto con un dibujo preparado con gnuplot de la distribucion Bin(n, p) con los valores definidos para n y p. Autor: Efrain Soto Apolinar. fecha de ultima modificacion: 15 de agosto de 2008 */ #include <stdio.h> #include <math.h> #include <stdlib.h> int combinaciones(int m, int k); float binomial(double p, int N, int k); void bernoulli(int n, double p, int N); float uniforme(void); int main(int argc, char** args) { char letra; int n, k, N = 15; int i, j; // contadores double p = 0.4; float resp; printf("\nEste programa simula un proceso"); printf("\nbinomial por la ley de los grandes numeros"); printf("\n\nparametro p = 0.4"); printf("\n\nparametro N = 15"); printf("\nIntroduce el numero de simulaciones:"); scanf("%i", &n); // La simulacion es: bernoulli(n, p, N); printf("\n\nValores teoricos:\n"); for(i = 0 ; i < 16 ; i++){ printf("\nk = %i, p = %f,", i, binomial(p,N,i)); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 85 } printf("\n\n"); printf("\nPresiona una tecla..."); scanf("%c", &letra); return 0; } /*----------------------------------------------Funcion para calcular las combinaciones -------------------------------------------------*/ int combinaciones(int m, int k){ int i; // contador long int num = 1; long int den = 1; int r = 1; // resultado for(i = 0 ; i < k ; i++){ num = num * (m - i); den = den * (i + 1); // simplifico para que no crezca rapido... while(num % 2 == 0 && den % 2 == 0){ num /= 2; den /= 2; } while(num % 3 == 0 && den % 3 == 0){ num /= 3; den /= 3; } while(num % 5 == 0 && den % 5 == 0){ num /= 5; den /= 5; } } r = num / den; return r; } 74 75 76 77 78 79 80 81 82 83 /*----------------------------------------------Funcion para calcular la probabilidad binomial -------------------------------------------------*/ float binomial(double p, int N, int k){ int i; // contador float r; // respuesta r = (int)(combinaciones(N,k)) * pow(p,k) * pow(1-p,N-k); return r; } 84 85 86 87 88 89 /*----------------------------------------------Funcion para el proceso de Bernoulli... Voy a realizar n exprimentos de Bernoulli p = probabilidad de exito N = numero de ensayos por experimento Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 86 Códigos 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 n = numero de experimentos -------------------------------------------------*/ void bernoulli(int n, double p, int N){ int arreglo[16]; // cuenta int i, j, c; // contadores int tote; // total de exitos float u; // reinicio el arreglo for(c = 0 ; c < 16 ; c++){ arreglo[c] = 0; } // Vienen los n ensayos de Bernoulli for(i = 1 ; i <= n ; i++){ tote = 0; // reinicio total exitos for(j = 0 ; j <= N ; j++){ u = uniforme(); // pseudo-uniforme (0,1) if (u <= p){ // exito tote++; } 109 } arreglo[tote]++; 110 111 } // Imprimo los resultados... printf("\n\nResultados de la simulacion:\n"); for (c = 0 ; c < 16 ; c++){ printf("\nk = %i, p = %f,", c, 1.0 * arreglo[c]/n); } 112 113 114 115 116 117 118 } 119 120 121 122 123 124 125 126 127 /*----------------------------------------------Funcion para generar uniformes (0,1) -------------------------------------------------*/ float uniforme(void){ float u; u = (float)(rand()) / RAND_MAX; return u; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.5 Mis tareas 2.5.11 87 Introducción a la dinámica de poblaciones 1. Definir estado inicial N (población inicial) 2. Probabilidad de un nacimiento sin muerte p (homogenea) 3. Probabilida de una muerte sin nacimiento q (homogenea) 4. Probabilidad de mantener el mismo estado 1 − p − q 3 Observar el desarrollo del tamaño de la población sobre varias repeticiones del proceso. 3 Variar los valores de p y q. 1 2 3 /* Simulacion de la dinamica de poblaciones Fecha: 19 de agosto de 2008 4 5 6 7 8 9 Caso discreto. Definir estado inicial N (poblacion inicial) Probabilidad de un nacimiento sin muerte p (homogenea) Probabilida de una muerte sin nacimiento q (homogenea) Probabilidad de mantener el mismo estado 1 - p - q 10 11 12 13 14 15 16 Observar el desarrollo del tamaño de la poblacion sobre varias repeticiones del proceso */ #include <stdlib.h> #include <stdio.h> #include <math.h> 17 18 double uniforme(void); 19 20 21 22 23 24 25 26 27 int main(int argc, char** args){ int i = 0; // contadores double p = 0.45; // probabilidad de nuevo nacimiento double q = 0.45; // probabilidad de muerte double eq = 1 - p - q; // probabilidad de quedar igual double r; // numero aleatorio int N = 10000; // poblacion inicial int MAXP = 10 * N; // poblacion final 28 29 30 31 32 33 // para el manejo del archivo... FILE *stream_f; // stream_f = fopen("datos.txt", "w"); // abrir para lectura if (stream_f == NULL){ printf ("\nNo se puede abrir el archivo <<datos.txt>>\n"); Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 88 Códigos printf("\nPor favor, verifique el nombre archivo"); } srand(unsigned(time(0))); printf("\nEspere por favor...\n"); printf("\nSimulando dinamica de la poblacion..."); while (N > 0 && N < MAXP){ r = uniforme(); if (r <= p){ // Felicidades! nacio un changuito N++; } if (r > p && r <= p + q){ // Desgracia, un changuito fue devorado N--; } //if (r > p + q){ // Nadie nacio... // Nadie murio... //} printf("\nt = %i \tN = %i",i, N); // guardo en archivo... if(i % 25 == 0){ fprintf(stream_f, "\n%i \t%i",i, N); } i++; if (i > 10000){ break; } } fclose(stream_f); printf("\nSimulacion exitosa..."); return 0; 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 } 67 68 69 70 71 72 73 74 75 /*----------------------------------------------Funcion para generar uniformes (0,1) -------------------------------------------------*/ double uniforme(void){ double u; u = 1.0 * rand() / RAND_MAX; return u; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.6 Proyectos 2.6 89 Proyectos En esta sección encontrarás códigos de problemas que he resuelto para incrementar mi biblioteca de programas. Espero que sean de ayuda para ti. 2.6.1 Regresión lineal /* Nombre del archivo: LR.cpp Este programa pide las coordenadas (x,y) de n puntos y los graba en un archivo. Después lee estos datos y calcula la recta de mejor ajuste por el método de mı́nimos cuadrados. ------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Fecha de última Modificación: 21 de marzo de 2008 ------------------------------------------------------------------*/ #include <cstdio> // #include <cstdlib> // #include <iostream> // Funciones básicas input/output #include <math.h> // funciones matemáticas #include <conio.h> // para usar: getche, getch #include <fstream> // para grabar datos generados... // using namespace std; int main(void){ char respuesta, letra; // char file_name[15]; int i, j, n; // contadores double b, m; // parámetros... double xi, yi; // datos double Sx, Sy, Sxs, Sxy; // sumas de datos... for(;;){ // for infinito... Sx = 0; Sy = 0; Sxs = 0; Sxy = 0; // Información sobre el programa... cout << "\n\nEste programa pide un grupo de datos "; cout << "\nque corresponden a las coordenadas de n"; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 90 Códigos cout << "\npuntos en el plano, guarda esta información"; cout << "\nen un archivo y después lee esa información"; cout << "\npara encontrar la recta de regresión"; cout << "\n\n\nPor favor, introduce las coordenadas de "; cout << "\nlos puntos conocidos, ingresando primero"; cout << "\nlacoordenada en x y después la coordenada en y"; cout << "\nCuando hayas terminado introduce el número "; cout << "\n1 000 000, pero sin espacios."; ifstream in_stream; ofstream out_stream; // cout << "\nNombre del archivo: "; // cin >> file_name; //out_stream.open(file_name); // creo y abro el archivo... // out_stream.open("LR.txt"); // creo y abro el archivo... if (out_stream.fail()){ // si no puede abrir el archivo... cout << "\n\nNo se pudo abrir el archivo..."; cout << "\nPor favor, reinicie el programa..."; exit(1); // Termina el programa } for (i = 1 ; ; i++){ cout << "\nCoordenada en x del punto " << i << ": "; cin >> xi; if (xi == 1000000){ cout << "\n\n\nEl último valor no se incluye en los datos..."; out_stream.close();// Cierro el archivo... cout << "\nLos datos se han grabado correctamente..."; cout << "\n\nProcesando información..."; n = i - 1; // Número total de datos... break; } cout << "\nCoordenada en y del punto " << i << ": "; cin >> yi; if (yi == 1000000){ cout << "\n\n\nEl último valor no se incluye en los datos..."; out_stream.close();// Cierro el archivo... cout << "\nLos datos se han grabado correctamente..."; cout << "\n\nProcesando información..."; n = i - 1; // número total de datos... break; } out_stream << xi << " " << yi << " i\n"; cout << "Dato " << i << " grabado correctamente"; cout << "\n"; } // Termino de grabar la información... // Abrimos el archivo para leer... in_stream.open("LR.txt"); if (in_stream.fail()){// si no puede abrir el archivo... Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.6 Proyectos 91 cout << "\n\nNo se pudo abrir el archivo..."; cout << "\nPor favor, reinicie el programa..."; exit(1); // Termina el programa } for (j=1; j <= n ; j++){ // realizo cálculos... in_stream >> xi >> yi; do { // estoy buscando el siguiente renglón in_stream >> letra; } while (!letra == ’\n’); // Sx += xi; // Suma de x Sy += yi; // Suma de y Sxy += xi * yi; // Suma de xy Sxs += xi * xi; // Suma de x cuadrada } // Cierro el archivo de lectura... in_stream.close(); // Calculo los parámetros... m = (n * Sxy - Sx * Sy) / (n * Sxs - Sx * Sx); b = (Sy - m * Sx) / n; // Muestro los resultados... cout << "\n\n\n"; // espacio cout << "La recta de mejor ajuste es: \n"; cout << "\n y = " << b << " + " << m << " x."; // pregunto si desea salir... cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; } // end for infinito... return 0; } 2.6.2 Regresión cuadrática /* Nombre del archivo:CR.cpp Este programa pide las coordenadas (x,y) de n puntos y los graba en un archivo. Después lee estos datos y calcula: a) la recta demejor ajuste, la cual se expresa como: y = beta + mx b) La parábola de mejor ajuste, que se expresa como: y = axˆ2 + bx + c Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 92 Códigos ambos por el método de mı́nimos cuadrados. ------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Fecha de última Modificación: 21 de marzo de 2008 ------------------------------------------------------------------*/ #include <cstdio> // #include <cstdlib> // #include <iostream> // Funciones básicas input/output #include <conio.h> // para usar getche, getch #include <fstream> // para grabar los datos generados... // using namespace std; int main(void){ char respuesta, letra; // char file_name[15]; int i, j, n; // contadores double a, b, c; // parámetros para parábola... double m, beta; // parámetros para recta... double Da = 0, Dp = 0; double xi, yi; // datos double Sx, Sy, Sx2, Sx3, Sx4, Sxy, Sx2y; double Error_p = 0, Error_r = 0; double dip, dir, y_approxp, y_approxr; for(;;){ // for infinito... Sx = 0; Sy = 0; Sxy = 0; Sx2 = 0; Sx3 = 0; Sx4 = 0; Sx2y = 0; // Información sobre el programa... cout << "\n\nEste programa pide un grupo de datos "; cout << "\nque corresponden a las coordenadas de n"; cout << "\npuntos en el plano, guarda esta información"; cout << "\nen un archivo y después lee esa información"; cout << "\npara encontrar la parábola de regresión"; cout << "\n\n\nPor favor, introduce las coordenadas de "; cout << "\nlos puntos conocidos, ingresando primero"; cout << "\nlacoordenada en x y después la coordenada en y"; cout << "\nCuando hayas terminado introduce el número "; cout << "\n1 000 000, pero sin espacios."; ifstream in_stream; ofstream out_stream; // cout << "\nNombre del archivo: "; // cin >> file_name; //out_stream.open(file_name); // creo y abro el archivo... // out_stream.open("CR.txt"); // creo y abro el archivo... Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.6 Proyectos 93 if (out_stream.fail()){ // si no puede abrir el archivo... cout << "\n\nNo se pudo abrir el archivo..."; cout << "\nPor favor, reinicie el programa..."; exit(1); // Termina el programa } for (i = 1 ; ; i++){ cout << "\nCoordenada en x del punto " << i << ": "; cin >> xi; if (xi == 1000000){ cout << "\n\n\nEl último valor no se incluye en los datos..."; out_stream.close();// Cierro el archivo... cout << "\nLos datos se han grabado correctamente..."; cout << "\n\nProcesando información..."; n = i - 1; // Número total de datos... break; } cout << "\nCoordenada en y del punto " << i << ": "; cin >> yi; if (yi == 1000000){ cout << "\n\n\nEl último valor no se incluye en los datos..."; out_stream.close();// Cierro el archivo... cout << "\nLos datos se han grabado correctamente..."; cout << "\n\nProcesando información..."; n = i - 1; // número total de datos... break; } out_stream << xi << " " << yi << " i\n"; cout << "Dato " << i << " grabado correctamente"; cout << "\n"; } // Termino de grabar la información... // Abrimos el archivo para leer... in_stream.open("CR.txt"); if (in_stream.fail()){ // si no abrir el archivo... cout << "\n\nNo se pudo abrir el archivo..."; cout << "\nPor favor, reinicie el programa..."; exit(1); // Termina el programa } for (j = 1; j <= n ; j++){ // realizo cálculos... in_stream >> xi >> yi; do { // estoy buscando el siguiente renglón in_stream >> letra; } while (!letra == ’\n’); // Sx += xi; // Suma de x Sy += yi; // Suma de y Sxy += xi * yi; // Suma de xy Sx2 += xi * xi; // Suma de x cuadrada Sx3 += xi * xi * xi; // Suma de x cúbica Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 94 Códigos Sx4 += xi * xi * xi * xi; // Suma x cuarta Sx2y += xi * xi * yi; } // Cierro el archivo de lectura... in_stream.close(); // Calculo parámetros de recta... m = (n * Sxy - Sx * Sy) / (n * Sx2 - Sx * Sx); beta = (Sy - m * Sx) / n; // Calculo los parámetros de parábola... Da = Sy * Sx2 * Sx2 + n * Sxy * Sx3 + Sx * Sx * Sx2y; Da = Da - n * Sx2 * Sx2y - Sx * Sx3 * Sy - Sx * Sxy * Sx2; Dp = Sx2 * Sx2 * Sx2 + n * Sx3 * Sx3 + Sx4 * Sx * Sx; Dp = Dp - n * Sx2 * Sx4 - 2 * Sx * Sx2 * Sx3; a = Da / Dp; b = (Sx * (Sy - a * Sx2) - n * (Sxy - a * Sx3)) / (Sx * Sx - n * Sx2); c = (Sy - a * Sx2 - b * Sx) / n; // Muestro los resultados... cout << "\n\n\n"; // espacio cout << "La recta de mejor ajuste es: \n"; cout << "\n y = " << beta << " + " << m << " x "; cout << "\n\n\n"; // espacio cout << "La parábola de mejor ajuste es: \n"; cout << "\n y = " << a << " xˆ2 + " << b << " x + " << c; cout << "\n\n\n"; // // // Vuelvo a abrir el archivo... in_stream.open("CR.txt"); if (in_stream.fail()){ // si no puede abrir el archivo... cout << "\n\nNo se pudo abrir el archivo..."; cout << "\nPor favor, reinicie el programa..."; exit(1); // Termina el programa } for (j = 1; j <= n ; j++){ // realizo cálculos... in_stream >> xi >> yi; do { // estoy buscando el siguiente renglón in_stream >> letra; } while (!letra == ’\n’); // // calculo el pronóstico con parábola de regresión... y_approxp = a * xi * xi + b * xi + c; y_approxr = beta + m * xi; // discrepancia... dip = (yi - y_approxp) * (yi - y_approxp); dir = (yi - y_approxr) * (yi - y_approxr); Error_p += dip; // Error total Error_r += dir; } Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.6 Proyectos 95 // Cierro el archivo de lectura... in_stream.close(); cout << "\n\n\n"; // espacio cout << "\nError total para la recta: " << Error_r; cout << "\nError total para la parábola: " << Error_p; // // // cout << "\n\n\n"; // espacio cout << "Generando datos de la parábola de mejor ajuste..."; // creo y abro el archivo... // pma = parábola de mejor ajuste. out_stream.open("pma.txt"); if (out_stream.fail()){ // si no puede abrir el archivo... cout << "\n\nNo se pudo abrir el archivo..."; cout << "\nPor favor, reinicie el programa..."; exit(1); // Termina el programa } // Reinicio las coordenadas... xi = 0; yi = 0; for (i = 0 ; i <= 100 ; i++){ yi = a * xi * xi + b * xi + c; // grabamos los datos en el archivo... out_stream << xi << " " << yi << " i\n"; xi = xi + 0.07; } cout << "\n\n\nSe han grabado 100 datos en el intervalo"; cout << "\n(0,7) en el archivo <<pma.txt>>"; out_stream.close();// Cierro el archivo... // pregunto si desea salir... cout << "\n\n\nPresione < S > para salir..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; } // end for infinito... return 0; } Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 96 Códigos 2.7 Librerı́a Estadı́stica Crear una librerı́a con funciones estadı́sticas básicas para utilizar durante los siguientes semestres de la maestrı́a. • Media / Desviación estándar / Varianza • Moda (intervalo de mayor frecuencia) • Graficar el histograma de frecuencias • Generadores de números pseudoalestorios con las siguientes distribuciones: 3 Uniforme en el intervalo (0,1), 3 Uniforme en el intervalo (a, b), definido por el usuario, 3 Normal con media 0.0 y desviación estándar 1.0, 3 Normal con media µ y desviación estándar σ, definidas por el usuario, 3 Exponencial con parámetro λ, definido por el usuario, 3 Weibull con parámetros de forma c y de escala k, definidos por el usuario, 3 Rayleigh con media µ, definida por el usuario. La librerı́a se codificará de manera que se pueda utilizar en el lenguaje C++ , con posibilidad de adaptarla al lenguaje ANSI-C. 2.8 Implementación Puede accesar al archivo estadistica.h con un clı́c derecho y elija Open File en el siguiente ı́cono : . O bien, con doble clı́c sobre el mismo. A continuación está el código del mismo archivo. 1 2 3 4 5 /* Nombre del archivo: "estadistica.h" Descripción: Este archivo contiene funciones y clases para trabajar con cuestiones de probabilidad. 6 7 8 Las funciones se detallan con comentarios en el código. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 97 9 10 11 Fecha de última Modificación: 02 de junio de 2008. 12 13 14 15 16 17 18 19 20 21 BIBLIOGRAFÍA CONSULTADA: ----------------------------------------CUESTIONES DE ESTADÍSTICA... ----------------------------------------[1] Jerry Banks, John S. Carson II, Barry L. Nelson. Discrete-Event System Simulation. Ed. Prentice Hall. 2nd Edition. 1996. U.S.A. 22 23 24 25 26 27 [2] John E. Freund Mathematical Statistics Ed. Prentice Hall 5th Edition. 1992. U.S.A. 28 29 30 31 32 33 34 35 ----------------------------------------CUESTIONES DE PROGRAMACIÓN... ----------------------------------------[1] Walter Savitch Problem Solving with C++: The Object of Programming Ed. Addison Wesley Longmann Inc. U.S.A. 1999. 36 37 38 39 40 41 [2] Edward Scheinerman C++ for Mathematicians An Introduction for Students and Professionals Ed. Chapman & Hall/CRC 2006. U.S.A. 42 43 44 45 46 47 [3] Herbert Schildt C++: The Complete Reference Third Edition Ed. McGraw-Hill 1998. U.S.A. 48 49 50 51 52 53 54 ----------------------------------------Sitios de Internet Consultados... ----------------------------------------- Algoritmo para generar números pseudoaleatorios con distribución Rayleigh: http://www.brighton-webs.co.uk/distributions/rayleigh.asp 55 56 */ 57 58 #ifndef PROBABILITY_H Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 98 Códigos 59 #define PROBABILITY_H 60 61 62 63 64 65 66 67 #include #include #include #include #include #include #include <math.h> <time.h> <stdlib.h> <stdio.h> <wchar.h> <ctype.h> <assert.h> 68 69 70 71 const double PI = 3.141592654; const long PROBABILITY_RAND_MAX = 2147483647;// = 2ˆ31 - 1; 72 73 74 75 76 77 78 79 // Declaro las funciones... void suniforme(unsigned seed); double uniforme(void); double uniforme(float a, float b); void funiforme(int N, char filename[]); void funiforme(int N, float a, float b, char filename[]); double lpuniforme(void); 80 81 82 83 84 85 86 87 //double triangular(double media); double normal(void); double normal(double media, double desviacionStd); void fnormal(int N, char filename[]); void fnormal(int N, char filename[], double media, double desvStd); void errorDNormal(void); 88 89 90 double weibull(double c, double k); void fweibull(int N, double C, double K, char filename[]); 91 92 93 float exponencial(float lambda); void fexponencial(int N, float Lambda, char filename[]); 94 95 96 97 98 int geometrica(float p); void fgeometrica(int N, float p, char filename[]); int poisson(float alpha); void fpoisson(int N, float a, char filename[]); 99 100 101 102 double rayleigh(float media); void frayleigh(int N, char filename[], float M); void ftriangular(int N, char filename[], float media); 103 104 105 double media(char filename[]); double desviacionStd(char filename[]); 106 107 108 double media(char filename[]); double desviacionStd(char filename[]); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 99 109 110 111 112 void histograma(char filename[]); void histograma(char filename[], int No_Int); //hist Phistograma(char filename[], int No_Int); 113 114 void PchiUniforme(char filename[], int Num_Int, float alpha); 115 116 117 118 119 120 121 122 123 124 125 126 127 128 /*************************************************** double uniforme(void) Descripción: Esta función genera un número pseudo-aleatorio con distribución uniforme en el intervalo (0,1). BUGS: Ninguno conocido... ****************************************************/ double uniforme(void){/*** [tested] ***/ double u; u = (double)(rand()) / (double)(RAND_MAX); return u; } 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 /*************************************************** double uniforme(float a, float b) Descripción: Esta función genera un número pseudo-aleatorio con distribución uniforme en el intervalo (a,b). ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ****************************************************/ double uniforme(float a, float b){/*** [tested] ***/ double x; x = (double)(a) + uniforme() * (double)(b - a); return x; } 146 147 148 149 150 151 152 153 154 155 156 157 158 /*************************************************** void funiforme(int N, char filename[15]) Descripción: Esta función guarda N números pseudoaleatorios con distribución uniforme en el intervalo (0,1) en el archivo con nombre <<filename>>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido. ****************************************************/ void funiforme(int N, char filename[15]){/*** [tested] ***/ float x; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 100 Códigos FILE *stream_unif; // stream_unif = fopen(filename, "w"); // abrir archivo if (stream_unif == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_unif, "# Este archivo contiene %i números\n", N); fprintf(stream_unif, "# pseudoaletorios con distribucion uniforme\n"); fprintf(stream_unif, "# en el intervalo [0.0, 1.0]\n"); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = uniforme(); // generamos un número fprintf(stream_unif, "%f\n", x); // grabamos... } fclose(stream_unif); // cerrar archivo... 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 } 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 /*************************************************** void funiforme(int N, char filename[], float a, float b) Descripción: Esta función guarda N números pseudoaleatorios con distribución uniforme en el intervalo (a,b) en el archivo con nombre <<filename>>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido. ****************************************************/ void funiforme(int N, char filename[], float a, float b){ /*** [tested] ***/ float x; FILE *stream_unif; // stream_unif = fopen(filename, "w"); // abrir archivo if (stream_unif == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_unif, "# Este archivo contiene %i números\n", N); fprintf(stream_unif, "# pseudoaletorios con distribucion uniforme\n"); fprintf(stream_unif, "# en el intervalo [%.3f,%.3f]\n", a, b); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación x = uniforme(a, b); // generamos un número fprintf(stream_unif, "%f\n", x); // grabamos... 209 210 } 211 fclose(stream_unif); // cerrar archivo... 212 213 101 } 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 /*************************************************** double lpuniforme(void) Descripción: Esta función genera números pseudoaleatorios con distribución normal con media 0.0 y desviación estándar 1.0. ///////////////////////////////////////////////////// BUGS: * Este generador de números seudoaleatorios solamente ha sido probado dibujando histogramas y parece presentar distribución uniforme. NO se ha sometido a ninguna prueba estadı́stica formal. * Se sugiere utilizar para requerimientos de grandes cantidades de números pseudoaleatorios. * Cuando se utiliza para generar números pseudoaleatorios con distribución normal el histograma aparece con sesgo negativo (corrido hacia la derecha). [Instancia de 10,000 números generados] ****************************************************/ double lpuniforme(void){ double u; int primo1 = 8191; // = 2ˆ13 - 1; Número primo int primo2 = 524287; // = 2ˆ19 - 1; Otro número primo static int semilla = 1001; // es primo... static bool first = true; if (first){ first = false; return ((double)(semilla)/((double) (PROBABILITY_RAND_MAX))); } unsigned modular = semilla; // modular = (primo1 * modular + primo2) % PROBABILITY_RAND_MAX; semilla = modular; // cambio el valor de la semilla... // calculo el valor que me va a devolver... u = (double)(modular) / ((double) (PROBABILITY_RAND_MAX)); return (u); } 258 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 102 Códigos 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 /*************************************************** double normal(void) Descripción: Esta función genera números pseudoaleatorios con distribución normal con media 0.0 y desviación estándar 1.0. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ****************************************************/ double normal(void){/*** [tested] ***/ double media = 0.0, desviacionStd = 1.0; double u, x, v, z; u = uniforme(); v = uniforme(); x = sqrt(-2 * log(u)) * cos(2 * PI * v); if (u >= 0.5){ z = media + desviacionStd * x; } else{ z = media - desviacionStd * x; } return z; } 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 /*************************************************** double normal(double media, double desviacionStd) Descripción: Esta función genera números pseudoaleatorios con distribución normal con media << media >> y desviación estándar << desviacionStd >> ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ****************************************************/ double normal(double media, double desviacionStd){ /*** [tested] ***/ if (desviacionStd <= 0){ errorDNormal(); return 0.0; } double u, x, v, z; u = uniforme(); v = uniforme(); x = sqrt(-2 * log(u)) * cos(2 * PI * v); if (u >= 0.5){ z = media + desviacionStd * x; } else{ z = media - desviacionStd * x; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación } return z; 309 310 311 103 } 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 /*************************************************** void fnormal(int N, char filename[15]) Descripción: Esta función guarda N números pseudoaleatorios con distribución normal con media 0.0 y desviacion estándar 1.0 en el archivo con nombre <<filename>>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ****************************************************/ void fnormal(int N, char filename[]){/*** [tested] ***/ double x; FILE *stream_normal; // stream_normal = fopen(filename, "w"); // abrir archivo if (stream_normal == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_normal, "# Este archivo contiene %i números\n", N); fprintf(stream_normal, "# pseudoaletorios con distribucion normal\n"); fprintf(stream_normal, "# con media = 0.0 y desviacion estandar = 1.0\n"); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = normal(); // generamos un número fprintf(stream_normal, "%f\n", x); // grabamos... } fprintf(stream_normal, "\n# Fin del archivo...\n"); fclose(stream_normal); // cerrar archivo... } /********************************************** void fnormal(int N, char filename[], float med, float desvStd) Descripción: Esta función guarda N números pseudoaleatorios con distribución normal con media << med >> y desviacion estándar << desvStd >> en el archivo de nombre <<filename>>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... **********************************************/ Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 104 Códigos 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 void fnormal(int N, char filename[], float med, float desvStd){ /*** [tested] ***/ if (desviacionStd <= 0){ errorDNormal(); return; } double x; FILE *stream_normal; // stream_normal = fopen(filename, "w"); // abrir archivo if (stream_normal == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_normal, "# Este archivo contiene %i números\n", N); fprintf(stream_normal, "# pseudoaletorios con distribucion normal\n"); fprintf(stream_normal, "# con media = %.3f y desviacion estándar = %.3f.\n", med, desvStd); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = normal(med, desvStd); // generamos un número fprintf(stream_normal, "%f\n", x); // grabamos... } fprintf(stream_normal, "\n# Fin del archivo...\n"); fclose(stream_normal); // cerrar archivo... return; } 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 /*************************************************** double lnormal(void) Descripción: Esta función genera números pseudoaleatorios con distribución normal con media 0.0 y desviación estándar 1.0. ///////////////////////////////////////////////////// BUGS: Esta función genera números que presentan un sesgo hacia la derecha cuando se grafican su histograma de frecuencias. Sin embargo, los calculos de media y desciación estándar están cercanos a 0.0 y 1.0, respectivamente. ****************************************************/ double lnormal(void){/*** [tested] ***/ double media = 0.0, desviacionStd = 1.0; double u, x, v, z; u = lpuniforme(); v = lpuniforme(); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación x = sqrt(-2 * log(u)) * cos(2 * PI * v); if (u >= 0.5){ z = media + desviacionStd * x; } else{ z = media - desviacionStd * x; } return z; 409 410 411 412 413 414 415 416 417 105 } 418 419 420 421 422 423 424 425 426 427 428 429 430 void errorDNormal(void){ // Imposible generar número // con distribución normal ası́... printf("\n\nError en el segundo argumento de función:"); printf("\ndouble normal(double media, double desviacionStd)"); printf("\ndesviacionStd debe ser un número positivo..."); printf("\nPor favor corrija el valor..."); return; } 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 /************************************** float exponencial(float lambda) Descripción: Esta función genera números pseudoaleatorios con distribución exponencial de parámetro lambda. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ float exponencial(float lambda){/*** [tested] ***/ double x; x = -log(1 - uniforme()) / lambda; return x; } 447 448 449 450 451 452 453 454 455 456 457 458 /************************************** void fexponencial(int N, float Lambda, char filename[15]) Descripción: Esta función genera N números pseudoaleatorios con distribución exponencial, con parámetro << Lambda >>, y los graba en el archivo de nombre << filename >> ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 106 Códigos 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 void fexponencial(int N, float Lambda, char filename[]){ /*** [tested] ***/ float x; FILE *stream_exponencial; // stream_exponencial = fopen(filename, "w");//abrir archivo if (stream_exponencial == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_exponencial, "# Este archivo contiene %i números\n", N); fprintf(stream_exponencial, "# pseudoaletorios con distribucion exponencial\n"); fprintf(stream_exponencial, "# con parámetro lambda = %.3f\n", Lambda); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = exponencial(Lambda); // generamos un número fprintf(stream_exponencial, "%f\n", x); } fprintf(stream_exponencial, "\n# Fin del archivo...\n"); fclose(stream_exponencial); // cerrar archivo... } 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 /************************************** float geometrica(float p) Descripción: Esta función genera números pseudoaleatorios con distribución geometrica de parámetro p. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ int geometrica(float p){ double x; int y; x = (log(1 - uniforme()) / log(1 - p)) - 1; y = (int)(x + 0.5); // redondeo... [round Up] return y; } 502 503 504 505 506 507 508 /************************************** void fgeometrica(int N, float p, char filename[15]) Descripción: Esta función genera N números pseudoaleatorios con distribución geometrica, con parámetro Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 107 << p >>, y los graba en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ void fgeometrica(int N, float p, char filename[]){ /*** [tested] ***/ int x; FILE *stream_geometrica; // stream_geometrica = fopen(filename, "w");// abrir archivo if (stream_geometrica == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_geometrica, "# Este archivo contiene %i números\n", N); fprintf(stream_geometrica, "# pseudoaletorios con distribucion geométrica\n"); fprintf(stream_geometrica, "# con parámetro p = %.3f\n", p); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = geometrica(p); // generamos un número fprintf(stream_geometrica, "%i\n", x); } fprintf(stream_geometrica, "\n# Fin del archivo...\n"); fclose(stream_geometrica); // cerrar archivo... } 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 /************************************** int poisson(float alpha) Descripción: Esta función genera números pseudoaleatorios con distribución Poisson de parámetro alpha. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ int poisson(float alpha){ int n = 0; static int p = 1; double comparador; double u; do{ u = (double)(rand()) / (double)(RAND_MAX); comparador *= p * u; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 108 Códigos n++; } while (comparador > exp(-alpha)); return n; 559 560 561 562 } 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 /************************************** void fpoisson(int N, float a, char filename[15]) Descripción: Esta función genera N números pseudoaleatorios con distribución poisson, con parámetro << a >>, y los graba en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ void fpoisson(int N, float a, char filename[]){ /*** [tested] ***/ int x; FILE *stream_poisson; // stream_poisson = fopen(filename, "w");// abrir archivo if (stream_poisson == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_poisson, "# Este archivo contiene %i números\n", N); fprintf(stream_poisson, "# pseudoaletorios con distribucion geométrica\n"); fprintf(stream_poisson, "# con parámetro p = %.3f\n", a); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = poisson(a); // generamos un número fprintf(stream_poisson, "%i\n", x); } fprintf(stream_poisson, "\n# Fin del archivo...\n"); fclose(stream_poisson); // cerrar archivo... } 601 602 603 604 605 606 607 608 /*************************************************** double weibull(double c, double k) Esta función genera números pseudoaleatorios con distribución Weibull. Los parámetros c y k corresponden a la forma Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 609 610 611 612 613 614 615 616 617 618 109 y escala de la distribución, respectivamente. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ****************************************************/ double weibull(double c, double k){/*** [tested] ***/ double x; x = c * pow(-log(1 - uniforme()), 1/k); return x; } 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 /*************************************************** void fweibull(int N, char filename[15], float C, float K) Descripción: Esta función genera N números pseudoaleatorios con distribución weibull, con parámetros << C >> y << K >>, y los graba en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ****************************************************/ void fweibull(int N, char filename[], float C, float K){ /*** [tested] ***/ float x; FILE *stream_weib; // stream_weib = fopen(filename, "w"); // abrir archivo if (stream_weib == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_weib, "# Este archivo contiene %i números\n", N); fprintf(stream_weib, "# pseudoaletorios con distribucion Weibull\n"); fprintf(stream_weib, "# con parámetros C = %.3f y K = %.3f\n", C, K); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = weibull(C, K); // generamos un número fprintf(stream_weib, "%f\n", x); // grabamos... } fclose(stream_weib); // cerrar archivo... } 655 656 657 658 /************************************** double rayleigh(float media) Descripción: Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 110 Códigos 659 660 661 662 663 664 665 666 667 668 669 670 671 672 Esta función genera números pseudoaleatorios con distribución rayleigh con media << media >> Fuente: http://www.brighton-webs.co.uk/distributions/rayleigh.asp ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ double rayleigh(float media){/*** [tested] ***/ double factor, r; factor = media / 1.253314; r = sqrt(-2 * factor * factor * log(uniforme())); return r; } 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 /*************************************************** void frayleigh(int N, char filename[15], float M) Descripción: Esta función genera N números pseudoaleatorios con distribución rayleigh, con media << M >> y los graba en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ****************************************************/ void frayleigh(int N, char filename[], float M){ /*** [tested] ***/ float x; FILE *stream_rayl; // stream_rayl = fopen(filename, "w"); // abrir archivo if (stream_rayl == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_rayl, "# Este archivo contiene %i números\n", N); fprintf(stream_rayl, "# pseudoaletorios con distribución Rayleigh\n"); fprintf(stream_rayl, "# con media = %.3f\n", M); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = rayleigh(M); // generamos un número fprintf(stream_rayl, "%f\n", x); // grabamos... } fclose(stream_rayl); // cerrar archivo... } 708 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 111 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 /*************************************************** double triangular(double media) Esta función genera números pseudoaleatorios con distribución triangular con parámetro << media >> ///////////////////////////////////////////////////// BUGS: Al dibujar el histograma la distribución en realidad no parece triangular... NO USAR... BUSCAR EN INTERNET CÓMO SIMULARLA... ****************************************************/ double triangular(double media){ double R, x; R = uniforme(); if (R <= 0.5){ x = sqrt(2 * media * R); // Ok... } else{ x = media * (2 - sqrt(2 * (R))); } return x; } 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 /*************************************************** void ftriangular(int N, char filename[], float media) Descripción: Esta función genera N números pseudoaleatorios con distribución rayleigh, con media << M >> y los graba en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ****************************************************/ void ftriangular(int N, char filename[], float media){ /*** [tested] ***/ float x; FILE *stream_tria; // stream_tria = fopen(filename, "w"); // abrir archivo if (stream_tria == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } fprintf(stream_tria, "# Este archivo contiene %i números\n", N); fprintf(stream_tria, "# pseudoaletorios con distribución Rayleigh\n"); Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 112 Códigos fprintf(stream_tria, "# con media = %.3f\n", media); // Aquı́ va el código para grabar... for(int i = 1 ; i <= N ; i++){ x = triangular(media); // generamos un número fprintf(stream_tria, "%f\n", x); // grabamos... } fclose(stream_tria); // cerrar archivo... 759 760 761 762 763 764 765 766 } 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 /************************************** double media(char filename[]) Descripción: Esta función calcula la media aritmética de los datos contenidos en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ double media(char filename[]){/*** [tested] ***/ char respuesta, letra = ’ ’; double datum; double x, Sx; double media; // lo que va a regresar int n = 0, j = 1, i = 0; // contadores... char dato[15]; char B4; // letra leida antes... FILE *stream_media; // stream_uniforme stream_media = fopen(filename, "r+"); // abrir archivo if (stream_media == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); system("PAUSE"); return 0; } Sx = 0; // reinicio la suma de datos // Ahora leemos los datos... do{ letra = fgetc(stream_media); // leer un char if (letra == feof(stream_media)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 113 if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float Sx += x; // Suma de x i = 0; n++; } break; case ’\t’: // para el caso de varias columnas... //if (i > 0){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float Sx += x; // Suma de x i = 0; n++; //} break; case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float Sx += x; // Suma de x i = 0; n++; break; } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_media); if (letra == feof(stream_media)){ break; } } while (letra!=’\n’); i = 1; dato[0] = letra; break; default: dato[i] = letra; i++; 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 } } while(!feof(stream_media)); fclose(stream_media); // cerrar archivo... 848 849 850 851 media = Sx / (1.0 * n); return(media); 852 853 854 } 855 856 857 858 /************************************** double desviacionStd(char filename[15]) Descripción: Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 114 Códigos 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 Esta función calcula la desviación estándar de los datos contenidos en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ double desviacionStd(char filename[]){/*** [tested] ***/ char respuesta, letra = ’ ’; double datum; double x, Sx, Sx2; double varianza, sd; int n = 0, j = 1, i = 0; // contadores... char dato[15]; char B4; // letra leida antes... FILE *stream_sd; // stream_uniforme stream_sd = fopen(filename, "r+"); // abrir archivo if (stream_sd == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return 0.0; } Sx = 0, Sx2 = 0; // reinicio los contadores // Ahora leemos los datos... do{ letra = fgetc(stream_sd); // leer un char if (letra == feof(stream_sd)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float Sx += x; // Suma de x Sx2 += x * x; // Suma de xˆ2 i = 0; n++; } break; case ’\t’: // para el caso de varias columnas... //if (i > 0){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float Sx += x; // Suma de x Sx2 += x * x; // Suma de xˆ2 i = 0; n++; //} Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación break; case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float Sx += x; // Suma de x Sx2 += x * x; // Suma de xˆ2 i = 0; n++; break; } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_sd); if (letra == feof(stream_sd)){ break; } } while (letra!=’\n’); i = 1; dato[0] = letra; break; default: dato[i] = letra; i++; 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 } } while(!feof(stream_sd)); fclose(stream_sd); // cerrar archivo... varianza = (Sx2 - Sx * Sx / (1.0 * n)) / (n - 1.0); sd = sqrt(varianza); return(sd); printf("\n\n\n"); 933 934 935 936 937 938 939 940 115 } 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 /************************************** void histograma(char filename[15]) Descripción: Esta función genera un histograma en la pantalla a partir de los datos leı́dos en el archivo de nombre filename. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ void histograma(char filename[]){/*** [tested] ***/ int I[10]; // los intervalos... int errores = 0, max =0, min = 1000000; int n = 0, j = 1, i = 0; // contadores Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 116 Códigos 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 int imax, imin;// double vmax = -2147483647, vmin = 2147483647; double anchoIntervalo; // = vmax - vmin char dato[15]; // cada dato en forma de string float x; // el número generado... double escala; // para hacer la gráfica... int factor; // para hacer la gráfica... char letra = ’ ’; // // limpio la memoria del array para el histograma... for (i = 0 ; i <= 9 ; i++){ I[i] = 0; } // Histograma FILE *stream_histo; // stream_histo = fopen(filename, "r+"); // abrir archivo if (stream_histo == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } // Ahora leemos los datos... do{ letra = fgetc(stream_histo); // leer un char if (letra == feof(stream_histo)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float // encuentro el mı́nimo y el máximo... if (x > vmax){ vmax = x; } if (x < vmin){ vmin = x; } i = 0; n++; } break; case ’\t’: // para el caso de varias columnas... dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float // encuentro el mı́nimo y el máximo... if (x > vmax){ vmax = x; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación } if (x < vmin){ vmin = x; } i = 0; n++; break; case ’ ’: // espacio en if (i > 1){ dato[i] = ’\0’; x = atof(dato); i = 0; n++; // encuentro el if (x > vmax){ vmax = x; } if (x < vmin){ vmin = x; } 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 117 blanco... // fin del arreglo // convierto a float mı́nimo y el máximo... 1029 1030 break; } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_histo); if (letra == feof(stream_histo)){ break; } } while (letra!=’\n’); i = 1; dato[0] = letra; break; default: dato[i] = letra; i++; 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 } } while(!feof(stream_histo)); anchoIntervalo = vmax - vmin; // regreso al inicio del archivo fseek(stream_histo, 0, SEEK_SET); // Volvemos a leer los datos... // Ahora para generar el histograma do{ letra = fgetc(stream_histo); // leer un char if (letra == feof(stream_histo)){ break; // Salir del ciclo... } switch(letra){ Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 118 Códigos case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j <= 9 ; j++){ if ((x > (0.1 * j * anchoIntervalo + vmin)) && (x <= (0.1 * (j+1) * anchoIntervalo + vmin))){ I[j]++; break; } } } break; case ’\t’: // para el caso de varias columnas... dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j <= 9 ; j++){ if ((x > (0.1 * (j) * anchoIntervalo + vmin)) && (x <= (0.1 * (j+1) * anchoIntervalo + vmin))){ I[j]++; break; } } break; case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j <= 9 ; j++){ if ((x > (0.1 * (j) * anchoIntervalo + vmin)) && (x <= (0.1 * (j+1) * anchoIntervalo + vmin))){ I[j]++; break; } } break; } case ’#’: // comentario... 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación do{ // leer todos los alfanuméricos letra = fgetc(stream_histo); if (letra == feof(stream_histo)){ break; } } while (letra!=’\n’); i = 1; dato[0] = letra; break; 1109 1110 1111 1112 1113 1114 1115 1116 1117 default: dato[i] = letra; i++; 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 119 } } while(!feof(stream_histo)); fclose(stream_histo); // cerrar archivo... // Encuentro el intervalo con mayor número de ocurrencias for (i = 0; i <= 9 ; i++){ if (I[i] > max){ max = I[i]; imax = i; } if (I[i] < min){ min = I[i]; imin = i; } } // Ahora imprimo los resultados... printf("\n\n"); // un poco de espacio... for (i = 0 ; i <= 9 ; i++){ printf("\n Intervalo %.1f -- %.1f ", (anchoIntervalo * i / 10 + vmin),(anchoIntervalo * (i+1) / 10) + vmin); escala = 35.0 * I[i] / max; factor = int(escala + 0.5); // redondeo // Imprime la barra del intervalo (i-1) for (j = 0 ; j <= factor ; j++){ printf("|"); } // termina de imprimir la barra... if (I[i] == max){ printf(" (%i) [Max]\n", I[i]); continue; } if (I[i] == min){ printf(" (%i) [Min]\n", I[i]); continue; } printf(" (%i)\n", I[i]); } return; } // Fin de la función HISTOGRAMA 1158 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 120 Códigos 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 /************************************** void histograma(char filename[], int No_Int) Descripción: Esta función genera un histograma de << No_Int >> intervalos en la pantalla a partir de los datos leı́dos en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ void histograma(char filename[], int No_Int){ /*** [tested] ***/ int I[No_Int - 1]; // los intervalos... int errores = 0, max =0, min = 1000000; int n = 0, j = 1, i = 0; // contadores int imax, imin;// double vmax = -2147483647, vmin = 2147483647; double anchoIntervalo; // = vmax - vmin char dato[15]; // cada dato en forma de string float x; // el número generado... double escala; // para hacer la gráfica... int factor; // para hacer la gráfica... char letra = ’ ’; // // limpio la memoria del array para el histograma... for (i = 0 ; i < No_Int ; i++){ I[i] = 0; } // Histograma FILE *stream_histo; // stream_histo = fopen(filename, "r+"); // abrir archivo if (stream_histo == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } // Ahora leemos los datos... do{ letra = fgetc(stream_histo); // leer un char if (letra == feof(stream_histo)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float // encuentro el mı́nimo y el máximo... if (x > vmax){ Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 121 vmax = x; } if (x < vmin){ vmin = x; } i = 0; n++; 1209 1210 1211 1212 1213 1214 1215 } break; case ’\t’: // para el caso de varias columnas... dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float // encuentro el mı́nimo y el máximo... if (x > vmax){ vmax = x; } if (x < vmin){ vmin = x; } i = 0; n++; break; case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // encuentro el mı́nimo y el máximo... if (x > vmax){ vmax = x; } if (x < vmin){ vmin = x; } 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 break; } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_histo); if (letra == feof(stream_histo)){ break; } } while (letra!=’\n’); i = 1; dato[0] = letra; break; default: 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 122 Códigos dato[i] = letra; i++; 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 } } while(!feof(stream_histo)); anchoIntervalo = vmax - vmin; // regreso al inicio del archivo fseek(stream_histo, 0, SEEK_SET); // Volvemos a leer los datos... // Ahora para generar el histograma do{ letra = fgetc(stream_histo); // leer un char if (letra == feof(stream_histo)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j < No_Int ; j++){ if ((x > (j * anchoIntervalo / No_Int + vmin)) && (x <= ((j+1) * anchoIntervalo / No_Int + vmin))){ I[j]++; break; } } } break; case ’\t’: // para el caso de varias columnas... dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j < No_Int ; j++){ if ((x > (j * anchoIntervalo / No_Int + vmin)) && (x <= ((j+1) * anchoIntervalo / No_Int + vmin))){ I[j]++; break; } } break; case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j < No_Int ; j++){ if ((x > (j * anchoIntervalo / No_Int + vmin)) && (x <= ((j+1) * anchoIntervalo / No_Int + vmin))){ I[j]++; break; } } break; 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_histo); if (letra == feof(stream_histo)){ break; } } while (letra!=’\n’); i = 1; dato[0] = letra; break; default: dato[i] = letra; i++; 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 123 } } while(!feof(stream_histo)); fclose(stream_histo); // cerrar archivo... // Encuentro el intervalo con mayor número de ocurrencias for (i = 0; i < No_Int ; i++){ if (I[i] > max){ max = I[i]; imax = i; } if (I[i] < min){ min = I[i]; imin = i; } } // Ahora imprimo los resultados... printf("\n\n"); // un poco de espacio... for (i = 0 ; i < No_Int ; i++){ printf("\n Intervalo %.1f -- %.1f ", (anchoIntervalo * i / No_Int + vmin),(anchoIntervalo * (i+1) / No_Int) + vmin); escala = 35.0 * I[i] / max; factor = int(escala + 0.5); // redondeo // Imprime la barra del intervalo (i-1) for (j = 0 ; j <= factor ; j++){ Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 124 Códigos 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 printf("|"); } // termina de imprimir la barra... if (I[i] == max){ printf(" (%i) [Max]\n", I[i]); continue; } if (I[i] == min){ printf(" (%i) [Min]\n", I[i]); continue; } printf(" (%i)\n", I[i]); } return; } // Fin de la función HISTOGRAMA 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 struct hist{ /* Esta estructura servirá para crear un histograma y pasarlo como argumento y regresarlo... */ //int size; int I[30]; int imax, imin; float vmin, vmax; int total_datos; }; 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 /************************************** void histograma(char filename[15]) Descripción: Esta función genera un histograma de No_Int intervalos en la pantalla a partir de los datos leı́dos en el archivo de nombre << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ***************************************/ hist Phistograma(char filename[], int No_Int){ /*** [tested] ***/ int errores = 0, max =0, min = 1000000; int n = 0, j = 1, i = 0; // contadores int imax, imin;// 1407 1408 double anchoIntervalo; // = vmax - h.vmin Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 125 char dato[15]; // cada dato en forma de string float x; // el número generado... double escala; // para hacer la gráfica... int factor; // para hacer la gráfica... char letra = ’ ’; hist h; // Nuevo histograma h.imax = -1; h.imin = -1; h.vmax = -2147483647; // máximo h.vmin = 2147483647; // mı́nimo h.total_datos = 0; // // limpio la memoria del array para el histograma... for (i = 0 ; i < 30 ; i++){ h.I[i] = 0; } // Histograma FILE *stream_histo; // stream_histo = fopen(filename, "r+"); // abrir archivo if (stream_histo == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return h; } // Ahora leemos los datos... do{ letra = fgetc(stream_histo); // leer un char if (letra == feof(stream_histo)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float h.total_datos++; // encuentro el mı́nimo y el máximo... if (x > h.vmax){ h.vmax = x; } if (x < h.vmin){ h.vmin = x; } i = 0; n++; } break; case ’\t’: // para el caso de varias columnas... dato[i] = ’\0’; // fin del arreglo Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 126 Códigos x = atof(dato); // convierto a float h.total_datos++; // encuentro el mı́nimo y el máximo... if (x > h.vmax){ h.vmax = x; } if (x < h.vmin){ h.vmin = x; } i = 0; n++; break; case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float h.total_datos++; i = 0; n++; // encuentro el mı́nimo y el máximo... if (x > h.vmax){ h.vmax = x; } if (x < h.vmin){ h.vmin = x; } 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 break; } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_histo); if (letra == feof(stream_histo)){ break; } } while (letra!=’\n’); i = 1; dato[0] = letra; break; default: dato[i] = letra; i++; 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 } } while(!feof(stream_histo)); anchoIntervalo = h.vmax - h.vmin; // regreso al inicio del archivo fseek(stream_histo, 0, SEEK_SET); // Volvemos a leer los datos... // Ahora para generar el histograma Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 1509 127 do{ letra = fgetc(stream_histo); // leer un char if (letra == feof(stream_histo)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j < No_Int ; j++){ if ((x > (j * anchoIntervalo / No_Int + h.vmin)) && (x <= ((j+1) * anchoIntervalo / No_Int + h.vmin))){ h.I[j]++; break; } } } break; case ’\t’: // para el caso de varias columnas... dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j < No_Int ; j++){ if ((x > (j * anchoIntervalo / No_Int + h.vmin)) && (x <= ((j+1) * anchoIntervalo / No_Int + h.vmin))){ h.I[j]++; break; } } break; case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo x = atof(dato); // convierto a float i = 0; n++; // Asigno al arreglo para el histograma for(j = 0 ; j < No_Int ; j++){ if ((x > (j * anchoIntervalo / No_Int + h.vmin)) && (x <= ((j+1) * anchoIntervalo / No_Int + h.vmin))){ h.I[j]++; 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 128 Códigos break; 1559 } 1560 } break; 1561 1562 } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_histo); if (letra == feof(stream_histo)){ break; } } while (letra!=’\n’); i = 1; dato[0] = letra; break; default: dato[i] = letra; i++; 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 } } while(!feof(stream_histo)); fclose(stream_histo); // cerrar archivo... for (i = 0; i < No_Int ; i++){ if (h.I[i] > max){ max = h.I[i]; h.imax = i; } if (h.I[i] < min){ min = h.I[i]; h.imin = i; } } return h; } // Fin de la función HISTOGRAMA 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 /****************************************************** void PchiUniforme(char filename[], int Num_Int) Descripción: Esta función prueba que los datos contenidos en el archivo de nombre << filename >> presenten una distribución normal, calculando el valor de Chiˆ2. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... -----------------------------------------------------NOTAS: A. El algoritmo es el siguiente: 1. Se leen los datos del archivo para contar Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 129 las frecuencias realtivas en cada intervalo del histograma y el total de datos N contenidos en el archivo. 2. Se generan N numeros pseudoaleatorios con distribución uniforme en el intervalo (0,1) ********************************************************/ void PchiUniforme(char filename[], int Num_Int){ float discrepancia = 0.0; hist observado; // datos leidos hist teorico; // datos generados float pt, po; int i; // Primero generamos el histograma // a partir de los datos contenidos en el archivo observado = Phistograma(filename, Num_Int); // Ahora generamos números en ese mismo intervalo... funiforme(observado.total_datos, "ChiUnif.txt"); teorico = Phistograma("ChiUnif.txt", Num_Int); // pt = 1.0 / (float)(Num_Int); for(i = 0 ; i < Num_Int ; i++){ po = (float)(observado.I[i]) / (float)(observado.total_datos); discrepancia += (po - pt) * (po - pt) / (pt); } printf("\nEl archivo %s contiene %i datos.", filename, observado.total_datos); printf("\n\nChiˆ2 = %f", discrepancia); if (discrepancia < 0.15 && teorico.total_datos > 1000){ printf("\nLos datos contenidos en el archivo %s", filename); printf("\nparecen presentar distribucion uniforme."); return; } } 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 /****************************************************** void PchiNormal(char filename[], int Num_Int) Descripción: Esta función prueba que los datos contenidos en el archivo de nombre << filename >> presenten una distribución uniforme. Devuelve el número de datos leidos del archivo, la media de esos datos y su desviación estándar. También despliega el valor de Chiˆ2. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ********************************************************/ Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 130 Códigos 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 void PchiNormal(char filename[], int Num_Int){ float discrepancia = 0.0; hist observado; // datos leidos hist teorico; // datos generados float m, DStd; float pt, po; float z; // punto medio del intervalo i int i; int NI; // Primero generamos el histograma // a partir de los datos contenidos en el archivo observado = Phistograma(filename, Num_Int); // Calculamos los parámetros de la distribución... m = media(filename); DStd = desviacionStd(filename); // Ahora generamos números con esos parámetros... fnormal(100000, "ChiNorm.txt", m, DStd); teorico = Phistograma("ChiNorm.txt", Num_Int); // Comparamos los dos histogramas... for(i = 0 ; i < Num_Int ; i++){ po = (float)(observado.I[i]) / (float)(observado.total_datos); pt = (float)(teorico.I[i]) / (float)(teorico.total_datos); discrepancia += (po - pt) * (po - pt) / (pt); } // Resultados... printf("\nEl archivo %s contiene %i datos.", filename, observado.total_datos); printf("\nMedia calculada: %f", m); printf("\nDesviacion Estandar calculada: %f", DStd); printf("\n\nChiˆ2 = %f\n", discrepancia); if (discrepancia < 0.15 && teorico.total_datos > 1000){ printf("\nLos datos contenidos en el archivo %s", filename); printf("\nparecen presentar distribucion normal."); return; } } 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 /****************************************************** void PchiExponencial(char filename[], int Num_Int, float lambda) Descripción: Esta función prueba que los datos contenidos en el archivo de nombre << filename >> presenten una distribución exponencial con parámetro << lambda >>. Devuelve el número de datos leidos del archivo, la media de esos datos el valor de Chiˆ2. ///////////////////////////////////////////////////// Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 131 BUGS: Ninguno conocido... ********************************************************/ void PchiExponencial(char filename[], int Num_Int, float lambda){ float discrepancia = 0.0; hist observado; // datos leidos hist teorico; // datos generados float m; float pt, po; int i; // Primero generamos el histograma // a partir de los datos contenidos en el archivo observado = Phistograma(filename, Num_Int); // Calculamos los parámetros de la distribución... m = media(filename); // Ahora generamos números pseudoaleatorios... fexponencial(100000, lambda, "ChiExpo.txt"); teorico = Phistograma("ChiExpo.txt", Num_Int); // Comparamos los dos histogramas... for(i = 0 ; i < Num_Int ; i++){ po = (float)(observado.I[i]) / (float)(observado.total_datos); pt = (float)(teorico.I[i]) / (float)(teorico.total_datos); discrepancia += (po - pt) * (po - pt) / (pt); } printf("\nEl archivo %s contiene %i datos.", filename, observado.total_datos); printf("\nMedia calculada: %f", m); printf("\n\nChiˆ2 = %f\n", discrepancia); if (discrepancia < 0.15 && teorico.total_datos > 1000){ printf("\nLos datos contenidos en el archivo %s", filename); printf("\nparecen presentar distribucion exponencial."); return; } } 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 /****************************************************** void PchiWeibull(char filename[], int Num_Int, float c, float k) Descripción: Esta función prueba que los datos contenidos en el archivo de nombre << filename >> presenten una distribución Weibull con parámetro << promedio >>. Devuelve el número de datos leidos del archivo, la media de esos datos el valor de Chiˆ2. ///////////////////////////////////////////////////// Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 132 Códigos 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 BUGS: Ninguno conocido... ********************************************************/ void PchiWeibull(char filename[], int Num_Int, float c, float k){ float discrepancia = 0.0; hist observado; // datos leidos hist teorico; // datos generados float m; // media calculada float pt, po; int i; // Primero generamos el histograma // a partir de los datos contenidos en el archivo observado = Phistograma(filename, Num_Int); // Calculamos los parámetros de la distribución... m = media(filename); // Ahora generamos números pseudoaleatorios... fweibull(100000, "ChiWeib.txt", c, k); teorico = Phistograma("ChiWeib.txt", Num_Int); // Comparamos los dos histogramas... for(i = 0 ; i < Num_Int ; i++){ po = (float)(observado.I[i]) / (float)(observado.total_datos); pt = (float)(teorico.I[i]) / (float)(teorico.total_datos); discrepancia += (po - pt) * (po - pt) / (pt); } printf("\nEl archivo %s contiene %i datos.", filename, observado.total_datos); printf("\nMedia calculada: %f", m); printf("\n\nChiˆ2 = %f\n", discrepancia); if (discrepancia < 0.15 && teorico.total_datos > 1000){ printf("\nLos datos contenidos en el archivo %s", filename); printf("\nparecen presentar distribucion Weibull."); return; } } 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 /****************************************************** void PchiRayleigh(char filename[], int Num_Int, float media) Descripción: Esta función prueba que los datos contenidos en el archivo de nombre << filename >> presenten una distribución exponencial con parámetro << lambda >>. Devuelve el número de datos leidos del archivo, la media de esos datos el valor de Chiˆ2. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 133 ********************************************************/ void PchiRayleigh(char filename[], int Num_Int, float Media){ float discrepancia = 0.0; hist observado; // datos leidos hist teorico; // datos generados float m; float pt, po; int i; // Primero generamos el histograma // a partir de los datos contenidos en el archivo observado = Phistograma(filename, Num_Int); // Calculamos los parámetros de la distribución... m = media(filename); // Ahora generamos números pseudoaleatorios... frayleigh(100000, "ChiExpo.txt", Media); teorico = Phistograma("ChiExpo.txt", Num_Int); // Comparamos los dos histogramas... for(i = 0 ; i < Num_Int ; i++){ po = (float)(observado.I[i]) / (float)(observado.total_datos); pt = (float)(teorico.I[i]) / (float)(teorico.total_datos); discrepancia += (po - pt) * (po - pt) / (pt); } printf("\nEl archivo %s contiene %i datos.", filename, observado.total_datos); printf("\nMedia calculada: %f", m); printf("\n\nChiˆ2 = %f\n", discrepancia); if (discrepancia < 0.15 && teorico.total_datos > 1000){ printf("\nLos datos contenidos en el archivo %s", filename); printf("\nparecen presentar distribucion Rayleigh."); return; } } 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 /****************************************************** void RL(char filename[]) Descripción: Esta función calcula la recta de mejor ajuste a los datos contenidos en el archivo << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ********************************************************/ void RL(char filename[]){ char letra; char dato[15]; // cada dato en forma de string float x, y; // coordenadas del punto Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 134 Códigos 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 int i, j = 0; // contadores float m, beta; // parámetros para recta... float Sx, Sy, Sx2, Sxy; // sumas de datos... float Error_r = 0; float dir, y_approxr; int punto = 0; Sx = 0; Sy = 0; Sxy = 0; Sx2 = 0; FILE *stream_RL; // stream_RL = fopen(filename, "r+"); // abrir archivo if (stream_RL == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } do{ letra = fgetc(stream_RL); // leer un char if (letra == feof(stream_RL)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo if (j % 2 == 0){ // dato impar... x = atof(dato);// convierto a un float punto = 0; } else{ y = atof(dato); punto = 1; } j++; i = 0; } break; case ’\t’: // para el caso de varias columnas... dato[i] = ’\0’; // fin del arreglo if (j % 2 == 0){ x = atof(dato);// convierto a un float punto = 0; } else{ y = atof(dato); punto = 1; } j++; i = 0; break; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo if (j % 2 == 0){ x = atof(dato);// convierto a un float punto = 0; } else{ y = atof(dato); punto = 1; } j++; i = 0; break; } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_RL); if (letra == feof(stream_RL)){ break; } } while (letra!=’\n’); i = 0; dato[0] = letra; break; default: dato[i] = letra; punto = 0; i++; 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 135 } if (punto == 1){ // realizar cálculos // Realizamos los cálculos... Sx += x; // Suma de x Sy += y; // Suma de y Sxy += x * y; // Suma de xy Sx2 += x * x; // Suma de x cuadrada punto = 0; } } while(!feof(stream_RL)); 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 // Calculo parámetros de recta... if (j > 4){ m = (j * Sxy - Sx * Sy) / (j * Sx2 - Sx * Sx); beta = (Sy - m * Sx) / j; // Muestro los resultados... printf("\n\nLa recta de mejor ajuste es:"); printf("\n y = %.3f + %.3f x.\n", beta, m); } else{ printf("\nNo se pueden realizar los calculos."); Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 136 Códigos printf("\nEl archivo contiene dos datos o menos..."); } // cierro el archivo... fclose(stream_RL); //system("PAUSE"); return; 1959 1960 1961 1962 1963 1964 1965 } 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 /****************************************************** void RC(char filename[]) Descripción: Esta función calcula la recta de mejor ajuste a los datos contenidos en el archivo << filename >>. ///////////////////////////////////////////////////// BUGS: Ninguno conocido... ********************************************************/ void RC(char filename[]){ char letra; char dato[15]; // cada dato en forma de string float x, y; // coordenadas del punto int i, j = 0; // contadores float a, b, c; // parámetros para parábola... float Da = 0, Dp = 0; float Sx, Sy, Sx2, Sx3, Sx4, Sxy, Sx2y;// sumas de datos. float Error_p = 0; float dip, y_approxp; int punto = 0; Sx = 0; Sy = 0; Sxy = 0; Sx2 = 0; Sx3 = 0; Sx4 = 0; Sx2y = 0; 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 FILE *stream_RC; // stream_RC = fopen(filename, "r+"); // abrir archivo if (stream_RC == NULL){ printf ("\nNo se puede abrir el archivo %s\n", filename); printf("\nPor favor, verifique el nombre archivo"); return; } do{ letra = fgetc(stream_RC); // leer un char if (letra == feof(stream_RC)){ break; // Salir del ciclo... } switch(letra){ case ’\n’: // llegó a un nuevo renglón if (i > 1){ dato[i] = ’\0’; // fin del arreglo if (j % 2 == 0){ // dato impar... x = atof(dato); // convierto a un float Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 137 punto = 0; } else{ y = atof(dato); punto = 1; } j++; i = 0; 2009 2010 2011 2012 2013 2014 2015 2016 } break; case ’\t’:// para el caso de varias columnas... dato[i] = ’\0’; // fin del arreglo if (j % 2 == 0){ x = atof(dato); // convierto a un float punto = 0; } else{ y = atof(dato); punto = 1; } j++; i = 0; break; case ’ ’: // espacio en blanco... if (i > 1){ dato[i] = ’\0’; // fin del arreglo if (j % 2 == 0){ x = atof(dato); // convierto a un float punto = 0; } else{ y = atof(dato); punto = 1; } j++; i = 0; break; } case ’#’: // comentario... do{ // leer todos los alfanuméricos letra = fgetc(stream_RC); if (letra == feof(stream_RC)){ break; } } while (letra!=’\n’); i = 0; dato[0] = letra; break; default: dato[i] = letra; 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 138 Códigos punto = 0; i++; 2059 2060 } if (punto == 1){ // Realizamos los cálculos... Sx += x; // Suma de x Sy += y; // Suma de y Sxy += x * y; // Suma de xy Sx2 += x * x; // Suma de x cuadrada Sx3 += x * x * x; // Suma de x cúbica Sx4 += x * x * x * x; // Suma x cuarta Sx2y += x * x * y; punto = 0; } } while(!feof(stream_RC)); 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 // Calculo parámetros de la parábola... if (j > 6){ // Calculo los parámetros de parábola... Da = Sy * Sx2 * Sx2 + j * Sxy * Sx3 + Sx * Sx * Sx2y; Da = Da - j * Sx2 * Sx2y - Sx * Sx3 * Sy - Sx * Sxy * Sx2; Dp = Sx2 * Sx2 * Sx2 + j * Sx3 * Sx3 + Sx4 * Sx * Sx; Dp = Dp - j * Sx2 * Sx4 - 2 * Sx * Sx2 * Sx3; a = Da / Dp; b = (Sx * (Sy - a * Sx2) - j * (Sxy - a * Sx3)) / (Sx * Sx - j * Sx2); c = (Sy - a * Sx2 - b * Sx) / j; // Muestro los resultados... printf("\nLa parabola de mejor ajuste es:"); printf("\n y = %.3f xˆ2 + %.3f x + %.3f\n\n", a, b, c); } else{ printf("\nNo se pueden realizar los calculos."); printf("\nEl archivo contiene menos de tres datos..."); } // cierro el archivo... fclose(stream_RC); //system("PAUSE"); return; 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 } 2099 2100 2101 2102 #endif // PROBABILITY_H Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 2.8.1 139 Ejemplos de uso En esta sección se muestra cómo utilizar dentro de programas las funciones que se definieron anteriormente. Después de cada código se muestra el resultado que imprimió cada programa. Dado que el encabezado del programa es el mismo siempre se muestra solamente el programa completo en el primer programa y en los demás se omite. 2.8.1.1 funiforme(total, archivo) Función 2.8.1 void funiforme(int N, char filename[]) Descripción: Esta función guarda N números pseudoaleatorios con distribución uniforme en el intervalo (0.0, 1.0) en el archivo con nombre filename. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /* Nombre del archivo: testP.cpp Con este programa estoy revisando que las funciones que he incluido en el archivo: <<estadistica.h>> que estoy elaborando estén correctas. ------------------------------------------------------------------Nombre del Archivo: testP.cpp Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Fecha de última modificación: 29 de mayo de 2008 ------------------------------------------------------------------*/ #include "estadistica.h" 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... printf("\nEste programa verifica que las funciones"); printf("\nincluidas en el codigo del archivo"); printf("\n<< estadistica.h >>"); printf("\nfuncionen correctamente..."); printf("\n\nEstamos probando las funciones: \n"); printf("- funiforme(int N, char filename[]),\n"); printf("- histograma(char filename[]),\n"); printf("- media(char filename[]),\n"); printf("- desviacionStd(char filename[]),\n"); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); funiforme(total, archivo); histograma(archivo); printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 140 Códigos 39 40 41 42 printf("\n\n\n"); system("PAUSE"); return 0; } El programa arroja los siguientes resultados ante los siguientes datos: Este programa verifica que las funciones incluidas en el codigo del archivo << estadistica.h >> funcionen correctamente... Estamos probando las funciones: - funiforme(int N, char filename[15]), - histograma(char filename[15]), - media(char filename[15]), - desviacionStd(char filename[15]), Cuantos numeros desea generar: 10000 Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 ----------- 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 |||||||||||||||||||||||||||||||||| (987) |||||||||||||||||||||||||||||||||| (1004) |||||||||||||||||||||||||||||||| (955) [Min] ||||||||||||||||||||||||||||||||| (978) |||||||||||||||||||||||||||||||||| (996) ||||||||||||||||||||||||||||||||| (984) |||||||||||||||||||||||||||||||||||| (1062) [Max] |||||||||||||||||||||||||||||||||| (1001) |||||||||||||||||||||||||||||||||| (1014) ||||||||||||||||||||||||||||||||||| (1018) Media calculada: 0.503787 Desviacion Estandar calculada: 0.288886 Presione una tecla para continuar . . . 2.8.1.2 funiforme(total, archivo, A, B) Función 2.8.2 void funiforme(int N, char filename[], float a, float b) Descripción: Esta función guarda N números pseudoaleatorios con distribución uniforme en el intervalo (a, b) en el archivo con nombre filename. Modificamos la lı́nea 35 del programa anterior (lı́nea 25 del siguiente programa) para utilizar la función funiforme, ahora considerando también un intervalo (A, B) defindo por el usuario: 1 #include "estadistica.h" 2 3 using namespace std; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 141 int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... float A, B; // parametros de la distribucion printf("\nEste programa verifica que las funciones"); printf("\nincluidas en el codigo del archivo"); printf("\n<< estadistica.h >>"); printf("\nfuncionen correctamente..."); printf("\n\nEstamos probando las funciones: \n"); printf("- funiforme(int N, char filename[], float a, float b),\n"); printf("- histograma(char filename[]),\n"); printf("- media(char filename[]),\n"); printf("- desviacionStd(char filename[]),\n"); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nLimite inferior de la distribucion: "); scanf("%f", &A); printf("\n\nLimite superior de la distribucion: "); scanf("%f", &B); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); funiforme(total, archivo, A, B); histograma(archivo); printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); printf("\n\n\n"); system("PAUSE"); return 0; } Nóte que se agregaron algunas lı́neas de código para pedir los parámetros A y B, que corresponden a los lı́mites inferior y superior del intervalo donde se generarán los números pseudoaleatorios con distribución uniforme. El programa ahora arroja los siguientes resultados: ... Cuantos numeros desea generar: 10000 Limite inferior de la distribucion: -100 Limite superior de la distribucion: 100 Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo -100.0 -- -80.0 |||||||||||||||||||||||||||||||||| (987) -80.0 -- -60.0 |||||||||||||||||||||||||||||||||| (1004) -60.0 -- -40.0 |||||||||||||||||||||||||||||||| (955) [Min] -40.0 -- -20.0 ||||||||||||||||||||||||||||||||| (978) -20.0 -- 0.0 |||||||||||||||||||||||||||||||||| (996) 0.0 -- 20.0 ||||||||||||||||||||||||||||||||| (984) 20.0 -- 40.0 |||||||||||||||||||||||||||||||||||| (1062) [Max] 40.0 -- 60.0 |||||||||||||||||||||||||||||||||| (1001) 60.0 -- 80.0 |||||||||||||||||||||||||||||||||| (1014) 80.0 -- 100.0 ||||||||||||||||||||||||||||||||||| (1018) Media calculada: 0.757347 Desviacion Estandar calculada: 57.777105 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 142 Códigos 2.8.1.3 fnormal(total, archivo) Función 2.8.3 void fnormal(int N, char filename[]) Descripción: Esta función guarda N números pseudoaleatorios con distribución normal con media 0.0 y desviacion estándar 1.0 en el archivo con nombre filename. 1 #include "estadistica.h" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... printf("\nEste programa verifica que las funciones"); printf("\nincluidas en el codigo del archivo"); printf("\n<< estadistica.h >>"); printf("\nfuncionen correctamente..."); printf("\n\nEstamos probando las funciones: \n"); printf("- fnormal(int N, char filename[]),\n"); printf("- histograma(char filename[]),\n"); printf("- media(char filename[]),\n"); printf("- desviacionStd(char filename[]),\n"); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); fnormal(total, archivo);//, A, B histograma(archivo); printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); printf("\n\n\n"); system("PAUSE"); return 0; } El programa arroja: Cuantos numeros desea generar: 10000 Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo -3.8 -- -3.0 | (13) -3.0 -- -2.2 ||| (134) -2.2 -- -1.4 |||||||| (608) -1.4 -- -0.6 |||||||||||||||||||||| (1827) -0.6 -- 0.1 |||||||||||||||||||||||||||||||||||| (3039) [Max] 0.1 -- 0.9 ||||||||||||||||||||||||||||||| (2645) 0.9 -- 1.7 |||||||||||||||| (1308) 1.7 -- 2.5 ||||| (367) 2.5 -- 3.3 || (52) 3.3 -- 4.1 | (6) [Min] Media calculada: -0.002336 Desviacion Estandar calculada: 0.997851 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 2.8.1.4 143 fnormal(total, archivo, media, SD) Función 2.8.4 void fnormal(int N, char filename[], float med, float desvStd) Descripción: Esta función guarda N números pseudoaleatorios con distribución normal con media med y desviacion estándar desvStd en el archivo de nombre filename. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... float mean, SD; char archivo[15]; // nombre del archivo... printf("\nEste programa verifica que las funciones"); printf("\nincluidas en el codigo del archivo"); printf("\n<< estadistica.h >>"); printf("\nfuncionen correctamente..."); printf("\n\nEstamos probando las funciones: \n"); printf("- fnormal(int N, char filename[], float med, float desvStd),\n"); printf("- histograma(char filename[]),\n"); printf("- media(char filename[]),\n"); printf("- desviacionStd(char filename[]),\n"); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nMedia de la distribucion: "); scanf("%f", &mean); printf("\n\nDesviacion estandar de la distribucion: "); scanf("%f", &SD); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); fnormal(total, archivo, mean, SD);// histograma(archivo); printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 10000 Media de la distribucion: 100 Desviacion estandar de la distribucion: 7 Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 73.4 -- 78.9 | (13) 78.9 -- 84.5 ||| (134) 84.5 -- 90.0 |||||||| (608) 90.0 -- 95.5 |||||||||||||||||||||| (1827) 95.5 -- 101.0 |||||||||||||||||||||||||||||||||||| (3039) [Max] 101.0 -- 106.6 ||||||||||||||||||||||||||||||| (2645) 106.6 -- 112.1 |||||||||||||||| (1308) 112.1 -- 117.6 ||||| (367) 117.6 -- 123.1 || (52) 123.1 -- 128.7 | (6) [Min] Media calculada: 99.983645 Desviacion Estandar calculada: 6.984954 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 144 Códigos 2.8.1.5 fexponencial(total, lambda, archivo) Función 2.8.5 void fexponencial(int N, float Lambda, char filename[]) Descripción: Esta función genera N números pseudoaleatorios con distribución exponencial, con parámetro Lambda, y los graba en el archivo de nombre filename. 1 #include "estadistica.h" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... float L; // parametro de la distribucion printf("\nEste programa verifica que las funciones"); printf("\nincluidas en el codigo del archivo"); printf("\n<< estadistica.h >>"); printf("\nfuncionen correctamente..."); printf("\n\nEstamos probando las funciones: \n"); printf("- fexponencial(int N, float Lambda, char filename[]),\n"); printf("- histograma(char filename[]),\n"); printf("- media(char filename[]),\n"); printf("- desviacionStd(char filename[]),\n"); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nParametro Lambda de la distribucion: "); scanf("%f", &L); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); fexponencial(total, L, archivo);//, mean, SD histograma(archivo); printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 10000 Parametro Lambda de la distribucion: 0.5 Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 -- 1.9 |||||||||||||||||||||||||||||||||||| 1.9 -- 3.9 ||||||||||||||| (2400) 3.9 -- 5.8 |||||| (916) 5.8 -- 7.8 ||| (319) 7.8 -- 9.7 || (123) 9.7 -- 11.6 | (58) 11.6 -- 13.6 | (29) 13.6 -- 15.5 | (5) 15.5 -- 17.5 | (4) 17.5 -- 19.4 | (2) [Min] (6143) [Max] Media calculada: 2.026312 Desviacion Estandar calculada: 2.031012 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 2.8.1.6 145 fgeometrica(total, p, archivo) Función 2.8.6 void fgeometrica(int N, float p, char filename[15]) Descripción: Esta función genera N números pseudoaleatorios con distribución geometrica, con parámetro p, y los graba en el archivo de nombre filename. 1 #include "estadistica.h" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... float p; // parametro de la distribucion printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nParametro p de la distribucion: "); scanf("%f", &p); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); fgeometrica(total, p, archivo);//, mean, SD printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 1200 Parametro p de la distribucion: 0.75 Nombre del archivo: [Incluye extension] test.txt Media calculada: 2.045000 Desviacion Estandar calculada: 5.566383 Presione una tecla para continuar . . . 2.8.1.7 fpoisson(total, alpha, archivo) Función 2.8.7 void fpoisson(int N, float a, char filename[]) Descripción: Esta función genera N números pseudoaleatorios con distribución poisson, con parámetro α, y los graba en el archivo de nombre filename. 1 #include "estadistica.h" 2 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 146 Códigos 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 using namespace std; int main(void){ char filename[15]; float a; // parametro de la distribucion int total, i; printf("\nEste programa verifica que la funcion"); printf("\nvoid fpoisson(int N, float alpha, char filename[])"); printf("\nfuncione correctamente...\n"); printf("Cuantos numeros desea generar? "); scanf("%i", &total); printf("\nParametro Alpha supuesto: "); scanf("%f", &a); printf("\nNombre del archivo: "); scanf("%s", &filename); fpoisson(total, a, filename); printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion void fpoisson(int N, float alpha, char filename[]) funcione correctamente... Cuantos numeros desea generar? 1200 Parametro Alpha supuesto: 3 Nombre del archivo: test.txt Presione una tecla para continuar . . . 2.8.1.8 fweibull(total, archivo, c, k) Función 2.8.8 void fweibull(int N, char filename[], float C, float K) Descripción: Esta función genera N números pseudoaleatorios con distribución weibull, con parámetros C y K, y los graba en el archivo de nombre filename. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include "estadistica.h" using namespace std; int main(void){ int total; // de números a generar... char archivo[15]; // nombre del archivo... float C, K; // parametros de la distribucion printf("\nEste programa verifica que las funciones"); printf("\nincluidas en el codigo del archivo"); printf("\n<< estadistica.h >>"); printf("\nfuncionen correctamente..."); printf("\n\nEstamos probando las funciones: \n"); printf("- fweibull(int N, char filename[], float C, float K),\n"); printf("- histograma(char filename[]),\n"); printf("- media(char filename[]),\n"); printf("- desviacionStd(char filename[]),\n"); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 18 19 20 21 22 23 24 25 26 27 28 29 30 31 147 printf("\n\nParametro C de la distribucion: "); scanf("%f", &C); printf("\n\nParametro K de la distribucion: "); scanf("%f", &K);/**/ printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); fweibull(total, archivo, C, K); histograma(archivo); printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 10000 Parametro C de la distribucion: 11.86 Parametro K de la distribucion: 1.77 Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.1 -- 4.3 ||||||||||||||||||||| (1534) 4.3 -- 8.6 |||||||||||||||||||||||||||||||||||| (2726) [Max] 8.6 -- 12.9 |||||||||||||||||||||||||||||||||| (2572) 12.9 -- 17.2 ||||||||||||||||||||||| (1682) 17.2 -- 21.4 ||||||||||||| (907) 21.4 -- 25.7 |||||| (367) 25.7 -- 30.0 ||| (132) 30.0 -- 34.3 || (65) 34.3 -- 38.5 | (9) 38.5 -- 42.8 | (5) [Min] Media calculada: 10.635908 Desviacion Estandar calculada: 6.204015 2.8.1.9 frayleigh(total, archivo, media) Función 2.8.9 void frayleigh(int N, char filename[], float M) Descripción: Esta función genera N números pseudoaleatorios con distribución rayleigh, con media M y los graba en el archivo de nombre filename. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... float mean; printf("\nEste programa verifica que las funciones"); printf("\nincluidas en el codigo del archivo"); printf("\n<< estadistica.h >>"); printf("\nfuncionen correctamente..."); printf("\n\nEstamos probando las funciones: \n"); printf("- frayleigh(int N, char filename[], float M),\n"); printf("- histograma(char filename[]),\n"); printf("- media(char filename[]),\n"); Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 148 Códigos 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 printf("- desviacionStd(char filename[]),\n"); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nMedia de la distribucion: "); scanf("%f", &mean); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); frayleigh(total, archivo, mean); histograma(archivo); printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 10000 Media de la distribucion: 9.8 Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.1 -- 3.4 |||||||||||||| (946) 3.4 -- 6.8 ||||||||||||||||||||||||||||||| (2237) 6.8 -- 10.2 |||||||||||||||||||||||||||||||||||| (2598) [Max] 10.2 -- 13.5 |||||||||||||||||||||||||||| (1996) 13.5 -- 16.9 |||||||||||||||||| (1274) 16.9 -- 20.3 ||||||||| (603) 20.3 -- 23.6 |||| (234) 23.6 -- 27.0 || (78) 27.0 -- 30.4 | (28) 30.4 -- 33.7 | (5) [Min] Media calculada: 9.748030 Desviacion Estandar calculada: 5.145890 2.8.1.10 histograma(archivo, intervalos) Función 2.8.10 histograma(char filename[], int No Int) Descripción: Esta función genera un histograma de No Int intervalos en la pantalla a partir de los datos leı́dos en el archivo de nombre filename. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... float mean; // parametro de la distribucion printf("\nEste programa verifica que las funciones"); printf("\nincluidas en el codigo del archivo"); printf("\n<< probability.h >>"); printf("\nfuncionen correctamente..."); printf("\n\nEstamos probando las funciones: \n"); printf("- funiforme(int N, char filename[]),\n"); printf("- histograma(char filename[]),\n"); printf("- media(char filename[]),\n"); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 15 16 17 18 19 20 21 22 23 24 25 26 149 printf("- desviacionStd(char filename[]),\n"); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nMedia de la distribucion: "); scanf("%f", &mean); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); frayleigh(total, archivo, mean); histograma(archivo, 20); system("PAUSE"); return 0; } Cuantos numeros desea generar: 10000 Media de la distribucion: 9.8 Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.1 -- 1.8 |||||||| (259) 1.8 -- 3.4 ||||||||||||||||||| (687) 3.4 -- 5.1 ||||||||||||||||||||||||||| (1027) 5.1 -- 6.8 |||||||||||||||||||||||||||||||| (1210) 6.8 -- 8.5 |||||||||||||||||||||||||||||||||||| (1367) [Max] 8.5 -- 10.2 ||||||||||||||||||||||||||||||||| (1231) 10.2 -- 11.9 |||||||||||||||||||||||||||||| (1116) 11.9 -- 13.5 |||||||||||||||||||||||| (880) 13.5 -- 15.2 |||||||||||||||||||| (747) 15.2 -- 16.9 |||||||||||||| (527) 16.9 -- 18.6 |||||||||| (339) 18.6 -- 20.3 |||||||| (264) 20.3 -- 21.9 ||||| (142) 21.9 -- 23.6 ||| (92) 23.6 -- 25.3 || (45) 25.3 -- 27.0 || (33) 27.0 -- 28.7 | (19) 28.7 -- 30.4 | (9) 30.4 -- 32.0 | (3) 32.0 -- 33.7 | (2) [Min] Una caso en el que se requiere un histograma con un mayor número de intervalos en el histograma se justifica, por ejemplo, en el caso del pronóstico del recurso eólico de un local. En este caso, la energı́a eléctrica que se puede producir utilizando un generador eólico es proporcional al cubo de la velocidad. Cuando la velocidad del viento varı́a en un 25.99%, la√cantidad de energı́a producida con el viento aumenta al doble, debido a que 3 2 ≈ 1.2599. Por esa misma razón, sin la velocidad del viento disminuye en ese mismo porcentaje, la cantidad de energı́a producida se reduce ahora a la mitad. Por otra parte, si la velocidad del√viento aumenta un 44.22%, la energı́a producida aumenta al triple, porque 3 3 ≈ 1.4422. Entonces, distribución más suave nos permite calcular un pronóstico de la energı́a producida por un generador eólico con mayor precisión. Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 150 Códigos Otro ejemplo, donde se hace evidente la cantidad de información extra que muestra esta función para un mismo conjunto de datos es el siguiente: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream> #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... float C, K; // parametros de la distribucion... cout << "\nCuantos numeros desea generar: "; cin >> total; cout << "\nParametro C de la distribucion: "; cin >> C; cout << "\nParametro K de la distribucion: "; cin >> K; cout << "\nNombre del archivo: [Incluye extension] "; cin >> archivo; fweibull(total, archivo, C, K); cout << "\nHistograma con 10 intervalos:"; histograma(archivo,10); cout << "\nHistograma con 20 intervalos:"; histograma(archivo,20); cout << "\nHistograma con 30 intervalos:"; histograma(archivo,30); cout << "\nMedia calculada: " << media(archivo); cout << "\nDesviacion Estandar calculada: " << desviacionStd(archivo); cout << "\n\n\n"; system("PAUSE"); return 0; } Cuantos numeros desea generar: 525600 Parametro C de la distribucion: 11.86 Parametro K de la distribucion: 1.77 Nombre del archivo: [Incluye extension] weibull.txt Histograma con 10 intervalos: Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 -- 4.5 |||||||||||||||||||| (84735) 4.5 -- 8.9 |||||||||||||||||||||||||||||||||||| (152812) [Max] 8.9 -- 13.4 |||||||||||||||||||||||||||||||| (135245) 13.4 -- 17.8 ||||||||||||||||||||| (85517) 17.8 -- 22.3 ||||||||||| (42269) 22.3 -- 26.7 ||||| (17150) 26.7 -- 31.2 || (5674) 31.2 -- 35.6 | (1712) 35.6 -- 40.1 | (363) 40.1 -- 44.5 | (83) [Min] Histograma con 20 intervalos: Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 -- 2.2 ||||||||||||| (26559) 2.2 -- 4.5 ||||||||||||||||||||||||||| (58176) 4.5 -- 6.7 |||||||||||||||||||||||||||||||||| (74215) 6.7 -- 8.9 |||||||||||||||||||||||||||||||||||| (78597) [Max] 8.9 -- 11.1 |||||||||||||||||||||||||||||||||| (73003) 11.1 -- 13.4 ||||||||||||||||||||||||||||| (62242) 13.4 -- 15.6 ||||||||||||||||||||||| (49103) 15.6 -- 17.8 ||||||||||||||||| (36414) 17.8 -- 20.0 |||||||||||| (25392) 20.0 -- 22.3 ||||||||| (16877) 22.3 -- 24.5 |||||| (10727) Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 24.5 26.7 28.9 31.2 33.4 35.6 37.8 40.1 42.3 ---------- 26.7 28.9 31.2 33.4 35.6 37.8 40.1 42.3 44.5 151 |||| (6423) ||| (3664) || (2010) || (1138) | (574) | (244) | (119) | (44) | (39) [Min] Histograma con 30 intervalos: Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 -- 1.5 |||||||||| (13088) 1.5 -- 3.0 ||||||||||||||||||||| (30209) 3.0 -- 4.5 ||||||||||||||||||||||||||||| (41438) 4.5 -- 5.9 |||||||||||||||||||||||||||||||||| (48517) 5.9 -- 7.4 |||||||||||||||||||||||||||||||||||| (52126) 7.4 -- 8.9 |||||||||||||||||||||||||||||||||||| (52169) [Max] 8.9 -- 10.4 |||||||||||||||||||||||||||||||||| (49325) 10.4 -- 11.9 |||||||||||||||||||||||||||||||| (45771) 11.9 -- 13.4 |||||||||||||||||||||||||||| (40149) 13.4 -- 14.8 |||||||||||||||||||||||| (34137) 14.8 -- 16.3 |||||||||||||||||||| (28353) 16.3 -- 17.8 |||||||||||||||| (23027) 17.8 -- 19.3 ||||||||||||| (18022) 19.3 -- 20.8 |||||||||| (13989) 20.8 -- 22.3 |||||||| (10258) 22.3 -- 23.7 |||||| (7683) 23.7 -- 25.2 ||||| (5599) 25.2 -- 26.7 |||| (3868) 26.7 -- 28.2 ||| (2690) 28.2 -- 29.7 || (1796) 29.7 -- 31.2 || (1188) 31.2 -- 32.7 || (841) 32.7 -- 34.1 | (535) 34.1 -- 35.6 | (336) 35.6 -- 37.1 | (187) 37.1 -- 38.6 | (98) 38.6 -- 40.1 | (78) 40.1 -- 41.6 | (29) 41.6 -- 43.0 | (33) 43.0 -- 44.5 | (21) [Min] Media calculada: 10.5595 Desviacion Estandar calculada: 6.15714 Evidentemente, mientras más intervalos conozcamos, podremos hacer cálculos más refinados y tener resultados más precisos. Mientras el primer histograma (10 intervalos) nos indica alguna información, no se compara con el nivel de detalle que nos proporciona el último histograma (30 intervalos). Si hacemos el pronóstico de la energı́a producida en un año a partir de las probabilidades asignadas a cada intervalo, los resultados serán muy diferentes, porque en ese caso, cada intervalos representa los lı́mites superior e inferior de la velocidad del viento. Como la energı́a producida depende del cubo de la velocidad del viento, tendremos una diferencia considerable al realizar el pronóstico. Tomando el punto medio de cada intervalo, elevándolo al cubo y multiplicando por la probabilidad que le corresponde a ese intervalo, tendremos una aproximación simplificada del resultado (falta considerar cuestiones técnicas relativas al generador eólico, alCódigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 152 Códigos gunas cuestiones de conversión de la energı́a cinética del viento a la electricidad generada por el generador eólico, etc.) y podemos ver la gran diferencia en cada caso. Nota: Los datos que se introdujeron en el último ejemplo corresponden a la distribución que presenta la velocidad de viento en la Venta, Oaxaca, Mex. Fuente: Evaluación del recurso eólico de La Venta, Juchitán, Oaxaca. M. A. Borja, O. A. Jaramillo, M. F. Morales. Instituto de Investigaciones Eléctricas. Temixco, Morelos, México. [email protected]. El valor 525 600 = 60 × 24 × 365, el número de minutos en un año no bisiesto. Entonces, el valor que aparece entre paréntesis indica el número de minutos al año que la velocidad presentó una velocidad en el intervalo que le corresponde. El promedio calculado con la ayuda de la función media(archivo) corresponde a la media aritmética de los datos. No considera la frecuencia relativa por la cual debe multiplicarse para realizar este cálculo. Histogramas con mayores intervalos nos muestran información que nos ayudarán, en este caso, a pronosticar con mayor precisión el valor buscado, dado que tendremos una curva más suave. Histograma con 40 intervalos: Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 -- 1.1 |||||||| (7846) 1.1 -- 2.2 |||||||||||||||||| (18713) 2.2 -- 3.3 |||||||||||||||||||||||| (26181) 3.3 -- 4.5 ||||||||||||||||||||||||||||| (31995) 4.5 -- 5.6 ||||||||||||||||||||||||||||||||| (35839) 5.6 -- 6.7 ||||||||||||||||||||||||||||||||||| (38376) 6.7 -- 7.8 |||||||||||||||||||||||||||||||||||| (39618) [Max] 7.8 -- 8.9 ||||||||||||||||||||||||||||||||||| (38979) 8.9 -- 10.0 |||||||||||||||||||||||||||||||||| (37305) 10.0 -- 11.1 ||||||||||||||||||||||||||||||||| (35698) 11.1 -- 12.2 |||||||||||||||||||||||||||||| (32791) 12.2 -- 13.4 ||||||||||||||||||||||||||| (29451) 13.4 -- 14.5 |||||||||||||||||||||||| (26195) 14.5 -- 15.6 ||||||||||||||||||||| (22908) 15.6 -- 16.7 |||||||||||||||||| (19512) 16.7 -- 17.8 |||||||||||||||| (16902) 17.8 -- 18.9 ||||||||||||| (13930) 18.9 -- 20.0 ||||||||||| (11462) 20.0 -- 21.1 ||||||||| (9468) 21.1 -- 22.3 |||||||| (7409) 22.3 -- 23.4 |||||| (5946) 23.4 -- 24.5 ||||| (4781) 24.5 -- 25.6 |||| (3714) 25.6 -- 26.7 ||| (2709) 26.7 -- 27.8 ||| (2100) 27.8 -- 28.9 || (1564) 28.9 -- 30.1 || (1138) 30.1 -- 31.2 || (872) 31.2 -- 32.3 || (667) 32.3 -- 33.4 | (471) 33.4 -- 34.5 | (353) 34.5 -- 35.6 | (221) 35.6 -- 36.7 | (134) 36.7 -- 37.8 | (110) 37.8 -- 39.0 | (75) 39.0 -- 40.1 | (44) 40.1 -- 41.2 | (29) 41.2 -- 42.3 | (15) [Min] Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación Intervalo 42.3 -- 43.4 Intervalo 43.4 -- 44.5 153 | | (18) (21) Histograma con 50 intervalos: Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Códigos en C++ 0.0 -- 0.9 ||||||| (5258) 0.9 -- 1.8 ||||||||||||||| (12698) 1.8 -- 2.7 ||||||||||||||||||||| (18220) 2.7 -- 3.6 |||||||||||||||||||||||||| (22630) 3.6 -- 4.5 |||||||||||||||||||||||||||||| (25929) 4.5 -- 5.3 |||||||||||||||||||||||||||||||| (28446) 5.3 -- 6.2 |||||||||||||||||||||||||||||||||| (30203) 6.2 -- 7.1 |||||||||||||||||||||||||||||||||||| (31348) 7.1 -- 8.0 |||||||||||||||||||||||||||||||||||| (31668) [Max] 8.0 -- 8.9 ||||||||||||||||||||||||||||||||||| (31147) 8.9 -- 9.8 |||||||||||||||||||||||||||||||||| (30042) 9.8 -- 10.7 ||||||||||||||||||||||||||||||||| (28861) 10.7 -- 11.6 ||||||||||||||||||||||||||||||| (27510) 11.6 -- 12.5 ||||||||||||||||||||||||||||| (25550) 12.5 -- 13.4 ||||||||||||||||||||||||||| (23282) 13.4 -- 14.2 ||||||||||||||||||||||||| (21302) 14.2 -- 15.1 |||||||||||||||||||||| (19039) 15.1 -- 16.0 |||||||||||||||||||| (16896) 16.0 -- 16.9 |||||||||||||||||| (14965) 16.9 -- 17.8 |||||||||||||||| (13315) 17.8 -- 18.7 |||||||||||||| (11387) 18.7 -- 19.6 |||||||||||| (9700) 19.6 -- 20.5 |||||||||| (8388) 20.5 -- 21.4 ||||||||| (7033) 21.4 -- 22.3 ||||||| (5761) 22.3 -- 23.2 |||||| (4872) 23.2 -- 24.0 ||||| (4038) 24.0 -- 24.9 ||||| (3413) 24.9 -- 25.8 |||| (2728) 25.8 -- 26.7 ||| (2099) 26.7 -- 27.6 ||| (1732) 27.6 -- 28.5 ||| (1358) 28.5 -- 29.4 || (1088) 29.4 -- 30.3 || (820) 30.3 -- 31.2 || (676) 31.2 -- 32.1 || (571) 32.1 -- 32.9 | (403) 32.9 -- 33.8 | (319) 33.8 -- 34.7 | (241) 34.7 -- 35.6 | (178) 35.6 -- 36.5 | (111) 36.5 -- 37.4 | (104) 37.4 -- 38.3 | (56) 38.3 -- 39.2 | (48) 39.2 -- 40.1 | (44) 40.1 -- 41.0 | (12) 41.0 -- 41.9 | (32) 41.9 -- 42.7 | (0) [Min] 42.7 -- 43.6 | (18) 43.6 -- 44.5 | (21) Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 154 Códigos 2.8.1.11 PchiUniforme(archivo, No Int) Función 2.8.11 void PchiUniforme(char filename[], int Num Int) Descripción: Esta función sirve de apoyo en la prueba de bondad de ajuste que los datos contenidos en el archivo de nombre filename presenten una distribución uniforme, calculando el valor de χ2 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... int i; // contador printf("\nEste programa verifica que la funcion"); printf("\nChiUniforme(char filename[], int Num_Int)"); printf("\nfuncione correctamente..."); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); funiforme(total, archivo); // genero uniformes... PchiUniforme(archivo, 15); // prueba chiˆ2 printf("\nHistograma Observado..."); histograma(archivo, 15); // dibujar histograma... printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion ChiUniforme(char filename[], int Num_Int, float alpha) funcione correctamente... Cuantos numeros desea generar: 20000 Nombre del archivo: [Incluye extension] test.txt El archivo test.txt contiene 20000 datos. Chiˆ2 = 0.001277 Los datos contenidos en el archivo test.txt parecen presentar distribucion uniforme. Histograma Observado... Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 0.1 0.1 0.2 0.3 0.3 0.4 0.5 0.5 0.6 0.7 0.7 0.8 Efraı́n Soto A. -------------- 0.1 0.1 0.2 0.3 0.3 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.9 ||||||||||||||||||||||||||||||||| (1351) ||||||||||||||||||||||||||||||| (1248) [Min] ||||||||||||||||||||||||||||||||| (1345) ||||||||||||||||||||||||||||||||| (1342) |||||||||||||||||||||||||||||||| (1283) |||||||||||||||||||||||||||||||| (1293) ||||||||||||||||||||||||||||||||| (1321) |||||||||||||||||||||||||||||||| (1281) |||||||||||||||||||||||||||||||||| (1367) |||||||||||||||||||||||||||||||||||| (1458) [Max] ||||||||||||||||||||||||||||||||| (1322) |||||||||||||||||||||||||||||||| (1312) |||||||||||||||||||||||||||||||||| (1358) Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación Intervalo 0.9 -- 0.9 Intervalo 0.9 -- 1.0 155 |||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||||||||| (1359) (1359) Presione una tecla para continuar . . . El siguiente prueba un archivo que tiene datos con distribución normal estándar. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include "estadistica.h" using namespace std; int main(void){ char archivo[15]; // nombre del archivo... printf("\nEste programa verifica que la funcion"); printf("\nChiUniforme(char filename[], int Num_Int)"); printf("\nfuncione correctamente..."); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); PchiUniforme(archivo, 15); printf("\nHistograma Observado..."); histograma(archivo,15); printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion ChiUniforme(char filename[], int Num_Int) funcione correctamente... Nombre del archivo: [Incluye extension] normal.txt El archivo normal.txt contiene 99999 datos. Chiˆ2 = 1.339906 Histograma Observado... Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo -1.1 -- -0.9 | (11) [Min] -0.9 -- -0.7 | (92) -0.7 -- -0.5 || (517) -0.5 -- -0.3 |||| (1948) -0.3 -- -0.1 |||||||||| (5820) -0.1 -- 0.1 ||||||||||||||||||||| (12346) 0.1 -- 0.2 ||||||||||||||||||||||||||||||| (19189) 0.2 -- 0.4 |||||||||||||||||||||||||||||||||||| (22026) [Max] 0.4 -- 0.6 ||||||||||||||||||||||||||||||| (18597) 0.6 -- 0.8 |||||||||||||||||||| (11736) 0.8 -- 1.0 |||||||||| (5414) 1.0 -- 1.2 |||| (1747) 1.2 -- 1.4 || (460) 1.4 -- 1.6 | (80) 1.6 -- 1.8 | (15) Presione una tecla para continuar . . . Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 156 Códigos 2.8.1.12 PchiNormal(archivo, No Int) Función 2.8.12 void PchiNormal(char filename[], int Num Int) Descripción: Esta función sirve de apoyo en la prueba de bondad de ajuste que los datos contenidos en el archivo de nombre filename presenten una distribución normal, calculando el valor de χ2 . La función calcula la media y la desviación estándar de los datos contenidos en el archivo y los utiliza para realizar el cálculo de χ2 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include "estadistica.h" using namespace std; int main(void){ char archivo[15]; // nombre del archivo... printf("\nEste programa verifica que la funcion"); printf("\nPchiNormal(char filename[], int Num_Int)"); printf("\nfuncione correctamente..."); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); PchiNormal(archivo, 15); printf("\nHistograma Observado..."); histograma(archivo,15); printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion PchiNormal(char filename[], int Num\_Int) funcione correctamente... Nombre del archivo: [Incluye extension] Normal.txt El archivo Normal.txt contiene 99999 datos. Media calculada: 0.336161 Desviacion Estandar calculada: 0.338613 Chiˆ2 = 0.000004 Los datos contenidos en el archivo Normal.txt parecen presentar distribucion normal. Histograma Observado... Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo -1.1 -- -0.9 | (11) [Min] -0.9 -- -0.7 | (92) -0.7 -- -0.5 || (517) -0.5 -- -0.3 |||| (1948) -0.3 -- -0.1 |||||||||| (5820) -0.1 -- 0.1 ||||||||||||||||||||| (12346) 0.1 -- 0.2 ||||||||||||||||||||||||||||||| (19189) 0.2 -- 0.4 |||||||||||||||||||||||||||||||||||| (22026) [Max] 0.4 -- 0.6 ||||||||||||||||||||||||||||||| (18597) 0.6 -- 0.8 |||||||||||||||||||| (11736) 0.8 -- 1.0 |||||||||| (5414) 1.0 -- 1.2 |||| (1747) 1.2 -- 1.4 || (460) 1.4 -- 1.6 | (80) 1.6 -- 1.8 | (15) Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 157 Presione una tecla para continuar . . . Un segundo ejemplo donde se utiliza un archivo con datos uniformes es el siguiente: Este programa verifica que la funcion PchiNormal(char filename[], int Num\_Int) funcione correctamente... Nombre del archivo: [Incluye extension] Uniforme.txt El archivo Uniforme.txt contiene 99999 datos. Media calculada: 0.501481 Desviacion Estandar calculada: 0.288523 Chiˆ2 = 79.591026 Histograma Observado... Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 0.1 0.1 0.2 0.3 0.3 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.9 0.9 ---------------- 0.1 0.1 0.2 0.3 0.3 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.9 0.9 1.0 ||||||||||||||||||||||||||||||||||| (6650) ||||||||||||||||||||||||||||||||||| (6591) ||||||||||||||||||||||||||||||||||| (6733) |||||||||||||||||||||||||||||||||| (6522) |||||||||||||||||||||||||||||||||| (6514) ||||||||||||||||||||||||||||||||||| (6677) ||||||||||||||||||||||||||||||||||| (6681) ||||||||||||||||||||||||||||||||||| (6673) ||||||||||||||||||||||||||||||||||| (6701) |||||||||||||||||||||||||||||||||||| (6880) [Max] ||||||||||||||||||||||||||||||||||| (6665) |||||||||||||||||||||||||||||||||| (6513) [Min] ||||||||||||||||||||||||||||||||||| (6730) |||||||||||||||||||||||||||||||||||| (6849) ||||||||||||||||||||||||||||||||||| (6618) Presione una tecla para continuar . . . 2.8.1.13 PchiExponencial(archivo, Num Int, lambda) Función 2.8.13 void PchiExponencial(char filename[], int Num Int, float lambda) Descripción: Esta función sirve de apoyo en la prueba de bondad de ajuste que los datos contenidos en el archivo de nombre filename presenten una distribución normal, calculando el valor de χ2 . La función calcula la media y la desviación estándar de los datos contenidos en el archivo y los utiliza para realizar el cálculo de χ2 . 1 2 3 4 5 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... char archivo[15]; // nombre del archivo... Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 158 Códigos 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 float L; printf("\nEste programa verifica que la funcion"); printf("\nPchiExponencial(char filename[], int Num_Int, float lambda)"); printf("\nfuncione correctamente..."); printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nParametro Lambda de la distribucion: "); scanf("%f", &L); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); fexponencial(total, 3.0, archivo); // genero numeros pseudoaleatorios PchiExponencial(archivo, 15, 3); // prueba de bondad de ajuste printf("\nHistograma Observado..."); histograma(archivo,15); printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion PchiExponencial(char filename[], int Num\_Int, float lambda) funcione correctamente... Cuantos numeros desea generar: 250 Parametro Lambda de la distribucion: 3 Nombre del archivo: [Incluye extension] test.txt El archivo test.txt contiene 250 datos. Media calculada: 0.337249 Chiˆ2 = 0.762427 Histograma Observado... Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 0.2 0.4 0.5 0.7 0.9 1.1 1.3 1.4 1.6 1.8 2.0 2.2 2.3 2.5 ---------------- 0.2 0.4 0.5 0.7 0.9 1.1 1.3 1.4 1.6 1.8 2.0 2.2 2.3 2.5 2.7 |||||||||||||||||||||||||||||||||||| ||||||||||||||||||||||||| (68) |||||||||||||| (35) ||||||||| (23) ||||| (10) ||| (5) || (2) | (1) || (2) || (2) | (1) | (1) | (0) [Min] | (0) [Min] | (1) (98) [Max] Presione una tecla para continuar . . . Enseguida se da un ejemplo donde se utiliza el archivo Uniforme.txt que contiene datos con distribución uniforme. En la lı́nea 10 del código se indica a la función que suponemos que el archivo contiene datos con distribución exponencial con parámetro λ = 3.0 1 2 #include "estadistica.h" using namespace std; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 159 int main(void){ char archivo[15]; // nombre del archivo... float L; // parametro lambda printf("\nEste programa verifica que la funcion"); printf("\nChiUniforme(char filename[], int Num_Int, float alpha)"); printf("\nfuncione correctamente...\n"); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); printf("\nParametro Lambda supuesto: "); scanf("%f", &L); PchiExponencial(archivo, 15, L); printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion ChiUniforme(char filename[], int Num_Int, float alpha) funcione correctamente... Nombre del archivo: [Incluye extension] Uniforme.txt Parametro Lambda supuesto: 3.0 El archivo Uniforme.txt contiene 99999 datos. Media calculada: 0.501481 Chiˆ2 = 288.591888 Presione una tecla para continuar . . . 2.8.1.14 PchiWeibull(Archivo, Num Int, C, K) Función 2.8.14 void PchiWeibull(char filename[], int Num Int, float c, float k) Descripción: Esta función prueba que los datos contenidos en el archivo de nombre filename presenten una distribución Weibull con parámetro promedio. Devuelve el número de datos leidos del archivo, la media de esos datos el valor de χ2 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include "estadistica.h" using namespace std; int main(void){ char archivo[15]; // nombre del archivo... float C, K; // intervalo para generar uniformes printf("\nEste programa verifica que la funcion"); printf("\nChiUniforme(char filename[], int Num_Int, float alpha)"); printf("\nfuncione correctamente..."); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); printf("\nValor del parametro C: "); scanf("%f", &C); printf("\nValor del parametro K: "); scanf("%f", &K); PchiWeibull(archivo, 15, C, K); Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 160 Códigos 16 17 18 19 20 21 printf("\nHistograma Observado..."); histograma(archivo,15); printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion ChiUniforme(char filename[], int Num_Int, float alpha) funcione correctamente... Nombre del archivo: [Incluye extension] Weibull.txt Valor del parametro C: 11.86 Valor del parametro K: 1.77 El archivo Weibull.txt contiene 525577 datos. Media calculada: 10.559526 Chiˆ2 = 0.000090 Los datos contenidos en el archivo Weibull.txt parecen presentar distribucion Weibull. Histograma Observado... Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.0 -- 3.0 |||||||||||||||| (43297) 3.0 -- 5.9 ||||||||||||||||||||||||||||||| (89955) 5.9 -- 8.9 |||||||||||||||||||||||||||||||||||| (104295) [Max] 8.9 -- 11.9 ||||||||||||||||||||||||||||||||| (95096) 11.9 -- 14.8 |||||||||||||||||||||||||| (74286) 14.8 -- 17.8 |||||||||||||||||| (51380) 17.8 -- 20.8 |||||||||||| (32011) 20.8 -- 23.7 ||||||| (17941) 23.7 -- 26.7 |||| (9467) 26.7 -- 29.7 ||| (4486) 29.7 -- 32.7 || (2029) 32.7 -- 35.6 | (871) 35.6 -- 38.6 | (285) 38.6 -- 41.6 | (107) 41.6 -- 44.5 | (54) [Min] Presione una tecla para continuar . . . Otro ejemplo, donde los datos NO presentan distribución Weibull... Este programa verifica que la funcion ChiUniforme(char filename[], int Num_Int, float alpha) funcione correctamente... Nombre del archivo: [Incluye extension] test.txt Valor del parametro C: 11.86 Valor del parametro K: 1.77 El archivo test.txt contiene 250 datos. Media calculada: 0.337249 Chiˆ2 = 1.659585 Histograma Observado... Intervalo 0.0 -- 0.2 Intervalo 0.2 -- 0.4 Intervalo 0.4 -- 0.5 Efraı́n Soto A. |||||||||||||||||||||||||||||||||||| ||||||||||||||||||||||||| (68) |||||||||||||| (35) Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. (98) [Max] Códigos en C++ 2.8 Implementación Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.5 0.7 0.9 1.1 1.3 1.4 1.6 1.8 2.0 2.2 2.3 2.5 ------------- 0.7 0.9 1.1 1.3 1.4 1.6 1.8 2.0 2.2 2.3 2.5 2.7 161 ||||||||| (23) ||||| (10) ||| (5) || (2) | (1) || (2) || (2) | (1) | (1) | (0) [Min] | (0) [Min] | (1) Presione una tecla para continuar . . . 2.8.1.15 PchiRayleigh(archivo, Num Int, media) Función 2.8.15 void PchiRayleigh(char filename[], int Num Int, float Media) Descripción: Esta función prueba que los datos contenidos en el archivo de nombre filename presenten una distribución exponencial con parámetro λ. Devuelve el número de datos leidos del archivo, la media de esos datos el valor de χ2 . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include "estadistica.h" using namespace std; int main(void){ char archivo[15]; // nombre del archivo... float mean; // intervalo para generar uniformes printf("\nEste programa verifica que la funcion"); printf("\nChiUniforme(char filename[], int Num_Int, float alpha)"); printf("\nfuncione correctamente..."); printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); printf("\nMedia de la distribución: "); scanf("%f", &mean); PchiRayleigh(archivo, 15, mean); printf("\nHistograma Observado..."); histograma(archivo,15); printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion ChiUniforme(char filename[], int Num_Int, float alpha) funcione correctamente... Nombre del archivo: [Incluye extension] Rayleigh.txt Media de la distribucion: 12 El archivo Rayleigh.txt contiene 1000 datos. Media calculada: 12.064783 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 162 Códigos Chiˆ2 = 0.541957 Histograma Observado... Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 0.2 -- 2.6 ||||||| (28) 2.6 -- 5.0 ||||||||||||||||||| (87) 5.0 -- 7.4 ||||||||||||||||||||||||||||| (136) 7.4 -- 9.8 |||||||||||||||||||||||||||||||||||| (172) [Max] 9.8 -- 12.2 |||||||||||||||||||||||||||||| (142) 12.2 -- 14.5 ||||||||||||||||||||||||| (119) 14.5 -- 16.9 ||||||||||||||||||| (89) 16.9 -- 19.3 ||||||||||||||||||| (89) 19.3 -- 21.7 |||||||||||| (53) 21.7 -- 24.1 |||||||||| (43) 24.1 -- 26.5 |||| (17) 26.5 -- 28.8 || (7) 28.8 -- 31.2 || (7) 31.2 -- 33.6 || (5) [Min] 33.6 -- 36.0 || (5) [Min] Presione una tecla para continuar . . . 2.8.1.16 RL(archivo) Función 2.8.16 void RL(char filename[]) Descripción: Esta función calcula la recta de mejor ajuste a los datos contenidos en el archivo filename. 1 2 3 4 5 6 7 8 9 10 #include "estadistica.h" using namespace std; int main(void){ char archivo[15]; // nombre del archivo... printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); RL(archivo); system("PAUSE"); return 0; } Nombre del archivo: [Incluye extension] test.txt La recta de mejor ajuste es: y = 1.712 + 0.719 x. Presione una tecla para continuar . . . Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 2.8.1.17 163 RC(archivo) Función 2.8.17 void RC(char filename[]) Descripción: Esta función calcula la parábola de mejor ajuste a los datos contenidos en el archivo filename. 1 2 3 4 5 6 7 8 9 10 #include "estadistica.h" using namespace std; int main(void){ char archivo[15]; // nombre del archivo... printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); RC(archivo); system("PAUSE"); return 0; } Nombre del archivo: [Incluye extension] test.txt La parabola de mejor ajuste es: y = -0.045 xˆ2 + 1.454 x + 0.933 Presione una tecla para continuar . . . Para las dos funciones anteriores, se utilizó el archivo test.txt que contiene la siguiente información: # Este archivo contiene 50 números # pseudoaletorios con distribucion normal # con media = 12.000 y desviacion estándar = 5.000. 28.840973 8.729749 6.863858 6.250802 11.933395 6.088670 7.881029 4.318137 19.204657 7.066312 11.284149 1.689564 23.058068 6.932590 8.060572 16.921389 15.777704 21.330462 13.134103 10.166203 11.624262 13.341073 15.478254 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 164 Códigos 11.428067 12.683624 13.958144 12.400598 8.131033 14.381212 14.918339 6.156746 16.142108 -1.425609 13.150411 10.138522 11.561960 10.334757 8.227782 6.067277 14.986136 8.198230 8.960726 8.599253 10.486869 9.866934 17.731067 9.864873 17.186035 6.512353 7.776886 # Fin del archivo... Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 2.8.2 165 Otras funciones Las siguientes son funciones que están incluidas en el archivo estadistica.h. Las funciones antes mencionadas utilizan las funciones definidas en esta sección para generar números pseudoaleatorios con distibuciones dadas conocidos sus parámetros (en caso de que se requiera indicar). 2.8.2.1 uniforme() Función 2.8.18 double uniforme(void) Descripción: Esta función genera un número pseudoaleatorio con distribución uniforme en el intervalo (0, 1). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... int i; // contador printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); for(i = 1 ; i <= total ; i++){ printf("\n %i,\t %f", i, uniforme()); // } printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 15 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, Presione Códigos en C++ 0.001251 0.563585 0.193304 0.808741 0.585009 0.479873 0.350291 0.895962 0.822840 0.746605 0.174108 0.858943 0.710501 0.513535 0.303995 una tecla para continuar . . . Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 166 Códigos 2.8.2.2 uniforme(a,b) Función 2.8.19 double uniforme(float a, float b) Descripción: Esta función genera un número pseudo-aleatorio con distribución uniforme en el intervalo (a, b). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... float A, B; // intervalo para generar uniformes int i; // contador printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nLimite inferior de la distribucion: "); scanf("%f", &A); printf("\n\nLimite superior de la distribucion: "); scanf("%f", &B); for(i = 1 ; i <= total ; i++){ printf("\n %i,\t %f", i, uniforme(A,B)); // } printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 25 Limite inferior de la distribucion: -100 Limite superior de la distribucion: 100 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, Presione -99.749748 12.717063 -61.339152 61.748100 17.001862 -4.025391 -29.941710 79.192480 64.568010 49.320963 -65.178381 71.788690 42.100284 2.706992 -39.201025 -97.003082 -81.719413 -27.109592 -70.537431 -66.820276 97.705008 -10.861538 -76.183355 -99.066134 -98.217719 una tecla para continuar . . . Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 2.8.2.3 167 weibull(c,k) Función 2.8.20 double weibull(double c, double k) Descripción: Esta función genera números pseudoaleatorios con distribución Weibull. Los parámetros c y k corresponden a la forma y escala de la distribución, respectivamente. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... float C, K; // intervalo para generar uniformes int i; // contador printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nParametro C de la distribucion: "); scanf("%f", &C); printf("\n\nParametro K de la distribucion: "); scanf("%f", &K); for(i = 1 ; i <= total ; i++){ printf("\n %i,\t %f", i, weibull(C,K)); // } printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 25 Parametro C de la distribucion: 11.86 Parametro K de la distribucion: 1.77 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, Presione Códigos en C++ 0.271845 10.668868 4.974081 15.760481 11.030096 9.327647 7.374055 18.813593 16.168644 14.185015 4.658680 17.339041 13.390201 9.855590 6.684013 1.109751 3.152986 7.584638 4.201994 4.521017 27.628521 8.803132 3.692812 0.572603 0.825961 una tecla para continuar . . . Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 168 Códigos 2.8.2.4 rayleigh(media) Función 2.8.21 double rayleigh(float media) Descripción: Esta función genera números pseudoaleatorios con distribución Rayleigh con media media. 1 #include "estadistica.h" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using namespace std; int main(void){ float mean; // parametro de la distribucion int total, i; printf("\nEste programa verifica que la funcion"); printf("\nfloat rayleigh(float media)"); printf("\nfuncione correctamente...\n"); printf("Cuantos numeros deseas generar? "); scanf("%i", &total); printf("\nMedia de la distribucion: "); scanf("%f", &mean); for(i = 1 ; i <= total ; i++){ printf("\nGenerado: %f", rayleigh(mean)); } printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion float rayleign(float media) funcione correctamente... Cuantos numeros deseas generar? 25 Media de la distribucion: 12 Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: 35.005940 10.253663 17.358807 6.238612 9.914491 11.602552 13.868260 4.487969 5.979245 7.319658 17.902631 5.279985 7.916121 11.053911 14.775617 27.752294 20.944032 13.603776 18.738855 18.148271 1.454668 12.172394 19.752192 31.368345 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 169 Generado: 29.418927 Presione una tecla para continuar . . . 2.8.2.5 normal() Función 2.8.22 double normal(void) Descripción: Esta función genera números pseudoaleatorios con distribución uniforme con media = 0.0 y desviacionStd = 1.0, es decir, distribución normal estandarizada. 1 2 3 4 5 6 7 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... int i; // contador printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); 8 9 10 11 12 13 14 15 for(i = 1 ; i <= total ; i++){ printf("\n %i,\t %f", i, normal()); // } printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 25 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, Códigos en C++ 3.368195 -0.654050 -1.027228 -1.149840 -0.013321 -1.182266 -0.823794 -1.536373 1.440931 -0.986738 -0.143170 -2.062087 2.211614 -1.013482 -0.787886 0.984278 0.755541 1.866092 0.226821 -0.366759 -0.075148 0.268215 0.695651 -0.114387 Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 170 Códigos 25, 0.136725 Presione una tecla para continuar . . . 2.8.2.6 normal(media, desviacionStd) Función 2.8.23 double normal(double media, double desviacionStd) Descripción: Esta función genera números pseudoaleatorios con distribución uniforme con media media y desviación estándar desviacionStd, definidas por el usuario. 1 2 3 4 5 6 7 8 9 10 11 12 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... float mean, SD; // intervalo para generar uniformes int i; // contador printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nMedia de la distribucion: "); scanf("%f", &mean); printf("\n\nDesviacion estandar de la distribucion: "); scanf("%f", &SD); 13 14 15 16 17 18 19 for(i = 1 ; i <= total ; i++){ printf("\n %i,\t %f", i, normal(mean, SD)); // printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 20 Media de la distribucion: 100 Desviacion estandar de la distribucion: 12 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 140.418334 92.151398 87.673259 86.201924 99.840149 85.812808 90.114470 81.563529 117.291178 88.159150 98.281958 75.254955 126.539363 87.838215 90.545373 111.811334 109.066489 122.393108 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 19, 20, 171 102.721846 95.598887 Presione una tecla para continuar . . . 2.8.2.7 exponencial(lambda) Función 2.8.24 float exponencial(float lambda) Descripción: Esta función genera números pseudoaleatorios con distribución exponencial y parámetro lambda definido por el usuario. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include "estadistica.h" using namespace std; int main(void){ int total; // números a generar... int i; // contador float L; // Parametro de la distribucion printf("\n\nCuantos numeros desea generar: "); scanf("%i", &total); printf("\n\nParametro lambda de la distribucion: "); scanf("%f", &L); for(i = 1 ; i <= total ; i++){ printf("\n %i,\t %f", i, exponencial(L)); // } printf("\n\n\n"); system("PAUSE"); return 0; } Cuantos numeros desea generar: 25 Media de la distribucion: 0.5 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, Códigos en C++ 0.002504 1.658325 0.429617 3.308248 1.758998 1.307365 0.862463 4.526006 3.461405 2.745610 0.382583 3.917189 2.479210 1.441180 0.724797 0.030196 0.191707 0.906535 0.318725 0.362801 8.935176 1.180071 Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 172 Códigos 23, 24, 25, Presione 0.253584 0.009361 0.017903 una tecla para continuar . . . 2.8.2.8 geometrica(p) Función 2.8.25 int geometrica(float p) Descripción: Esta función genera números pseudoaleatorios con distribución geometrica de parámetro p. 1 #include "estadistica.h" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using namespace std; int main(void){ float p; // parametro de la distribucion int total, i; printf("\nEste programa verifica que la funcion"); printf("\nint geometrica(float p)"); printf("\nfuncione correctamente...\n"); printf("Cuantos numeros deseas generar? "); scanf("%i", &total); printf("\nParametro p supuesto: "); scanf("%f", &p); for(i = 1 ; i <= total ; i++){ printf("\nGenerado: %i", geometrica(p)); } printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion int geometrica(float p) funcione correctamente... Cuantos numeros deseas generar? 25 Parametro p supuesto: 0.25 Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: 0 2 0 5 2 1 0 7 5 4 0 6 3 2 0 0 Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: 173 0 1 0 0 15 1 0 0 0 Presione una tecla para continuar . . . 2.8.2.9 poisson(alpha) Función 2.8.26 int poisson(float alpha) Descripción: Esta función genera números pseudoaleatorios con distribución Poisson de parámetro α. 1 #include "estadistica.h" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using namespace std; int main(void){ float a; // parametro de la distribucion int total, i; printf("\nEste programa verifica que la funcion"); printf("\nint poisson(float alpha)"); printf("\nfuncione correctamente...\n"); printf("Cuantos numeros deseas generar? "); scanf("%i", &total); printf("\nParametro Alpha supuesto: "); scanf("%f", &a); for(i = 1 ; i <= 25 ; i++){ printf("\nGenerado: %i", poisson(a)); } printf("\n\n\n"); system("PAUSE"); return 0; } Este programa verifica que la funcion int poisson(float alpha) funcione correctamente... Cuantos numeros deseas generar? 25 Parametro Alpha supuesto: 3 Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Códigos en C++ 1 598 593 579 655 585 611 604 Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 174 Códigos Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: Generado: 637 606 616 592 622 628 587 565 618 592 613 616 621 610 612 640 581 Presione una tecla para continuar . . . 2.8.2.10 media(archivo), desviacionStd(archivo) Función 2.8.27 double media(char filename[]) Descripción: Esta función calcula la media aritmética de los datos contenidos en el archivo de nombre filename. Función 2.8.28 double desviacionStd(char filename[]) Descripción: Esta función calcula la desviación estándar de los datos contenidos en el archivo de nombre filename. 1 2 3 4 5 6 7 8 9 10 11 12 13 #include "estadistica.h" using namespace std; int main(void){ char archivo[15]; // nombre del archivo... printf("\nNombre del archivo: [Incluye extension] "); scanf("%s", &archivo); histograma(archivo, 20); printf("\n\nMedia calculada: %f", media(archivo)); printf("\n\nDesviacion Estandar calculada: %f", desviacionStd(archivo)); printf("\n\n\n"); system("PAUSE"); return 0; } Nombre del archivo: [Incluye extension] test.txt Intervalo Intervalo Intervalo Intervalo 103.8 118.5 133.2 147.9 Efraı́n Soto A. ----- 118.5 133.2 147.9 162.6 | (4) [Min] | (39) | (126) || (458) Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo Intervalo 162.6 177.3 192.1 206.8 221.5 236.2 250.9 265.6 280.3 295.0 309.8 324.5 339.2 353.9 368.6 383.3 ----------------- 177.3 192.1 206.8 221.5 236.2 250.9 265.6 280.3 295.0 309.8 324.5 339.2 353.9 368.6 383.3 398.0 175 |||| (1210) ||||||| (3011) |||||||||||||| (5881) |||||||||||||||||||||| (9987) ||||||||||||||||||||||||||||||| (13892) |||||||||||||||||||||||||||||||||||| (16299) [Max] |||||||||||||||||||||||||||||||||||| (16221) |||||||||||||||||||||||||||||| (13426) ||||||||||||||||||||| (9513) ||||||||||||| (5625) ||||||| (2636) ||| (1117) || (404) | (110) | (29) | (10) Media calculada: 250.080285 Desviacion Estandar calculada: 34.947873 Presione una tecla para continuar... Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 176 Códigos 2.8.3 Simulación del recurso eólico Este es el proyecto que elegı́ para la materia Simulación de Sistemas en mis cursos. Puedes ver las notas de este curso en mi página de Internet4 . 2.8.3.1 Energı́a extraida del viento Un generador eólico utiliza la energı́a cinética del viento para generar electricidad. Lo que pasa en realidad es que la energı́a del viento es transferida a un rotor que tiene dos o más aspas acopladas mecánicamente al generador eléctrico. La enegı́a cinética que contienen m kilogramos de viento que se mueve a velocidad v [m/s] es: 1 Ek = mv 2 2 Sin embargo, generalmente no conocemos la masa de aire que atravesarán las aspas del generador eólico, ası́ que es una mejor idea expresarlo con términos de la densidad y la velocidad del viento. Por definición, la densidad ρ del viento es igual al cociente de su masa al volumen. De donde, m = ρ · V . Podemos ver el volumen de aire que atraviesan las aspas del generador eólico como el cilindro de altura v · t y área de base igual al área A [m2 ] que barren las aspas del generador. Entonces, por unidad de tiempo, el volumen de aire que atraviesan las aspas del generador eólico es: V =A·v Flujo volumétrico (m3 /s) Ası́ que la energı́a cinética del viento con velocidad v puede expresarse como: P = 1 ρAv 3 2 potencia (W) El recurso eólico de dos sitios distintos se compara en base a la potencia eólica especı́fica, es decir, por cada metro cuadrado de área que barren sus aspas. Sabemos que la potencia eólica especı́fica varı́a con el cubo de la velocidad del viento. 4 Puede accesar a mi página de Internet en: http://yalma.fime.uanl.mx/˜ efrain/ Para encontrar las notas vaya a Descargas, después a Notas de mis Cursos, y finalmente a Mis Notas Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 177 √ Considerando que 3 2 ≈ 1.2599, podemos darnos cuenta que cuando la velocidad del viento aumenta en un 25.99% la potencia generada crece al doble. Por otra parte, si la velocidad del viento disminuye el mismo porcentaje, la potencia generada disminuye a la mitad. √ También, 3 3 ≈ 1.4422 nos indica que si la velocidad del viento crece un 44.22%, la potencia eléctrica generada aumentará al triple, mientras que si la velocidad del viento disminuye en esa misma cantidad, la potencia generada disminuirá a la tercera parte. He aquı́ la importancia de caracterizar la distribución de la velocidad del viento para poder determinar correctamente la potencia generada en un sitio especı́fico. La energı́a extraida del viento es igual a la diferencia de la energı́a cinética del viento que atraviesa el generador antes y después de pasar a través de él: P0 = 1 · ṁ · (v 2 − v02 ) 2 donde P0 es la potencia [W] absorvida por el generador, ṁ es el flujo másico [kg/s], v es la velocidad del viento [m/s] al entrar al generador y v0 es la velocidad del viento [m/s] después de atravesar el generador. La velocidad del viento es discontinua de v a v0 en el plano de las aspas del generador. El flujo másico del viento a través de las aspas se calcula multiplicando la densidad por la velocidad promedio: v + v0 ṁ = ρ · A · 2 La potencia mecánica que mueve al rotor, que mueve finalmente al generador eléctrico es: 1 v + v0 P0 = ρA · · (v 2 − v02 ) 2 2 Esta expresión puede reescribirse como: v 2 v0 0 1+ 1− 1 v v P0 = ρ A · v 3 2 2 Podemos definir: v 2 v0 0 1− v v Cp = 2 que representa la fracción del viento que “aprovechan” las aspas del generador eólico. 1+ Para velocidades de entrada del viento a las aspas del generador eólico, los valores de Cp dependen de la proporción v0 /v, alcanzando un máximo cuando este cociente es igual a 1/3. Entonces, Cp = 16/27 ≈ 0.5926. Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 178 Códigos La máxima potencia transmitida a las aspas ocurrirá cuando v = 3 v0 , o bien, cuando Cp = 0.5926. Entonces, P0 = 1 ρ A · v 3 · (0.59) 2 En diseños prácticos de aspas, el valor máximo alcanzado es de aproximadamente 0.5 para turbinas de alta velocidad que trabajan con dos aspas, y entre 0.2 y 0.4 para turbinas de baja velocidad con más aspas. Considerando Cp = 0.5 obtenemos una expresión más simple: P0 = 2.8.4 1 ρ A · v3 4 Distribución del viento Dato que el viento se origina con las diferencias de densidad en el aire debido a los cambios de temperatura que el sol ocasiona en el aire atmosférico, con la colaboración del movimiento rotativo de la tierra, los patrones de viento generalmente se repiten con periodicidad de un año. Dado que la potencia generada con un generador eólico es proporcional al cubo de la velocidad del viento, su distribución se convierte en la medición más importante para determinar la cantidad de energı́a que un sitio considerado. El comportamiento de la velocidad del viento nunca es estable. Depende de muchos factores, entre el clima, la topografı́a del lugar y la altura en la que se mide a partir del suelo. La velocidad del viento cambia continuamente, por lo que la velocidad promedio debe basarse en mediciones de al menos una década. De esta manera tendremos mayor confianza en el valor asignado al sitio. Sin embargo, medir la velocidad del viento por 10 años requiere de una inversión grande además de que un proyecto generalmente no puede esperar tanto. En los casos en que se tienen poca información, se mide la velocidad del viento y ésta se compara con la velocidad medida en otro sitio cercano y a partir de estas consideraciones se realiza una estimación del promedio anual del sitio considerado. Las variaciones de la velocidad del viento se pueden describir por una función de distribución de probabilidad. 2.8.4.1 Distribución Weibull La distribución de la velocidad del viento en una localidad puede descibirse utilizando al distribución Weibull con el parámetro k de forma y el parámetro c de escala. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 179 La probabilidad de que la velocidad de viento sea de v m/s durante algún intervalo de tiempo dado es: k v k−1 −(v/c)k e para 0 < v < ∞ h(v) = c c En la gráfica de distribución de probabilidad se grafica h vs. v para distintos intervalos de tiempo, donde: h= Fracción de tiempo en que la velocidad del viento está entre v y v + ∆v ∆v Por definición de la función de probabilidad, la probabilidad de que la velocidad del viento esté entre cero e infinito en ese periodo de tiempo es igual a uno: Z∞ h dv = 1 0 Si elegimos el periodo de tiempo igual a un año, y expresamos la integral en términos del número de horas en un año, entonces tenemos: h= Número de horas que la velocidad del viento está entre v y v + ∆v ∆v Las unidades de h son horas por año por metros por segundo, y la integral se convierte en 8 760, el número total de horas en el año, en lugar de la unidad. Para la distribución Weibull con valor de k = 1 tenemos la distribución exponencial. En el caso k = 2 la distribución se conoce como distribución Rayleigh. Este tipo de distribución es el que presenta la velocidad de viento en muchos sitios. 2.8.4.2 Distribución Rayleigh • Distribución Rayleigh: 2 f (x) = Φ(u) = 2 αxe−αx para x > 0 0 para x ≤ 0 donde: α > 0 u 2 2u exp − 2 c c Para esta distribución: µ = σ2 Códigos en C++ = r 1 π 2 α 1 π 1− α 4 Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 180 Códigos 2.8.4.3 Distribución de energı́a Si definimos la función de densidad de energı́a como: e= Contribución en kWh al año por las velocidades entre v y v + ∆v ∆v podremos graficar esta distribución y la distribución de probabilidad de la velocidad y conocer a partir de qué velocidad el número de horas que el viento presenta esa velocidad, decrece más rápido que v 3 . Este valor nos indicará un decremento neto en la contribución energética anual global. 2.8.4.4 Anemómetros digitales La velocidad promedio de un sitio en un periodo de tiempo se calcula sumando muchas lecturas en ese periodo de tiempo entre el número de lecturas. La mayorı́a de los anemómetros se instalaban con el propósito de medir la velocidad del viento y no con propósitos de la medición del recurso energético. Ası́ que el promedio calculado como se indicó se realizaba de manera semejante para una hora, un dı́a y para un año: n 1X vi v̄ = n i=1 Pero para estimar el recurso eólico disponible en un lugar necesitamos calcular: v u n u1 X 3 3 vrmc = t v n i=1 i La expresión anterior no toma en cuenta la densidad del aire, que también afecta la cantidad de energı́a producida por el viento. Para calcular el recurso eólico de un sitio se recomienda utilizar la siguiente fórmula: n Prmc = 1 X ρi vi3 2 n i=1 donde n es el número de mediciones realizadas, ρi es la densidad del aire [kg/m3 ] en el momento de realizar la i-ésima medición y vi es la velocidad del viento [m/s] en la i-ésima medición, y Prmc representa la densidad de energı́a promedio. 2.8.4.5 Predicción del recurso eólico La energı́a que podemos aprovechar del viento depende de su velocidad, la cual es una variable aleatoria. Para el operador de la granja eólica esto representa Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 181 una dificultad para designar el despacho de energı́a a la red, además de que no se conoce la cantidad de energı́a disponible con anticipación. Sin embargo, si la velocidad del viento puede pronosticarse con varias horas de anticipación, podemos despachar la energı́a de una manera cómoda. Alexiadis, et al5 , han propuesto una nueva técnica para pronosticar la velocidad del viento y la cantidad de energı́a producida con muchas horas de anticipación. La técnica está basada en correlación cruzada en sitios vecinos y redes artificiales neuronales. La técnica propuesta puede mejorar significativamente la precisión de las predicciones comparado con el modelo comúnmente usado. El modelo propuesto se calibra en diferentes sitios en un periodo de un año. 2.8.5 Un caso especı́fico • La Venta, Oaxaca. México6 . – El viento presenta Distribución Weibull. – Velocidad promedio del viento: 9.3 m/s. – k = 1.77, c = 11.86 m/s a una altura de 32 metros. – k = 1.73, c = 10.44 m/s a una altura de 15 metros. 2.8.6 Implementación Enseguida se muestra el código de la implementación elaborada en el lenguaje C++ . /* Nombre del archivo: windFinal.cpp Este programa simula la velocidad de viento de una localidad de acuerdo a la distribución que se especifique. Calcula además, la densidad de recurso eólico local (Watts/metro cuadrado) y en el caso de la distribución Weibull, calcula la velocidad de viento promedio como media ponderada de la velocidad media de cada intervalo por la probabilidad de que el viento presente esa velocidad. ------------------------------------------------------------------Autor: Efraı́n Soto Apolinar Email: [email protected] [email protected] Fecha de última Modificación: 01 de mayo de 2008 5 Alexiadis, M. C., Dokopoulos, P. S., and Sahsamanogdou, H. S. 1998. Wind Speed and Power Forecasting Based on Spatial Correlation Models, IEEE Paper No. PE-437-EC-0-041998. 6 Fuente: Evaluación del recurso eólico de La Venta, Juchitán, Oaxaca. M. A. Borja, O. A. Jaramillo, M. F. Morales. Instituto de Investigaciones Eléctricas. Temixco, Morelos, México. Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 182 Códigos ------------------------------------------------------------------*/ #include <cstdio> // Librerı́a básica... #include <cstdlib> // Otra Librerı́a... #include <iostream> // Funciones básicas: input/output #include <math.h> // funciones matemáticas #include <conio.h> // para usar: getche, getch #include <fstream> // para grabar los datos generados... // double uniforme (void); double weibull(double c, double k); // void duniforme(void); void drayleigh(void); void dweibull(void); float windPower(double windSpeed); using namespace std; int main(void){ char respuesta, semilla; int i = 0; int continuar; char distribucion; for (;;){ // for infinito... //continuar = 0; cout << "Este programa simula el Recurso Eolico"; cout << "\nde un sitio dados los parametros de su distribucion."; for (;;){ // hasta que presione S ó N cout << "\n\nDesea iniciar la semilla del aleatorio? [S/N] "; cin >> semilla; if (semilla == ’S’ || semilla == ’s’){ srand(time(0)); cout << "Se reinicia la semilla..."; break; // salir del for infinito } if (semilla == ’N’ || semilla == ’n’){ cout << "No se reinicia la semilla..."; break; // salir del for infinito } cout << "\n\nError en argumento..."; } // end for infinito para la semilla cout << "\n\nSeleccione la distribucion estadistica "; cout << "\nque presenta el viento de la localidad: "; cout << "\n[R] Rayleigh."; cout << "\n[W] Weibull."; cout << "\n[C] Cancelar..."; cout << "\nIngrese una opcion: "; cin >> distribucion; switch (distribucion){ case ’R’: drayleigh(); break; case ’r’: drayleigh(); break; case ’W’: dweibull(); break; case ’w’: dweibull(); break; case ’C’: break; case ’c’: break; default: cout << "\n\nError en argumento..."; Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 183 cout << "\nPor favor, intente de nuevo..."; continuar = 1; } // end switch if (continuar == 0){ // se debe salir... break; } // pregunto si desea salir... cout << "\n\nPresione < S > para salir... < C > para continuar..."; respuesta = getche(); if ((respuesta == ’S’)||(respuesta == ’s’)){ break; // Salir del ciclo for inicial... } cout << "\n\n\n"; respuesta = getche(); } // end for infinito... return 0; } /************************************** Declaro la función UNIFORME... ***************************************/ double uniforme(void){ // Esta función genera un número pseudoaleatorio // en el intervalo (0,1) con distribución uniforme. return (1.0 * rand()/(1.0 * RAND_MAX)); } /************************************** Declaro la función WEIBULL... ***************************************/ double weibull(double c, double k){ // Esta función genera números pseudoaleatorios // con distribución Weibull double x; x = c * pow(-log(1 - uniforme()), 1/k); return x; } /************************************** Declaro la función RAYLEIGH... ***************************************/ double rayleigh(double media){ // Esta función genera números pseudoaleatorios // con distribución rayleigh // Fuente: // http://www.brighton-webs.co.uk/distributions/rayleigh.asp double factor, r; factor = media / 1.253314; r = sqrt(-2 * factor * factor * log(uniforme())); return r; } /************************************** Declaro la función DWEIBULL.. ***************************************/ void dweibull(void){ /* Para simular viento con distribución Weibull... */ int I[24]; // los intervalos... int max =0, min = 1000000; //int total; // cuántos vamos a generar... int i = 0, j; // contadores double x; // el número generado... double escala; // para hacer la gráfica... int factor; // para hacer la gráfica... //double k = 0.0, c = 1.0; // parámetros Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 184 Códigos double c, k; // parámetros alpha y beta double t; // tiempo float velocidadProm = 0; // Velocidad Promedio float sv3 = 0;// suma de cubo de velocidad float densidadEnergetica; float energia = 0; // Energia anual // cout << "\nValor del parametro c: "; cin >> c; // alpha cout << "Valor del parametro k: "; cin >> k; // beta t = 0; // reinicio el tiempo del experimento... FILE* f = fopen("speedwei.txt", "w+"); // limpio la memoria del array... for (i = 0 ; i <= 24 ; i++){ I[i] = 0; } for (t = 0; t < 8760; t++){ x = weibull(c, k);// Genero un pseudoaleatorio fprintf(f, "%f\n", x); // grabo en archivo... sv3 += pow(x, 3.0) / 4.0; energia += windPower(x); for (i = 0 ; i <= 24 ; i++){ if ((x > 0.1 * i * c) && (x <= 0.1 * (i + 1) *c)){ I[i]++; break; } } } fclose(f); // Calculo la velocidad promedio... for (i = 0 ; i <= 24 ; i++){ velocidadProm += 1.0 * I[i] * c / 8760; } velocidadProm = velocidadProm * 465 / 593; // factor de escala... // Encuentro el intervalo con mayor número de ocurrencias for (i = 0; i <= 24 ; i++){ if (I[i] > max){ max = I[i]; } if (I[i] < min){ min = I[i]; } } for (i = 0 ; i <= 24 ; i++){ printf("\n%.2f m/s -- %.2f m/s ", (0.1*i*velocidadProm), (0.1*(i+1)*velocidadProm)); escala = 35.0 * I[i] / max; factor = (int)(escala + 0.5); // redondeo // Imprime la barra del intervalo (i-1) for (j = 0 ; j <= factor ; j++){ cout << "|"; } // termina de imprimir la barra... if (I[i] == max){ cout << " (" << I[i] << ") [Maximo]"; continue; } if (I[i] == min){ cout << " (" << I[i] << ") [Minimo]"; continue; } cout << " (" << I[i] << ")"; } printf("\n\nVelocidad Promedio del viento: %.2f m/s.", velocidadProm); // calculo recurso energético... densidadEnergetica = sv3 / (2 * 8760); printf("\nDensidad energetica promedio: %.3f W/mˆ2", densidadEnergetica); printf("\nEnergia anual estimada: %.2f W-hr/mˆ2.", energia); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 185 return; } // Fin de la función DWEIBULL /************************************** Declaro la función DRAYLEIGH.. ***************************************/ void drayleigh(void){ int I[24]; // los intervalos... int max =0, min = 1000000; int total; // cuántos vamos a generar... int i, j; // contadores int imax, imin; double t; double x; // el número generado... float sv3 = 0.0; float densidadEnergetica; float energia = 0; // Energia anual float media; // parámetro de la distribución double escala; // para hacer la gráfica... int factor; // para hacer la gráfica... FILE* f = fopen("speedray.txt", "w+"); for(;;){// hasta que indique el valor de lambda cout << "\nIntroduzca la velocidad media del viento: "; scanf("%f", &media); if (media <= 0.0){ cout << "\n\nEl valor debe ser positivo..."; cout << "\nPor favor intente de nuevo...\n"; continue; } break; } // limpio la memoria del array... for (i = 0 ; i <= 24 ; i++){ I[i] = 0; } for (t = 0; t < 8760; t++){ x = rayleigh(media);// Genero un pseudoaleatorio x = x * 593 / 465; fprintf(f, "%f\n", x); // grabo en archivo... sv3 += pow(x, 3.0) / 4; energia += windPower(x); for(i = 0 ; i <= 24 ; i++){ if ((x > 0.1 * i * media) && (x <= 0.2 * (i + 1) * media)){ I[i]++; break; } } } fclose(f); // Encuentro el intervalo con mayor número de ocurrencias for (i = 0; i <= 24 ; i++){ if (I[i] > max){ max = I[i]; imax = i; } if (I[i] < min){ min = I[i]; imin = i; } } // Ahora imprimo los resultados... for (i = 0 ; i <= 24 ; i++){ printf("\n%.2f m/s -- %.2f m/s ", (0.1*i*media), (0.1*(i+1)*media)); escala = 35.0 * I[i] / max; factor = (int)(escala + 0.5); // redondeo // Imprime la barra del intervalo (i-1) for (j = 0 ; j <= factor ; j++){ Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 186 Códigos cout << "|"; } // termina de imprimir la barra... if (I[i] == max){ cout << " (" << I[i] << ") [Maximo]"; continue; } if (I[i] == min){ cout << " (" << I[i] << ") [Minimo]"; continue; } cout << " (" << I[i] << ")"; } // calculo recurso energético... densidadEnergetica = sv3 / (2 * 8760); printf("\n\nDensidad energetica promedio: %.3f W/mˆ2", densidadEnergetica); printf("\nEnergia anual estimada: %.2f W-hr/mˆ2.", energia); return; } // Fin de la función DRAYLEIGH /************************************** Declaro la función WINDPOWER.. ***************************************/ float windPower(double windSpeed){ /* Esta función calcula la energı́a producida por el generador considerando la el teorema de Welt’z, Densidad del aire = 1,000 kg/mˆ3, Area de rotor = 1 mˆ2, v ---> generada por el programa, windspeed (con distribución dada) */ double rho = 1.00; // densidad del aire double potencia; // Potencia generada double eficiencia = 0.15; // eficiencia del generador double weltz = 0.59; // factor de terorema de Weltz potencia = eficiencia * rho * weltz * pow(windSpeed,3); return potencia; }s 2.8.7 Resultados de la simulación Se consideraron los siguientes datos: • Velocidad promedio del viento: 9.3 m/s. • k = 1.77, c = 11.86 m/s. que corresponden a La Venta, Oaxaca. Los parámetros de la distribución Weibull están calculados a partir de mediciones de velocidad de viento realizadas a 53 metros de altura (respecto del suelo). Este programa simula el Recurso Eolico de un sitio dados los parametros de su distribucion. Desea iniciar la semilla del aleatorio? [S/N] s Se reinicia la semilla... Seleccione la distribucion estadistica que presenta el viento de la localidad: Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.8 Implementación 187 [R] Rayleigh. [W] Weibull. [C] Cancelar... Ingrese una opcion: w Valor del parametro c: 11.86 Valor del parametro k: 1.77 0.00 m/s -- 0.93 m/s ||||||||| (168) 0.93 m/s -- 1.85 m/s ||||||||||||||||||| (366) 1.85 m/s -- 2.78 m/s ||||||||||||||||||||||| (443) 2.78 m/s -- 3.70 m/s |||||||||||||||||||||||||||||||| (609) 3.70 m/s -- 4.63 m/s |||||||||||||||||||||||||||||||||||| (693) [Maximo] 4.63 m/s -- 5.55 m/s ||||||||||||||||||||||||||||||||||| (674) 5.55 m/s -- 6.48 m/s |||||||||||||||||||||||||||||||||||| (684) 6.48 m/s -- 7.40 m/s |||||||||||||||||||||||||||||||||| (652) 7.40 m/s -- 8.33 m/s ||||||||||||||||||||||||||||||||||| (681) 8.33 m/s -- 9.25 m/s ||||||||||||||||||||||||||||||| (600) 9.25 m/s -- 10.18 m/s |||||||||||||||||||||||||||| (538) 10.18 m/s -- 11.10 m/s |||||||||||||||||||||||| (453) 11.10 m/s -- 12.03 m/s |||||||||||||||||||||| (420) 12.03 m/s -- 12.95 m/s ||||||||||||||||||| (363) 12.95 m/s -- 13.88 m/s ||||||||||||||| (287) 13.88 m/s -- 14.80 m/s |||||||||||||| (262) 14.80 m/s -- 15.73 m/s |||||||||| (180) 15.73 m/s -- 16.65 m/s |||||||||| (187) 16.65 m/s -- 17.58 m/s |||||||| (144) 17.58 m/s -- 18.50 m/s ||||| (85) 18.50 m/s -- 19.43 m/s ||||| (87) 19.43 m/s -- 20.35 m/s ||| (39) 20.35 m/s -- 21.28 m/s ||| (46) 21.28 m/s -- 22.21 m/s ||| (32) 22.21 m/s -- 23.13 m/s || (22) [Minimo] Velocidad Promedio del viento: 9.25 m/s. Densidad energetica promedio: 313.121 W/mˆ2 Energia anual estimada: 1942003.75 W-hr/mˆ2. Presione < S > para salir... < C > para continuar...c Este programa simula el Recurso Eolico de un sitio dados los parametros de su distribucion. Desea iniciar la semilla del aleatorio? [S/N] s Se reinicia la semilla... Seleccione la distribucion estadistica que presenta el viento de la localidad: [R] Rayleigh. [W] Weibull. [C] Cancelar... Ingrese una opcion: r Introduzca la velocidad media del viento: 9.3 0.00 m/s -- 0.93 m/s ||||||| (182) 0.93 m/s -- 1.86 m/s ||||||||||||||||| (496) 1.86 m/s -- 2.79 m/s ||||||||||||||||||||||||| (727) 2.79 m/s -- 3.72 m/s |||||||||||||||||||||||||||||| (895) 3.72 m/s -- 4.65 m/s |||||||||||||||||||||||||||||||||| (991) 4.65 m/s -- 5.58 m/s |||||||||||||||||||||||||||||||||||| (1064) [Maximo] 5.58 m/s -- 6.51 m/s |||||||||||||||||||||||||||||||| (950) 6.51 m/s -- 7.44 m/s |||||||||||||||||||||||||||||||| (937) 7.44 m/s -- 8.37 m/s ||||||||||||||||||||||||| (733) 8.37 m/s -- 9.30 m/s ||||||||||||||||||| (557) 9.30 m/s -- 10.23 m/s |||||||||||||| (399) 10.23 m/s -- 11.16 m/s |||||||||| (284) Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 188 Códigos 11.16 12.09 13.02 13.95 14.88 15.81 16.74 17.67 18.60 19.53 20.46 21.39 22.32 m/s m/s m/s m/s m/s m/s m/s m/s m/s m/s m/s m/s m/s -------------- 12.09 13.02 13.95 14.88 15.81 16.74 17.67 18.60 19.53 20.46 21.39 22.32 23.25 m/s m/s m/s m/s m/s m/s m/s m/s m/s m/s m/s m/s m/s |||||||| (222) |||||| (145) ||| (75) || (36) || (35) || (17) | (6) | (6) | (1) | (2) | (0) [Minimo] | (0) [Minimo] | (0) [Minimo] Densidad energetica promedio: 395.494 W/mˆ2 Energia anual estimada: 2452892.00 W-hr/mˆ2. Presione < S > para salir... < C > para continuar... El número entre paréntesis a la derecha de cada intervalo indica la cantidad de horas que se tuvieron velocidades de viento en ese intervalo en un año, considerando que la distribución de probabilidad de esa variable aleatoria sigue la distribución indicada. Es de notar que la densidad energética varı́a al considerar distintas distribuciones, a pesar de utilizar los datos de un sitio obtenidos a partir del mismo estudio y realizar el cálculo de la densidad de recurso eólico local con la misma metodologı́a. Para la distribución Weibull se obtuvo una densidad energética de 315.558 W/m2 , mientras que para el caso de la distribuión Rayleigh se obtuvo un valor correspondiente de 403.202 W/m2 . El primer caso siendo un 78.26% de la segunda estimación. También es importante indicar que no se calcula la densidad de recurso eólico a partir de la velocidad promedio estimada, sino con las velocidades de viento, conforme se van generando estos valores con la distribución correspondiente. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.9 Esqueletos 2.9 189 Esqueletos Aquı́ encontrarás partes de programas que pueden servir. Solamente necesitas copiar y pegar. • Declaración de variables y constantes. double aumento=0.076; int meses; char respuesta = ’c’; const double pi = 3.141592654; char nombre[15]; // el [15] indica la longitud de la cadena <<nombre>> • Ingresar una variable. cout << "\nIngresa una variable: "; cin >> variable; • Ciclo infinito. for (;;) { // Aquı́ va el procedimiento... } • Preguntar si desea continuar... // No olvides declarar la variable // char respuesta; // al inicio del programa... // Cuando termine va a preguntar: cout << "Presione < S > para salir..."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)) { break; // Salir del ciclo... } cout <<"\n\n\n"; Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 190 Códigos • Los dos anteriores combinados. // No olvides declarar la variable // char respuesta; // al inicio del programa... for (;;) { // Aquı́ va el procedimiento... // Cuando termine va a preguntar: cout << "Presione < S > para salir..."; cin >> respuesta; if ((respuesta == ’S’)||(respuesta == ’s’)) { break; // Salir del ciclo... } cout << "\n\n\n"; } • Manejo de archivos. I/O. /* ifstream -> Significa Input - File - Stream ofstream -> Significa Ouput - File - Stream Para trabajar con archivos se requiere incluir: #include <fstream.h> en el preámbulo del programa... */ // Paso 1. Abrir el archivo de encabezado #include <fstream.h> // Otras cosas que se requieren... int x,y; // Declaro las variables para el archivo // desde el cual voy a leer la información... // Paso 2. Declarar el ifstream in_file; // ofstream out_file; // // ifstream y ofstream // archivo fstream.h Stream Desde aquı́ voy a leer... Aquı́ voy agrabar información... están definidos en el // Paso 3. Abrir el archivo para leer información... in_stream.open("misdatos.dat"); Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.9 Esqueletos 191 // Paso 4. Leo información desde el archivo... in_stream >> x >> y; // Paso 5. Abrir el archivo para grabar infomación... out_stream.open("misdatos.dat"); // Paso 6. Escribo información en el archivo... out_stream << x << y; // Paso 7. Cierro los archivos... in_stream.close(); out_stream.close(); /* En C++ no se requiere cerrar los archivos, pero NO todos los compiladores tienen esta caracterı́sitica... Puede ser que en ANSI-C ó en C esto cambie... */ • Pregunto si se logró abrir el archivo... in_stream.open("misdatos.dat"); if (in_stream.fail()) { cout << " No se logró abrir el archivo..." exit(1); // Finaliza el programa } out_stream.open("misdatos.dat"); if (out_stream.fail()) { cout << " No se logró abrir el archivo..." exit(1); // Finaliza el programa } /* La función exit está definida en el archivo: stdlib.h de manera que debemos incluir en el preámbulo del programa la instrucción: #include <stdlib.h> Utilizamos: exit(1); En caso de que el programa deba abortar debido a un error en el programa o exit(0); En cualquier otro caso. */ Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 192 Códigos • Números de dı́gitos a grabar... /* Formato para los datos a grabar en los archivos... En este caso se supone ue se graban datos tipo double. */ out_stream.setf(ios::fixed); out_stream.setf(ios::showpoint); out_stream.precision(2); • Uso de manipuladores de formato de datos... /* Para utilizar los manipuladores en este código se requiere incluir: #include <iomanip.h> */ cout.setf(ios::fixed); cout.setf(ios::showpoint); cout << "(" << setprecision(2) << x << "," << y << ")" << endl; /* Esto imprime en pantalla: (x_val,y_val) Donde x_val -> es el valor de la variable x, y_val -> es el valor de la variable y. */ Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 2.10 Lecciones aprendidas 2.10 193 Lecciones aprendidas 1. No utilices dos apóstrofos seguidos cuando apliques la instrucción cout. Debes usar comillas dobles (") en su lugar. 2. En la instruccion cout debes utilizar << sin dejar espacio entre ellos. 3. Podemos definir las variables justo antes de usarlas, igual que al principio. 4. Los identificadores (nombres de las variables y constantes) deben iniciar con una letra o con un guión bajo. 5. Se requiere un punto y coma (;) por cada cout utilizado. No utilices varios ; aún si se extiende varios renglones. 6. La instrucción \n para indicar un salto de lı́nea siempre debe estar encerrado dentro de las comillas. Posiblemente junto a una cadena de caracteres. 7. La instrucción endl; nunca debe estar encerrado dentro de las comillas. 8. Los números no deben contener comas. Usa punto (decimal) en su lugar. 9. Las constantes del tipo int no deben contener punto decimal. 10. Las constantes del tipo long equivale a long int. 11. Las constantes del tipo char deben encerrarse entre apóstrofos (’). 12. Las constantes del tipo string deben encerrarse entre comillas ("). ’c’ es una constante del tipo char. ”c” es una constante del tipo string. 13. No podemos almacenar el valor de un tipo de dato en un otro tipo. 14. Si una variable del tipo bool tiene un valor distinto de cero, entonces tomará el valor true. Si su valor es cero, entonces, tomará el valor false. 15. Si sumamos uno o dos datos del tipo double, el resultado será del tipo double. 16. El operador % (módulo) debe ser usado con datos del tipo entero. 17. C++ siempre respeta la prioridad de las operaciones de acuerdo al álgebra básica. 18. El operador para comparar la igualdad entre dos valores es: ==. 19. El operador para asignar un valor a un identificador es: =. Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 194 Códigos • Si cometemos el error de escribir a = 5 en lugar de a == 5, C++ siempre ejecuta la parte then{}, es decir, supone que la expresión booleana es verdadera. • lo anterior ocurrirá siempre que se asigne un valor distinto de cero. • En caso de que se asigne cero al identificador, se ejecutará la parte else{}. 20. Las expresiones booleanas deben ser encerradas entre paréntesis, para evitar errores en el uso del if...then. 21. Es una buena idea empezar el programa imprimiendo en pantalla una pequeña descripción de lo que realiza el mismo. Ası́ el usuario conocerá qué datos tiene sentido dar al programa y además qué resultados esperar. 22. Debemos definir la función antes de llamarla... Debe hacerse después de las instrucciones #include y antes del int main(). 23. inline member functions no deben incluir ciclos (for, while...) porque al compilar las va a enviar como out of line functions. lo más que se debe hacer con inline member functions es asignar valores o leerlos.7 7 Disculpa esta nota... Sé que solamente la entiendo yo. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 3 End matter Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 196 End matter 3.1 Fuentes bibliográficas Actualmente estoy aprendiendo a programar en el lenguaje C++ por medio de varios libros que he encontrado muy buenos, sobre todo para los principiantes, como yo. Te recomiendo que los adquieras. Los libros enlistados son los que más he consultado, aunque leo otros más para conocer varias explicaciones de una misma herramienta y poder adquirir una visión más clara del arte llamado C++ . m m C++ for dummies Stephen Randy Davis. Wiley Publishing Co. 2004. New Jersey, USA. (5th Edition) Problem solving with C++ Walter Savitch. Ed. Addison Wesley. 1999. (2nd Edition) C++ for mathematicians Edward Scheinerman. Ed. Chapman & Hall. 2006. C++ Demystified: A Self-Teaching Guide Jeff Kent McGraw-Hill/Osborne. 2004 C++ for Business Programming John C. Molluzzo Prentice Hall. 2005. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ Indice alfabético Algoritmo, 8 Asignación, 13 Funciones Predefinidas, 22 Trigonométricas, 22 Código, 8 Caracteres especiales, 12 Ciclo, 16 do... while, 16 for, 16 while, 16 Comparaciones, 15 Compilador, 8 Compilar, 9 Constantes, 12 Correr, 9 Datos Tipos de, 11 Identificador, 10 If then else, 15 Operaciones Booleanas, 21 Unitarias, 15 Operadores de comparación, 15 Palabras reservadas, 11 Programa, 8 Sintaxis, 9 Fórmulas matemáticas, 14 Ejemplo Variable Cadenas de caracteres, 41 Definición, 10 Ciclo for, 49, 50, 55–58 Variables Ciclo while, 58 Declaración, 12 Condicional If, 46, 51–53, 58 Declarar constantes, 41 Fórmulas matemáticas, 42, 43, 45 Funciones matemáticas, 54, 55 Error de Sintaxis, 9 Lógico, 10 Mensajes de, 9 Códigos en C++ Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Efraı́n Soto A. 198 INDICE ALFABÉTICO 3.2 Términos de uso Utiliza los códigos como una guı́a para aprender a programar. No hay ninguna garantı́a de que los códigos estén libres de cualquier tipo de error. Efraı́n Soto Apolinar no es responsable por cualesquiera daños ocasionados por el uso de este material. Tienes derecho de leer el material y de divulgarlo a otras personas, con la única condición de que no modifiques el documento en ninguna forma. Si deseas utilizar alguna parte del material, puedes hacerlo, con la única condición de que menciones la fuente, i.e., este material y a Efraı́n Soto Apolinar como el autor. Espero que este material pueda ser de ayuda a muchas personas que desean aprender a programar en C++. Con estos programas estoy aprendiendo junto contigo. En realidad el material que estas leyendo lo estoy generando como un resumen de lo que voy aprendiendo. Voy a utilizarlo en lo futuro como una referencia. Este material está siendo actualizado continuamente. Te agradeceré que me envı́es un mensaje en caso de que encuentres errores en los códigos, en las definiciones o en la ortografı́a y/o gramática del mismo. El material no ha tenido ninguna revisión. Agradezco infinitamente tu ayuda. Efraı́n Soto Apolinar. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++ 3.3 Créditos Este documento se preparó con el software de tipografı́a cientı́fica LATEX 2ε . Créditos Autor: Efraı́n Soto Apolinar. Edición: Efraı́n Soto Apolinar. Composición tipográfica: Efraı́n Soto Apolinar. Productor general: Efraı́n Soto Apolinar. Revisión técnica: Pendiente. Compilador: Dev–C++ Ver. 4.9.9.2. (http://www.bloodshed.net/) Año de edición: 2007 Año de publicación: Pendiente August 19, 2008 Última revisión: 7:59pm Agradezco tus sugerencias, comentarios, correcciones, reclamos y todo lo que se le parezca a la cuenta de correo electrónico: [email protected] @ 200 INDICE ALFABÉTICO 3.4 Simbologı́a utilizada i Cuando encuentres un párrafo con este sı́mbolo en el margen del texto, debes considerarlo como información importante que puede ayudarte a evitar problemas futuros. ! Un párrafo con este sı́mbolo indica que debes poner especial atención y metabolizarla bien. Es muy importante. Este párrafo tiene información que te guı́a de manera que no te confundas con conceptos parecidos y vayas a entender una cosa por otra. @ Indica que busques más información relativa al tema en Internet, o bien envı́es un mensaje de correo electrónico al autor de este material. j Indica que el párrafo incluye un procedimiento que debes realizar bajo tu propio riesgo. Indica que el párrafo incluye un procedimiento que debes realizar bajo tu propio riesgo. L Indica que nunca debes realizar ese procedimiento, a menos que desees que la memoria de tu computadora se sature o el programa se cicle y nunca termine. A m Indica que eso todo el mundo lo sabe. Tú también deberı́as saberlo. o Indica que debes ponerte a practicar. Tienes que intentarlo por tı́ mismo y desarrollar algunas cosas. Nadie aprende en cabeza ajena. Indica que este código puedes copiarlo y usarlo libremente. ÿ Cuando veas esta imagen, piensa en el compa que está elaborando estas notas. i Siempre que aparezca una de estas imagenes a lo largo del texto aparecerá en el margen. Por ejemplo, en este párrafo se incluye la imagen referente a los párrafos que dan información. Espero que esto sea de ayuda. Efraı́n Soto A. Este material NO está listo para su publicación. Prohibida la reproducción sin permiso previo del autor. Códigos en C++