mfm0f -

Info iconThis preview shows pages 1–6. Sign up to view the full content.

View Full Document Right Arrow Icon

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Departamento de F isica, Facultad de Ciencias, Universidad de Chile. ~ n Las Palmeras 3425, Nu~oa. Casilla 653, Correo 1, Santiago fono: 562 978 7276 fax: 562 271 2973 e-mail: [email protected] Apuntes de un curso de PROGRAMACION Y METODOS NUMERICOS Sptima edicin, revisin 061107-14 e o o Jos Rogan C. e V ictor Mu~oz G. n ii Agradecimientos: Xavier Andrade. Denisse Pastn. e De la promocin del 2004 a: Daniel Asenjo y Max Ram o irez. De la promocin del 2005 a: Alejandro Varas y Mar Daniela Cornejo. o ia De la promocin del 2006 a: Nicols Verschueren y Paulina Chacn, o a o Sergio Valdivia y Elizabeth Villanueva. iv Indice I Computacin o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 3 3 4 4 5 5 6 6 7 9 9 10 11 11 12 12 13 16 23 23 23 24 25 26 27 27 27 29 29 29 31 31 33 33 1. Elementos del sistema operativo unix. 1.1. Introduccin. . . . . . . . . . . . . . . . . . . . . o 1.2. Ingresando al sistema. . . . . . . . . . . . . . . . 1.2.1. Terminales. . . . . . . . . . . . . . . . . . 1.2.2. Login. . . . . . . . . . . . . . . . . . . . . 1.2.3. Passwords. . . . . . . . . . . . . . . . . . . 1.2.4. Cerrando la sesin. . . . . . . . . . . . . . o 1.3. El Proyecto Debian. . . . . . . . . . . . . . . . . 1.4. Archivos y directorios. . . . . . . . . . . . . . . . 1.5. Ordenes bsicas. . . . . . . . . . . . . . . . . . . a 1.5.1. Ordenes relacionadas con archivos. . . . . 1.5.2. Ordenes relacionadas con directorios. . . . 1.5.3. Visitando archivos. . . . . . . . . . . . . . 1.5.4. Copiando, moviendo y borrando archivos. 1.5.5. Espacio de disco. . . . . . . . . . . . . . . 1.5.6. Links. . . . . . . . . . . . . . . . . . . . . 1.5.7. Proteccin de archivos. . . . . . . . . . . . o 1.5.8. Filtros. . . . . . . . . . . . . . . . . . . . . 1.5.9. Otros usuarios y mquinas . . . . . . . . . a 1.5.10. Fecha . . . . . . . . . . . . . . . . . . . . 1.5.11. Diferencias entre sistemas. . . . . . . . . . 1.6. Shells. . . . . . . . . . . . . . . . . . . . . . . . . 1.6.1. Variables de entorno. . . . . . . . . . . . 1.6.2. Redireccin. . . . . . . . . . . . . . . . . . o 1.6.3. Ejecucin de comandos. . . . . . . . . . . o 1.6.4. Aliases. . . . . . . . . . . . . . . . . . . . 1.6.5. La shell bash. . . . . . . . . . . . . . . . . 1.6.6. Archivos de script. . . . . . . . . . . . . . 1.7. Ayuda y documentacin. . . . . . . . . . . . . . . o 1.8. Procesos. . . . . . . . . . . . . . . . . . . . . . . . 1.9. Editores. . . . . . . . . . . . . . . . . . . . . . . . 1.9.1. El editor vi. . . . . . . . . . . . . . . . . . 1.9.2. Editores modo emacs. . . . . . . . . . . . 1.10. El sistema X Windows. . . . . . . . . . . . . . . . v vi INDICE 1.11. Uso del ratn. . . . . . . . . o 1.12. Internet. . . . . . . . . . . . 1.12.1. Acceso a la red. . . . 1.12.2. El correo electrnico. o 1.12.3. Ftp anonymous. . . . 1.12.4. WWW. . . . . . . . 1.13. Impresin. . . . . . . . . . . o 1.14. Compresin. . . . . . . . . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 35 36 37 39 39 39 40 43 43 43 43 44 44 45 45 46 46 46 46 47 48 49 49 49 50 50 50 52 52 52 53 53 53 54 54 54 55 55 55 56 56 57 2. Introduccin a programacin. o o 2.1. Qu es programar? . . . . . . . . . . . . . . . e 2.2. Lenguajes de programacin. . . . . . . . . . . o 2.2.1. Cdigo de Mquina binario. . . . . . . o a 2.2.2. Lenguaje de Ensamblador (Assembler). 2.2.3. Lenguaje de alto nivel. . . . . . . . . . 2.2.4. Lenguajes interpretados. . . . . . . . . 2.2.5. Lenguajes especializados. . . . . . . . . 2.3. Lenguajes naturales y formales. . . . . . . . . 2.3.1. Lenguajes naturales. . . . . . . . . . . 2.3.2. Lenguajes formales. . . . . . . . . . . . 2.4. Desarrollando programas. . . . . . . . . . . . 2.5. La interfaz con el usuario. . . . . . . . . . . . 2.6. Sacar los errores de un programa. . . . . . . . 3. Una breve introduccin a Python. o 3.1. Python. . . . . . . . . . . . . . . . . . . . . . 3.1.1. Interactivo versus scripting. . . . . . . 3.1.2. Creando un script. . . . . . . . . . . . 3.2. Lenguaje Python. . . . . . . . . . . . . . . . . 3.2.1. Algunos tipos bsicos. . . . . . . . . . a 3.2.2. Imprimiendo en la misma l inea. . . . . 3.2.3. Imprimiendo un texto de varias l ineas. 3.2.4. Variables. . . . . . . . . . . . . . . . . 3.2.5. Asignacin de variables. . . . . . . . . o 3.2.6. Reciclando variables. . . . . . . . . . . 3.2.7. Operaciones matemticas. . . . . . . . a 3.2.8. Operaciones con strings. . . . . . . . . 3.2.9. Composicin. . . . . . . . . . . . . . . o 3.2.10. Comentarios. . . . . . . . . . . . . . . 3.2.11. Entrada (input). . . . . . . . . . . . . 3.3. Condicionales. . . . . . . . . . . . . . . . . . . 3.3.1. Posibles condicionales. . . . . . . . . . 3.3.2. El if. . . . . . . . . . . . . . . . . . . 3.3.3. El if. . . else. . . . . . . . . . . . . . . 3.3.4. El if...elif...else. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDICE 3.3.5. La palabra clave pass. . . . . . . . . . . . 3.3.6. Operadores lgicos. . . . . . . . . . . . . . o 3.3.7. Forma alternativa. . . . . . . . . . . . . . 3.4. Funciones Pre-hechas. . . . . . . . . . . . . . . . 3.4.1. Algunas funciones incorporadas. . . . . . . 3.4.2. Algunas funciones del mdulo math. . . . . o 3.4.3. Algunas funciones del mdulo string. . . o 3.4.4. Algunas funciones del mdulo random. . . o 3.4.5. Algunos otros mdulos y funciones. . . . . o 3.5. Funciones hechas en casa. . . . . . . . . . . . . . 3.5.1. Receta para una funcin. . . . . . . . . . . o 3.5.2. Variables globales. . . . . . . . . . . . . . 3.5.3. Pasando valores a la funcin. . . . . . . . o 3.5.4. Valores por defecto de una funcin. . . . . o 3.6. Argumentos Claves. . . . . . . . . . . . . . . . . . 3.7. DocStrings. . . . . . . . . . . . . . . . . . . . . . 3.7.1. La palabra clave return. . . . . . . . . . . 3.7.2. Funciones que tienen un valor de retorno. . 3.7.3. Recursin. . . . . . . . . . . . . . . . . . . o 3.8. Parmetros desde la l a inea de comando. . . . . . . 3.9. Iteraciones con while. . . . . . . . . . . . . . . . 3.10. Los strings. . . . . . . . . . . . . . . . . . . . . . 3.10.1. Indice negativos. . . . . . . . . . . . . . . 3.10.2. Cun largo es un string? . . . . . . . . . a 3.10.3. Recorriendo un string. . . . . . . . . . . . 3.10.4. El ciclo for. . . . . . . . . . . . . . . . . . 3.10.5. Comparando strings. . . . . . . . . . . . . 3.11. Listas. . . . . . . . . . . . . . . . . . . . . . . . . 3.11.1. Rebanando listas. . . . . . . . . . . . . . . 3.11.2. Mutabilidad. . . . . . . . . . . . . . . . . 3.11.3. Agregando a una lista. . . . . . . . . . . . 3.11.4. Operaciones con listas. . . . . . . . . . . . 3.11.5. Borrando items de una lista. . . . . . . . . 3.11.6. Qu contiene una lista? . . . . . . . . . . e 3.11.7. Un ciclo for y las listas. . . . . . . . . . . 3.11.8. Otros trucos con listas. . . . . . . . . . . . 3.11.9. Generando listas de nmeros. . . . . . . . u 3.12. Tuplas. . . . . . . . . . . . . . . . . . . . . . . . . 3.13. El comando break. . . . . . . . . . . . . . . . . . 3.14. Trabajando con archivos. . . . . . . . . . . . . . . 3.14.1. Funciones del mdulo os. . . . . . . . . . . o 3.14.2. Funciones del mdulo os.path. . . . . . . o 3.14.3. Ejemplo de un cdigo. . . . . . . . . . . . o 3.14.4. Abriendo un archivo. . . . . . . . . . . . . 3.14.5. Leyendo un archivo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii 57 57 58 58 59 60 60 60 60 61 61 62 62 62 63 64 64 65 65 66 67 67 68 68 68 68 69 69 70 70 71 71 71 71 72 72 72 73 73 74 74 74 75 75 75 viii INDICE 3.14.6. Escribiendo a un archivo. . . . . . . . . . . . 3.14.7. Cerrando un archivo. . . . . . . . . . . . . . 3.14.8. Archivos temporales. . . . . . . . . . . . . . 3.14.9. Ejemplo de lectura escritura. . . . . . . . . . 3.15. Excepciones. . . . . . . . . . . . . . . . . . . . . . . 3.16. Diccionarios. . . . . . . . . . . . . . . . . . . . . . . 3.16.1. Editando un diccionario. . . . . . . . . . . . 3.16.2. Un ejemplo de cdigo, un men. . . . . . . . o u 3.16.3. Tuplas y diccionarios como argumentos. . . 3.17. Modules y Shelve. . . . . . . . . . . . . . . . . . . . 3.17.1. Partiendo el cdigo. . . . . . . . . . . . . . . o 3.17.2. Creando un mdulo. . . . . . . . . . . . . . o 3.17.3. Agregando un nuevo directorio al path. . . . 3.17.4. Haciendo los mdulos fciles de usar. . . . . o a 3.17.5. Usando un mdulo. . . . . . . . . . . . . . . o 3.17.6. Trucos con mdulos. . . . . . . . . . . . . . o 3.17.7. Preservando la estructura de la informacin. o 3.17.8. Cmo almacenar? . . . . . . . . . . . . . . o 3.17.9. Ejemplo de shelve. . . . . . . . . . . . . . . 3.17.10.Otras funciones de shelve. . . . . . . . . . . 3.18. Clases y mtodos. . . . . . . . . . . . . . . . . . . . e 3.18.1. Clase de muestra LibretaNotas. . . . . . . . 3.18.2. Valores por defecto. . . . . . . . . . . . . . . 3.19. Sobrecarga de Operadores. . . . . . . . . . . . . . . 3.19.1. Funcin driver. . . . . . . . . . . . . . . . . o 3.19.2. Atributos de las clases. . . . . . . . . . . . . 3.19.3. Ejemplo de clase vectores. . . . . . . . . . . 3.20. Algunos mdulos interesantes. . . . . . . . . . . . . o 3.20.1. El mdulo Numeric. . . . . . . . . . . . . . o 3.20.2. El mdulo Tkinter. . . . . . . . . . . . . . o 3.20.3. El mdulo Visual. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 76 76 76 77 77 78 79 79 79 79 79 80 80 80 81 81 81 82 82 82 83 84 84 85 85 86 86 86 87 87 89 89 89 90 92 92 94 95 95 95 96 98 98 4. Una breve introduccin a C++. o 4.1. Estructura bsica de un programa en C++. a 4.1.1. El programa ms simple. . . . . . . . a 4.1.2. Definicin de funciones. . . . . . . . o 4.1.3. Nombres de variables. . . . . . . . . 4.1.4. Tipos de variables. . . . . . . . . . . 4.1.5. Ingreso de datos desde el teclado. . . 4.1.6. Operadores aritmticos. . . . . . . . e 4.1.7. Operadores relacionales. . . . . . . . 4.1.8. Asignaciones. . . . . . . . . . . . . . 4.1.9. Conversin de tipos. . . . . . . . . . o 4.2. Control de flujo. . . . . . . . . . . . . . . . . 4.2.1. if, if... else, if... else if. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDICE 4.2.2. Expresin condicional. . . . . . . . . . . . . . . o 4.2.3. switch. . . . . . . . . . . . . . . . . . . . . . . 4.2.4. for. . . . . . . . . . . . . . . . . . . . . . . . . 4.2.5. while. . . . . . . . . . . . . . . . . . . . . . . . 4.2.6. do... while. . . . . . . . . . . . . . . . . . . . 4.2.7. goto. . . . . . . . . . . . . . . . . . . . . . . . 4.3. Funciones. . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.1. Funciones tipo void. . . . . . . . . . . . . . . . 4.3.2. return. . . . . . . . . . . . . . . . . . . . . . . 4.3.3. Funciones con parmetros. . . . . . . . . . . . . a 4.3.4. Parmetros por defecto. . . . . . . . . . . . . . a 4.3.5. Ejemplos de funciones: ra cuadrada y factorial. iz 4.3.6. Alcance, visibilidad, tiempo de vida. . . . . . . 4.3.7. Recursin. . . . . . . . . . . . . . . . . . . . . . o 4.3.8. Funciones internas. . . . . . . . . . . . . . . . . 4.4. Punteros. . . . . . . . . . . . . . . . . . . . . . . . . . 4.5. Matrices o arreglos. . . . . . . . . . . . . . . . . . . . . 4.5.1. Declaracin e inicializacin. . . . . . . . . . . . o o 4.5.2. Matrices como parmetros de funciones. . . . . a 4.5.3. Asignacin dinmica. . . . . . . . . . . . . . . . o a 4.5.4. Matrices multidimensionales. . . . . . . . . . . . 4.5.5. Matrices de caracteres: cadenas (strings). . . . . 4.6. Manejo de archivos. . . . . . . . . . . . . . . . . . . . . 4.6.1. Archivos de salida. . . . . . . . . . . . . . . . . 4.6.2. Archivos de entrada. . . . . . . . . . . . . . . . 4.6.3. Archivos de entrada y salida. . . . . . . . . . . 4.7. main como funcin. . . . . . . . . . . . . . . . . . . . . o 4.7.1. Tipo de retorno de la funcin main. . . . . . . . o 4.8. Clases. . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8.1. Definicin. . . . . . . . . . . . . . . . . . . . . . o 4.8.2. Miembros. . . . . . . . . . . . . . . . . . . . . . 4.8.3. Miembros pblicos y privados. . . . . . . . . . . u 4.8.4. Operador de seleccin (.). . . . . . . . . . . . . o 4.8.5. Implementacin de funciones miembros. . . . . o 4.8.6. Constructor. . . . . . . . . . . . . . . . . . . . . 4.8.7. Destructor. . . . . . . . . . . . . . . . . . . . . 4.8.8. Arreglos de clases. . . . . . . . . . . . . . . . . 4.9. Sobrecarga. . . . . . . . . . . . . . . . . . . . . . . . . 4.9.1. Sobrecarga de funciones. . . . . . . . . . . . . . 4.9.2. Sobrecarga de operadores. . . . . . . . . . . . . 4.9.3. Coercin. . . . . . . . . . . . . . . . . . . . . . o 4.10. Herencia. . . . . . . . . . . . . . . . . . . . . . . . . . . 4.11. Ejemplo: la clase de los complejos. . . . . . . . . . . . . 4.12. Compilacin y debugging. . . . . . . . . . . . . . . . . o 4.12.1. Compiladores. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix 100 100 101 103 104 104 104 104 105 106 109 110 113 115 116 117 119 119 119 120 121 123 125 125 128 129 130 132 133 134 134 134 135 136 136 137 138 138 139 139 139 140 141 145 145 x INDICE 147 . 147 . 148 . 148 . 149 . 149 . 150 . 151 153 . 153 . 153 . 154 . 154 . 154 . 155 . 155 . 156 . 157 . 157 . 157 . 158 . 159 . 160 . 160 . 161 . 162 . 163 . 164 . 164 . 164 . 165 . 165 . 166 . 166 . 166 . 168 . 169 . 171 . 172 . 172 . 172 . 173 . 173 . 174 5. Grfica. a 5.1. Visualizacin de archivos grficos. . . o a 5.2. Modificando imgenes . . . . . . . . a 5.3. Conversin entre formatos grficos. . o a 5.4. Captura de pantalla. . . . . . . . . . 5.5. Creando imgenes. . . . . . . . . . . a 5.6. Graficando funciones y datos. . . . . 5.7. Graficando desde nuestros programas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6. El sistema de preparacin de documentos TEX . o 6.1. Introduccin. . . . . . . . . . . . . . . . . . . . . o 6.2. Archivos. . . . . . . . . . . . . . . . . . . . . . . . 6.3. Input bsico. . . . . . . . . . . . . . . . . . . . . a 6.3.1. Estructura de un archivo. . . . . . . . . . 6.3.2. Caracteres. . . . . . . . . . . . . . . . . . 6.3.3. Comandos. . . . . . . . . . . . . . . . . . 6.3.4. Algunos conceptos de estilo. . . . . . . . . 6.3.5. Notas a pie de pgina. . . . . . . . . . . . a 6.3.6. Frmulas matemticas. . . . . . . . . . . . o a 6.3.7. Comentarios. . . . . . . . . . . . . . . . . 6.3.8. Estilo del documento. . . . . . . . . . . . . 6.3.9. Argumentos de comandos. . . . . . . . . . 6.3.10. T itulo. . . . . . . . . . . . . . . . . . . . . 6.3.11. Secciones. . . . . . . . . . . . . . . . . . . 6.3.12. Listas. . . . . . . . . . . . . . . . . . . . . 6.3.13. Tipos de letras. . . . . . . . . . . . . . . . 6.3.14. Acentos y s imbolos. . . . . . . . . . . . . . 6.3.15. Escritura de textos en castellano. . . . . . 6.4. Frmulas matemticas. . . . . . . . . . . . . . . . o a 6.4.1. Sub y supra indices. . . . . . . . . . . . . . 6.4.2. Fracciones. . . . . . . . . . . . . . . . . . . 6.4.3. Ra ices. . . . . . . . . . . . . . . . . . . . . 6.4.4. Puntos suspensivos. . . . . . . . . . . . . . 6.4.5. Letras griegas. . . . . . . . . . . . . . . . . 6.4.6. Letras caligrficas. . . . . . . . . . . . . . a 6.4.7. S imbolos matemticos. . . . . . . . . . . . a 6.4.8. Funciones tipo logaritmo. . . . . . . . . . 6.4.9. Matrices. . . . . . . . . . . . . . . . . . . . 6.4.10. Acentos. . . . . . . . . . . . . . . . . . . . 6.4.11. Texto en modo matemtico. . . . . . . . . a 6.4.12. Espaciado en modo matemtico. . . . . . . a 6.4.13. Fonts. . . . . . . . . . . . . . . . . . . . . 6.5. Tablas. . . . . . . . . . . . . . . . . . . . . . . . . 6.6. Referencias cruzadas. . . . . . . . . . . . . . . . . 6.7. Texto centrado o alineado a un costado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDICE 6.8. Algunas herramientas importantes . . . . . . 6.8.1. babel . . . . . . . . . . . . . . . . . A 6.8.2. AMS-L TEX . . . . . . . . . . . . . . 6.8.3. fontenc . . . . . . . . . . . . . . . . 6.8.4. enumerate . . . . . . . . . . . . . . . 6.8.5. Color. . . . . . . . . . . . . . . . . . 6.9. Modificando el estilo de la pgina. . . . . . . a 6.9.1. Estilos de pgina. . . . . . . . . . . . a 6.9.2. Corte de pginas y l a ineas. . . . . . . 6.10. Figuras. . . . . . . . . . . . . . . . . . . . . 6.10.1. graphicx.sty . . . . . . . . . . . . . 6.10.2. Ambiente figure. . . . . . . . . . . . 6.11. Cartas. . . . . . . . . . . . . . . . . . . . . . A 6.12. L TEX y el formato pdf. . . . . . . . . . . . . A 6.13. Modificando L TEX. . . . . . . . . . . . . . . 6.13.1. Definicin de nuevos comandos. . . . o 6.13.2. Creacin de nuevos paquetes y clases o 6.14. Errores y advertencias. . . . . . . . . . . . . 6.14.1. Errores. . . . . . . . . . . . . . . . . 6.14.2. Advertencias. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi 175 175 176 179 179 179 180 180 181 184 185 185 187 189 190 190 195 202 202 205 II Mtodos Numricos. e e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 209 . 209 . 221 . 221 . 223 225 225 225 227 228 229 229 230 232 232 234 235 237 241 241 7. Preliminares. 7.1. Programas y funciones. . . . 7.2. Errores numricos. . . . . . e 7.2.1. Errores de escala. . . 7.2.2. Errores de redondeo. 8. EDO: Mtodos bsicos. e a 8.1. Movimiento de un proyectil. . . . . . . . . . . . . . . . . . . 8.1.1. Ecuaciones bsicas. . . . . . . . . . . . . . . . . . . . a 8.1.2. Derivada avanzada. . . . . . . . . . . . . . . . . . . . 8.1.3. Mtodo de Euler. . . . . . . . . . . . . . . . . . . . . e 8.1.4. Mtodos de Euler-Cromer y de Punto Medio. . . . . e 8.1.5. Errores locales, errores globales y eleccin del paso de o 8.1.6. Programa de la pelota de baseball. . . . . . . . . . . . 8.2. Pndulo simple. . . . . . . . . . . . . . . . . . . . . . . . . . e 8.2.1. Ecuaciones bsicas. . . . . . . . . . . . . . . . . . . . a 8.2.2. Frmulas para la derivada centrada. . . . . . . . . . . o 8.2.3. Mtodos del "salto de la rana" y de Verlet. . . . . . . e 8.2.4. Programa de pndulo simple. . . . . . . . . . . . . . e 8.3. Listado de los programas en python. . . . . . . . . . . . . . 8.3.1. balle.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tiempo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii INDICE 8.3.2. pendulo.py . . . 8.4. Listado de los programas 8.4.1. balle.cc . . . . 8.4.2. pendulo.cc . . . . . . . . en c++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 245 245 246 9. EDO II: Mtodos Avanzados. e 9.1. Orbitas de cometas. . . . . . . . . . . . . . . . . . 9.1.1. Ecuaciones bsicas. . . . . . . . . . . . . . a 9.1.2. Programa orbita. . . . . . . . . . . . . . 9.2. Mtodos de Runge-Kutta. . . . . . . . . . . . . . e 9.2.1. Runge-Kutta de segundo orden. . . . . . . 9.2.2. Frmulas generales de Runge-Kutta. . . . o 9.2.3. Runge-Kutta de cuarto orden. . . . . . . . 9.2.4. Pasando funciones a funciones. . . . . . . 9.3. Mtodos adaptativos . . . . . . . . . . . . . . . . e 9.3.1. Programas con paso de tiempo adaptativo. 9.3.2. Funcin adaptativa de Runge-Kutta. . . . o 9.4. Listados del programa. . . . . . . . . . . . . . . . 9.4.1. orbita.cc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 . 249 . 249 . 251 . 255 . 255 . 257 . 258 . 259 . 260 . 260 . 261 . 264 . 264 271 . 271 . 271 . 272 . 273 . 275 . 275 . 276 . 278 . 278 . 280 . 281 . 282 . 282 . 283 . 284 . 285 . 287 . 287 . 288 . 292 . 293 . 293 . 295 10.Resolviendo sistemas de ecuaciones. 10.1. Sistemas de ecuaciones lineales. . . . . . . . . . . . . . . . . . . 10.1.1. Estado estacionario de EDO. . . . . . . . . . . . . . . . . 10.1.2. Eliminacin Gaussiana. . . . . . . . . . . . . . . . . . . . o 10.1.3. Pivoteando. . . . . . . . . . . . . . . . . . . . . . . . . . 10.1.4. Determinantes. . . . . . . . . . . . . . . . . . . . . . . . 10.1.5. Eliminacin Gaussiana en Octave. . . . . . . . . . . . . . o 10.1.6. Eliminacin Gaussiana con C++ de objetos matriciales. o 10.2. Matriz inversa. . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2.1. Matriz inversa y eliminacin Gaussiana. . . . . . . . . . o 10.2.2. Matrices singulares y patolgicas. . . . . . . . . . . . . . o 10.2.3. Osciladores armnicos acoplados. . . . . . . . . . . . . . o 10.3. Sistemas de ecuaciones no lineales. . . . . . . . . . . . . . . . . 10.3.1. Mtodo de Newton en una variable. . . . . . . . . . . . . e 10.3.2. Mtodo de Newton multivariable. . . . . . . . . . . . . . e 10.3.3. Programa del mtodo de Newton. . . . . . . . . . . . . . e 10.3.4. Continuacin. . . . . . . . . . . . . . . . . . . . . . . . . o 10.4. Listados del programa. . . . . . . . . . . . . . . . . . . . . . . . 10.4.1. Definicin de la clase Matrix. . . . . . . . . . . . . . . . o 10.4.2. Implementacin de la clase Matrix. . . . . . . . . . . . . o 10.4.3. Funcin de eliminacin Gaussiana ge. . . . . . . . . . . . o o 10.4.4. Funcin para inversin de matrices inv. . . . . . . . . . o o 10.4.5. Programa newtn en Octave. . . . . . . . . . . . . . . . . 10.4.6. Programa newtn en c++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDICE 11.Anlisis de datos. a 11.1. Ajuste de curvas. . . . . . . . . . . . . . . . . . . . 11.1.1. El calentamiento global. . . . . . . . . . . . 11.1.2. Teor general. . . . . . . . . . . . . . . . . ia 11.1.3. Regresin lineal. . . . . . . . . . . . . . . . . o 11.1.4. Ajuste general lineal de m inimos cuadrados. 11.1.5. Bondades del ajuste. . . . . . . . . . . . . . 12.Integracin numrica bsica o e a 12.1. Definiciones . . . . . . . . . . . . . . 12.2. Regla trapezoidal . . . . . . . . . . . 12.3. Interpolacin con datos equidistantes. o 12.4. Reglas de cuadratura . . . . . . . . . 12.5. Integracin de Romberg . . . . . . . o 12.6. Cuadratura de Gauss. . . . . . . . . 12.7. Bibliograf . . . . . . . . . . . . . . ia 12.8. Listados del programa. . . . . . . . . 12.8.1. trapecio.cc . . . . . . . . . 12.8.2. romberg.cc . . . . . . . . . . xiii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 . 299 . 299 . 300 . 301 . 304 . 305 307 307 308 309 310 312 314 316 317 317 317 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . III Apndices. e 321 323 A. Transferencia a diskettes. B. Las shells csh y tcsh. 325 B.1. Comandos propios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 B.2. Variables propias del shell. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 C. Editores tipo emacs. D. Una breve introduccin a Octave/Matlab o D.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . . o D.2. Interfase con el programa . . . . . . . . . . . . . . . . D.3. Tipos de variables . . . . . . . . . . . . . . . . . . . . D.3.1. Escalares . . . . . . . . . . . . . . . . . . . . . D.3.2. Matrices . . . . . . . . . . . . . . . . . . . . . D.3.3. Strings . . . . . . . . . . . . . . . . . . . . . . D.3.4. Estructuras . . . . . . . . . . . . . . . . . . . D.4. Operadores bsicos . . . . . . . . . . . . . . . . . . . a D.4.1. Operadores aritmticos . . . . . . . . . . . . . e D.4.2. Operadores relacionales . . . . . . . . . . . . . D.4.3. Operadores lgicos . . . . . . . . . . . . . . . o D.4.4. El operador : . . . . . . . . . . . . . . . . . D.4.5. Operadores de aparicin preferente en scripts o D.5. Comandos matriciales bsicos . . . . . . . . . . . . . a 329 337 . 337 . 337 . 338 . 338 . 338 . 340 . 340 . 341 . 341 . 342 . 342 . 342 . 343 . 343 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv INDICE D.6. Comandos . . . . . . . . . . . . . . . . . . D.6.1. Comandos generales . . . . . . . . D.6.2. Como lenguaje de programacin . . o D.6.3. Matrices y variables elementales . . D.6.4. Polinomios . . . . . . . . . . . . . . D.6.5. Algebra lineal (matrices cuadradas) D.6.6. Anlisis de datos y transformada de a D.6.7. Grficos . . . . . . . . . . . . . . . a D.6.8. Strings . . . . . . . . . . . . . . . . D.6.9. Manejo de archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fourier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 343 344 347 349 350 350 351 355 356 E. Asignacin dinmica. o a 361 E.1. Arreglos dinmicos bidimensionales. . . . . . . . . . . . . . . . . . . . . . . . . 362 a F. make & Makefile. G. Herramientas bsicas en el uso de L.A.M.P. a G.1. Objetivo. . . . . . . . . . . . . . . . . . . . . . . . . G.2. Prerequisitos . . . . . . . . . . . . . . . . . . . . . G.3. Breve referencia sobre paginas web. . . . . . . . . . G.3.1. Ejemplos . . . . . . . . . . . . . . . . . . . . G.4. Administrador de Bases de datos. . . . . . . . . . . G.5. Servidor Web. . . . . . . . . . . . . . . . . . . . . . G.6. Pginas Bsicas en html. . . . . . . . . . . . . . . . a a G.6.1. Estructura de una pgina en html. . . . . . . a G.6.2. Algo de estilo. . . . . . . . . . . . . . . . . . G.6.3. Formularios. . . . . . . . . . . . . . . . . . . G.7. MySql. . . . . . . . . . . . . . . . . . . . . . . . . . G.7.1. Iniciando sesin. . . . . . . . . . . . . . . . o G.7.2. Creando una base de datos. . . . . . . . . . G.7.3. Creando tablas. . . . . . . . . . . . . . . . . G.7.4. Interactuando con la Tabla. . . . . . . . . . G.8. Programacin en PHP. . . . . . . . . . . . . . . . . o G.8.1. Lenguaje PHP. . . . . . . . . . . . . . . . . G.8.2. Variables. . . . . . . . . . . . . . . . . . . . G.8.3. Recuperando variables desde un formulario. G.8.4. Control de flujo. . . . . . . . . . . . . . . . . G.8.5. Funcin require. . . . . . . . . . . . . . . . . o G.8.6. Sesin. . . . . . . . . . . . . . . . . . . . . . o G.8.7. PHP interactuando con MySql. . . . . . . . G.9. Ejemplo Final. . . . . . . . . . . . . . . . . . . . . G.9.1. Paso I: Estructura de las tablas. . . . . . . . G.9.2. Paso II: rbol de pginas. . . . . . . . . . . a a G.10.Conclusiones. . . . . . . . . . . . . . . . . . . . . . G.10.1.Mejoras al Ejemplo final. . . . . . . . . . . . 363 367 . 367 . 367 . 367 . 368 . 369 . 369 . 369 . 370 . 370 . 373 . 376 . 376 . 376 . 377 . 377 . 380 . 380 . 381 . 381 . 382 . 383 . 383 . 385 . 387 . 387 . 388 . 392 . 392 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDICE xv G.11.Tabla de Colores en html. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393 xvi INDICE Indice de figuras 6.1. Un sujeto caminando. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 7.1. Salida grfica del programa interp. . . . . . . . . . . . . . . . . . . . . . . . . 216 a 7.2. Salida grfica del programa interp. . . . . . . . . . . . . . . . . . . . . . . . . 219 a 7.3. Error absoluto (h), ecuacin (7.9), versus h para f (x) = x2 y x = 1. . . . . . 224 o 8.1. 8.2. 8.3. 8.4. 8.5. 8.6. 8.7. 9.1. 9.2. 9.3. 9.4. 9.5. 9.6. 9.7. 9.8. Trayectoria para un paso de tiempo con Euler. . . . Movimiento de proyectil sin aire. . . . . . . . . . . Movimiento de proyectil con aire. . . . . . . . . . . Mtodo de Euler para m = 10 . . . . . . . . . . . . e Mtodo de Euler con paso del tiempo ms peque~o. e a n Mtodo de Verlet para m = 10 . . . . . . . . . . . e Mtodo de Verlet para m = 170 . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 231 232 239 240 240 241 250 253 254 254 255 260 263 263 Orbita el iptica alrededor del Sol. . . . . . . . . . . . . . . . . . . . . . . . . . . Trayectoria y energ usando el mtodo de Euler. . . . . . . . . . . . . . . . . ia e Trayectoria y energ usando el mtodo de Euler-Cromer. . . . . . . . . . . . . ia e Trayectoria y energ usando el mtodo de Euler-Cromer. . . . . . . . . . . . . ia e Trayectoria y energ con el paso de tiempo ms peque~o en Euler-Cromer. . . ia a n Trayectoria y energ usando el mtodo de Runge-Kutta. . . . . . . . . . . . . ia e Trayectoria y energ usando el mtodo de Runge-Kutta adaptativo. . . . . . . ia e Paso de tiempo en funcin de la distancia radial del Runge-Kutta adaptativo. o 10.1. Sistema de bloques acoplados por resortes anclados entre paredes. . . . . . . . 281 10.2. Representacin grfica del mtodo de Newton. . . . . . . . . . . . . . . . . . . 283 o a e 11.1. Dixido de carbono medido en Hawai. . . . . . . . . . . . . . . . . . . . . . . . 300 o 11.2. Ajuste de datos a una curva. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 12.1. Subintervalos. . . . . . . . . . . . . . . . . . . . . 12.2. Sucesin de l o ineas rectas como curva aproximante. 12.3. Aproximaciones, (a) lineal, (b) cuadrtica. . . . . a 12.4. Regla trapezoidal versus cuadratura de Gauss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 308 310 314 D.1. Grfico simple. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 a D.2. Curvas de contorno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 D.3. Curvas de contorno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 xvii xviii INDICE DE FIGURAS G.1. Esquema de una tabla en html, utilizando los elementos de una matriz. . . . . 373 G.2. Los 256 colores posibles de desplegar en una pgina en html, con su respectivo a cdigo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393 o Parte I Computacin o 1 Cap itulo 1 Elementos del sistema operativo unix. versin revisada 7.1, 31 de Julio del 2007 o 1.1. Introduccin. o En este cap itulo se intentar dar los elementos bsicos para poder trabajar en un ama a biente unix. Sin pretender cubrir todos los aspectos del mismo, nuestro inters se centra en e entregar las herramientas al lector para que pueda realizar los trabajos del curso bajo este sistema operativo. Como comentario adicional, conscientemente se ha evitado la traduccin o de gran parte de la terminolog tcnica teniendo en mente que documentacin disponible ia e o se encuentre, por lo general, en ingls y nos interesa que el lector sea capaz de reconocer los e trminos. e El sistema operativo unix es el ms usado en investigacin cient a o ifica, tiene una larga historia y muchas de sus ideas y mtodos se encuentran presentes en otros sistemas operativos. e Algunas de las caracter isticas relevantes del unix moderno son: Multitarea (Multitasking): Cada programa tiene asignado su propio "espacio" de memoria. Es imposible que un programa afecte a otro sin usar los servicios del sistema operativo. Si dos programas escriben en la misma direccin de memoria cada uno mano tiene su propia "idea" de su contenido. Multiusuario: Ms de una persona puede usar la mquina al mismo tiempo. Programas a a de otros usuarios continan ejecutndose a pesar de que un nuevo usuario entre a la u a mquina. a Memoria grande, lineal y virtual: Un programa en una mquina de 32 Bits puede acceder a y usar direcciones hasta los 4 GB en una mquina de slo 4 MB de RAM. El sistema a o slo asigna memoria autntica cuando le hace falta, en caso de falta de memoria de o e RAM, se utiliza el disco duro (swap). Casi todo tipo de dispositivo puede ser accedido como un archivo. Existen muchas aplicaciones dise~adas para trabajar desde la l n inea de comandos. Adems, a la mayor de las aplicaciones permiten que la salida de una pueda ser la entrada de la ia otra. Permite compartir dispositivos (como disco duro) entre una red de mquinas. a 3 4 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. Por su naturaleza de multiusuario, nunca se deber apagar impulsivamente una mquina ia a 1 unix , ya que una mquina apagada sin razn puede matar trabajos de d perder los a o ias, ultimos cambios de tus archivos e ir degradando el sistema de archivos en dispositivos como el disco duro. Entre los sistemas operativos unix actuales cabe destacar: Linux fue originalmente desarrollado primero para computadores personales PCs basados en x86 de 32 bits (386 o superiores). Hoy Linux corre sobre Intel x86/IA64, Motorola 68k, Sun SPARC, Alpha, Motorola/IBM PowerPC, Arm, MISP CPUs, HP PA-RISC, IA-64, ibm S/390, AMD64, ppc64, Hitachi SuperH, armeb y arquitecturas Renesas M32R. SunOS2 : disponible para la familia 68K as como para la familia sparc de estaciones i de trabajo sun Solaris3 : disponible para la familia sparc de Sun as como para la familia x86. i OSF14 : disponible para Alpha. Ultrix: disponible para vax de Digital SYSVR45 : disponible para la familia x86, vax. IRIX: disponible para mips. AIX6 : disponible para RS6000 de IBM y PowerPC. 1.2. Ingresando al sistema. En esta seccin comentaremos las operaciones de comienzo y fin de una sesin en unix o o as como la modificacin de la contrase~a (que a menudo no es la deseada por el usuario, y i o n que por lo tanto puede olvidar con facilidad). 1.2.1. Terminales. Para iniciar una sesin es necesario poder acceder a un terminal. Pueden destacarse dos o tipos de terminales: Terminal de texto: consta de una pantalla y de un teclado. Como indica su nombre, en la pantalla slo es posible imprimir caracteres de texto. o Terminal grfico: Consta de pantalla grfica, teclado y mouse. Dicha pantalla suele ser a a de alta resolucin. En este modo se pueden emplear ventanas que emulan el comportao miento de un terminal de texto (xterm o gnome-terminal). 1 Incluyendo el caso en que la mquina es un PC normal corriendo Linux u otra versin de unix. a o SunOS 4.1.x tambin se conoce como Solaris 1. e 3 Tambin conocido como SunOS 5.x, solaris 2 o Slowaris :-). e 4 Tambin conocido como Dec Unix. e 5 Tambin conocido como Unixware y Novell-Unix. e 6 Tambin conocido como Aches. e 2 1.2. INGRESANDO AL SISTEMA. 5 1.2.2. Login. El primer paso es encontrar un terminal libre donde aparezca el login prompt del sistema: Debian GNU/Linux 4.0 hostname tty2 hostname login: Tambin pueden ocurrir un par de cosas: e La pantalla no muestra nada. Comprobar que la pantalla est encendida. e Pulsar alguna tecla o mover el mouse para desactivar el protector de pantalla. Otra persona ha dejado una sesin abierta. En este caso existe la posibilidad de intentar o en otra mquina o bien finalizar la sesin de dicha persona (si sta no se halla en las a o e proximidades). Una vez que se haya superado el paso anterior de encontrar el login prompt se procede con la introduccin del Username al prompt de login y despus la contrase~a (password) o e n adecuada. 1.2.3. Passwords. El password puede ser cualquier secuencia de caracteres a eleccin. Deben seguirse las o siguientes pautas: Debe ser fcil de recordar por uno mismo. Si se olvida, deber pasarse un mal rato a a dicindole al administrador de sistema que uno lo ha olvidado. e Para evitar que alguna persona no deseada obtenga el password y tenga libre acceso a los archivos de tu cuenta: Las maysculas y minsculas no son equivalentes, sin embargo se recomienda que u u se cambie de una a otra. Los caracteres numricos y no alfabticos tambin ayudan. Debe tenerse sin eme e e bargo la precaucin de usar caracteres alfanumricos que se puedan encontrar en o e todos los terminales desde los que se pretenda acceder. Las palabras de diccionario deben ser evitadas. Debe cambiarlo si cree que su password es conocido por otras personas, o descubre que algn intruso7 est usando su cuenta. u a El password debe ser cambiado con regularidad. 7 Intruso es cualquier persona que no sea el usuario. 6 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. La instruccin para cambiar el password en unix es passwd. A menudo, cuando existen o varias mquinas que comparten recursos (disco duro, impresora, correo electrnico, . . . ), para a o facilitar la administracin de dicho sistema se unifican los recursos de red (entre los que se o hayan los usuarios de dicho sistema) en una base de datos comn. Dicho sistema se conoce u 8 como NIS (Network Information Service) . Si el sistema empleado dispone de este servicio, la modificacin de la contrase~a en una mquina supone la modificacin en todas las mquinas o n a o a que constituyan el dominio NIS. 1.2.4. Cerrando la sesin. o Es importante que nunca se deje abierta una sesin, pues algn "intruso" podr tener o u ia libre acceso a archivos de propiedad del usuario y manipularlos de forma indeseable. Para evitar todo esto basta teclear logout o exit y habrs acabado la sesin de unix en dicha a o mquina9 . a 1.3. El Proyecto Debian. El proyecto Debian es una asociacin de personas que han creado un sistema operativo o gratis y de cdigo abierto (free). Este sistema operativo se denomina Debian GNU/Linux o o simplemente Debian. Actualmente Debian ocupa el kernel Linux desarrollado por Linus Torvalds apoyado por miles de programadores de todo el mundo. Tambin estn implementados otros kernels como e a Hurd, desarrollado por GNU, NetBSD y FreeBSD. La mayor de las herramientas del sistema operativo Debian provienen del proyecto ia GNU y por ende son free. Cabe destacar que actualmente Debian tiene un total de ms de a 18733 paquetes (por paquetes entendemos software precompilado, para la versin estable, o en un formato que permite su fcil instalacin en nuestra mquina). Entre estos paquetes a o a encontramos desde las herramientas bsicas para procesar texto, hojas de clculo, edicin de a a o imgenes, audio, video, hasta aplicaciones de gran utilidad cient a ifica. Es importante recordar que todo este software es free y por lo tanto est al alcance de todos sin la necesidad de a comprar licencias ni pagar por actualizaciones. Tambin existe la posibilidad de modificar el e software ya que tenemos acceso al cdigo fuente de los programas. Debian siempre mantiene o activas al menos tres versiones que tienen las siguientes clasificaciones: stable (estable): Es la ultima versin oficial de Debian que ha sido probada para asegurar o su estabilidad. Actualmente corresponde a la versin 4.0r0 cuyo nombre cdigo es etch. o o testing (en prueba): Esta es la versin que se est probando para asegurar su estabilidad o a y para luego pasar a ser versin estable. Nombre cdigo lenny. o o unstable (inestable): Aqu es donde los programadores verdaderamente desarrollan Dei bian y por esto no es muy estable y no se recomienda para el uso diario. Esta versin o se denomina siempre sid. Para informacin sobre Debian y cmo bajarlo visite la pgina oficial http://www.debian.org. o o a Antiguamente se conoc como YP (Yellow Pages), pero debido a un problema de marca registrada de ia United Kingdom of British Telecomunications se adoptaron las siglas nis. 9 En caso que se estuviera trabajando bajo X-Windows debes cerrar la sesin con Log Out Usuario de o Gnome. 8 1.4. ARCHIVOS Y DIRECTORIOS. 7 1.4. Archivos y directorios. Aunque las diferentes distribuciones ubiquen sus programas en diferentes partes, la estructura bsica de directorios en una mquina Linux es ms o menos la misma: a a a /-|--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> bin boot cdrom dev emul etc home initrd lib lib32 lib64 media mnt opt proc root sbin selinux sys tmp usr--|--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> |--> var--|... |--> |--> |--> |--> |... bin games include lib lib32 lib64 local -|--> bin |--> include |--> lib |... sbin share src --> linux X11R6 lock log mail www 8 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. El rbol que observamos muestra el t a ipico rbol de directorios en Linux. Pueden haber a peque~as variaciones en algunos de los nombres de estos directorios dependiendo de la distrin bucin o versin de Linux que se est usando. Entre los directorios ms destacados tenemos: o o e a /home - Espacio reservado para las cuentas de los usuarios. /bin, /usr/bin - Binarios (ejecutables) bsicos de unix. a /etc, aqu se encuentran los archivos de configuracin de todo los diferentes softwares i o de la mquina. a /proc, es un sistema de archivos virtuales. Contiene archivos que residen en memoria y no en el disco duro. Hace referencia a los programas que estn corriendo en este a momento en el sistema. /dev (device) (dispositivo). Aqu se guardan los archivos asociados a los dispositivos. i Se usan para acceder los dispositivos f isicos del sistema y recursos tales como discos duros, modems, memoria, mouse, etc. Algunos dispositivos: hd: hda1 ser el disco duro IDE, primario (a), y la primera particin (1). a o fd: los archivos que empiecen con las letras fd se referirn a los controladores de a las disketteras: fd0 ser la primera diskettera, fd1 ser la segunda y as sucesiia ia i vamente. ttyS: se usan para acceder a los puertos seriales como por ejemplo ttyS0, que es el puerto conocido como com1. sd: son los dispositivos SCSI y/o SATA. Su uso es muy similar al del hd. Tambin e se usa para denominar a los dispositivos de almacenamiento conectados v USB ia (pendrives). lp: son los puertos paralelos. lp0 es el puerto conocido como LPT1. null: ste es usado como un agujero negro, ya que todo lo que se dirige all desae i parece. tty: hacen referencia a cada una de las consolas virtuales. Como es de suponer, tty1 ser la primera consola virtual, tty2 la segunda, etc. a /usr/local - Zona con las aplicaciones no comunes a todos los sistemas unix, pero no por ello menos utilizadas. /usr/share/doc aqu se puede encontrar informacin relacionada con aplicaciones (en i o forma de pginas de manual, texto, html o bien archivos dvi, Postscript o pdf). Tambin a e encontramos archivos de ejemplo, tutoriales, HOWTO, etc. 1.5. ORDENES BASICAS. 9 1.5. Ordenes bsicas. a Para ejecutar un comando, basta con teclear su nombre (tambin debes tener permiso para e hacerlo). Las opciones o modificadores empiezan normalmente con el caracter - (p. ej. ls -l). Para especificar ms de una opcin, se pueden agrupar en una sola cadena de caracteres a o (ls -l -h es equivalente a ls -lh). Algunos comandos aceptan tambin opciones dadas por e palabras completas, en cuyo caso usualmente comienzan con -- (ls --color=auto). 1.5.1. Ordenes relacionadas con archivos. En un sistema computacional la informacin se encuentra en archivos que la contienen o (tabla de datos, texto ASCII, fuente en lenguaje Python, Fortran o C++, ejecutable, imagen, mp3, figura, resultados de simulacin, . . . ). Para organizar toda la informacin se dispone de o o una entidad denominada directorio, que permite el almacenamiento en su interior tanto de archivos como de otros directorios10 . Se dice que la estructura de directorios en unix es jerrquica o arborescente, debido a a que todos los directorios nacen en un mismo punto (denominado directorio ra De hecho, iz). la zona donde uno trabaja es un nodo de esa estructura de directorios, pudiendo uno a su vez generar una estructura por debajo de ese punto. Un archivo se encuentra situado siempre en un directorio y su acceso se realiza empleando el camino que conduce a l en el Arbol de e Directorios del Sistema. Este camino es conocido como el path. El acceso a un archivo se puede realizar empleando: Path Absoluto, aqul que empieza con / e Por ejemplo : /etc/printcap Path Relativo, aqul que no empieza con / e Por ejemplo : ../examples/rc.dir.01 Los nombres de archivos y directorios pueden usar un mximo de 255 caracteres, cuala quier combinacin de letras y s o imbolos (el caracter / no se permite). Los caracteres comod (wildcard ) pueden ser empleados para acceder a un conjunto in de archivos con caracter isticas comunes. El signo * puede sustituir cualquier conjunto de caracteres11 y el signo ? a cualquier caracter individual. Por ejemplo:12 Normalmente se acude a la imagen de una carpeta que puede contener informes, documentos o bien otras carpetas, y as sucesivamente. i 11 Incluido el punto `.', unix no es dos. 12 bash$ es el prompt en todos los ejemplos. 10 10 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. bash$ ls f2c.1 flexdoc.1 rcmd.1 rptp.1 zforce.1 face.update.1 ftptool.1 rlab.1 rxvt.1 zip.1 faces.1 funzip.1 robot.1 zcat.1 zipinfo.1 flea.1 fvwm.1 rplay.1 zcmp.1 zmore.1 flex.1 rasttoppm.1 rplayd.1 zdiff.1 znew.1 bash$ ls rp* rplay.1 rplayd.1 rptp.1 bash$ ls *e?? face.update.1 zforce.1 zmore.1 Los archivos cuyo nombre comiencen por . se denominan ocultos, as por ejemplo en el i directorio de partida de un usuario. bash$ ls -a user . .alias .fvwmrc .login .xinitrc .. .cshrc .joverc .profile .Xdefaults .enviroment .kshrc .tcshrc Algunos caracteres especiales para el acceso a archivos son: . Directorio actual .. Directorio superior en el rbol a ~ Directorio $HOME ~user Directorio $HOME del usuario user 1.5.2. Ordenes relacionadas con directorios. ls (LiSt) Este comando permite listar los archivos de un determinado directorio. Si no se le suministra argumento, lista los archivos y directorios en el directorio actual. Si se a~ade el nombre de n un directorio el listado es del directorio suministrado. Existen varias opciones que modifican su funcionamiento entre las que destacan: -l (Long listing) proporciona un listado extenso, que consta de los permisos13 de cada archivo, el usuario, el tama~o del archivo, . . . , etc. Adicionalmente la opcin -h imprime n o los tama~os en un formato fcil de leer (Human readable). n a -a (list All) lista tambin los archivos ocultos. e -R (Recursive) lista recursivamente el contenido de todos los directorios que encuentre. -t ordena los archivos por tiempo de modificacin. o -S ordena los archivos por tama~o. n -r invierte el sentido de un ordenamiento. -p agrega un caracter al final de cada nombre de archivo, indicando el tipo de archivo (por ejemplo, los directorios son identificados con un / al final). 13 Se comentar posteriormente este concepto. a 1.5. ORDENES BASICAS. 11 pwd (Print Working Directory) Este comando proporciona el nombre del directorio actual. cd (Change Directory) Permite moverse a travs de la estructura de directorios. Si no se le proporciona argumento se e provoca un salto al directorio $HOME. El argumento puede ser un nombre absoluto o relativo de un directorio. cd - vuelve al ultimo directorio visitado. mkdir (MaKe DIRectory) Crea un directorio con el nombre (absoluto o relativo) proporcionado. rmdir (ReMove DIRectory) Elimina un directorio con el nombre (absoluto o relativo) suministrado. Dicho directorio debe de estar vac io. 1.5.3. Visitando archivos. Este conjunto de rdenes permite visualizar el contenido de un archivo sin modificar su o contenido. cat Muestra por pantalla el contenido de un archivo que se suministra como argumento. more Este comando es anlogo al anterior, pero permite la paginacin. a o less Es una versin mejorada del anterior. Permite moverse en ambas direcciones. Otra ventaja o es que no lee el archivo entero antes de arrancar. 1.5.4. Copiando, moviendo y borrando archivos. cp (CoPy) Copia un archivo(s) con otro nombre y/o a otro directorio, por ejemplo, el comando para copiar el archivo1.txt con el nombre archivo2.txt es: cp archivo1.txt archivo2.txt Veamos algunas opciones: -a copia en forma recursiva, no sigue los link simblicos y preserva los atributos de lo o copiado. -i (interactive), impide que la copia provoque una prdida del archivo destino si ste e e existe14 . -R (recursive), copia un directorio y toda la estructura que cuelga de l. e mv (MoVe) Mueve un archivo(s) a otro nombre y/o a otro directorio, por ejemplo, el comando para mover el archivo1.txt al nombre archivo2.txt es: 14 Muchos sistemas tienen esta opcin habilitada a travs de un alias, para evitar equivocaciones. o e 12 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. mv archivo1.txt archivo2.txt Este comando dispone de opciones anlogas al anterior. a rm (ReMove) Borra un archivo(s). En caso de que el argumento sea un directorio y se haya suministrado la opcin -r, es posible borrar el directorio y todo su contenido. La opcin -i pregunta antes o o de borrar. 1.5.5. Espacio de disco. El recurso de almacenamiento en el disco es siempre limitado. A continuacin se comentan o un par de comandos relacionados con la ocupacin de este recurso: o du (Disk Usage) Permite ver el espacio de disco ocupado (en bloques de disco15 ) por el archivo o directorio suministrado como argumento. La opcin -s impide que cuando se aplique recursividad en o un directorio se muestren los subtotales. La opcin -h imprime los tama~os en un formato o n fcil de leer (Human readable). a df (Disk Free) Muestra los sistemas de archivos que estn montados en el sistema, con las cantidades totales, a usadas y disponibles para cada uno. df -h muestra los tama~os en formato fcil de leer. n a 1.5.6. Links. ln (LiNk) Permite realizar un enlace (link) entre dos archivos o directorios. Un enlace puede ser: hard link : se puede realizar slo entre archivos del mismo sistema de archivos. El archivo o enlazado apunta a la zona de disco donde se ubica el archivo original. Por tanto, si se elimina el archivo original, el enlace sigue teniendo acceso a dicha informacin. Es el o enlace por omisin. o symbolic link : permite enlazar archivos/directorios16 de diferentes sistemas de archivos. El archivo enlazado apunta al nombre del original. As si se elimina el archivo original i el enlace apunta hacia un nombre sin informacin asociada. Para realizar este tipo de o enlace debe emplearse la opcin -s. o Un enlace permite el uso de un archivo en otro directorio distinto del original sin necesidad de copiarlo, con el consiguiente ahorro de espacio. Veamos un ejemplo. Creemos un enlace clsico en Linux, al directorio existente linux-2.6.12.5 nombrmoslo sencillamente linux. a e mitarro:/usr/src# ln -s linux-2.6.12.5 linux 15 16 1 bloque normalmente es 1 Kbyte. Debe hacerse notar que los directorios slo pueden ser enlazados simblicamente. o o 1.5. ORDENES BASICAS. 13 1.5.7. Proteccin de archivos. o Dado que el sistema de archivos unix es compartido por un conjunto de usuarios, surge el problema de la necesidad de privacidad. Sin embargo, dado que existen conjuntos de personas que trabajan en comn, es necesaria la posibilidad de que un conjunto de usuarios puedan u tener acceso a una serie de archivos (que puede estar limitado para el resto de los usuarios). Cada archivo y directorio del sistema dispone de un propietario, un grupo al que pertenece y unos permisos. Existen tres tipos fundamentales de permisos: lectura (r-Read ): en el caso de un archivo, significa poder examinar el contenido del mismo; en el caso de un directorio significa poder entrar en dicho directorio. escritura (w-Write): en el caso de un archivo significa poder modificar su contenido; en el caso de un directorio es crear un archivo o directorio en su interior. ejecucin (x-eXecute): en el caso de un archivo significa que ese archivo se pueda o ejecutar (binario o archivo de procedimientos); en el caso de un directorio es poder ejecutar alguna orden dentro de l. e Se distinguen tres grupos de personas sobre las que se deben especificar permisos: user: el usuario propietario del archivo. group: el grupo propietario del archivo (excepto el usuario). Como ya se ha comentado, cada usuario puede pertenecer a uno o varios grupos y el archivo generado pertenece a uno de los mismos. other: el resto de los usuarios (excepto el usuario y los usuarios que pertenezcan al grupo) Tambin se puede emplear all que es la unin de todos los anteriores. Para visualizar las e o protecciones de un archivo o directorio se emplea la orden ls -l, cuya salida es de la forma: -rw-r--r-- ...otra informacin... nombre o Los 10 primeros caracteres muestran las protecciones de dicho archivo: El primer caracter indica el tipo de archivo de que se trata: archivo d directorio l enlace (link ) c dispositivo de caracteres (p.e. puerta serial) b dispositivo de bloques (p.e. disco duro) s socket (conexin de red) o Los caracteres 2, 3, 4 son los permisos de usuario Los caracteres 5, 6, 7 son los permisos del grupo 14 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. Los caracteres 8, 9, 10 son los permisos del resto de usuarios As en el ejemplo anterior -rw-r--r-- se trata de un archivo donde el usuario puede i leer y escribir, mientras que el grupo y el resto de usuarios slo pueden leer. Estos suelen o ser los permisos por omisin para un archivo creado por un usuario. Para un directorio o los permisos por omisin suelen ser: drwxr-xr-x, donde se permite al usuario "entrar" o en el directorio y ejecutar rdenes desde l. o e chmod (CHange MODe) Esta orden permite modificar los permisos de un archivo. Con opcin -R es recursiva. o chmod permisos files Existen dos modos de especificar los permisos: Modo absoluto o modo numrico. Se realiza empleando un nmero que resulta de la OR e u binario de los siguientes modos: 400 200 100 040 020 010 004 002 001 4000 lectura por el propietario. escritura por el propietario. ejecucin (bsqueda) por el propietario. o u lectura por el grupo. escritura por el grupo. ejecucin (bsqueda) por el grupo. o u lectura por el resto. escritura por el resto. ejecucin (bsqueda) por el resto. o u Set User ID, cuando se ejecuta el proceso corre con los permisos del due~o del archivo. n Por ejemplo: chmod 640 *.txt Permite la lectura y escritura por el usuario, lectura para el grupo y ningn permiso u para el resto, de un conjunto de archivos que acaban en .txt Modo simblico o literal. Se realiza empleando una cadena (o cadenas separadas por o comas) para especificar los permisos. Esta cadena se compone de los siguientes tres elementos: who operation permission who : es una combinacin de: o u g o a : : : : user group others all (equivalente a ugo) Si se omite este campo se supone a, con la restriccin de no ir en contra de la o mscara de creacin (umask). a o operation: es una de las siguientes operaciones: + : a~adir permiso. n 1.5. ORDENES BASICAS. - : eliminar permiso. = : asignar permiso, el resto de permisos de la misma categor se anulan. ia permission: es una combinacin de los caracteres: o r : read. w : write. x : execute. s : en ejecucin fija el usuario o el grupo. o Por ejemplo: chmod u+x tarea Permite la ejecucin por parte del usuario17 del archivo tarea. o 15 chmod u=rx, go=r *.txt Permite la lectura y ejecucin del usuario, y slo la lectura por parte del grupo y el o o resto de usuarios. umask Esta es una orden intr inseca del Shell que permite asignar los permisos que se desea tengan los archivos y directorios por omisin. El argumento que acompa~a a la orden es un nmero o n u octal que aplicar una xor sobre los permisos por omisin (rw-rw-rw-) para archivos y a o (rwxrwxrwx) para directorios. El valor por omisin de la mscara es 022 que habilita al o a usuario para lectura-escritura, al grupo y al resto para lectura. Sin argumentos muestra el valor de la mscara. a chgrp (CHange GRouP) Cambia el grupo propietario de una serie de archivos/directorios chgrp grupo files El usuario que efecta esta orden debe pertenecer al grupo mencionado. u chown (CHange OWNer) Cambia el propietario y el grupo de una serie de archivos/directorios chown user:group files La opcin -r hace que la orden se efecte recursivamente. o u id Muestra la identificacin del usuario18 , as como el conjunto de grupos a los que el usuario o i pertenece. [email protected]:~$ id uid=1000(user) gid=1000(group) groups=1000(group),25(floppy),29(audio) [email protected]:~$ Un error muy frecuente es la creacin de un archivo de rdenes (script file) y olvidar permitir la ejecucin o o o del mismo. 18 A pesar de que el usuario se identifica por una cadena denominada username, tambin existe un nmero e u denominado uid que es un identificativo numrico de dicho usuario. e 17 16 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. 1.5.8. Filtros. Existe un conjunto de rdenes en unix que permiten el procesamiento de archivos de texto. o Se denominan filtros (Unix Filters), porque normalmente se trabaja empleando redireccin o 19 20 recibiendo datos por su stdin y retornndolos modificados por su stdout . a Para facilitar la comprensin de los ejemplos siguientes supondremos que existen tres o archivos llamados mylist.txt, yourlist.txt y tercero.txt que tienen en su interior: mylist.txt 1 190 2 280 3 370 yourlist.txt 1 190 2 281 3 370 tercero.txt 11 b 33 c 222 a echo Este no es propiamente un filtro, pero nos ser muy util ms adelante. Despliega sobre la a a pantalla un mensaje, sin argumento despliega una l inea en blanco. La opcin -n elimina el o cambio de l inea al final del mensaje. [email protected]:~$ echo Hola Mundo Hola Mundo [email protected]:~$ echo ; echo chao; echo chao [email protected]:~$ Varias instrucciones pueden ser separadas por ; cat Es el filtro ms bsico, copia la entrada a la salida. a a [email protected]:~$ cat 1 190 2 280 3 370 [email protected]:~$ mylist.txt Tambin lo podemos usar para crear un archivo e [email protected]:~$ cat Este es mi archivo con muchas lineas ^d [email protected]:~$ 19 20 > myfile.txt Entrada estndar. a Salida estndar. a 1.5. ORDENES BASICAS. El caracter final ^d corresponde a fin de archivo y termina el ingreso. seq Genera una secuencia de nmeros naturales consecutivos. u [email protected]:~$ seq 4 8 4 5 6 7 8 17 cut Para un archivo compuesto por columnas de datos, permite escribir sobre la salida cierto intervalo de columnas. La opcin -b N-M permite indicar el intervalo en bytes que se escribirn o a en la salida. [email protected]:~$ cut -b 3-4 mylist.txt 19 28 37 [email protected]:~$ paste Mezcla l ineas de distintos archivos. Escribe l ineas en el stdout pegando secuencialmente las l ineas correspondientes de cada uno de los archivo separadas por tab. Ejemplo, supongamos que tenemos nuestros archivos mylist.txt y yourlist.txt y damos el comando [email protected]:~$ paste mylist.txt yourlist.txt 1 190 1 190 2 280 2 281 3 370 3 370 [email protected]:~$ sed Es un editor de flujo. Veamos algunos ejemplos [email protected]:~$ sed = mylist.txt 1 1 190 2 2 280 3 3 370 [email protected]:~$ Numera las l ineas. [email protected]:~$ sed -n -e '3p' mylist.txt 3 370 [email protected]:~$ 18 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. Slo muestra la l o inea 3. El modificador -n suprime la impresin de todas las l o ineas excepto aquellas especificadas por p. El modificador -e corre un script, secuencia de comandos. Separando por coma damos un rango en el nmero de l u ineas. [email protected]:~$ sed -e '2q' mylist.txt 1 190 2 280 [email protected]:~$ Muestra hasta la l inea 2 y luego se sale de sed. [email protected]:~$ sed -e 's/0/a/g' mylist.txt 1 19a 2 28a 3 37a [email protected]:~$ Reemplaza todos los 0 del archivo por la letra a. Este es uno de los usos ms comunes. a [email protected]:~$ sed -e '/2 2/s/0/a/g' mylist.txt 1 190 2 28a 3 370 [email protected]:~$ Busca las l ineas con la secuencia 2 2 y en ellas reemplaza todos los 0 por la letra a. [email protected]:~$ sed -e 's/1/XX/2' mylist.txt 1 XX90 2 280 3 370 [email protected]:~$ Reemplaza la segunda aparicin de un 1 en una l o inea por los caracteres XX. A continuacin mostramos otras posibilidades del comando sed o Para remover una l inea especifica (X) de un archivo (file.txt) [email protected]:~$ sed -e 'Xd' file.txt Para remover un intervalo de l ineas de un archivo [email protected]:~$ sed -e 'X,Yd' file.txt Para mostrar slo las l o ineas X e Y de un archivo 1.5. ORDENES BASICAS. [email protected]:~$ sed -n -e 'Xp;Yp' file.txt Para mostrar un archivo salvo las l ineas que contengan key [email protected]:~$ sed -e '/key/d' file.txt Para mostrar de un archivo slo las l o ineas que contengan key [email protected]:~$ sed -n -e '/key/p' file.txt Para mostrar un archivo salvo las l ineas que comienzan con # [email protected]:~$ sed -e '/^#/d' file.txt Expresiones regulares: ^ Matches al comienzo de la l inea $ Matches al final de la l inea, se pone despus del caracter a buscar. e . Matches cualquier caracter. Matches con todos los caracteres dentro de los parntesis e diff Permite comparar el contenido de dos archivos o directorios [email protected]:~$ diff mylist.txt yourlist.txt 2c2 < 2 280 --> 2 281 [email protected]:~$ Hay una diferencia entre los archivos en la segunda fila. sort Permite ordenar alfabticamente e [email protected]:~$ sort tercero.txt 11 b 222 a 33 c [email protected]:~$ [email protected]:~$ sort -r tercero.txt 33 c 222 a 11 b [email protected]:~$ 19 20 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. [email protected]:~$ sort -n tercero.txt 11 b 33 c 222 a [email protected]:~$ [email protected]:~$ sort -k 2 tercero.txt 222 a 11 b 33 c [email protected]:~$ La opcin -n considera los valores numricos y la opcin -r invierte el orden. La opcin -k o e o o permite especificar la columna a usar para hacer el sort. find Permite la bsqueda de un archivo en la estructura de directorios u find . -name file.dat -print Comenzando en el directorio actual(.) recorre la estructura de directorios buscando el archivo file.dat, cuando lo encuentre imprime el path al mismo, actualmente es innecesaria la opcin print. o find . -name '*~' -exec rm '{}' \; Esta es otra aplicacin de find que busca en la estructura de directorios un archivo que o termine en ~ y lo borra. El comando xargs ordena repetir orden para cada argumento que se lea desde stdin. Este lo podemos combinar con find. find . -name '*.dat' -print | xargs mv ../data \; Logrando un comando que busca en la estructura de directorios todos los archivos que termines en .dat, y los mueve a un directorio ../data. grep Permite la bsqueda de una cadena de caracteres en uno o varios archivos, imprimiendo el u nombre del archivo y la l inea en que se encuentra la cadena. [email protected]:~$ grep 1 *list.txt mylist.txt:1 190 yourlist.txt:1 190 yourlist.txt:2 281 [email protected]:~$ Algunas opciones utiles -c Elimina la salida normal y slo cuenta el nmero de apariciones de la cadena en o u cada archivo. -i Ignora para la comparacin entre la cadena dada y el archivo, si la cadena est en o a maysculas o minsculas. u u -n Incluye el nmero de l u ineas en que aparece la cadena en la salida normal. 1.5. ORDENES BASICAS. -r Hace la bsqueda recursiva. u 21 -v Invierte la bsqueda mostrando todas las l u ineas donde no aparece la cadena pedida. head Muestra las primeras diez l ineas de un archivo. head -30 file Muestra las 30 primeras l ineas de file. [email protected]:~$ head -1 1 190 [email protected]:~$ mylist.txt tail Muestra las diez ultimas l ineas de un archivo. tail -30 file Muestra las 30 ultimas l ineas de file. tail +30 file Muestra desde la l inea 30 en adelante de file. [email protected]:~$ tail -1 3 370 [email protected]:~$ mylist.txt La opcin -f permite que se actualice la salida cuando el archivo crece. o awk Es un procesador de archivos de texto que permite la manipulacin de las l o ineas de forma tal que tome decisiones en funcin del contenido de la misma. Ejemplo, supongamos que tenemos o nuestro archivo mylist.txt con sus dos columnas [email protected]:~$ awk '{print }' 1 190 2 280 3 370 [email protected]:~$ Funciona como el comando cat [email protected]:~$ awk '{print $2, $1 }' 190 1 280 2 370 3 [email protected]:~$ Imprime esas dos columnas en orden inverso. [email protected]:~$ awk '{print ``a'', 8*$1, $2-1 }' a 8 189 a 16 279 a 24 369 [email protected]:~$ mylist.txt mylist.txt mylist.txt 22 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. Permite operar sobre las columnas. [email protected]:~$ awk '{ if (NR>1 && NR < 3) print}' mylist.txt 2 280 [email protected]:~$ Slo imprime la l o inea 2. tar Este comando permite la creacin/extraccin de archivos contenidos en un unico archivo o o denominado tarfile (o tarball). Este tarfile suele ser luego comprimido con gzip, la versin de compresin gnu,21 o bien con bzip2. o o La accin a realizar viene controlada por el primer argumento: o c (Create) creacin o x (eXtract) extraccin o t (lisT) mostrar contenido r a~adir al final n u (Update) a~adir aquellos archivos que no se hallen en el tarfile o que hayan sido n modificados con posterioridad a la versin que aparece. o A continuacin se colocan algunas de las opciones: o v Verbose (indica qu archivos son agregados a medida que son procesados) e z Comprimir o descomprimir el contenido con gzip. j Comprimir o descomprimir el contenido con bzip2. f File: permite especificar el archivo para el tarfile. Veamos algunos ejemplos: tar cvf simul.tar *.dat Genera un archivo simul.tar que contiene todos los archivos que terminen en .dat del directorio actual. A medida que se va realizando indica el tama~o en bloques de cada archivo n a~adido modo verbose. n tar czvf simul.tgz *.dat Igual que en el caso anterior, pero el archivo generado simul.tgz ha sido comprimido empleando gzip. tar tvf simul.tar Muestra los archivos contenidos en el tarfile simul.tar. tar xvf simul.tar Extrae todos los archivos contenidos en el tarfile simul.tar. gnu es un acrnimo recursivo, significa: gnu's Not unix! gnu es el nombre del producto de la Free o Software Foundation, una organizacin dedicada a la creacin de programas compatibles con unix algunos o o mejorado respecto a los estndars, y de libre distribucin. La distribucin de Linux gnu es debian. a o o 21 1.5. ORDENES BASICAS. wc (Word Count) Contabiliza el nmero de l u ineas, palabras y caracteres de un archivo. [email protected]:~$ wc 3 6 [email protected]:~$ mylist.txt 18 mylist.txt 23 El archivo tiene 3 l ineas, 6 palabras, considerando cada nmero como una palabra i.e. 1 es la u primera palabra y 190 la segunda, y finalmente 18 caracteres. Cules son los 18 caracteres? a 1.5.9. Otros usuarios y mquinas a users who w Para ver quin est conectado en la mquina. e a a ping Verifica si una mquina est conectada a la red y si el camino de Internet hasta la misma a a funciona correctamente. finger finger user, muestra informacin22 sobre el usuario user en la mquina local. o a finger [email protected], muestra informacin sobre un usuario llamado user en una mquina o a hostname. finger @hostname, muestra los usuarios conectados de la mquina hostname. a Este comando suele estar desabilitado en las mquinas actuales. a 1.5.10. Fecha cal Muestra el calendario del mes actual. Con la opcin -y y el a~o presenta el calendario del o n a~o completo. n date Muestra el d y la hora actual. ia 1.5.11. Diferencias entre sistemas. Cuando se transfieren archivos de texto entre windows y unix sin las precauciones adecuadas pueden aparecer los siguientes problemas: En unix no existe obligatoriedad respecto a que los archivos llevan extensin. Incluso o pueden tener ms de una extensin algo.v01.tar.gz, esto puede complicar a otros a o sistemas que usan slo una extensin de tres caracteres. o o La informacin proporcionada es el nombre completo del usuario, las ultimas sesiones en dicha mquina, o a si ha le o no su correo y el contenido de los archivos .project y .plan del usuario. ido 22 24 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. El cambio de l inea en un archivo de texto windows se compone de Carriage Return y Line Feed. Sin embargo, en unix slo existe el Carriage Return. As un archivo de o i unix visto desde windows parece una unica l inea. El caso inverso es la aparicin del o caracter ^M al final de cada l inea. Adems, el fin de archivo en windows es ^Z y en a unix es ^D. Usando el comando tr se puede transformar un archivo con cambios de l ineas para DOS en uno para unix. Sabiendo que ^M es ascii 13 decimal, pero 15 en octal: tr -d '\015' < datafile > TEMPFILE mv -f TEMPFILE datafile En Debian, instalando el paquete sysutils, queda instalado el comando dos2unix que tambin lo hace. e 1.6. Shells. El sistema operativo unix soporta varios intrpretes de comandos o shells, que ayudan a e que la interaccin con el sistema sea lo ms cmoda y amigable posible. La eleccin de cul o a o o a es la shell ms cmoda es algo personal; en este punto slo indicaremos algunos de los ms a o o a populares: sh : Bourne SHell, el shell bsico, no pensado para uso interactivo. a csh : C-SHell, shell con sintaxis como el lenguaje "C". El archivo de configuracin es o .cshrc (en el directorio $HOME). ksh : Korn-SHell, shell dise~ada por David Korn en los Laboratorios AT&T Bell. Es n un intento para una shell interactiva y para uso en script. Su lenguaje de comandos es un superconjunto de el lenguaje de shell sh. tcsh : alTernative C-Shell (Tenex-CSHell), con editor de l inea de comando. El archivo de configuracin es .tcshrc, o en caso de no existir, .cshrc (en el directorio $HOME). o bash : Bourne-Again Shell, con lo mejor de sh, ksh y tcsh. El archivo de configuracin o es .bash_profile cuando se entra a la cuenta por primera vez, y despus el archivo de e configuracin es .bashrc siempre en el directorio $HOME. La l o inea de comando puede ser editada usando comandos (secuencias de teclas) del editor emacs. Es el shell por defecto de Linux. Si queremos cambiar de shell en un momento dado, slo ser necesario que tecleemos el o a nombre del mismo y estaremos usando dicho shell. Si queremos usar de forma permanente otro shell del que tenemos asignado por omisin23 podemos emplear la orden chsh que permite o realizar esta accin. o En los archivos de configuracin se encuentran las definiciones de las variables de entorno o (enviroment variables) como camino de bsqueda PATH, los aliases y otras configuraciones u personales. Veamos unos caracteres con especial significado para el Shell: 23 Por omisin se asigna bash. o 1.6. SHELLS. 25 ` 24 permite que el output de un comando reemplace al nombre del comando. Por ejemplo: echo `pwd` imprime por pantalla el nombre del directorio actual. [email protected]:~$ echo `pwd` /home/user [email protected]:~$ ' 25 preserva el significado literal de cada uno de los caracteres de la cadena que delimita. [email protected]:~$ echo 'Estoy en `pwd`' Estoy en `pwd` [email protected]:~$ " 26 preserva el significado literal de todos los caracteres de la cadena que delimita, salvo $, `, \. [email protected]:~$ echo "Estoy en `pwd`" Estoy en /home/user [email protected]:~$ ; permite la ejecucin de ms de una orden en una sola l o a inea de comando. [email protected]:~$ mkdir textos; cd textos; cp ../*.txt . ; cd .. [email protected]:~$ 1.6.1. Variables de entorno. Las variables de entorno permiten la configuracin, por defecto, de muchos programas o cuando ellos buscan datos o preferencias. Se encuentran definidas en los archivos de configuracin anteriormente mencionados. Para referenciar a las variables se debe poner el s o imbolo $ delante, por ejemplo, para mostrar el camino al directorio por defecto del usuario user: [email protected]:~$ echo $HOME /home/user [email protected]:~$ Las variables de entorno ms importantes son: a HOME - El directorio por defecto del usuario. PATH - El camino de bsqueda, una lista de directorios separados con `:' para buscar u programas. Acento agudo o inclinado hacia atrs, backquote. a Acento usual o inclinado hacia adelante, single quote. 26 double quote. 25 24 26 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. EDITOR - El editor por defecto del usuario. DISPLAY - Bajo el sistema de X windows, el nombre de mquina y pantalla que est usana a do. Si esta variable toma el valor :0 el despliegue es local. TERM - El tipo de terminal. En la mayor de los casos bajo el sistema X windows se ia trata de xterm y en la consola en Linux es linux. En otros sistemas puede ser vt100. SHELL - La shell por defecto. MANPATH - Camino para buscar pginas de manuales. a PAGER - Programa de paginacin de texto (less o more). o TMPDIR - Directorio para archivos temporales. 1.6.2. Redireccin. o Cuando un programa espera que se teclee algo, aquello que el usuario teclea se conoce como el Standard Input: stdin. Los caracteres que el programa retorna por pantalla es lo que se conoce como Standard Output: stdout (o Standard Error : stderr27 ). El signo < permite que un programa reciba el stdin desde un archivo en vez de la interaccin con el usuario. o Por ejemplo: mail root < file, invoca el comando mail con argumento (destinatario del mail) root, siendo el contenido del mensaje el contenido del archivo file en vez del texto que usualmente teclea el usuario. Ms a menudo aparece la necesidad de almacenar en un archivo a la salida de un comando. Para ello se emplea el signo >. Por ejemplo, man bash > file, invoca el comando man con argumento (informacin deseada) bash pero indicando que la o informacin debe ser almacenada en el archivo file en vez de ser mostrada por pantalla. o En otras ocasiones uno desea que la salida de un programa sea la entrada de otro. Esto se logra empleando los denominados pipes, para ello se usa el signo |. Este signo permite que el stdout de un programa sea el stdin del siguiente. Por ejemplo: zcat manual.gz | more Invoca la orden de descompresin de zcat y conduce el flujo de caracteres hacia el paginador o more, de forma que podamos ver pgina a pgina el archivo descomprimido. A parte de los a a s imbolos mencionados existen otros que permiten acciones tales como: >> A~adir el stdout al final del archivo indicado (append ).28 n >& o &> (slo csh, tcsh y bash) Redireccionar el stdout y stderr. Con 2> redireco cion slo el stderr. o o >>& Igual que >& pero en modo append. 27 28 Si estos mensajes son de error. En bash, si el archivo no existe, es creado. 1.6. SHELLS. 27 1.6.3. Ejecucin de comandos. o Si el comando introducido es propio del shell (built-in), se ejecuta directamente. En caso contrario: Si el comando contiene /, el shell lo considera un PATH e intenta resolverlo (entrar en cada directorio especificado para encontrar el comando). En caso contrario el shell busca en una tabla hash table que contiene los nombres de los comandos que se han encontrado en los directorios especificados en la variable PATH, cuando ha arrancado el shell. 1.6.4. Aliases. Para facilitar la entrada de algunas rdenes o realizar operaciones complejas, los shells o interactivos permiten el uso de aliases. La orden alias permite ver qu aliases hay definidos e y tambin definir nuevos. Es corriente definir el alias rm =`rm -i', de esta forma la orden e siempre pide confirmacin para borrar un archivo. Si alguna vez quieres usar rm sin alias, slo o o hace falta poner delante el s imbolo \, denominado backslash . Por ejemplo \rm elimina los alias aplicados a rm. Otro ejemplo, bastante frecuente podr ser (debido a la complejidad de la ia orden): alias ffind ='find . -name \!*'. Para emplearlo: ffind tema.txt, el resultado es la bsqueda recursiva a partir del directorio actual de un archivo que se llame tema.txt, u mostrando el camino hasta el mismo. 1.6.5. La shell bash. Slo bash puede considerarse un shell interactivo, permitiendo la edicin de la l o o inea de comandos, y el acceso a la historia de rdenes (readline). En uso normal (historia y editor o de l inea de comandos) bash es compatible con otras shells como tcsh y ksh, ver apndice. e En bash el modo de completado (file completion) es automtico (usando TAB slo) si el shell a o est en modo interactivo. a Comandos del shell. help Ayuda interna sobre los comandos del shell. set Muestra el valor de todas las variables. VARIABLE=VALUE Permite asignar el valor de una variable de entorno. Para que dicha variable sea "heredada" es necesario emplear: export VARIABLE o bien combinarlas: export VARIABLE=VALUE. for var in wordlist do comandos done A la variable var, que puede llamarse de cualquier modo, se le asignan sucesivamente los 28 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. valores de la cadena wordlist, y se ejecuta el conjunto de comandos. El contenido de dicha variable puede ser empleado en los comandos: $var. Ejemplo: $ for i in 1 2 tres 4; do echo $i; done 1 2 tres 4 alias En bash, alias slo sirve para substitucin simple de una cadena por otra. Por ejemplo: o o alias ls='ls -F'. Para crear alias con argumentos se usan funciones, ver la documentacin. o unalias name Elimina un alias asignado. history Muestra las ultimas rdenes introducidas en el shell. Algunos comandos relacionados con el o Command history son: !! Repite la ultima orden. !n Repite la orden n-sima. e !string Repite la orden ms reciente que empiece por la cadena string. a !?string Repite la orden ms reciente que contenga la cadena string. a str1 str2 o !!:s/str1/str2/ (substitute) Repite la ultima orden reemplanzando la primera ocurrencia de la cadena str1 por la cadena str2. !!:gs/str1/str2/ (global substitute) Repite la ultima orden reemplazando todas las ocurrencias de la cadena str1 por la cadena str2. !$ Es el ultimo argumento de la orden anterior que se haya tecleado. source file Ejecuta las rdenes del fichero file en el shell actual. o umask value 1.7. AYUDA Y DOCUMENTACION. Asigna la mscara para los permisos por omisin. a o Los comandos umask , source , history , unalias y hash shell tcsh. 29 29 , funcionan igual en la 1.6.6. Archivos de script. Un archivo de script es una sucesin de comandos de la shell que se ejecutan secuencialo mente. Veamos un ejemplo simple: #!/bin/bash variable=''/home/yo'' cp $1 /tmp/$2 rm $1 cd $variable # Hecho por mi La primera l inea declara la shell espec ifica que se quiere usar. En la segunda l inea hay una declaracin de una variable interna. La tercera contiene los dos primeros argumentos con que o fue llamado el script. Por ejemplo, si el anterior script est en un archivo llamado ejemplo, a el comando ejemplo file1 file2 asocia $1 a file1 y $2 a file2. La l inea 5 hace uso de la variable interna dentro de un comando. La ultima l inea, que comienza con un # corresponde a un comentario. Notemos que la primera tambin es un comentario, pero la combinacin #! e o en la primera l inea fuerza a que se ejecute esa shell. Esto slo es una m o inima pincelada de una herramienta muy poderosa y util. Los comandos disponibles en la shell conforman un verdadero lenguaje de programacin en s y los scripts o i, pueden dise~arse para realizar tareas montonas y complejas. Este es un tema que le ser util n o a profundizar. 1.7. Ayuda y documentacin. o Para obtener ayuda sobre comandos de unix, se puede emplear la ayuda on-line, en la forma de pginas de manual. As man comando proporciona la ayuda sobre el comando dea i seado. Por ejemplo, para leer el manual de los shells, puedes entrar: man sh csh tcsh bash, la orden formatea las pginas y te permite leer los manuales en el orden pedido. En el caso a de bash se puede usar el comando help, por ejemplo, help alias. Adems, para muchos a comandos y programas se puede obtener informacin tipeando info comando. Finalmeno te, algunos comandos tienen una opcin de ayuda (--help), para recordar rpidamente las o a opciones ms comunes disponibles (ls --help). a 1.8. Procesos. En una mquina existen una multitud de procesos que pueden estar ejecutndose sia a multneamente. La mayor de ellos no corresponden a ninguna accin realizada por el usuaa ia o En bash y sh la hash table se va generando dinmicamente a medida que el usuario va empleando las a o rdenes. As el arranque del shell es ms rpido, y el uso de orden equivalente hash -r casi nunca hace falta. i a a 29 30 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. rio y no merecen que se les preste mayor atencin. Estos procesos corresponden a programas o ejecutados en el arranque del sistema y tienen que ver con el funcionamiento global del servidor. En general, los programas suelen tener uno de estos dos modos de ejecucin: o foreground: Son aquellos procesos que requieren de la interaccin y/o atencin del o o usuario mientras se estn ejecutando, o bien en una de sus fases de ejecucin (i.e. a o introduccin de datos). As por ejemplo, la consulta de una pgina de manual es un o i a proceso que debe ejecutarse claramente en foreground. background: Son aquellos procesos que no requieren de la interaccin con el usuario o para su ejecucin. Si bien el usuario desear estar informado cuando este proceso o ia termine. Un ejemplo de este caso ser la impresin de un archivo. ia o Sin embargo, esta divisin que a primera vista pueda parecer tan clara y concisa, a menudo o en la prctica aparece la necesidad de conmutar de un modo al otro, detencin de tareas a o indeseadas, etc. As por ejemplo, puede darse el caso de que estemos leyendo una pgina de i a manual y de repente necesitemos ejecutar otra tarea. Un proceso viene caracterizado por: process number job number Veamos algunas de las rdenes ms frecuentes para la manipulacin de procesos: o a o comando & Ejecucin de un comando en el background. o 30 Ctrl-Z Detiene el proceso que estuviera ejecutndose en el foreground y lo coloca a detenido en el background. Ctrl-C Termina un proceso que estaba ejecutndose en foreground. a Ctrl-\ Termina de forma definitiva un proceso que estaba ejecutndose en foreground. a ps x Lista todos los procesos que pertenezcan al usuario, incluyendo los que no estn a asociados a un terminal. jobs Lista los procesos que se hayan ejecutado desde el shell actual, mostrando el job number. fg (job number) Pasa a ejecucin en foreground un proceso que se hallase en backo ground. bg (job number) Pasa a ejecucin en background un proceso que se hallase detenido o con Ctrl-Z. kill (process number) Env una se~al31 a un proceso unix. En particular, para ia n enviar la se~al de trmino a un programa, damos el comando kill -KILL, pero no n e hace falta al ser la se~al por defecto. n 30 31 Por omisin un comando se ejecuta siempre en el foreground. o Para ver las se~ales disponibles entra la orden kill -l (l por list). n 1.9. EDITORES. 31 Cuando se intenta abandonar una sesin con algn proceso an detenido en el background o u u del shell, se informa de ello con un mensaje del tipo: There are stopped jobs si no importa, el usuario puede intentar abandonar de nuevo el shell y ste matar los jobs, o puedes utilizar e a fg para traerlos al foreground y ah terminar el mismo. i 1.9. Editores. Un editor es un programa que permite crear y/o modificar un archivo. Existen una multitud de editores diferentes, y al igual que ocurre con los shells, cada usuario tiene alguno de su predileccin. Mencionaremos algunos de los ms conocidos: o a vi - El editor standard de unix. emacs (xemacs) - Editor muy configurable escrito en lenguaje Lisp. Existen muchos modos para este editor (lector de mail, news, www,. . . ) que lo convierten en un verdadero shell para multitud de usuarios. Las ultimas versiones del mismo permiten la ejecucin desde X-windows o terminal indistintamente con el mismo binario. Posee un o tutorial en l inea, comando C-H t dentro del editor. El archivo de configuracin persoo nalizada es: $HOME/.emacs. jove - Basado en Emacs, (Jonathan's Own Version of Emacs). Posee tutorial en una utilidad asociada: teachjove. El archivo de configuracin personalizada es: $HOME/.joverc. o jed - Editor configurable escrito en S-Lang. Permite la emulacin de editores como o emacs y Wordstar. Posee una ayuda en l inea C-H C-H. El archivo de configuracin o personalizada es: $HOME/.jedrc. gedit - Un peque~o y liviano editor de texto para Gnome n xjed - Versin de jed para el X-windows system. Presenta como ventaja que es capaz o de funcionar en muchos modos: lenguaje C, Fortran, TeX, etc., reconociendo palabras clave y signos de puntuacin, empleando un colorido distinto para ellos. El archivo de o configuracin personalizada es el mismo que el de jed. o Dado que los editores del tipo de gedit disponen de mens auto explicativos, daremos a u continuacin unas ligeras nociones slo de vi y emacs. o o 1.9.1. El editor vi. El vi es un editor de texto muy poderoso pero un poco dif de usar. Lo importante icil de este editor es que se puede encontrar en cualquier sistema unix y slo hay unas pocas o diferencias entre un sistema y otro. Explicaremos lo bsico solamente. Comencemos con el a comando para invocarlo: localhost:/# vi 32 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. ~ ~ ~ /tmp/vi.9Xdrxi: new file: line 1 La sintaxis para editar un archivo es: localhost:/# vi nombre.de.archivo ~ ~ ~ nombre.de.archivo: new file: line 1 Insertar y borrar texto en vi. Cuando se inicia el vi, editando un archivo, o no, se entra en un modo de rdenes, es decir, o que no se puede empezar a escribir directamente. Si se quiere entrar en modo de insercin o de texto se debe presionar la tecla i. Entrando en el modo de insercin, se puede empezar a o escribir. Para salir del modo de insercin de texto y volver al modo de rdenes se apreta ESC. o o Aqui ya estamos escribiendo porque apretamos la tecla 'i' al estar en modo ordenes. ~ ~ La tecla a en el modo de rdenes tambin entra en modo de insercin de texto, pero en o e o vez de comenzar a escribir en la posicin del cursor, empieza un espacio despus. o e La tecla o en el modo de rdenes inserta texto pero desde la l o inea que sigue a la l inea donde se est ubicado. a Para borrar texto, hay que salir al modo rdenes, y presionar la tecla x que borrar el o a texto que se encuentre sobre el cursor. Si se quiere borrar las l ineas enteras, entonces se debe presionar dos veces la tecla d sobre la l inea que deseo eliminar. Si se presionan las teclas dw se borra la palabra sobre la que se est ubicado. a La letra R sobre una palabra se puede escribir encima de ella. Esto es una especie de modo de insercin de texto pero slo se podr modificar la palabra sobre la que se est situado. La o o a a tecla ~ cambia de mayscula a minscula la letra sobre la que se est situado. u u a Moverse dentro de vi. Estando en modo rdenes podemos movernos por el archivo que se est editando usando o a las flechas hacia la izquierda, derecha, abajo o arriba. Con la tecla 0 nos movemos al comienzo de la l inea y con la tecla $ nos movemos al final de la misma. 1.10. EL SISTEMA X WINDOWS. 33 Con las teclas w y b nos movemos al comienzo de la siguiente palabra o al de la palabra anterior respectivamente. Para moverme hacia la pantalla siguiente la combinacin de teclas o CTRL F y para volver a la pantalla anterior CTRL B. Para ir hasta el principio del archivo se presiona la tecla G. Opciones de comandos. Para entrar al men de comandos se debe presionar la tecla : en el modo de rdenes. u o Aparecern los dos puntos (:). Aqu se pueden ingresar ordenes para guardar, salir, cambiar a i de archivo entre otras cosas. Veamos algunos ejemplos: :w Guardar los cambios. :w otherfile.txt Guardar con el nuevo nombre otherfile.txt :wq Guardar los cambios y salir. :q! Salir del archivo sin guardar los cambios. :e file1.txt Si deseo editar otro archivo al que se le pondr por nombre file1.txt. a :r file.txt Si se quiere insertar un archivo ya existente, por ejemplo file.txt. :r! comando Si se quiere ejecutar algn comando del shell y que su salida aparezca en u el archivo que se est editando. a 1.9.2. Editores modo emacs. El editor GNU Emacs, escrito por Richard Stallman de la Free Software Foundation, es uno de los que tienen mayor aceptacin entre los usuarios de unix, estando disponible bajo o 32 e o licencia GNU GPL para una gran cantidad de arquitecturas. Tambin existe otra versin de emacs llamada XEmacs totalmente compatible con la anterior pero presentando mejoras significativas respecto al GNU Emacs. Dentro de los "inconvenientes" que presenta es que no viene por defecto incluido en la mayor de los sistemas unix. Las actuales distribuciones ia de Linux y en particular Debian GNU/Linux contienen ambas versiones de emacs, tanto GNU Emacs como XEmacs, como tambin versiones de jove, jed, xjed y muchos otros editores. e Para mayor informacin ver Apndice. o e 1.10. El sistema X Windows. El X Windows system es el sistema estndar de ventanas en las estaciones de trabajo. Lo a usual actualmente es que el sistema de ventanas sea arrancado automticamente cuando la a mquina parte. En el sistema X Windows deben distinguirse dos conceptos: a La licencia de GNU, da el permiso de libre uso de los programas con sus fuentes, pero los autores mantienen el Copyright y no es permitido distribuir los binarios sin acceso a sus fuentes. Los programas derivados de dichos fuentes heredan la licencia GNU. 32 34 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. server : Es un programa que se encarga de escribir en el dispositivo de video y de capturar las entradas (por teclado, ratn, etc.). Asimismo se encarga de mantener o los recursos y preferencias de las aplicaciones. Slo puede existir un server para cada o pantalla. client : Es cualquier aplicacin que se ejecute en el sistema X Windows. No hay l o imite (en principio) en el nmero de clientes que pueden estarse ejecutando simultneamente. u a Los clientes pueden ser locales o remotos. Window Manager (WM) Es un cliente con "privilegios especiales": controla el comportamiento (forma, tama~o,. . . ) del resto de clientes. Existen varios, destacando: n icewm : Ice Window Manager, uno de los window managers gnome compatible. sawfish : Window managers gnome compatible, altamente configurable y muy integrado al gnome desktop. Metacity : Window managers gnome 2 compatible. El look and feel (o GUI) de X Windows es extremadamente configurable, y puede parecer que dos mquinas son muy distintas, pero esto se debe al WM que se est usando y no a que a e las aplicaciones sean distintas. Para configurar tu sesin es necesario saber qu programas ests usando y ver las pginas o e a a de manual. Los archivos principales son: .xinitrc o .xsession archivo le al arrancar X Windows. Aqu se pueden definir ido i los programas que aparecen al inicio de tu sesin. o .fvwmrc archivo de configuracin del fvwm. Ver las pginas del manual de fvwm. o a .olwmrc archivo de configuracin del olwm. Ver las pginas del manual de olwm. o a .Xdefaults Configuracin general de las aplicaciones de X Windows. Aqu puedes o i definir los resources que encontrars en los manuales de las aplicaciones de X. a En caso de que tengas que correr una aplicacin de X que no est disponible en la mquina o e a que ests usando, eso no representa ningn problema. Las rdenes necesarias son (por ejemplo, a u o para arrancar un gnome-terminal remoto): [email protected]:~$ ssh -XC [email protected] [email protected]'s password: [email protected]:~$ gnome-terminal & Las opciones XC en el comando ssh corresponden a que exporte el DISPLAY y que comprima, respectivamente. La forma antigua 1.11. USO DEL RATON. [email protected]:~$ xhost +hostname2 hostname2 being added to access control list [email protected]:~$ ssh [email protected] [email protected]'s password: [email protected]:~$ export DISPLAY=hostname1:0 [email protected]:~$ gnome-terminal & 35 Si todo est previamente configurado, es posible que no haga falta dar el password. a Cuando quieres salir, normalmente puedes encontrar un icono con la opcin Log out, en o un men o panel de la pantalla. u 1.11. Uso del ratn. o El ratn es un dispositivo esencial en el uso de programas X, sin embargo, la funcin que o o realiza en cada uno de ellos no est normalizada. a Comentaremos la pauta seguida por la mayor de las aplicaciones, pero debe tenerse ia presente que es muy frecuente encontrar aplicaciones que no las respetan.33 Botn izquierdo (LB): Seleccionar. Comienza el bloque de seleccin. o o Botn central (MB): Pegar. Copia la seleccin en la posicin del cursor. o o o Botn derecho (RB): Habitualmente ofrece un men para partir aplicaciones. o u Existen dos modos para determinar cul es la ventana activa, aqulla que recibe las a e entradas de teclado: Focus Follows Mouse: La ventana que contenga al ratn es la que es activa. No usado o por defecto actualmente. Click To Focus: La ventana seleccionada es la activa. El modo que est activo depende e de la configuracin del Window Manager. o 1.12. Internet. En esta seccin denominaremos unix1 a la mquina local (desde donde ejecutamos la o a orden) y unix2 a la mquina remota (con la que interaccionamos). Ambos son los hostnames a de las respectivas mquinas. Existen algunos conceptos que previamente debemos comentar: a IP-number: es un conjunto de 4 nmeros separados por puntos (p.e. 200.89.74.6) que u se asocia a cada mquina. No puede haber dos mquinas conectadas en la misma red a a con el mismo nmero. u Las aplicaciones que son conscientes de un uso anormal y estn realizadas por programadores inteligentes, a muestran en pantalla la funcin de cada botn cuando son posibles varias alternativas. o o 33 36 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. hostname: es el nombre que tiene asociada la mquina (p.e. macul). A este nombre se a le suelen a~adir una serie de sufijos separados por puntos que constituye el denominado n dominio (p.e. macul.ciencias.uchile.cl). Una mquina por tanto puede tener ms a a de un nombre reconocido (se habla en este caso de alias). Se denomina resolucin o a la identificacin entre un hostname y el IP-number correspondiente. La consulta o se realiza inicialmente en el archivo /etc/hosts, donde normalmente se guardan las identificaciones de las mquinas ms comnmente empleadas. En caso de que no se a a u logre se accede al servicio DNS (Domain Name Service), que permite la identificacin o (resolucin) entre un hostname y un IP-number. o mail-address: es el nombre que se emplea para enviar correo electrnico. Este nombre o puede coincidir con el nombre de una mquina, pero se suele definir como un alias, con a objeto de que la direccin no deba de cambiarse si la mquina se estropea o se cambia o a por otra. 1.12.1. Acceso a la red. Existen muchos programas para la conexin de la red, los ms usados son: o a telnet unix2, hace un login en la mquina unix2, debe ingresarse el usuario y su a respectiva passwd. Adems, permite especificar el puerto en conexin en la mquina a o a remota. ssh [email protected], muy similar a telnet pero se puede especificar el usuario, si no se especifica se usa el nombre de la cuenta local. Adems, el passwd pasa encriptado a a travs de la red. ssh [email protected] comando, muy similar a rsh, el passwd pasa e encriptado y ejecuta el comando en la mquina remota, mostrando el resultado en la a mquina local. a scp file1 [email protected]:path/file, copia el archivo file1, del usuario1, que se encuentra en el directorio local en la mquina unix1, en la cuenta del usuario2 en la a mquina unix2 en $HOME/path/file. Si no se especifica el nombre del usuario se usa el a nombre de la cuenta local. Si se quiere copiar el archivo file2 del usuario3 en unix2 en la cuenta actual de unix1 el comando ser scp [email protected]:file2 .. Antes ia: de realizar cualquiera de las copias el sistema preguntar por el passwd del usuario en a cuestin en la mquina unix2. Nuevamente, el passwd pasa encriptado a travs de la o a e red. talk [email protected], intenta hacer una conexin para hablar con el usuario1 en la o mquina unix2. Existen varias versiones de talk en los diferentes sistemas operativos, a de forma que no siempre es posible establecer una comunicacin entre mquinas con o a sistemas operativos diferentes. ftp unix2, (file transfer protocol) aplicacin para copiar archivos entre mquinas de o a una red. ftp exige un nombre de cuenta y password para la mquina remota. Algunas a de las opciones ms empleadas (una vez establecida la conexin) son: a o 1.12. INTERNET. 37 bin: Establece el modo de comunicacin binario. Es decir, transfiere una imagen o exacta del archivo. asc: Establece el modo de comunicacin ascii. Realiza las conversiones necesarias o entre las dos mquinas en comunicacin. Es el modo por defecto. a o cd: Cambia directorio en la mquina remota. a lcd: Cambia directorio en la mquina local. a ls: Lista el directorio remoto. !ls: Lista el directorio local. prompt : No pide confirmacin para transferencia mltiple de archivos. o u get rfile [lfile]: transfiere el archivo rfile de la mquina remota a la mquia a na local denominndolo lfile. En caso de no suministrarse el segundo argumento a supone igual nombre en ambas mquinas. a put lfile [rfile] : transfiere el archivo lfile de la mquina local a la mquina a a remota denominndolo rfile. En caso de no suministrarse el segundo argumento a supone igual nombre en ambas mquinas. Tambin puede usarse send. a e mget rfile : igual que get, pero con ms de un archivo (rfile puede contener a caracteres comodines). mput lfile : igual que put, pero con ms de un archivo (lfile puede contener a caracteres comodines). Existen versiones mejoradas de ftp con muchas ms posibilidades, por ejemplo, ncftp. a Tambin existen versiones grficas de clientes ftp donde la eleccin de archivo, el sentido e a o de la transferencia y el modo de sta, se elige con el mouse (p.e. wxftp). e rlogin -l nombre unix2, (remote login), hace un login a la mquina unix2 como el a usuario nombre por defecto, sin los argumentos -l nombre rlogin usa el nombre de la cuenta local. Normalmente rlogin pide el password de la cuenta remota, pero con el uso del archivo .rhosts o /etc/hosts.equiv esto no es siempre necesario. rsh -l nombre unix2 orden, (remote shell ), ejecuta la orden en la mquina unix2 a como usuario nombre. Es necesario que pueda entrar en la mquina remota sin password a para ejecutar una orden remota. Sin especificar orden acta como rlogin. u 1.12.2. El correo electrnico. o El correo electrnico (e-mail) es un servicio para el env de mensajes entre usuarios, o io tanto de la misma mquina como de diferentes mquinas. a a Direcciones de correo electrnico. o Para mandar un e-mail es necesario conocer la direccin del destinatario. Esta direccin o o consta de dos campos que se combinan intercalando entre ellos el @ (at): [email protected] 38 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. user : es la identificacin del usuario (i.e. login) en la mquina remota. o a domain : es la mquina donde recibe correo el destinatario. A menudo, es frecuente a que si una persona tiene acceso a un conjunto de mquinas, su direccin de correo no a o corresponda con una mquina sino que corresponda a un alias que se resolver en un a a nombre espec ifico de mquina en forma oculta para el que env a ia. Si el usuario es local, no es necesario colocar el campo domain (ni tampoco el @). Nomenclatura. Veamos algunos conceptos relacionados con el correo electrnico: o Subject : Es una parte de un mensaje que piden los programas al comienzo y sirve como t itulo para el mensaje. Cc (Carbon Copy) : Permite el env de copias del mensaje que est siendo editado a io a terceras personas. Reply : Cuando se env un mensaje en respuesta a otro se suele a~adir el comienzo ia n del subject: Re:, con objeto de orientar al destinatario sobre el tema que se responde. Es frecuente que se incluya el mensaje al que se responde para facilitar al destinatario la comprensin de la respuesta. o Forward : Permite reenviar un mensaje completo (con modificaciones o sin ellas) a una tercera persona. Notando que Forward env tambin los archivos adjuntos, mientras ia e que la opcin Reply no lo hace. o Forwarding Mail : Permite a un usuario que disponga de cuentas en varias mquinas a 34 no relacionadas, de concentrar su correo en una cuenta unica . Para ello basta con tener un archivo $HOME/.forward que contenga la direccin donde desea centralizar su o correo. Mail group : Un grupo de correo es un conjunto de usuarios que reciben el correo dirigido a su grupo. Existen rdenes para responder a un determinado correo recibido o por esa v de forma que el resto del grupo sepa lo que ha respondido un miembro del ia mismo. In-Box : Es el archivo donde se almacena el correo que todav no ha sido le por el ia ido usuario. Suele estar localizado en /var/spool/mail/user. Mailer-Daemon : Cuando existe un problema en la transmisin de un mensaje se o recibe un mensaje proveniente del Mailer-Daemon que indica el problema que se ha presentado. Este comando debe usarse con conocimiento pues en caso contrario podr provocar un loop indefinido y ia no recibir nunca correo. 34 1.13. IMPRESION. Aplicacin mail. o 39 Es posiblemente la aplicacin ms simple. Para la lectura de mail teclear simplemente: o a mail y a continuacin aparece un o indice con los diferentes mensajes recibidos. Cada mensaje tiene una l inea de identificacin con nmero. Para leer un mensaje basta teclear su nmero y a o u u continuacin return. Para enviar un mensaje: mail (address) se pregunta por el Subject: o y a continuacin se introduce el mensaje. Para acabar se teclea slo un punto en una l o o inea o bien Ctr-D. Por ultimo, se pregunta por Cc:. Es posible personalizar el funcionamiento me diante el archivo $HOME/.mailrc. Para enviar un archivo de texto a travs del correo se suele e emplear la redireccin de entrada: mail (address) < file. Si queremos enviar un archivo o binario en forma de attach en el mail, el comando es mpack archivo-binario address. 1.12.3. Ftp anonymous. Existen servidores que permiten el acceso por ftp a usuarios que no disponen de cuenta en dichas mquinas. Para ello se emplea como login de entrada el usuario anonymous y como a passwd la direccin de e-mail personal. Existen servidores que no aceptan conexiones desde o mquinas que no estn declaradas correctamente en el servicio de nombre (dns), as como a a i algunas que no permiten la entrada a usuarios que no se identifican correctamente. Dada la sobrecarga que existe, muchos de los servidores tienen limitado el nmero de usuarios que u pueden acceder simultneamente. a 1.12.4. WWW. WWW son las siglas de World-Wide Web. Este servicio permite el acceso a informacin o entrelazada (dispone de un texto donde un trmino puede conducir a otro texto): hyperlinks. e Los archivos estn realizados en un lenguaje denominado html. Para acceder a este servicio a es necesario disponer de un lector de dicho lenguaje conocido como browser o navegador. Destacan actualmente: Iceweasel, Iceape, Opera, Camino (para MAC) y el simple pero muy rpido Lynx. a 1.13. Impresin. o Cuando se quiere obtener una copia impresa de un archivo se emplea el comando lpr. lpr file - Env el archivo file a la cola de impresin por defecto. Si la cola est activaia o a da, la impresora lista y ningn trabajo por encima del enviado, nuestro trabajo ser procesado u a de forma automtica. a A menudo existen varias posibles impresoras a las que poder enviar los trabajos. Para seleccionar una impresora en concreto (en vez de la por defecto) se emplea el modificador: lpr -Pimpresora, siendo impresora el nombre lgico asignado a esta otra impresora. Para o recibir una lista de las posibles impresoras de un sistema, as como su estado, se puede emi plear el comando /usr/sbin/lpc status. La lista de impresoras y su configuracin tambin o e est disponible en el archivo /etc/printcap. a Otras rdenes para la manipulacin de la cola de impresin son: o o o 40 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. lpq [-Pimpresora], permite examinar el estado de una determinada cola (para ver la cantidad de trabajos sin procesar de sta, por ejemplo). e lprm [-Pimpresora] jobnumber, permite eliminar un trabajo de la cola de impresin. o Uno de los lenguajes de impresin grfica ms extendidos en la actualidad es PostScript. o a a La extensin de los archivos PostScript empleada es .ps. Un archivo PostScript puede ser o visualizado e impreso mediante los programas: gv, gnome-gv o ghostview. Por ello muchas de las impresoras actuales slo admiten la impresin en dicho formato. o o En caso de desear imprimir un archivo ascii deber previamente realizarse la conversin a o a PostScript empleando la orden a2ps: a2ps file.txt Esta orden env a la impresora ia el archivo ascii file.txt formateado a 2 pginas por hoja. Otro programa que permite a convertir un archivo ascii en postscript es enscript. Otro tipo de archivos ampliamente difundido y que habitualmente se necesita imprimir es el conocido como Portable Document Format. Este tipo de archivo poseen una extensin o .pdf y pueden ser visualizados e impresos usando aplicaciones tales como: xpdf, acroread o gv. 1.14. Compresin. o A menudo necesitamos comprimir un archivo para disminuir su tama~o, o bien crear un n respaldo (backup) de una determinada estructura de directorios. Se comentan a continuacin o una serie de comandos que permiten ejecutar dichas acciones. u El compresor compress est relativamente fuera de uso35 pero an podemos encontrarnos a con archivos comprimidos por l. e uncompress file.Z : descomprime el archivo, creando el archivo file. Destruye el archivo original. zcat file.Z : muestra por el stdout el contenido descomprimido del archivo (sin destruir el original). compress file : comprime el archivo, creando el archivo file.Z. Destruye el archivo original. Otra alternativa de compresor mucho ms usada es gzip, el compresor de GNU que posee a una mayor razn de compresin que compress. Veamos los comandos: o o gzip file : comprime el archivo, creando el archivo file.gz. Destruye el archivo original. gunzip file.gz : descomprime el archivo, creando el archivo file. Destruye el archivo original. zless file.gz : muestra por el stdout el contenido descomprimido del archivo paginado por less. 35 Este comando no se incluye en la instalacin bsica. Debemos cargar el paquete ncompress para tenerlo o a 1.14. COMPRESION. 41 La extensin empleada en los archivos comprimidos con gzip suele ser .gz, pero a veces o se usa .gzip. Adicionalmente el programa gunzip tambin puede descomprimir archivos e creados con compress. La opcin con mayor tasa de compresin que gzip es bzip2 y su descompresor bunzip2. o o bzip2 file : comprime el archivo, creando el archivo file.bz2. Destruye el archivo original. bunzip2 file.bz2 : descomprime el archivo, creando el archivo file. Destruye el archivo original. bzcat file.bz2 : muestra por el stdout el contenido descomprimido del archivo. Debemos usar un paginador, adicionalmente, para verlo por pginas. a La extensin usada en este caso es .bz2. El kernel de Linux se distribuye en formao to bzip2. Tambin existe una versin paralelizada llamada pbzip2. Uno de los mejores e o algoritmos de compresin est disponible para Linux en el programa p7zip. Veamos un o a ejemplo: un archivo linux-2.6.18.tar que contiene el kernel 2.6.18 de Linux que tiene un tama~o de 230 Mb. Los resultados al comprimirlo con compress, gzip, bzip2 y 7za son: n linux-2.6.18.tar.Z 91 Mb, linux-2.6.18.tar.gz 51 Mb, linux-2.6.18.tar.bz2 40 Mb y linux-2.6.18.tar.7z 33 Mb.36 Existen tambin versiones de los compresores compatibles con otros sistemas operativos: e zip, unzip, unarj, lha, rar y zoo. En caso que se desee crear un archivo comprimido con una estructura de directorios debe ejecutarse la orden: tar cvzf nombre.tgz directorio o bien tar cvjf nombre.tbz directorio En el primer caso comprime con gzip y en el segundo con bzip2. Para descomprimir y restablecer la estructura de directorio almacenada se usan los comandos: tar xvzf nombre.tgz directorio si se realiz la compresin con gzip o bien o o tar xvjf nombre.tbz directorio si se realiz la compresin con bzip2. o o Los comandos gzip y bzip2 fueron dados con la opcin --best para lograr la mayor compresin. El o o comando usado para la compresin con 7z fue: 7za a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on o file.tar.7z file.tar, note la nueva extensin 7z. Para descomprimir con 7z basta 7z e file.tar.7z o 36 42 CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. Cap itulo 2 Introduccin a programacin. o o versin 1.0, 30 de Agosto del 2007 o En este cap itulo se intentar dar los elementos bsicos de lo que es un lenguaje de proa a gramacin y lo que es programar. o 2.1. Qu es programar? e A continuacin, presentamos algunas alternativas de respuesta a esta pregunta: o Hacer un programa. Hacer que un computador haga una secuencia de instrucciones que uno le pide. Darle, de alguna forma, una secuencia de pasos lgicos para que un computador los o ejecute con la intencin de alcanzar algn objetivo. o u Escribir una precisa secuencia de comandos o instrucciones, en algn lenguaje que el u computador entienda (a este tipo de lenguaje lo llamaremos lenguaje de programacin) o para que luego el computador las realice exactamente, paso a paso. Un programa es un archivo que puede ser tan corto como una sola l inea de cdigo, o tan o largo como varios millones de l ineas de cdigo. o 2.2. Lenguajes de programacin. o Existen diferentes tipos de lenguajes de programacin, algunos ms cercanos a la mquina o a a y menos al programador; otros ms cercanos al programador y distantes de la mquina. a a Realmente existe toda una jerarqu entre los lenguajes de programacin. Veamos algunos ia o ejemplos: 2.2.1. Cdigo de Mquina binario. o a Es el lenguaje de la CPU, y el lenguaje de ms bajo nivel. Compuesto de 0 y 1 binario, a lo que est muy cerca de la mquina pero muy lejos del programador. Una de sus grandes a a desventajas es que no es fcil de escribir o de leer para el programador. a Un programa simple, como Hola mundo, se ver en cdigo binario algo as como: ia o i 43 44 10001010101010011110010 10001011010101000111010 11000101000101010000111 00101010101010010110000 11110010101010101000011 10001010010101010101001 00101010101101010101001 CAP ITULO 2. INTRODUCCION A PROGRAMACION. 2.2.2. Lenguaje de Ensamblador (Assembler). El paso siguiente es reeplazar los 1 y 0 por una secuencia de abreviaturas del lenguaje de mquina, este tipo de lenguaje se conoce como lenguaje de Ensamblador o Assembler. a Est cerca de la mquina pero no tanto como el anterior y esta un poco ms cerca del a a a programador. Veamos el programa Hola mundo en lenguaje de Ensamblador para la familia de procesadores X86. title Programa Hola Mundo (hello.asm) ; Este programa muestra "Hola, Mundo!" dosseg .model small .stack 100h .data hello_message db 'Hola, Mundo!', 0dh, 0ah, '$' .code main proc mov ax, @ .data mov ds,ax mov ah,9 mov dx, offset hello_message int 21h mov ax,4C00h int 21h main endp end main 2.2.3. Lenguaje de alto nivel. Utilizan declaraciones en los programas, sentencias como palabras y expresiones algebraicas. Estos lenguajes fueron desarrollados en las dcadas del 50 y 60. Son lenguajes que estn e a ms cerca del programador que de la mquina, por lo tanto, necesitan una etapa de traducin a a o para que los entienda la mquina. Este proceso se puede hacer de dos maneras: compilando a o interpretando el programa fuente. Lenguajes Compilados. En este caso, otro programa (el compilador) lee el programa fuente, un archivo en ASCII donde se encuentran el listado de instruciones y lo reescribe en un archivo binario, en lenguaje de mquina para que la CPU pueda entenderlo. Esto se hace de una sola vez y el programa a final se guarda en esta nueva forma (un ejecutable). El ejecutable de un programa que es compilado se estima que ser considerablemente ms largo que el original, programa fuente. a a 2.2. LENGUAJES DE PROGRAMACION. 45 Algunos de los lenguajes compilados ms notables son Fortran, C y C++. Un ejemplo del a programa Hola mundo escrito en C++ es dado a continuacin: o // // Programa Hola Mundo // #include <iostream> using namespace std; int main() { cout << "Hola mundo" << endl; return 0; } 2.2.4. Lenguajes interpretados. En este caso otro programa (el intrprete) traduce las declaraciones del programa original e a lenguaje de mquina, l a inea por l inea, a medida que va ejecutando el programa original. Un programa interpretado suele ser ms peque~o que uno compilado pero tardar ms tiempo en a n a a ser ejecutado. Existe gran cantidad de este tipo de lenguajes, Python, Perl, Bash, por nombrar algunos. Un ejemplo del programa Hola mundo escrito en Python es dado a continuacin: o # Programa Hola mundo print "Hola Mundo" 2.2.5. Lenguajes especializados. Desde el punto de vista de la funcionalidad de los lenguajes podemos separarlos en lenguajes de carcter general y lenguajes especializados. Los lenguajes de carcter general son a a aquellos que sirven para programar una gran nmero de problemas, por ejemplo C o C++, u Python. Los lenguajes especializados han sido dise~ados para realizar tareas espec n ificas. Ejemplos de ello son PHP y JavaScript, especializados en crear pginas web, o SQL, creado para a manipular informacin en bases de datos. o Una lista de lenguajes. A continuacin, damos una lista, probablemente muy incompleta, de los lenguajes de o programacin ms comunes en la actualidad: o a ABC, Ada, ASP, Awk, BASIC, C, C++, C#, Caml, Cobol, cdigo de mquina, Corba, o a Delphi, Eiffel, Erlang, Fortran, Haskell, Java, JavaScript, Lisp, Logo, Modula, Modula 2, Mozart, Mumps, Oberon, Objetive C, Oz, Pascal, Perl, PHP, Python, Realbasic, Rebol, Rexx, RPG, Ruby, Scheme, Smaltalk, SQL, Squeak, TCL, Visual Basic. 46 CAP ITULO 2. INTRODUCCION A PROGRAMACION. 2.3. 2.3.1. Lenguajes naturales y formales. Lenguajes naturales. Son lenguajes hablados por la gente (por ejemplo: Espa~ol, Ingls, Alemn o Japons). n e a e Una de sus caracteristicas es que son ambiguos, por ejemplo: "Dame esa cosa" o "Oh, seguro, Grande!". En ambos ejemplos no es claro a que se estn refiriendo y se necesita un contexto a para entenderlos. Muchas veces estos lenguajes son redundantes y estn llenos de expresiones a idiomticas las cuales no deben ser tomadas literalmente, por ejemplo: "Me podr comer a ia una vaca", "Me mataste", o "Andate a la punta del cerro". 2.3.2. Lenguajes formales. Hecho por el hombre, como las matemticas, la notacin en qu a o imica o los lenguajes de programacin de computadores. Se caracterizan por ser inambiguos. Por ejemplo, una o expresin matemtica: 1 + 4 = 5; o una expresin en qu o a o imica: CH4 +2O2 2H2 O+CO2 ; o, finalmente, una expresin en lenguaje de programacin print "Hola mundo". Los lenguajes o o formales son adems concisos y estrictamente literales. a Sintaxis. Los lenguajes, tanto naturales como formales, tienen reglas de sintaxis. Por una parte, estn los tokens, que corresponden a los elementos bsicos (i.e. letras, palabras, s a a imbolos) del lenguaje: Tokens correctos: 1+3=4; gato, H2 O. Tokens incorrectos: 2@+#=!;C;Hh O. Por otro lado, tenemos las estructuras, esto es la manera en que los tokens son organizados: Estructuras correctas: 1 + 3 = 4, gato, H2 O. Estructuras incorrectas: 13+ = 4, gtoa, 2 HO. 2.4. Desarrollando programas. Para desarrollar sus primeros programas parta escribiendo en sus propias palabras lo que el programa deber hacer. Convierta esta descripcin en una serie de pasos en sus propias ia o palabras. Para cada uno de los pasos propuestos traduzca sus palabras en un cdigo (Python o o C++). Dentro del cdigo incluya instrucciones que impriman los valor de las variables para o probar que el programa est haciendo lo que usted esperaba. a 2.5. LA INTERFAZ CON EL USUARIO. 47 2.5. La interfaz con el usuario. Siempre que escriba un programa debe tener presente que alguien, que puede no ser usted mismo, lo puede usar alguna vez. Lo anterior significa, en particular, que el programa debe tener documentacin, ya que un programa sin documentacin es muy dif de usar. Pero o o icil adems es importante cuidar la parte del programa con la que el usuario interacta, es decir a u la interfaz con el usuario. Esta interfaz podr ser tanto mensajes simples de texto como soian fisticadas ventanas grficas. Lo importante es que ayuden al usuario a ejecutar correctamente a el programa. Revisemos una mala interfaz con el usuario. Tenemos un programa que no sabemos lo que hace, pero al ejecutarse resulta lo siguiente: Entre un numero 5 Entre otro numero 7 La respuesta es 12 Hay una evidente falta de instrucciones de parte del programador para el usuario, que primero no sabe para qu se le pide cada nmero, y luego no sabe qu hizo con ellos, slo la respuesta, e u e o 12, sin mayor explicacin de lo que significa. o Como contraparte, una buena interfaz con el usuario tiene documentacin anexa, o bien, o alguna ayuda en el mismo programa. Esta documentacin debiera explicar que hace el proo grama, los datos que necesitar y el o los resultados que entregar cuando finalice. a a Cada vez que se le pide algo al usuario deber estar claras las siguientes preguntas: ian qu es exactamente lo que se supone que yo tipee?; los nmeros que ingreso deben tener e u decimales?; o deben ser sin decimales?; en qu unidades de medidas debo ingresarlos?; los e nmeros que se piden son grandes o son nmeros peque~os? Si se trata de palabras, debo u u n ingresarlas en minsculas o maysculas? u u Algunos lineamientos bsicos que deber observar para construir interfaces con el usuario a ia que sea claras son los siguientes: Parta con un t itulo e indicaciones dentro del programa. Cuando pregunte por un dato que quiere que el usuario ingrese, dele la ayuda necesaria, por ejemplo Entre el largo en metros (0-100): Que las preguntas tengan sentido. Use espacios y caracteres especiales para mantener la pantalla despejada. Ind iquele al usuario que el programa termin. o Una versin mejorada del programa anterior podr ser la siguiente: o ia Calculo Ingrese Ingrese La suma de la suma de dos numeros un numero entero: 5 otro numero entero: 7 es 12 48 CAP ITULO 2. INTRODUCCION A PROGRAMACION. 2.6. Sacar los errores de un programa. Los errores en un programa son llamados bugs. Al proceso de rastrear los errores y corregirlos se le conoce como debugging. Un programa especializado en hacer debugging es llamado debugger. El debugging es una de las ms importantes habilidades en programaa cin. Los tres principales tipos de errores o bugs y sus consecuencias para la ejecucin del o o programa son: 1. Errores de sintaxis Usar un token o estructuralos en forma incorrecta El programa termina con un mensaje de error. 2. Errores de ejecucin (run-time error ) o Errores que ocurren durante la ejecucin. o El programa deja de correr abruptamente. 3. Errores lgicos o Errores en cmo el programa est lgicamente construido. o a o El programa corre, pero hace cosas mal. Cap itulo 3 Una breve introduccin a Python. o versin 2.1, 23 de Octubre del 2007 o En este cap itulo se intentar dar los elementos ms bsicos del lenguaje de programacin a a a o Python. No se pretende ms que satisfacer las m a inimas necesidades del curso, sirviendo como un ayuda de memoria de los tpicos abordados, para futura referencia. Se debe consignar que o no se consideran todas las posibilidades del lenguaje y las explicaciones estn reducidas al a m inimo. 3.1. Python. El Lenguaje Python fue inventado alrededor de 1990 por el cient ifico en computacin o holands Guido van Rossem y su nombre es un tributo a la grupo cmico Monty Python del e o cual Guido es admirador. El sitio oficial del lenguage en la web es http://www.python.org. 3.1.1. Interactivo versus scripting. El programa Python (como programa, no como lenguaje) posee un ambiente interactivo que nos permite ejecutar instrucciones del lenguaje Python directamente. Para ello, basta dar el comando: [email protected]:~$ python Python 2.4.4 (#2, Apr 5 2007, 20:11:18) [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> El programa ofrece un prompt (>>>), esperando instrucciones del usuario. Las instrucciones son interpretadas y ejecutadas de inmediato. Esta forma de usar Python tiene la ventaja de la retroalimentacin inmediata; de inmediato el programador sabe si la instruccin o o est correcta o incorrecta. Sin embargo, tiene la desventaja de que el cdigo no es guardado, a o y no puede por tanto ser reutilizado. Por otra parte, cuando escribimos un archivo de instrucciones en Python (script), tenemos la ventaja de que el cdigo s es almacenado, pudiendo ser reutilizado. En este caso las o i desventajas son que la retroalimentacin no es inmediata y que habitualmente requiere ms o a debugging para que el cdigo funcione correctamente. o 49 50 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. 3.1.2. Creando un script. Para crear un script de Python requerimos de un editor (vi, jed, xemacs, gedit. . . elija su favorito). Para ser ordenado, grbelo con extensin (supongamos que lo grabamos como a o archivo.py), para poder identificarlo rpidamente ms adelante. Recuerde darle los permia a sos de ejecucin adecuados (chmod u+x archivo.py). Para ejecutarlo basta ubicarse en el o directorio donde est el archivo y dar el comando a [email protected]:~/InProgress/python$ ./archivo.py 3.2. 3.2.1. Lenguaje Python. Algunos tipos bsicos. a Cadenas de caracteres (strings): Usualmente un conjunto de caracteres, i.e. un texto. Estn delimitados por "comillas" simples o dobles. a N meros enteros: Los nmeros, que pertenecen al conjunto Z, es decir, sin decimales. u u No pueden ser mayores que un tama~o fijo, en torno a dos billones (2 1012 ) en un n sistema de 32 bits usando signo . Cuando se dividen entre ellos slo dan valores o enteros. Por ejemplo: 4/3=1. N meros con punto flotante: Los nmeros, que pertenecen al conjunto R, es decir, u u con decimales (un nmero finito de ellos). u Enteros largos: Nmeros enteros mayores que 2 1012 . Los distinguimos por una L u al final del nmero, por ejemplo: 23434235234L. u Varios de los otros tipos sern explicados ms adelante en el cap a a itulo Tipo bool int long int float complex str tuple list dict file Descripcin o booleano entero entero largos nmero con punto flotante u nmero complejo u string tuplas listas diccionario archivo Ejemplo True o False 117 23434235234L 1.78 0.5 +2.0j 'abc' (1, 'hum', 2.0) [1, 'hum', 2.0] 'a':7.0, 23: True file('stuff.dat', 'w') Cuadro 3.1: Los tipos del lenguaje Python. 3.2. LENGUAJE PYTHON. Trabajando con n meros. u 51 Use el tipo de nmero en el cual quiere obtener su resultado. Es decir, si usted desea un u valor con decimales, use al menos un nmero con decimales en el clculo. Por ejemplo: 15/2.0 u a producir 7.5 y 15/2 producir 7, porque son ambos enteros. Si desea enteros largos, use al a a menos un entero largo en su expresin, por ejemplo: 23434235234L/2. o N mero complejos. u Los nmeros complejos son tambin soportados en Python. Los nmeros imaginarios puros u e u son escritos con un sufijo j o J. Los nmeros complejos con parte real no nula son escritos u como real +imagj, o pueden ser creados con la funcin complex(real,imag). Ejemplos o >>> 1j*1J (-1+0j) >>> 1j*complex(0,1) (-1+0j) >>> 3+1j*3 (3+3j) >>> (1+2j)/(1+1j) (1.5+0.5j) >>> a=1.5+0.5j >>> a.real 1.5 >>> a.imag 0.5 Cadenas de caracteres (strings). Una cadena de caracteres debe estar entre apstrofes o comillas simples o dobles. Por o ejemplo: nombre = "Este es tu nombre" nombre2= `Este es tambien su nombre' Si una cadena de caracteres necesita un apstrofe dentro de ella, anteponga un \ al o apstrofe extra. Ejemplos: o titulo = "Ella dijo: \"Te amo\"" titulo2 = `I\'m a boy' Algunas cadenas de caracteres con significado especial empiezan con el caracter \ (String Backslash Characters). \\ = Incluya \. \' = Apstrofe simple. o 52 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. \" = Apstrofe doble. o \n = L inea nueva. 3.2.2. Imprimiendo en la misma l inea. Agregando una coma (,) al final de una instruccin print har que el prximo comando o a o print aparezca en la misma l inea. Ejemplo print num1,"+", num2, "=", print respuesta 3.2.3. Imprimiendo un texto de varias l ineas. Si queremos imprimir un texto que tenga varias l ineas podemos usar dos formas distintas de la funcin print usando el caracter \n o bien usando un texto entre triple comilla o >>> print "primera linea\nsegunda linea" primera linea segunda linea >>> print """primera linea ... segunda linea""" primera linea segunda linea 3.2.4. Variables. Las variable son un nombre, usado dentro del programa, para referirse a un objeto o valor. Las limitaciones y consideraciones que hay que tener en cuenta para darle nombre a una variable son: No puede ser una palabra reservada del lenguaje (i.e. print, and, or, not). No puede comenzar por un nmero. u Las maysculas y las minsculas son diferentes. u u No puede incluir caracteres ilegales (i.e. $,%,+,=). Cree variables cuyos nombres signifiquen algo: MAL : diy=365 BIEN: days_in_year=365 3.2. LENGUAJE PYTHON. 53 3.2.5. Asignacin de variables. o Para asignarle un valor a una variable, digamos num, basta poner el nombre de la variable a la izquierda un signo igual y al lado derecho el valor o expresin que queremos asignarle o num=8.0 num=pi*3.0**2 Un mismo valor puede ser asignado a varias variables simultaneamente >>> x=y=z=0 # Todas las variables valen cero >>> print x,y,z 0 0 0 O bien podemos hacer asignasiones diferentes valores a diferentes variables en una misma asignacin o >>> >>> 0 1 >>> >>> 1 1 >>> >>> 0 1 a,b=0,1 print a,b a,b=b,a+b print a,b a,b,c=0,1,2 print a,b,c 2 3.2.6. Reciclando variables. Una vez que una variable es creada su valor puede ser reasignado. Veamos un ejemplo donde la variable card_value es reutilizada card_value=card1+card2 print card_value card_value=card1+card2+card3 print card_value 3.2.7. Operaciones matemticas. a Con Python podemos realizar las operaciones bsicas: suma (+), resta (-), multiplicacin a o () y divisin (/). Operaciones menos bsicas tambin estn disponibles: el exponente (), o a e a el mdulo ( %). o Entre las operaciones hay un orden de precedencia, unas se realizarn primero que otras. a A continuacin damos el orden de precedencia, partiendo por lo que se hace primero: o Parntesis, exponentes, multiplicacin y divisin, e o o Suma y resta. 54 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. De izquierda a derecha. Como ejemplo de la importancia de saber el orden de precedencia veamos los siguiente ejemplos: 2 (3 - 1) = 4 y 23-1=5 3.2.8. Operaciones con strings. Dos de las operaciones ms comunes con strings: a Concatenacin: se pueden concatenar dos strings al sumarlos, veamos un ejemplo: o >>> >>> >>> >>> x = "Hola" y = "Mundo" print x+y HolaMundo Repeticin: o >>> z = "Ja" >>> print z*3 >>> JaJaJa 3.2.9. Composicin. o Se pueden combinar sentencias simples en una compuesta, a travs del operador ",": e >>> x = "Elizabeth" >>> print "Tu nombre es : ",x >>> Tu nombre es : Elizabeth En el ejemplo, x fue asignado expl icitamente a una variable, pero naturalmente cualquier tipo de asignacin es posible, por ejemplo: o >>> promedio=(nota+extra_creditos)/posibles >>> print "Tu promedio es : ",promedio 3.2.10. Comentarios. Los comentarios son anotaciones que usted escribe para ayudar a explicar lo que est haa ciendo en el programa. Los comentarios comienzan con #. Lo escrito despus de #, hasta el e final de la l inea, es ignorado por el intrprete. Por ejemplo: e dias = 60 #disponibles para el proyecto Naturalmente, los comentarios no son muy utiles cuando se trabaja interactivamente con Python, pero s lo son cuando se escribe un script. De este modo se pueden insertar i explicaciones en el cdigo que ayuden a recordar qu hace el programa en cada una de sus o e secciones, o explicarlo a terceros. Es buena costumbre de programacin que las primeras o l ineas de un cdigo sean comentarios que incluyan el nombre del programador y una breve o descripcin del programa. o 3.3. CONDICIONALES. 55 3.2.11. Entrada (input). Para leer strings del stdin use la instruccin raw_input(), por ejemplo o nombre = raw_input("Cual es tu nombre?") Si necesita leer nmeros del stdin use la instruccin input(): u o numero=input("Cuantos?") En ambos casos, el mensaje entre comillas dentro de los parntesis es opcional, sin embare go, aclara al usuario lo que el programa le est solicitando. En el siguiente par de ejemplos, el a programa solicita informacin al usuario, salvo que en el primero, el programa queda esperano do una respuesta del usuario, quien, a menos que sepa de antemano qu quiere el programa, e no tiene modo de saber por qu le programa no se contina ejecutando. e u Ejemplo sin mensaje (queda esperando para siempre una respuesta): >>> nombre = raw_input() Ejemplo con mensaje: >>> nombre = raw_input("Cual es tu nombre?") Cual es tu nombre? Pedro >>> 3.3. Condicionales. Los condicionales son expresiones que puede ser ciertas o falsas. Por ejemplo, el usuario tipe la palabra correcta? o El nmero es mayor que 10? El resultado de la condicin decide o u o que suceder, por ejemplo, a todos los nmeros mayores que 100 rstele 20, cuando la palabra a u e ingresada sea la correcta, imprima "Bien" 3.3.1. Posibles condicionales. x == y x es igual a y. x != y x no es igual a y. x >y x es mayor que y. x <y x es menor que y. x >= y x es mayor igual a y. 56 x <= y x es menor igual a y. CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. A continuacin, algunos ejemplos de los anteriores condicionales: o x == 125: passwd == "nix": num >= 0: letter >"L": num/2 == (num1-num): num %5 != 0: 3.3.2. El if. A continuacin, estudiemos la instruccin if, partamos de la forma general de la instruco o cin: o if condition: statements Primero la palabra clave if, luego la condicin condition, que puede ser algo como x<y o o x==y, etc. La l inea termina con : requerido por la sintaxis del if. En las l ineas siguientes statements, viene las instrucciones a seguir si la condicin es cierta. Estas instrucciones o deben ir con sangr (indent). ia Un ejemplo de una construccin if simple. o num = input("Entre su edad") if num >= 30: old-person(num) print print "Gracias" 3.3.3. El if. . . else. La forma general de la construccin if...else a continuacin: o o if condition: statements_1 else: statements_2 El else debe de estar despus de una prueba condicional. Slo se ejecutar cuando condie o a cin evaluada en el if sea falsa. Use esta construccin cuando tenga dos conjuntos diferentes o o de instrucciones a realizar dependiendo de la condicin. Un ejemplo o 3.3. CONDICIONALES. if x%2 == 0: print "el numero es par" else: print "el numero es impar" 57 3.3.4. El if...elif...else. La forma general de la construccin if...elif...else, a continuacin: o o if condition_1: statements_1 elif condition_2: statements_2 else: statements_3 Para ms de dos opciones use la construccin con elif. elif es la forma acortada de las a o palabras else if. Las instrucciones asociadas a la opcin else se ejecutarn si todas las otras o a fallan. Un ejemplo concreto if x<0 : print x," elif x==0 : print x," elif x>0 : print x," else: print x," es negativo" es cero" es positivo" Error, no es un numero" 3.3.5. La palabra clave pass. El comando pass no realiza accin alguna, es decir, no hace nada. Un ejemplo o if x<0: HagaAlgo() else: pass 3.3.6. Operadores lgicos. o Los condicionales pueden ser unidos usando las palabras reservadas and, or o not. Si ocupamos un and para unir dos condiciones lgicas tenemos que ambas condiciones deben o satisfacerse para que el condicional sea cierto. En el caso de ocupar or para unir dos condiciones lgicas una de ellas debe ser satisfecha para que el condicional sea cierto. Finalmente o el not se antepone a una condicin y la niega, es decir, ser cierto si la condicin no es o a o satisfecha. En todos los caso se aplica que falso == 0 y cierto == 1 (en realidad cierto ! = 0). A continuacin, algunos ejemplos de operadores lgicos: o o 58 if x>0 and x<10: if y>0 and x>0: if pwd=="code" if y>0 or x<0: if not(x<y): CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. or pwd=="monster": if x>y or not(x<0): 3.3.7. Forma alternativa. Cuando pruebe valores para < o >, estas pruebas pueden ser escritas como un slo condio cional sin usar el and. Veamos ejemplos if 0<x<100: if 1000>=x >=0: 3.4. Funciones Pre-hechas. Una funcin define un conjunto de instrucciones. Es un conjunto de cdigo que puede ser o o usado una y otra vez. Puede ser creado por usted o importado desde algn mdulo. Ejemplos u o de funciones: De clculo matemtico a a log, sen, cos, tan, exp, hypot. Funciones que generan nmeros al azar, funciones de ingreso, funciones que hacen u cambios sobre un string. Cdigo hecho por el usuario que puede ser reciclado. o Hay un grupo de funciones que vienen hechas, es decir, listas para usar. Para encontrar qu funciones estn disponibles tenemos la documentacin del Python y un sitio web e a o http://www.python.org/doc/current/modindex.html Estas funciones pre-hechas vienen en grupos llamados mdulos. Para importar en nuestro o cdigo el mdulo apropiado, que contiene la funcin que nos interesa, usamos el comando o o o import modulo name Una vez importado el mdulo, cuando queremos llamar a la funcin para usarla, debemos o o dar el comando modulo name.function(arguments) 3.4. FUNCIONES PRE-HECHAS. Veamos un ejemplo com la funcin hypot del mdulo matemtico o o a import math math.hypot(8,9) 59 Si analizamos las l ineas anteriores de cdigo debemos decir que el mdulo que contiene las o o funciones matemticas se llama math y ste incluye la funcin hypot que devuelve el largo a e o de la hipotenusa. El s imbolo . separa el nombre del mdulo del de la funcin. Por supuesto o o hypot es el nombre de la funcin y () es el lugar para los argumentos. Una funcin podr o o ia no tener argumentos, pero an as deben ir los parntesis, son obligatorios. Los nmeros 8,9 u i e u son enviados a la funcin para que los procese. En el ejemplo, estos nmeros corresponden a o u los dos catetos de un tringulo rectngulo. a a En las secciones anteriores vimos funciones especializadas en el ingreso de strings y de nmeros. Nos referimos a input() para nmeros y a raw input() para strings. En este caso, u u input e raw input corresponden al nombre de las funciones, y entre los parntesis se acepta e un string como argumento, el cual es desplegado como prompt cuando se da el comando. Como vimos, este argumento es opcional en ambas funciones, sin embargo, lo incluyan o no, siempre se deben poner los parntesis. e a Funciones como input() y raw input() estn incorporadas al lenguaje y no necesitamos importar ningn mdulo para usarlas. u o 3.4.1. Algunas funciones incorporadas. float(obj) Convierte un string u otro nmero a un nmero de punto flotante. Con u u decimales. int(obj) Convierte un string u otro nmero a un nmero entero. Sin decimales. u u long(obj) Convierte un string u otro nmero a un nmero entero largo. Sin decimales. u u str(num) Convierte un nmero a un string. u divmod(x,y) Devuelve los resultados de x/y y x %y. len(s) Retorna el largo de un string u otro tipo de dato (una lista o diccionario). pow(x,y) Retorna x a la potencia y. range(start,stop,step) Retorna un conjunto de nmeros desde start hasta stop, u con un paso igual a step. round(x,n) Retorna el valor del punto flotante x redondeado a n digitos despus del e punto decimal. Si n es omitido el valor por defecto es cero. 60 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. 3.4.2. Algunas funciones del mdulo math. o acos(x), asin(x), atan(x) El arcocoseno, el arcoseno y la arcotangente de un nmeu ro. cos(x), sin(x), tan(x) El coseno, el seno y la tangente de un nmero. u log(x), log10(x) El logaritmo natural y el logaritmo en base 10 de un nmero. u pow(x,y) Retorna x a la potencia y. hypot(x,y) Retorna el largo de la hipotenusa de un tringulo rectngulo de catetos x a a e y. 3.4.3. Algunas funciones del mdulo string. o capitalize(string) Pone en mayscula la primera letra de la primera palabra. u capwords(string) Pone en mayscula la primera letra de todas las palabras. u lower(string) Todas las letras en minsculas. u upper(string) Todas las letras en maysculas. u replace(string,old,new) reemplaza todas las palabras old en string por las palabras new. center(string, width) Centra el string en un campo de un ancho dado por width. rjust(string, width) Justifica a la derecha el string en un campo de un ancho dado por width. ljust(string, width) Justifica a la izquierda el string en un campo de un ancho dado por width. 3.4.4. Algunas funciones del mdulo random. o randrange(start, stop, step) Da un nmero al azar entre el nmero start y el u u nmero stop. El nmero step es opcional. u u choice(sequence) Elige al azar un objeto que pertenece a la sequencia sequence (una lista). Por ejemplo sequence=["a", "b", "c", "d", "e"]. 3.4.5. Algunos otros mdulos y funciones. o Una funcin del mdulo time: o o sleep(x) El computador queda en pausa por x segundos. Un par de funciones del mdulo calendar: o 3.5. FUNCIONES HECHAS EN CASA. prcal(year) Imprime un calendario para el a~o year. n prmoth(year, month) Imprime un calendario para el mes month del a~o year. n 61 3.5. Funciones hechas en casa. Una funcin define un conjunto de instrucciones. A menudo son almacenadas en conjuntos o llamados mdulos. Pueden o no necesitar argumentos. Pueden o no retornar un valor al o programa. 3.5.1. Receta para una funcin. o Para crear una funcin primero hay que definir la funcin, darle un nombre y escribir el o o conjunto de instrucciones que la constituyen. La funcin realizar las instrucciones cuando o a es llamada. Despus, en el programa, llame la funcin que ya defini. A continuacin veamos e o o o la definicin formal de una funcin hecha por nosotros o o def nombre(argumentos): comandos Comenzamos con la palabra def, la cual es un palabra requerida. Debe ir en minsculas. u Luego nombre es el nombre que uno le da a la funcin. Despus vienes los argumentos o e (argumentos) que corresponden a las variables que se le pasan a la funcin para que las o utilice. Finalmente, :, requeridos al final de la l inea que define una funcin. El bloque de o commandos asociados a la funcin deben tener sangr para identificarlos como parte de la o ia misma. A continuacin, un ejemplo concreto: o # Definiendo la funcion def mi_function(): print "Nos gusta mucho la Fisica" # Usando la funcion mi_function() La definicin de una funcin puede ser en cualquier parte del programa con la salvedad o o que debe ser antes de que la funcin misma sea llamada. Una vez definida la funcin ellas se o o ejecutarn cuando sean llamadas. Cuando enviamos valores a nuestras funciones se crean las a variables nombradas en la definicin. Por ejemplo: o def mi_function(nombre1, nombre2): print nombre1+nombre2 Los nombres de las variables slo sern vlidos dentro de la funcin (es decir, las variables o a a o son locales). Las funciones usan variables locales. 62 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. 3.5.2. Variables globales. Si desea asignar una variable definida fuera de la funcin en la funcin, tiene que utilizar o o la sentencia global. Esta se emplea para declarar que la variable es global es decir que no es local. Puede utilizar los valores de las variables definidas fuera de la funcin (y no hay variables o con el mismo nombre dentro de la misma). Sin embargo, esto es inapropiado y debe ser evitado puesto que llega a ser confuso al lector del programa, en cuanto a donde se ha realizado dicha definicin de variables. Usando la sentencia global queda claro que la variable se define en o un bloque externo. #!/usr/bin/python def func(): global x print 'x es', x x = 2 print 'x cambiada a', x #main x = 50 func() print 'El valor de x es', x La salida del programa x es 50 Cambiada a 2 El valor de x es 2 3.5.3. Pasando valores a la funcin. o Para enviar los valores a nuestra funcin ponga los valores en la llamada de la funcin. El o o tipo de los valores debe estar de acuerdo con lo que la funcin espera. Las funciones pueden o tomar variables u otras funciones como argumentos. Veamos un ejemplo: def mi_function(nombre1, nombre2): print nombre1,nombre2 mi_function("azul","rojo") 3.5.4. Valores por defecto de una funcin. o En algunas funciones, se puede hacer que el uso de algunos parmetros sean opcionales a y usar valores predeterminados si el usuario no desea proporcionarlos (los valores de dichos parmetros). Esto se hace con la ayuda de valores pre-definidos. Puedes especificar los valores a por defecto despus del nombre del parmetro en la definicin de la funcin con el operador e a o o de asignacin (=) seguido por el argumento a definir. o 3.6. ARGUMENTOS CLAVES. #!/usr/bin/python def say(s, times = 1): print s * times say('Hola') say('Mundo', 5) Salida del programa Hola MundoMundoMundoMundoMundo 63 Solamente los parmetros que estn en el extremo de la lista de parmetros pueden tener a a a valores por defecto; es decir, no puedes tener un parmetro con un valor por defecto antes a de uno sin un valor, en el orden de los parmetros declarados, en la lista del parmetro de la a a funcin. Esto se debe a que los valores son asignados a los parmetros por la posicin. Por o a o ejemplo def func(a, b=5) es vlido, pero def func(a=5, b) no lo es a 3.6. Argumentos Claves. Si se tiene funciones con muchos parmetros y se quiere especificar solamente algunos de a ellos, entonces se puede asignar los valores para tales parmetros con solo nombrarlos, a esto a se denomina argumentos claves. Utilizamos el nombre en vez de la posicin que se ha estado o utilizando. Esto tiene dos ventajas: la primera, es que usar la funcin es ms fcil puesto que o a a no se necesita preocuparnos del orden de los argumentos. La segunda, es que podemos dar valores solamente a los parmetros que deseamos, a condicin de que los otros tengan valores a o por defecto. Usando Argumentos Claves #!/usr/bin/python def func(a, b=5, c=10): print 'a es', a, 'y b es', b, 'y c es', c func(3, 7) func(25, c=24) func(c=50, a=100) La salida es: a es 3 y b es 7 y c es 10 a es 25 y b es 5 y c es 24 a es 100 y b es 5 y c es 50 64 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. 3.7. DocStrings. Python tiene una caracter istica interesante llamada cadenas de documentacin que geo neralmente son llamadas por su nombre corto: docstrings. DocStrings es una herramienta importante de la que se puede hacer uso puesto que ayuda a documentar mejor el programa. Podemos incluso ubicar docstring en una funcin a tiempo de ejecucin, es decir cuando el o o programa est funcionando. Usando DocStrings a #!/usr/bin/python def printMax(x, y): '''Imprime el maximo de 2 numeros. Los dos valores deben ser enteros. Si hubieran decimales, son convertidos a enteros.''' x = int(x) # Convierte a enteros, si es posible y = int(y) if x > y: print x, 'es maximo' else: print y, 'es maximo' printMax(3, 5) print printMax.__doc__ La salida 5 es maximo Imprime el maximo de 2 numeros. Los dos valores deben ser enteros. Si hubieran decimales, son convertidos a enteros. 3.7.1. La palabra clave return. El comando return termina la ejecucin de una funcin. Un ejemplo o o import math def raiz(num): if num<0: print "Ingrese un numero positivo" return print math.sqrt(num) 3.7. DOCSTRINGS. 65 Los condicionales como el if son especialmente util para atrapar y manejar errores. Use el else para atrapar el error cuando la condicin no es satisfecha. o Los if pueden ser anidados. Sea cuidadoso, ya que la anidacin puede producir confusin o o y deber ser usada con moderacin y mesura. ia o 3.7.2. Funciones que tienen un valor de retorno. Podemos crear funciones que retornen un valor al programa que las llam. Por ejemplo o def sumalos(x,y): new = x+y return new # Llamada a la funcion sum = sumalos(5,6) 3.7.3. Recursin. o Se llama recursin cuando una funcin se llama a si misma. La recursin permite repetir o o o el uso de una funcin incluso dentro de la misma funcin. Un ejemplo es o o def count(x): x=x+1 print x count(x) Si la funcin nunca para, esta recursin es llamada recursin infinita. Para prevenir este o o o situacin creamos un caso base. El caso base es la condicin que causar que la funcin pare o o a o de llamarse a si misma. Un ejemplo def count(x): if x<100: x=x+1 print x count(x) else: return time.sleep(1) Un programa que calcula el factorial de un nmero en forma recursiva u #!/usr/bin/env python def fact(n): if n<2: return 1 else: 66 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. return n*fact(n-1) #main i=input("Ingrese un natural :") print "El factorial de",i," es ",fact(i) 3.8. Parmetros desde la l a inea de comando. Python puede recibir parmetros directamente de la l a inea de comando. La lista sys.argv los contiene. Supongamos que el programa se llama main.py y es como sigue: #!/usr/bin/python import sys for i in sys.argv: print i print sys.argv[0] Si ejecutamos el programa con la l inea de comando [email protected]:~$ ./main.py h -l --mas xvzf La salida ser a ./main.py h -l --mas xvzf ./main.py Otro ejemplo, un programa que suma dos nmeros desde la l u inea de comando, #!/usr/bin/python import sys if len(sys.argv)>2): n1=float(sys.argv[1]) n2=float(sys.argv[2]) print n1+n2 else: pass Si ejecutamos el programa con la l inea de comando [email protected]:~$ suma.py 1.2 3.5 La salida ser a 4.7 Si se llama el programa con menos argumentos, el programa no har nada. a 3.9. ITERACIONES CON WHILE. 67 3.9. Iteraciones con while. La palabra reservada while puede ser usada para crear una iteracin. La instruccin o o while necesita un contador que se incremente. Ejemplo while x < 10: print x x = x+1 Para hacer una seccin de cdigo reusable, en vez de usar valores contantes use variables. o o Primero un ejemplo no generalizado while x < 12: print 2*x x = x+1 Ahora el mismo ejemplo generalizado while x < max_num: print num*x x = x+1 Utilicemos la instruccin while para hacer una salida ordenada para un programa. El o cdigo de escape del tabulador (\t) en un string permite hacer tabulaciones. Los tabuladores o mantienen los items alineados dando una salida ordenada. Ejemplo, en este caso combinando la instruccin while y el cdigo de escape del tabulador haremos una tabla: o o while x < 10: print item1, "\t", item2 x = x+1 3.10. Los strings. Los strings son hechos de peque~as unidades, cada caracter individual. Cada uno de los n caracteres tiene una direccin numrica dentro del string, donde el primer caracter tiene la o e direccin cero (0). Cada caracter individual, o conjunto de caracteres, en un string puede ser o acccesado usando sus direcciones numricas. Use [ ] para accesar caracteres dentro de un e string. Veamos un ejemplo palabra = "computador" letra = palabra[0] Para acceder un conjunto de caracteres dentro de un string lo podemos hacer como sigue: Use [#:#] para obtener un conjunto de letras. parte = palabra[1:3] Para tomar desde el comienzo a un punto dado en el string. parte = palabra[:4] Para tomar desde un punto dado al final del string. parte = palabra[3:] 68 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. 3.10.1. Indice negativos. Veamos que pasa cuando usamos indices negativos >>> a="hola" >>> a[0] 'h' >>> a[-1] 'a' >>> a[-2] 'l' >>> a[-3] 'o' >>> a[-4] 'h' >>> a[-5] Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: string index out of range 3.10.2. Cun largo es un string ? a Para encontrar cuntos caracteres tiene un string usamos la funcin len(string). La a o funcin len requiere un string como argumento. Un ejemplo: o palabra = "computador" largo = len(palabra) 3.10.3. Recorriendo un string. Uno puede desear hacer una prueba sobre cada una de las letras que componen el string todas de una vez. Hay dos maneras de hacer esto usando una instruccin while o una o instruccin for para realizar el ciclo o loop. Primero veamos el ciclo con while: o palabra = "computador" indice = 0 while indice < len(palabra): letra = palabra[indice] print letra indice=indice +1 3.10.4. El ciclo for. Una manera ms compacta de escribir el ciclo while anterior es usando un ciclo for, a veamos cmo queda el cdigo o o 3.11. LISTAS. palabra = "computador" for letra in palabra: print letra 69 Notemos que hemos creado la variable letra cuando creamos el ciclo for. A continuacin, o un ejemplo ms completo del ciclo for: a #!/usr/bin/env python # -*- coding: iso-8859-1 -*# Programa que cuenta vocales import string palabra = raw_input("Entre una palabra : ") palabra_min = string.lower(palabra) vocales="aeiou" aeiou contador = 0 for letra in palabra_min: if letra in vocales: contador=contador +1 else: pass print "El nmero de vocales en la palabra que ingres fueron : ", contador u o Notemos la segunda l inea de este programa que nos permite ingresar e imprimir strings con caracteres acentuados y caracteres especiales. 3.10.5. Comparando strings. Los strings pueden ser usados en comparaciones. Ejemplo if palabra < "cebu": print palabra De acuerdo a Python, todas las letras maysculas son mayores que las letras minsculas. u u As a>Z. i Una buena idea es convertir todos los strings a mayscula o minscula, segn sea el caso, u u u antes de hacer comparaciones. Recordemos que el mdulo string contiene varias funciones o utiles incluyendo: lower(string), upper(string) y replace(string,string,string). Re vise la documentacin. o 3.11. Listas. Una lista es un conjunto ordenado de elementos. Las listas estn encerradas entre parntea e sis [ ]. Cada item en una lista est separado por una coma. Veamos ejemplos de listas a 70 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. mascotas = ["perros", "gatos", "canarios", "elefantes"] numeros = [1,2,3,4,5,6] cosas = [ 1, 15, "gorila", 23.9, "alfabeto"] Un elemento de una lista puede ser otra lista. Una lista dentro de otra lista es llamada lista anidada. A continuacin un ejemplo de listas anidadas o para_hacer = ["limpiar", ["comida perro", "comida gato","comida pez"], "cena"] 3.11.1. Rebanando listas. Una lista puede ser accesada al igual que un string usando el operador [ ]. Ejemplo >>> lista=["Pedro", "Andres", "Jaime", "Juan"] >>> print lista[0] Pedro >>> print lista[1:] ['Andres', 'Jaime', 'Juan'] Para accesar un item en una lista anidada hay que proveer dos indices. Ejemplo >>> lista_palabras = ["perro", ["fluffy", "mancha", "toto"], "gato"] >>> print lista_palabras[1][2] toto 3.11.2. Mutabilidad. A diferencia de los strings las listas son mutables, lo que significa que se pueden cambiar. Ejemplo >>> string = "perro" >>> string [2] = "d" # Traceback (most recent File "<stdin>", line TypeError: object does En cambio en una lista >>> lista = ["p", "e", "r", "r", "o"] >>> lista [2] = "d" >>> print lista ['p', 'e', 'd', 'r', 'o'] Como se muestra en la comparacin anterior una lista puede ser cambiada usando el o operador [ ]. Ejemplo >>> lista=["Pedro", "Andres", "Jaime", "Juan"] >>> lista[0]="Matias" >>> print lista ['Pedro', 'Andres', 'Jaime', 'Juan', 'Matias'] Esta NO es un instruccion VALIDA call last): 1, in ? not support item assignment 3.11. LISTAS. 71 3.11.3. Agregando a una lista. Para agregar items al final de una lista use list.append(item). Ejemplo >>> lista=["Pedro", "Andres", "Jaime", "Juan"] >>> lista.append("Matias") >>> print lista ['Pedro', 'Andres', 'Jaime', 'Juan', 'Matias'] 3.11.4. Operaciones con listas. las listas se pueden sumar resultando una solo lista que incluye ambas lista iniciales. Adems, podemos multiplicar una lista por un entero n obteniendo una lista con n replicas a de la lista inicial. Veamos ejemplos de ambas operaciones en forma interactiva >>> lista1=["Pedro", "Andres", "Jaime", "Juan"] >>> lista2=["gato", 2] >>> print lista1+lista2 ['Pedro', 'Andres', 'Jaime', 'Juan', 'gato', 2] >>> print lista2*2 ['gato', 2, 'gato', 2] >>> print 2*lista2 ['gato', 2, 'gato', 2] 3.11.5. Borrando items de una lista. Use el comando del para remover items basado en el indice de posicin. Ejemplo en forma o interactivo >>> lista=["Pedro", "Andres", "Jaime", "Juan"] >>> del lista[1] >>> print lista ['Pedro', 'Jaime', 'Juan'] Para remover items desde una lista sin usar el indice de posicin, use el siguiente comano do nombre_lista.remove("item") que borra la primera aparicin del item en la lista. Un o ejemplo interactivo >>> jovenes = ["Pancho", "Sole", "Jimmy", "Pancho"] >>> jovenes.remove("Pancho") >>> print jovenes ['Sole', 'Jimmy', 'Pancho'] 3.11.6. Qu contiene una lista? e Con la palabra reservada in podemos preguntar si un item est en la lista, veamos un a ejemplo 72 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. lista = ["rojo", "naranjo", "verde", "azul"] if "rojo" in lista: haga_algo() La palabra clave not puede ser combinada con in para hacer la pregunta contraria, es decir, si un item no est en un lista. Veamos un ejemplo a lista = ["rojo", "naranjo", "verde", "azul"] if "purpura" not in lista: haga_algo() 3.11.7. Un ciclo for y las listas. Los ciclos for pueden ser usados con listas de la misma manera que lo eran con strings, un ejemplo para mostrarlo email = ["[email protected]", "[email protected]"] for item in email: envie_mail(item) 3.11.8. Otros trucos con listas. len(list_name) Da el largo de la lista, su nmero de elementos. u list_name.sort() Pone la lista en orden alfabtico y numrico. e e random.choice(list_name) Escoge un elemento al azar de la lista. string.split(list_name) Convierte un string, como una frase, en una lista de palabras. string.join(list_name) Convierte una lista de palabras en una frase dentro de un string. 3.11.9. Generando listas de n meros. u La funcin range(num_init, num_fin, num_paso) toma tres argumentos enteros, el o nmero de partida, el numero final y el paso, para generar una lista de enteros que comienu za en el nmero de partida, termina con un nmero menor que el final saltandose el paso u u se~alado, si se omite el paso el salto ser de uno en uno. Veamos ejemplos n a range(10) = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] range(2,10) = [2, 3, 4, 5, 6, 7, 8, 9] range(0,11,2) = [0, 2, 4, 6, 8, 10] 3.12. TUPLAS. 73 3.12. Tuplas. Una tupla es una lista inmutable. Una tupla no puede modificarse de ningn modo despus u e de su creacin. o >>> t = ("a", "b", 8) >>> t[0] 'a' Una tupla se define del mismo modo que una lista, salvo que el conjunto se encierra entre parntesis ( ), en lugar de entre corchetes [ ]. Los elementos de la tupla tienen un orden e definido, como los de la lista. Las tuplas tienen primer indice 0, como las listas, de modo que el primer elemento de una tupla t, no vac es siempre t[0]. Los ia indices negativos cuentan desde el final de la tupla, como en las listas. Las porciones funcionan como en las listas. Advierta que al extraer una porcin de una lista, se obtiene una nueva lista; al extraerla o de una tupla, se obtiene una nueva tupla. No hay mtodos asociados a tuplas ( tal como e append() en una lista). No pueden a~adirse elementos a una tupla, no pueden eliminarse elementos de una tupla, n no pueden buscarse elementos en una tupla, se puede usar in para ver si un elelmento existe en la tupla. Las tuplas son ms rpidas que las listas. Si est definiendo un conjunto constante de a a a valores y todo lo que va ha hacer con l es recorrerlo, utilice una tupla en lugar de una e lista. Una tupla puede utilizarse como clave en un diccionario, pero las listas no. Las tuplas pueden convertirse en listas y vice versa. La funcin incorporada tuple(lista) toma una o lista y devuelve una tupla con los mismos elementos. La funcin list(tupla) toma una o tupla y devuelve una lista. 3.13. El comando break. El comando break es capaz de salirse de un ciclo for o while. Un ciclo puede tener una seccin else esta es ejecutada cuando el ciclo termina por haber agotado la lista en un ciclo o for o cuando la comparacin llega a ser falsa en un ciclo while, pero no cuando el ciclo o es ternimado con break. A continuacin, un programa que muestra este hecho y sirve para o encontrar nmeros primos u for n in range(2,10): for x in range(2,n): if n % x ==0: print n, "igual a", x,"*", n/x break else: print n,"es un numero primo" 74 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. 3.14. Trabajando con archivos. El lenguaje Python puede ser usado para crear programas que manipulan archivos sobre un sistema de archivos en un computador. El mdulo os contiene las funciones necesarias o para buscar, listar, renombrar y borrar archivos. El mdulo os.path contiene unas pocas o funciones especializadas para manipular archivos. Las funciones necesarias para abrir, leer y escribir archivos son funciones intr insecas de Python. 3.14.1. Funciones del mdulo os. o Funciones que slo dan una mirada. o getcwd() Retorna el nombre el directorio actual. listdir(path) Retorna una lista de todos los archivos en un directorio. chdir(path) Cambia de directorio. Mueve el foco a un directorio diferente. Funcin que ejecuta un comando del sistema operativo. o system('comando') Ejecuta el comando Funciones que agregan. mkdir(path) Hace un nuevo directorio con el nombre dado. mkdirs(path) Hace un subdirectorio y todos los directorios del path requeridos. Funciones que borran o remueven. remove(path) Borra un archivo. rmdir(path) Borra un directorio vac io. removedirs(path) Borra un directorio y todo dentro de l. e Funciones que cambian. rename(viejo,nuevo) Cambia el nombre de un archivo de viejo a nuevo renames(viejo,nuevo) Cambia el nombre de un archivo de viejo a nuevo cambiando los nombres de los directorios cuando es necesario. 3.14.2. Funciones del mdulo os.path. o Funciones que verifican. exists(file) Retorna un booleano si el archivo file existe. isdir(path) Retorna un booleano si el path es un directorio. isfile(file) Retorna un booleano si el file es un archivo. 3.14. TRABAJANDO CON ARCHIVOS. 75 3.14.3. Ejemplo de un cdigo. o Un programa que borra todo un directorio import os, os.path path = raw_input("Directorio a limpiar : ") os.chdir(path) files= os.listdir(path) print files for file in files: if os.path.isfile(file): os.remove(file) print "borrando", file elif os.path.isdir(file): os.removedirs(file) print "removiendo", file else: pass 3.14.4. Abriendo un archivo. Para abrir un archivos debemos dar la instruccin open(filename,mode) donde filename o es el nombre del archivo y el mode corresponde a una de tres letras "r" para lectura solamente del archivo, "w" para escritura y "a" para agregar al final del archivo. para poder manejar un archivo abierto hay que crear una variable con l. Ejemplo e salida= open("datos.txt","w") salidaAppend= open("programa.log","a") entrada= open("archivo.txt","r") 3.14.5. Leyendo un archivo. entrada.read() Lee el archivo completo como un string. entrada.readline() Lee una l inea en un string. entrada.readlines() Lee el archivo completo, cada l inea llega a ser un item tipo string en una lista. 3.14.6. Escribiendo a un archivo. salida.write(string) Escribe el string al archivo. Cmo se escribira este depende o de en qu modo el archivo fue abierto. e salida.writelines(list) Escribe todos los items tipo string en la lista list. Cada elemento en la lista estar en la misma l a inea a menos que un elemento contenga una caracter de newline 76 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. Si queremos usar la instruccion print para escribir sobre un archivo abierto, digamos salida, podemos usar la instruccin o salida = open("resultados.txt", "w") print >> salida, datos # Imprime datos en el archivo datos.txt print >> salida # Imprime una linea en blanco en el archivo datos.txt salida.close() 3.14.7. Cerrando un archivo. file.close() Cierra un archivo previamente abierto. 3.14.8. Archivos temporales. Las funciones en el mdulo tempfile puede ser usadas para crear y manejar archivos o temporales. La instruccin tempfile.mkstemp() devuelve una lista en el que el segundo o item es un nombre al azar que no ha sido usado. Los archivos temporales estarn localizados a en el directorio temporal por defecto. 3.14.9. Ejemplo de lectura escritura. # Programa que reemplaza una palabra vieja por otra nueva import string, tempfile, os # Preguntarle al usuario por Informacion filename = raw_input("Nombre del archivo: ") find = raw_input("Busque por: ") replace = raw_input("Reemplacelo por: ") # Abra el archivo del usuario, lealo y cierrelo file = open(filename, "r") text = file.readlines() file.close() # Edite la informacion del archivo del usuario nueva = for item in text: line = string.replace(item, find, replace) nueva.append(line) # Cree un nuevo archivo temporal newname=tempfile.mkstemp() temp_filename=newname[1] newfile = open(temp_filename, "w") newfile.writelines(nueva) 3.15. EXCEPCIONES. newfile.close() # Cambie los nombres de los archivos y borra los temporales oldfile=filename+"~" os.rename(filename, oldfile) os.system(" cp "+temp_filename+" "+filename) os.remove(temp_filename) 77 3.15. Excepciones. Las palabras reservadas try y except pueden ser usadas para atrapar errores de ejecucin o en el cdigo. Primero en el bloque try se ejecutan un grupo de instrucciones o alguna funcin. o o Si estas fallan o devuelven un error, el bloque de comandos encabezados por except se ejecutar. Lo anterior, puede ser usado para manejar programas que pueden fallar bajo a alguna circunstancia de una forma muy elegante. # Sample Try / Except def open_file(): filename = raw_input("Entre el nombre del archivo: ") try: file = open(filename) except: print "Archivo no encontrado." open_file() return file 3.16. Diccionarios. Las listas son colecciones de items (strings, nmeros o incluso otras listas). Cada item en u la lista tiene un indice asignado. >>> lista >>> print primero >>> print segundo >>> print tercero = ["primero", "segundo", "tercero"] lista[0] lista[1] lista[2] Para acceder a un valor de la lista uno debe saber su indice de posicin. Si uno remueve o un item desde la lista, el indice puede cambiar por el de otro item en la lista. Un diccionario es una coleccin de items que tiene una llave y un valor. Ellos son parecidos o a las listas, excepto que en vez de tener asignado un indice uno crea los indices. lista = ["primero", "segundo", "tercero"] diccionario = {0:"primero", 1:"segundo", 2:"tercero"} 78 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. Para crear un diccionario debemos encerrar los item entre parntesis de llave {}. Debemos e proveer una llave y un valor, un signo : se ubica entre la llave y el valor (llave:valor). cada llave debe ser unica. Cada par llave:valor est separado por una coma. Veamos un a par de ejemplos con diccionarios ingles = {'one':'uno', 'two':'dos'} Uno en japons e nihon_go = {} nihon_go["ichi"] = "uno" nihon_go["ni"] = "dos" nihon_go["san"] = "tres" print nihon_go { 'ichi':'uno', 'ni':'dos', 'san':'tres'} Para acceder el valor de un item de un diccionario uno debe entrar la llave. Los diccionarios slo trabajan en una direccin. Uno debe dar la llave y le devolvern el valor. Uno no puede o o a dar el valor y que le devuelvan la llave. Ejemplo nihon_go = { 'ichi':'uno', 'ni':'dos', 'san':'tres'} print nihon_go['ichi'] uno Notemos que este diccionario traduce del japons al espa~ol pero no del espa~ol al japons. e n n e 3.16.1. Editando un diccionario. Para cambiar un valor de un par, simplemente reas ignelo nihon_go["ichi"]=1 Para agregar un par valor:llave, ntrelo e nihon_go["shi"]=cuatro Para remover un par use del del nihon_go["ichi"] Para ver si una llave ya existe, use la funcin has_key() o nihon_go.has_key("ichi") Para copiar el diccionario entero use la funcin o mtodo copy(). o e japones= nihon_go.copy() Los diccionarios son mutables. Uno no tiene que reasignar el diccionario para hacer cambios en l. e Los diccionarios son utiles cada vez que usted tiene items que desea ligar juntos. Tambin e son utiles haciendo subtituciones (reemplace todos los x por y). Almacenando resultados para una inspeccin rpida. Haciendo mens para programas. Creando mini bases de datos o a u de informacin. o 3.17. MODULES Y SHELVE. 79 3.16.2. Un ejemplo de cdigo, un men . o u import string def add(num1,num2): print num1+num2 def mult(num1,num2): print num1*num2 # Programa num1 = input("Entre el primer numero: ") num2 = input("Entre el segundo numero: ") menu = {'S':add, 'M':mult} print "[S] para sumar, [M] para multiplicar: " choice = string.upper(raw_input()) menu[choice] (num1,num2) 3.16.3. Tuplas y diccionarios como argumentos. Si un parmetro formal de la forma **name est presente, la funcin recibe un diccionario. a a o Si un parmetro formal de la forma *name est presente, la funcin recibe una tupla. Los a a o parmetros formales *name deben ir antes que los **name. Ejemplo a def funcion(*mi_tupla, **nihon_go): .. 3.17. Modules y Shelve. Algunos problemas que se presentan a medida que los cdigos crecen son: con cientos o de l ineas es muy fcil perderse; trabaja en equipo se hace dif con cdigos muy grandes. a icil o Entonces, ser bueno poder separar el cdigo en peque~os archivos independientes. Por otra ia o n parte, se nos presenta otra dificultad, no podemos salvar estructuras de datos, es decir, si creamos un diccionario, sabemos como salvarlo como un archivo de texto, pero no podemos leerlo como un diccionario. Ser bueno poder salvar las listas como listas, los diccionarios ia como diccionarios y as luego poder leerlos e incorporarlos a nuestro cdigo en forma fcil. i o a 3.17.1. Partiendo el cdigo. o El cdigo puede ser dividido en archivos separados llamados modules. Ya hemos usado o varios de estos mdulos trabajando en Python (string, math, random, etc.). Para crear un o mdulo slo tipee su cdigo Python y slvelo de la manera usual. Su mdulo salvado puede o o o a o ser importado y usado tal como cualquier otro mdulo de Python. o 3.17.2. Creando un mdulo. o Lo principal para almacenar nuestro cdigo en un mdulo es escribir cdigo reusable. El o o o cdigo debe ser principalmente funciones y clases. Evite tener variables o comandos fuera de o 80 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. la definicin de funciones. Las funciones pueden requerir valores desde el programa quien las o llama. Salve el cdigo como un archivo regular .py. Luego en el programa principal, importe o el mdulo y uselo. o 3.17.3. Agregando un nuevo directorio al path. Cuando Python busca mdulos slo lo hace en ciertos directorios. La mayor de los o o ia mdulos que vienen con Python son salvados en /usr/lib/python. Cuando salve sus proo pios mdulos seguramente lo har en un lugar diferente, luego es necesario agregar el nuevo o a directorio a sys.path. Hay que consignar que el directorio desde el cual se invoca Python, si est en el path. Para editar el sys.path, en el modo interactivo tipee a >>> import sys >>> sys.path #imprime los actuales directorios en el path >>> sys.path.append('/home/usuario/mis_modulos') Dentro de un script usamos para importar mi mdulos mis_funciones que est salvado en o a mi directorio de mdulos o import sys sys.path.append('/home/usuario/mis_modulos') import mis_funciones 3.17.4. Haciendo los mdulos fciles de usar. o a Como ya vimos los comentarios con triple comilla son usados para agregar documentacin o al cdigo, ejemplo o def mi_funcion(x,y): """mi_funcion( primer nombre, ultimo nombre) """ Use al principio y al final triple comilla. El texto en triple comilla deber explicar lo que ia la funcin, clase o mdulo hace. Estas l o o ineas de documentacin las podr ver, en el modo o e interactivo, si da el comando help(module.mi_funcion). 3.17.5. Usando un mdulo. o En el programa principal incluya el comando import y el nombre del mdulo. Cuando o llame a una funcin del mdulo debe incluir el nombre del mdulo . el nombre de la funcin, o o o o esta no es la unica manera de importarlos, veamos unos ejemplo, primero la forma habitual: # Sean f(x,y) una funcion y C una clase con un metodo m(x) del modulo stuff import stuff print stuff.f(1,2) print stuff.C(1).m(2) 3.17. MODULES Y SHELVE. una segunda forma 81 # Sean f(x,y) una funcion y C una clase con un metodo m(x) del modulo stuff from stuff import f, C print f(1,2) print C(1).m(2) una tercera forma # Sean f(x,y) una funcion y C una clase con un metodo m(x) del modulo stuff from stuff import * print f(1,2) print C(1).m(2) una ultima manera # Sean f(x,y) una funcion y C una clase con un metodo m(x) del modulo stuff import stuff as st print st.f(1,2) print st.C(1).m(2) 3.17.6. Trucos con mdulos. o Un mdulo puede ser corrido como programa independiente si inclu o imos las siguientes l ineas en el final if __name__ == '__main__': funcion_a_correr() Sustituya funcion_a_correr() por el nombre de la funcin principal en el mdulo. o o 3.17.7. Preservando la estructura de la informacin. o Existen dos mtodos de preservar la data: e El mdulo pickle almacena una estructura de datos de Python en un archivo binario. o Est limitado a slo una estructura de datos por archivo. a o El mdulo shelve almacena estructuras de datos de Python pero permite ms de una o a estructura de datos y puede ser indexado por una llave. 3.17.8. Cmo almacenar? o Importe el mdulo shelve, abra un archivo shelve, asigne un item, por llave, al archivo o shelve. Para traer la data de vuelta al programa, abra el archivo shelve y accese el item por llave. Los shelve trabajan como un diccionario, podemos agregar, accesar y borrar items usando sus llaves. 82 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. 3.17.9. Ejemplo de shelve. import shelve colores = ["verde", "rojo", "azul"] equipos = ["audax", "union", "lachile"] shelf = shelve.open('mi_archivo') # Almacenendo items shelf['colores'] = colores shelf['equipos'] = equipos # trayendolos de vuelta newlist = shelf['colores'] # Cerrando shelf.close() 3.17.10. Otras funciones de shelve. Para tomar una lista de todas las llaves disponibles en un archivo shelve, use la funcin o keys(): lista = shelf.keys() Para borrar un item, use la funcin del: o del shelf('ST') Para ver si una llave existe, use la funcin has_key(): o if shelf.has_key('ST'): print "si" 3.18. Clases y mtodos. e Las clases son colecciones de data y funciones que pueden ser usadas una y otra vez. Para crear una clase parta con la palabra reservada class, luego necesita un nombre para la clase. Los nombres de las clases, por convencin, tiene la primera letra en mayscula. Despus del o u e nombre termine la l inea con un : y entonces cree el cuerpo de la clase, las instrucciones que forman el cuerpo deben ir con sangr En el cuerpo cree las definiciones de las funciones, ia. cada funcin debe tomar self como parmetro. o a class MiClase: def hola(self): print "Bienvenido. " def math(self,v1,v2): print v1+v2 Declarando y luego usando la clase class MiClase: def hola(self): print "Bienvenido. " def math(self,v1,v2): 3.18. CLASES Y METODOS. print v1+v2 fred = MiClase() fred.hola() fred.math(2,4) 83 Creamos una instancia de una clase al asignarla a una variable, fred = MiClase(). Para aplicar una funcin o mtodo a una nueva instancia debemos especificar en forma completa o e la instancia y el mtodo fred.hola(). Si el mtodo toma argumentos debemos estar seguro e e de incluir todos los valores necesitados, por ejemplo fred.math(2,4). 3.18.1. Clase de muestra LibretaNotas. class LibretaNotas: def __init__(self, name, value): self.nombre = name self.puntaje = value self.evaluaciones = 1 def sumanota(self, puntos): self.evaluaciones += 1 self.puntaje += puntos self.promedio = self.puntaje/float(self.evaluaciones) def promedio(self) print self.nombre, ": promedio =", self.promedio Las variables dentro de una clase deben ser accesadas poniendo el prefijo a su nombre la palabra self. La funcin __init__ es la que correr si una nueva instancia de la clase es creada. Esta o a funcin es especial y se conoce como el constructor de la clase. o Usando la clase LibretaNotas eli = LibretaNota('Elizabeth', 6.5) mario = LibretaNota('Mario', 6.0) carmen = LibretaNota('Carmen', 6.1) eli.sumanota(6.2) mario.sumanota(6.1) carmen.sumanota(6.3) eli.sumanota(6.8) mario.sumanota(6.7) carmen.sumanota(6.6) eli.promedio() mario.promedio() carmen.promedio() 84 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. Cada nueva instancia de la clase LibretaNotas debe tener un nombre y una primera nota porque as lo requiere la funcin constructor __init__. Notemos que cada instancia tiene su i o propio promedio. 3.18.2. Valores por defecto. Una funcin puede tener valores por defecto, estos valores son usados slo cuando la o o funcin es llamada sin especificar un valor. Ejemplo o def potencia(voltaje, corriente=0): return voltaje*corriente # Podemos llamarla potencia(220) potencia(voltaje=110, corriente=5) Veamos un ejemplo de valores por defecto en una clase class Dinero: def __init__(self, amount = 0) : self.amount=amount def print(self): print "Tienes", self.amount, "de dinero" # Llamadas posibles mi_dinero = Dinero(100) tu_dinero = Dinero() mi_dinero.print() tu_dinero.print() 3.19. Sobrecarga de Operadores. Las clases pueden redefinir comandos regulares de Python. Cambiar como los comandos regulares trabajan en una clase se llama sobrecarga de operadores. Para definir la sobrecarga, debemos usar nombres especiales cuando definimos los mtodos. Las definiciones sobrecargae das deben retornar un valor. Veamos un ejemplo de sobrecarga class Loca: def __init__(self, num1=2): self.num1=num1 def __del__(self): print "%d Destruido!" % self.num1 def __repr__(self): return "Su numero es %d" % self.num1 def __add__(self, newnum): return newnum*self.num1 3.19. SOBRECARGA DE OPERADORES. 85 Notemos que tenemos un mtodo nuevo el destructor que el la funcin que se invoca cuane o do una variable se destruye. A continuacin, una lista de nombre especiales para sobrecargar o los operadores __add__ La suma +. __sub__ La resta -. __mul__ La multiplicacin . o __div__ La divisin /. o __pow__ La exponenciacin . o __repr__ El comando print. __len__ El comando len(x). __call__ El comando de llamada x(). __init__ El mtodo constructor. e __del__ El mtodo destructor. e 3.19.1. Funcin driver. o Una funcin driver es puesta al final de la clase para probarla. La funcin toma la forma o o if __name__ == '__main__': funcion_a_correr() Cuando una clase o mdulo es llamado como programa principal, correr este cdigo. o a o 3.19.2. Atributos de las clases. La informacin que necesita acceder una clase en cada una de sus instancias u objetos o puede ser almacenada en atributos de la clase. Los valores sern creados fuera de las defia niciones de las funciones de la clase. La data ser accesada dentro de las definicin de las a o funciones o mtodos de la clase usando la notacin NombredelaClase.NombredelaVariable. e o Un ejemplo class Cuentas: alumnos= def __init__(self,nombre): self.nombre=nombre Cuentas.alumnos.append(self.nombre) def __del__(self) Cuentas.alumnos.remove(self.nombre) Notese que la lista de alumnos es siempre llamada por su nombre completo Cuentas.alumnos. Para acceder a la lista fuera de la clase, use su nombre completo Cuentas.alumnos. 86 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. 3.19.3. Ejemplo de clase vectores. Escribamso un mdulo vec2d.py con una clase de vectores bidimensionales sobrecargando o la suma, la resta, el producto, la impresin, entre otros mtodos o e from math import sqrt class Vec2d: def __init__(self, x=0, y=0): self.x = x self.y = y def module(self): return sqrt(self.x**2+self.y**2) def __repr__(self): return "(%11.5f,%11.5f)" % (self.x,self.y) def __add__(self,newvec): return Vec2d(self.x+newvec.x,self.y+newvec.y) def __sub__(self,newvec): return Vec2d(self.x-newvec.x,self.y-newvec.y) def __mul__(self,newvec): return self.x*newvec.x+self.y*newvec.y Ahora un programa que ocupa el mdulo o #!/usr/bin/env python from vec2d import * a=Vec2d(1.3278,2.67) b=Vec2d(3.1,4.2) print print print print print a, b a+b a-b a*b a.module(),b.module() 3.20. Algunos mdulos interesantes. o Hay muchos mdulos que le pueden ser utiles, aqu le sugerimos unos pocos particularo i mente importantes. 3.20.1. El mdulo Numeric. o Extensin numrica de Python que agrega poderosos arreglos multidimensionales. o e 3.20. ALGUNOS MODULOS INTERESANTES. >>> import Numeric as num >>> a = num.zeros((3,2), num.Float) >>> a array([[ 0., 0.], [ 0., 0.], [ 0., 0.]]) >>> a[1]=1 >>> a array([[ 0., 0.], [ 1., 1.], [ 0., 0.]]) >>> a[0][1]=3 >>> a array([[ 0., 3.], [ 1., 1.], [ 0., 0.]]) >>> a.shape (3, 2) 87 3.20.2. El mdulo Tkinter. o Un mdulo para escribir aplicaciones grficas portables con Phyton y Tk. o a #!/usr/bin/env python from Tkinter import * root = Tk() root.title("Mi ventana") btn = Button(root, text="Salir") btn.grid() def stop(event): root.destroy() btn.bind('<Button-1>', stop) root.mainloop() 3.20.3. El mdulo Visual. o Un mdulo que permite crear y manipular objetos 3D en un espacio 3D. o 88 CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. Cap itulo 4 Una breve introduccin a C++. o versin 7.50, 23 de Octubre del 2007 o En este cap itulo se intentar dar los elementos bsicos del lenguaje de programacin a a o C++. No se pretende ms que satisfacer las m a inimas necesidades del curso, sirviendo como un ayuda de memoria de los tpicos abordados, para futura referencia. Se debe consignar que o no se consideran todas las posibilidades del lenguaje y las explicaciones estn reducidas al a m inimo. 4.1. 4.1.1. Estructura bsica de un programa en C++. a El programa ms simple. a El primer ejemplo de todo manual es el que permite escribir "Hola" en la pantalla. // // Los comentarios comienzan con // // #include <iostream> using namespace std; int main() { cout << "Hola." << endl; return 0 ; } Las tres primeras l ineas corresponden a comentarios, todo lo que est a la derecha de a los caracteres // son comentarios y no sern considerados en la compilacin. En la l a o inea siguiente se incluye un archivo de cabecera, o header, con la instruccin de preprocesador o #include. El nombre del archivo se puede escribir como <nombre> o bien "nombre.h". En el primer caso el archivo nombre ser buscado en el path por defecto para los include, a t ipicamente /usr/include o /usr/include/c++/3.x/ en el caso de headers propios de C++; en el segundo caso la bsqueda se hace en el directorio local. Tambin podr u e iamos incluir un path completo cuando se ocupan las comillas. En nuestro ejemplo se incluye el archivo iostream, en el cual se hacen las definiciones adecuadas para el manejo de la entrada y salida en C++. Este archivo es necesario para enviar luego un mensaje a pantalla. 89 90 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. La funcin int main es donde comienza a ejecutarse el programa; siempre debe haber una o funcin main en nuestro programa. Debido a imposiciones del sistema operativo la funcin o o main devuelve un entero y por tanto debe ser declarada int. Los parntesis vac () indican e ios que el main no tiene argumentos de entrada (ms adelante se ver que puede tenerlos). Lo a a que est encerrado entre llaves {} corresponde al cuerpo de la funcin main. Cada una de a o las l ineas termina con el carcter ;. El identificador predefinido cout representa la salida a a pantalla. El operador << permite que lo que est a su derecha se le d salida por el dispositivo a e que est a su izquierda, en este caso cout. Si se quiere enviar ms de un objeto al dispositivo a a que est al inicio de la l a inea agregamos otro operador <<, y en este caso lo que est a la a derecha del operador se agregar a lo que est a la izquierda y todo junto ser enviado al a a a dispositivo. En nuestro caso se ha enviado endl, un objeto predefinido en el archivo iostream que corresponde a un cambio de l inea, el cual ser agregado al final del mensaje. La l a inea final contiene la instruccin de retorno del entero cero, return 0. o Si escribimos nuestro primer programa en el editor xemacs con el nombre de primero.cc las instrucciones para editarlo, compilarlo y correrlo sern: a [email protected]:~/tmp$ xemacs primero.cc [email protected]:~/tmp$ g++ -Wall -o primero primero.cc [email protected]:~/tmp$ ./primero Hola. [email protected]:~/tmp$ Luego de la compilacin, un archivo ejecutable llamado primero es creado en el directoo rio actual. Si el directorio actual no est en el PATH, nuestro programa debe ser ejecutado a anteponiendo ./. Si est en el PATH, para ejecutarlo basta escribir primero. (Para agrea gar el directorio local al PATH basta editar el archivo ~/.bashrc agregarle una l inea como PATH="${PATH}:." y ejecutar en la l inea de comando source ~/.bashrc para que los cambios tengan efecto.) 4.1.2. Definicin de funciones. o Las funciones en C++ son muy importantes, pues permiten aislar parte del cdigo en o una entidad separada. Esto es un primer paso a la modularizacin de nuestro programa, o es decir, a la posibilidad de escribirlo en partes que puedan ser editadas de modo lo ms a independiente posible. Ello facilita enormemente la creacin de cdigo complicado, pues simo o plifica su modificacin y la localizacin de errores. Nos encontraremos frecuentemente con o o este concepto. Aprovecharemos de introducir las funciones modificando el primer programa de manera que se delegue la impresin del mensaje anterior a una funcin independiente: o o // // Segunda version incluye funcion adicional // #include <iostream> using namespace std; 4.1. ESTRUCTURA BASICA DE UN PROGRAMA EN C++. void PrintHola() { cout << "Hola." << endl; } int main() { PrintHola(); return 0; } 91 La funcin debe estar definida antes de que sea ocupada, por eso va primero en el cdigo o o fuente. Como ya se dijo antes, la ejecucin del programa comienza en la funcin main a o o pesar de que no est primera en el cdigo fuente. Los parntesis vac indican que la funcin a o e ios o PrintHola no tiene argumentos y la palabra delante del nombre de la funcin indica el tipo o de dato que devuelve. En nuestro caso la palabra void indica que no devuelve nada a la funcin main. o Una alternativa al cdigo anterior es la siguiente: o #include <iostream> using namespace std; void PrintHola(); int main() { PrintHola(); return 0 ; } void PrintHola() { cout << "Hola." << endl; } En esta versin se ha separado la declaracin de la funcin de su implementacin. En o o o o la declaracin se establece el nombre de la funcin, los argumentos que recibe, y el tipo de o o variable que entrega como resultado. En la implementacin se da expl o icitamente el cdigo o que corresponde a la funcin. Hab o iamos dicho que una funcin debe estar definida antes que o sea ocupada. En verdad, basta con que la funcin est declarada. La implementacin puede o e o ir despus (como en el ejemplo anterior), o incluso en un archivo distinto, como veremos ms e a adelante. La separacin de declaracin e implementacin es otro paso hacia la modularizacin o o o o de nuestro programa. 92 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. 4.1.3. Nombres de variables. Nuestros datos en los programas sern almacenados en objetos llamados variables. Para a referirnos a ellas usamos un nombre que debe estar de acuerdo a las siguientes reglas: Deben comenzar con una letra (maysculas y minsculas son distintas). u u Pueden contener nmeros, pero no comenzar por uno. u Pueden contener el s imbolo _ (underscore). Longitud arbitraria. No pueden corresponder a una de las palabras reservadas de C++1 : asm auto break case catch char class const continue default delete do double else enum extern float for friend goto if inline int long new operator private protected public register return short signed sizeof static struct switch template this throw try typedef union unsigned virtual void volatile while 4.1.4. Tipos de variables. Todas las variables a usar deben ser declaradas de acuerdo a su tipo. Por ejemplo, si usamos una variable i que sea un nmero entero, debemos, antes de usarla, declararla, y slo u o entonces podemos asignarle un valor: int i; i=10; Esta necesidad de declarar cada variable a usar se relaciona con la caracter istica de C++ de 2 ser fuertemente "tipeado" . Algunos de los errores ms habituales en programacin se deben a o al intento de asignar a variables valores que no corresponden a sus tipos originales. Si bien esto puede no ser muy grave en ciertos contextos, a medida que los programas se vuelven ms complejos puede convertirse en un verdadero problema. El compilador de C++ es capaz a de detectar los usos indebidos de las variables pues conoce sus tipos, y de este modo nuestro cdigo se vuelve ms seguro. o a Es posible reunir las acciones de declaracin e inicializacin en una misma l o o inea: int i=10; A esta tabla hay que agregar algunas palabras adicionales, presentes en versiones ms recientes de C++, a como namespace y using 2 Una traduccin libre del trmino ingls strongly typed. o e e 1 4.1. ESTRUCTURA BASICA DE UN PROGRAMA EN C++. 93 o declarar ms de una variable del mismo tipo simultneamente, e inicializar algunas en la a a misma l inea: int r1, r2, r3 = 10; A veces se requiere que una variable no var una vez que se le asigna un valor. Por ejemplo, ie podr iamos necesitar definir el valor de = 3.14159..., y naturalmente no nos gustar que, ia por un descuido, a esa variable se le asignara otro valor en alguna parte del programa. Para asegurarnos de que ello no ocurra, basta agregar el modificador const a la variable: const float pi = 3.14159; Para nmeros reales se puede usar la notacin exponencial. Por ejemplo, 1.5e-3 repreu o senta el nmero 1.5 10-3 . u Una variable puede ser declarada slo una vez, pero naturalmente se le pueden asignar o valores en un nmero arbitrario de ocasiones. u Los 15 tipos de datos aritmticos fundamentales disponibles son3 : e Booleanos y caracteres bool char signed char unsigned char Booleanas true o false. Caracteres de 0 a 255 o -128 a 127, usa 8 bits, Caracteres -128 a 127, Caracteres de 0 a 255. Enteros short Enteros entre -215 = -32768 y 215 - 1 = 32767 unsigned short Enteros entre 0 y 65535 int Enteros entre -231 = -2147483648 y 231 - 1 = 2147483647 unsigned int Enteros entre 0 y 232 = 4294967295 long (32 bits) Entero entre -2147483648 y 2147483647, long (64 bits) Entero entre -9223372036854775808 y 9223372036854775807, unsigned long (32 bits) Enteros entre 0 y 4294967295, unsigned long (64 bits) Enteros entre 0 y 18446744073709551615, long long Enteros entre -9223372036854775808 y 9223372036854775807 unsigned long long Enteros entre 0 y 18446744073709551615 Float float Reales x tal que 1.17549435 10-38 |x| 3.40282347 1038 , (Precisin de 7 d o igitos decimales.) double Reales x tal que 2.2250738585072014 10-308 |x| 1.7976931348623157 10308 , (Precisin de 15 d o igitos decimales.) long double Reales x tal que 3.36210314311209350626 10-4932 |x| 1.18973149535723176502 104932 , (Precisin de 18 d o igitos decimales.) Los valores de los rangos indicados son simplemente representativos y dependen de la mquina utilizada a (32 bits o 64 bits). Adems, estos valores no corresponden exactamente a las versiones ms recientes de C++. a a 3 94 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. Las variables tipo char alojan caracteres, debiendo inicializarse en la forma: char c = 'a'; Adems de las letras maysculas y minsculas, y s a u u imbolos como &, (, :, etc., hay una serie de caracteres especiales (escape codes) que es posible asignar a una variable char. Ellos son: newline horizontal tab vertical tab backspace carriage return form feed alert (bell) backslash single quote double quote \n \t \v \b \r \f \a \\ \' \" Por ejemplo, la l inea: cout << "Primera columna\t Segunda columna\n Segunda linea" << endl; corresponde al output Primera columna Segunda linea Segunda columna 4.1.5. Ingreso de datos desde el teclado. El header iostream define un objeto especial llamado cin que est asociado al teclado o a stdin. Con el operador >> asignamos la entrada en el dispositivo de la izquierda a la variable de la derecha; una segunda entrada requiere de otro operador >> y de otra variable. En el siguiente ejemplo veremos una declaracin simultnea de dos variables del mismo tipo i y o a j, un mensaje a pantalla con las instrucciones a seguir, el ingreso de dos variables desde el teclado y luego su escritura en la pantalla. #include <iostream> using namespace std; int main() { int i, j ; cout << "Ingrese dos numeros enteros: " ; cin >> i >> j ; cout << "Los dos numeros ingresados fueron: " << i <<" "<< j << endl ; return 0; } 4.1. ESTRUCTURA BASICA DE UN PROGRAMA EN C++. 95 4.1.6. Operadores aritmticos. e Existen operadores binarios (i.e., que actan sobre dos variables, una a cada lado del u operador) para la suma, la resta, la multiplicacin y la divisin: o o + * / 4.1.7. Operadores relacionales. Los s imbolos para los operadores relacionales de igualdad, desigualdad, menor, menor o igual, mayor y mayor o igual son: == != < <= > >= Para las relaciones lgicas AND, OR y NOT: o && || ! 4.1.8. Asignaciones. a) Asignacin simple. Podemos asignar a una variable un valor expl o icito, o el valor de otra variable: i = 1; j = k; Una prctica habitual en programacin es iterar porciones del cdigo. La iteracin a o o o puede estar determinada por una variable cuyo valor aumenta (disminuye) cada vez, hasta alcanzar cierto valor mximo (m a inimo), momento en el cual la iteracin se detiene. o Para que una variable x aumente su valor en 2, por ejemplo, basta escribir: x = x + 2; Si x fuera una variable matemtica normal, esta expresin no tendr sentido. Esta a o ia expresin es posible porque el compilador interpreta a x de modo distinto a cada lado o del signo igual: a la derecha del signo igual se usa el valor contenido en la variable x (por ejemplo, 10); a la izquierda del signo igual se usa la direccin de memoria en la o cual est alojada la variable x. De este modo, la asignacin anterior tiene el efecto de a o colocar en la direccin de memoria que contiene a x, el valor que tiene x ms 2. En o a general, todas las variables tienen un rvalue y un lvalue: el primero es el valor usado a la derecha (right) del signo igual en una asignacin, y el segundo es el valor usado a la o izquierda (left), es decir, su direccin de memoria. o b) Asignacin compuesta. o La expresin o x = x + 2 se puede reemplazar por += -= *= /= x += 2. Existen los operadores 96 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. c) Operadores de incremento y decremento. La expresin o x = x + 1 se puede reescribir x += 1 o bien x++. Anlogamente, existe el operador --. Ambos operadores unarios, ++ y -- pueden ocua parse como prefijos o sufijos sobre una variable y su accin difiere en ambos casos. o Como prefijo la operacin de incremento o decremento se aplica antes de que el valor o de la variable sea usado en la evaluacin de la expresin. Como sufijo el valor de la vao o riable es usado en la evaluacin de la expresin antes que la operacin de incremento o o o o decremento. Por ejemplo, supongamos que inicialmente x = 3. Entonces la instruccin o y=x++ hace que y = 3, x = 4; por su parte, y=++x hace que y = 4, x = 4. Con estas consideraciones, deber iamos poder convencernos de que la salida del siguiente programa es 3 2 2-1 1 1 : // Ejemplo de operadores unarios ++ y --. #include <iostream> using namespace std; int main() { int y ; int x = (y = 1) ; int w = ++x + y++; cout << w <<" " << x << " " << y << "-" ; w = x-- - --y; cout << w << " " << x << " " << y << endl ; return 0; } Los operadores para asignacin compuesta, y los de incremento y decremento, no son slo o o abreviaciones. En realidad hay que preferirlas porque implican optimizaciones en el ejecutable resultante. 4.1.9. Conversin de tipos. o Una consecuencia de que C++ sea fuertemente "tipeado" es que no se pueden hacer operaciones binarias con objetos de tipos distintos. En la siguiente expresin, o int i = 3; float x = 43.8; cout << "Suma = " << x + i << endl; el computador debe sumar dos variables de tipos distintos, y en principio la operacin es o imposible. La estrategia para resolver este problema es convertir ambas variables a un tipo comn antes de efectuar la suma (en ingls, decimos que hacemos un cast de un tipo a otro). u e Existen dos modos de proceder: 4.1. ESTRUCTURA BASICA DE UN PROGRAMA EN C++. a) Conversin expl o icita. 97 Si i es un int, por ejemplo, entonces float(i) la convierte en float. As el programa i, anterior se puede reescribir: int i = 3; float x = 43.8; cout << "Suma = " << x + float(i) << endl; Ahora la suma es claramente entre dos variables float, y se puede realizar. Sin embargo, esto es bastante tedioso, por cuanto el programador debe realizar el trabajo de conversin personalmente cada vez que en su cdigo se desee sumar un real con un o o nmero entero. u b) Conversin impl o icita. En este caso, el compilador realiza las conversiones de modo automtico, prefiriendo a siempre la conversin desde un tipo de variable de menor precisin a uno de mayor o o precisin (de int a double, de short a int, etc.). As a pesar de lo que dijimos, el o i, cdigo anterior habr funcionado en su forma original. Evidentemente esto es muy o ia cmodo, porque no necesitamos hacer una conversin expl o o icita cada vez que sumamos un entero con un real. Sin embargo, debemos estar conscientes de que esta comodidad slo es posible porque ocurren varias cosas: primero, el compilador detecta el intento de o operar sobre dos variables que no son del mismo tipo; segundo, el compilador detecta, en sus reglas internas, la posibilidad de cambiar uno de los tipos (int en este caso) al otro (float); tercero, el compilador realiza la conversin, y finalmente la operacin se o o puede llevar a cabo. Entender este proceso nos permitir aprovechar las posibilidades a de la conversin impl o icita de tipos cuando nuestro cdigo involucre tipos de variables o ms complicados, y entender varios mensajes de error del compilador. a Es interesante notar cmo las conversiones impl o icitas de tipos pueden tener consecuencias insospechadas. Consideremos las tres expresiones: i) x = (1/2) * (x + a/x) ; ii) x = (0.5) * (x + a/x) ; iii) x = (x + a/x)/2 ; Si inicialmente x=0.5 y a=0.5, por ejemplo, i) entrega el valor x=0, mientras ii) y iii) entregan el valor x=1.5. Lo que ocurre es que 1 y 2 son enteros, de modo que 1/2 = 0. De acuerdo a lo que dijimos, uno esperar que en i), como conviven nmeros reales ia u con enteros, los nmeros enteros fueran convertidos a reales y, por tanto, la expresin u o tuviera el resultado esperado, 1.5. El problema es la prioridad de las operaciones. No todas las operaciones tienen igual prioridad (las multiplicaciones y divisiones se realizan antes que las sumas y restas, por ejemplo), y esto permite al compilador decidir cul a operacin efectuar primero. Cuando se encuentra con operaciones de igual prioridad o (dos multiplicaciones, por ejemplo), se procede a efectuarlas de izquierda a derecha. Pues bien, en i), la primera operacin es 1/2, una divisin entre enteros, i.e. cero. En o o ii) no hay problema, porque todas son operaciones entre reales. Y en iii) la primera 98 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. operacin es el parntesis, que es una operacin entre reales. Al dividir por 2 ste es o e o e convertido a real antes de calcular el resultado. i) an podr utilizarse, cambiando el prefactor del parntesis a 1.0/2.0, una prctica u ia e a que ser conveniente adoptar como standard cuando queremos utilizar enteros denia tro de expresiones reales, para evitar errores que pueden llegar a ser muy dif iciles de detectar. 4.2. 4.2.1. Control de flujo. if, if... else, if... else if. Las construcciones siguientes permiten controlar el flujo del programa en base a si una expresin lgica es verdadera o falsa. o o a) En el caso de la sentencia if se evaluar la expresin (a==b), si ella es cierta ejecutar la a o a o las l ineas entre los parntesis de llave y si la expresin es falsa el programa se salta e o esa parte del cdigo. o if (a==b) { cout << "a es igual a b" << endl; } En este y en muchos de los ejemplos que siguen, los parntesis cursivos son opcionales. e Ellos indican simplemente un grupo de instrucciones que debe ser tratado como una sola instruccin. En el ejemplo anterior, los parntesis cursivos despus del if (o despus de o e e e un while, for, etc. ms adelante) indican el conjunto de instrucciones que deben o no a ejecutarse dependiendo de si cierta proposicin es verdadera o falsa. Si ese conjunto de o instrucciones es una sola, se pueden omitir los parntesis: e if (a==b) cout << "a es igual a b" << endl; b) En el caso if... else hay dos acciones mutuamente excluyentes. La sentencia if (c!=b) evaluar la expresin (c!=b). Si ella es cierta ejecutar la o las l a o a ineas entre los parntesis de llave que le siguen, saltndose la o las l e a ineas entre los parntesis de e llave que siguen a la palabra clave else. Si la expresin es falsa el programa se salta la o primera parte del cdigo y slo ejecuta la o las l o o ineas entre los parntesis de llave que e siguen a else. if (c!=d) { cout << "c es distinto de d" << endl; } else { cout << "c es igual a d" << endl; } 4.2. CONTROL DE FLUJO. 99 c) En el ultimo caso se evaluar la expresin que acompa~a al if y si ella es cierta se a o n ejecutar la o las l a ineas entre los parntesis de llave que le siguen, saltndose todo el e a resto de las l ineas entre los parntesis de llave que siguen a las palabras claves else if e y else. Si la primera expresin es falsa el programa se salta la primera parte del cdigo o o y evala la expresin que acompa~a al primer else if y si ella es cierta ejecutar la u o n a o las l ineas entre los parntesis de llave que le siguen, saltndose todo el resto de las e a l ineas entre los parntesis que siguen a otros eventuales else if o al else. Si ninguna e de las expresiones lgicas resulta cierta se ejecutar la o las l o a ineas entre los parntesis e que siguen al else. if (e > f) { cout << "e es mayor que f" << endl; } else if (e == f) { cout << "e es igual a f" << endl; } else { cout << "e es menor que f" << endl; } Para C++, una expresin verdadera es igual a 1, y una falsa es igual a 0. Esto es, cuando o escribimos if(e>f), y e>f es falsa, en realidad estamos diciendo if(0). A la inversa, 0 es considerada una expresin falsa, y cualquier valor no nulo es considerado una expresin o o verdadera. As podr i, iamos hacer que una porcin del cdigo siempre se ejecute (o nunca) o o poniendo directamente if(1) o if(0), respectivamente. Naturalmente, lo anterior no tiene mucho sentido, pero un error habitual (y particularmente dif de detectar) es escribir a = b en vez de a == b en una expresin lgica. Esto icil o o normalmente trae consecuencias indeseadas, pues la asignacin a = b es una funcin que se o o evala siempre al nuevo valor de a. En efecto, una expresin como a=3 siempre equivale a u o verdadero, y a=0 siempre equivale a falso. Por ejemplo, en el siguiente programa: #include <iostream> using namespace std; int main(){ int k=3; if (k==3){ cout << "k es igual a 3" << endl; } k=4; if (k=3){ cout << "k es igual a 3" << endl; } return 0; } 100 la salida siempre es: k es igual a 3 k es igual a 3 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. aunque entre los dos if el valor de k cambia. 4.2.2. Expresin condicional. o Una construccin if else simple, que slo asigna un valor distinto a una misma variable o o segn si una proposicin es verdadera o falsa, es muy comn en programacin. Por ejemplo: u o u o if (a==b) { c = 1; } else { c = 0; } Existen dos maneras de compactar este cdigo. Este se puede reemplazar por o if (a==b) c = 1; else c = 0; Sin embargo, esto no es recomendable por razones de claridad al leer el cdigo. Una expresin o o ms compacta y clara, se consigue usando el operador ternario ? : a c = (a==b) ? 1 : 0; Como en el caso de los operadores de incremento y decremento, el uso del operador ? es preferible para optimizar el ejecutable resultante. 4.2.3. switch. La instruccin switch permite elegir mltiples opciones a partir del valor de una variable o u entera. En el ejemplo siguiente tenemos que si i==1 la ejecucin continuar a partir del caso o a case 1:, si i==2 la ejecucin continuar a partir del caso case 2: y as sucesivamente. Si o a i i toma un valor que no est enumerado en ningn case y existe la etiqueta default, la a u ejecucin continuar a partir de ah Si no existe default, la ejecucin contina luego del o a i. o u ultimo parntesis cursivo. e switch (i) { case 1: { cout << "Caso 1." << endl; } break; case 2: 4.2. CONTROL DE FLUJO. { cout << "Caso 2." << endl; } break; default: { cout << "Otro caso." << endl; } break; } 101 La instruccin break permite que la ejecucin del programa salte a la l o o inea siguiente despus e de la serie de instrucciones asociadas a switch. De esta manera slo se ejecutarn las l o a ineas correspondientes al case elegido y no el resto. Por ejemplo, si i==1 ver iamos en pantalla slo la l o inea Caso 1. En el otro caso, si no existieran los break, y tambin i==1, entonces e ver iamos en pantalla las l ineas Caso 1., Caso 2. y Otro caso. La instruccin default es o opcional. 4.2.4. for. Una instruccin que permite repetir un bloque de instrucciones un nmero definido de o u veces es el for. Su sintaxis comienza con una o varias inicializaciones, luego una condicin o lgica de continuacin mientras sea verdadera, y finalmente una o ms expresiones que se o o a evalan vuelta por vuelta no incluyendo la primera vez. Siguiendo al for(...) viene una u instruccin o un bloque de ellas encerradas entre parntesis de llave. En el ejemplo siguiente o e la variable entera i es inicializada al valor 1, luego se verifica que la condicin lgica sea o o cierta y se ejecuta el bloque de instrucciones. A la vuelta siguiente se evala la expresin a u o la extrema derecha (suele ser uno o ms incrementadores), se verifica que la condicin lgica a o o se mantenga cierta y se ejecuta nuevamente el bloque de instrucciones. Cuando la condicin o lgica es falsa se termina el loop, saltando la ejecucin a la l o o inea siguiente al parntesis que e indica el fin del bloque de instrucciones del for. En este ejemplo, cuando i=4 la condicin o de continuacin ser falsa y terminar la ejecucin del for. o a a o for (int i = 1; i < 4; i++) { cout << "Valor del indice: " << i << endl; } El output correspondiente es: Valor del indice: 1 Valor del indice: 2 Valor del indice: 3 Cualquier variable declarada en el primer argumento del for es local al loop. En este caso, la variable i es local, y no interfiere con otras posibles variables i que existan en nuestro cdigo. o 102 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. for es una instruccin particularmente flexible. En el primer y tercer argumento del for o se puede colocar ms de una instruccin, separadas por comas. Esto permite, por ejemplo, a o involucrar ms de una variable en el ciclo. El cdigo: a o for (int i=0, k=20; (i<10) && (k<50); i++, k+=6) { cout << "i + k = " << i + k << endl; } resulta en el output: i i i i i + + + + + k k k k k = = = = = 20 27 34 41 48 Adems, la condicin de continuacin (segundo argumento del for), no tiene por qu dea o o e pender de las variables inicializadas en el primer argumento. Y el tercer argumento no tiene por qu ser un incremento o decremento de las variables del loop; puede ser cualquier expree sin que queramos ejecutar cada vez que un ciclo termina. En el siguiente ejemplo, adems o a de incrementar los contadores en cada ciclo, se env un mensaje a pantalla: ia for (int i=1, k=2;k<5 && i<20;k++, i+=2, cout << "Fin iteracion" << endl){ cout << " i = " << i <<'',''; cout << " k = " << k << endl; } El resultado de las iteraciones: i = 1, k = 2 Fin iteracion i = 3, k = 3 Fin iteracion i = 5, k = 4 Fin iteracion Todos los argumentos del for son opcionales (no los ;), por lo cual se puede tener un for que carezca de inicializacin y/o de condicin de continuacin y/o de una expresin que se o o o o evale en cada iteracin. u o Un caso t ipico en que se aprovecha la opcionalidad de los argumentos del for es para tener un loop infinito, que puede servir para dejar el programa en pausa indefinida. Para salir del loop (y en general, para detener cualquier programa en C++), hay que presionar ^C: for (; ; ) cout << "Este es un loop infinito, ^C para detenerlo"<< endl; Se puede adems, salir abruptamente del loop con break. El cdigo: a o 4.2. CONTROL DE FLUJO. for(int indice=0; indice<10; indice++) { int cuadrado = indice*indice ; cout << indice << " " ; if(cuadrado > 10 ) break ; } cout << endl; da la salida a pantalla: 0 1 2 3 4 103 aun cuando la condicin de continuacin permite que indice llegue hasta 9. o o Finalmente, las variables involucradas en el for pueden ser modificadas dentro del ciclo. Por ejemplo, modifiquemos uno de los ejemplos anteriores, cambiando la variable k en medio del ciclo: for (int i=1, k=2;k<5 && i<8;k++, i+=2, cout << "Fin iteracion" << endl){ cout << " i = " << i << ", k = " << k << endl; k = k+5; } El resultado es: i = 1, k = 2 Fin iteracion En vez de pasar por el ciclo tres veces, como ocurr originalmente, el programa sale del loop, ia al cabo del primer ciclo, k = 2 + 5 = 7 > 5. En general no es una buena prctica modificar las variables internas del ciclo en medio a de l, porque no es muy ordenado, y el desorden normalmente conduce a los errores en e programacin, pero ocasionalmente puede ser util hacer uso de esta libertad que proporciona o el lenguaje. Los ciclos for pueden anidarse, tal que uno contenga a otro completamente. 4.2.5. while. La instruccin while permite repetir un bloque de instrucciones encerradas entre parnteo e sis de llave mientras la condicin lgica que acompa~a al while se mantenga cierta. La cono o n dicin es evaluada antes de que comience la primera iteracin; si es falsa en sta o en una o o e posterior evaluacin no se ejecuta el bloque de instrucciones que le siguen y se contina la o u ejecucin en la l o inea siguiente al parntesis que indica el fin del bloque asociado al while. e Hay que notar que la instruccin while podr no ejecutarse ni una sola vez si la condicin o ia o no se cumple inicialmente. Un ejemplo simple: int i=1; while (i < 3) { cout << i++ << " "; } 104 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. que da por resultado: 1 2. En el siguiente loop, la salida ser: 5 4 3 2 1 (Por qu?) a e int k=5 ; while(k) { cout << k-- <<" "; } 4.2.6. do... while. La instruccin do... while es anloga a while, salvo que la condicin lgica es evaluada o a o o despus de la primera iteracin. Por tanto, el bloque se ejecuta al menos una vez, siempre. e o Un ejemplo simple: do { cout << i++ << endl; } while (i<=20); Podemos construir de otra manera un loop infinito usando do while do { cout << "Este es un segundo loop infinito, ^C para detenerlo"<< endl; } while (1); 4.2.7. goto. Existe tambin en C++ una instruccin goto que permite saltar de un punto a otro del e o programa (goto salto; permite saltar a la l inea que contiene la instruccin salto:). Sin o embargo, se considera una mala tcnica de programacin usar goto, y siempre se puede die o se~ar un programa evitndolo. Es altamente no recomendable, pero si su utilizacin simplifica n a o el cdigo se puede usar. o 4.3. Funciones. Las funciones nos permiten programar partes del procedimiento por separado. Un ejemplo simple de ellas lo vimos en la subseccin 4.1.2. o 4.3.1. Funciones tipo void. Un caso especial de funciones es aquel en que el programa que llama la funcin no espera o que sta le entregue ningn valor al terminar. Por ejemplo, en la subseccin 4.1.2, la funcin e u o o PrintHola simplemente imprime un mensaje en pantalla. El resto del programa no necesita de ningn resultado parcial proveniente de la ejecucin de dicha funcin. La definicin de u o o o estas funciones debe ir precedida de la palabra void, como en el ejemplo citado. 4.3. FUNCIONES. 105 4.3.2. return. Si deseamos definir una funcin que calcule una ra cuadrada, evidentemente esperamos o iz que la funcin nos entregue un resultado: el valor de la ra cuadrada. En este caso hay que o iz traspasar el valor de una variable desde la funcin al programa que la llam. Esto se consigue o o con return. Veamos un ejemplo muy simple: int numero(){ int i = 3; return i; } int main(){ cout << "Llamamos a la funcion" << endl; cout << "El numero es: " << numero() << endl; int i = 5; i = i + numero(); cout << "El numero mas 5 es: " << i << endl; return 0; } En este caso, la funcin simplemente entrega el valor de la variable interna i, es decir 3, el o cual puede ser usado para salida en pantalla o dentro de operaciones matemticas corrientes. a Separando declaracin e implementacin de la funcin, el ejemplo anterior se escribe: o o o int numero(); int main(){ ... } int numero(){ int i = 3; return i; } Dos observaciones utiles: a) La declaracin de la funcin lleva antepuesto el tipo de variable que la funcin entrega. o o o En el ejemplo, la variable entregada es un entero, i, y la declaracin debe ser, por tanto, o int numero(). Podemos tener funciones tipo double, char, long, etc., de acuerdo al tipo de variable que corresponde a return. b) La variable i que se usa dentro de main() y la que se usa dentro de numero() son distintas. A pesar de que tienen el mismo nombre, se pueden usar independientemente como si se llamaran distinto. Se dice que i es una variable local. Despus de return debe haber una expresin que se evale a una variable del tipo correse o u pondiente, ya sea expl icitamente o a travs de un cast impl e icito. Las siguientes funciones devuelven un double al programa: 106 double f1(){ double l = 3.0; return l; } double f2(){ double l = 3.0, m = 8e10; return l*m; } double f3(){ int l = 3; return l; } CAP ITULO 4. UNA BREVE INTRODUCCION A C++. Sin embargo, la siguiente funcin har que el compilador emita una advertencia, pues se o a est tratando de devolver un double donde deber ser un int, y la conversin implica una a ia o prdida de precisin: e o int f4(){ double l=3.0; return l; } Naturalmente, podemos modificar la funcin anterior haciendo una conversin expl o o icita antes de devolver el valor: return int(l). 4.3.3. Funciones con parmetros. a Volviendo al ejemplo de la ra cuadrada, nos gustar llamar a esta funcin con un iz ia o parmetro (el nmero al cual se le va a calcular la ra cuadrada). Consideremos por ejemplo a u iz una funcin que necesita un solo parmetro, de tipo int, y cuyo resultado es otro int: o a int funcion(int i){ i+=4; return i; } int main(){ int i = 3; cout << "El valor de la funcion es " << funcion(i) << endl; cout << "El valor del parametro es " << i << endl; return 0 ; } El resultado en pantalla es: 4.3. FUNCIONES. El valor de la funcion es 7 El valor del parametro es 3 107 La funcin funcion entrega el valor del parmetro ms 4. Usamos el mismo nombre (i) o a a para las variables en main y funcion, pero son variables locales, as que no interfieren. Lo i importante es notar que cuando se llama a la funcin, la reasignacin del valor de i (i+=4) o o ocurre slo para la variable local en funcion; el parmetro externo mantiene su valor. o a Separando declaracin e implementacin el ejemplo anterior se escribe: o o int funcion(int); int main(){...} int funcion(int i){ i+=4; return i; } Si nuestra funcin necesita ms parmetros, basta separarlos con comas, indicando para o a a cada uno su tipo: int funcion2(int,double); void funcion3(double,int,float); double funcion4(float); El compilador verifica cuidadosamente que cada funcin sea llamada con el nmero de o u parmetros adecuados, y que cada parmetro corresponda al tipo especificado. En los ejema a plos anteriores, funcion2 debe ser llamada siempre con dos argumentos, el primero de los cuales es int y el segundo double. Como siempre, puede ser necesario un cast impl icito (si se llama funcion2 con el segundo argumento int, por ejemplo), pero si no existe una regla de conversin automtica (llamando a funcion2 con el primer argumento double, por ejemplo), o a el compilador enviar una advertencia. Adems, el compilador verifica que el valor de retorno a a de la funcin sea usado como corresponde. Por ejemplo, en las dos l o ineas: double m = funcion2(2,1e-3); int k = funcion4(0.4); la primera compilar exitosamente (pero hay un cast impl a icito), y la segunda dar una a advertencia. Existen dos modos de transferir parmetros a una funcin: a o a) Por valor. Se le pasan los parmetros para que la funcin que es llamada copie sus a o valores en sus propias variables locales, las cuales desaparecern cuando la funcin a o termine y no tienen nada que ver con las variables originales. Hasta ahora, en todos los ejemplos de esta subseccin el traspaso de parmetros ha sido o a por valor. En la funcin int funcion(int), en el cdigo de la pgina 106, lo que ha o o a ocurrido es que la funcin copia el valor de la variable externa i en una nueva variable o (que tambin se llama i, pero est en otra direccin de memoria). El valor con el que e a o trabaja la funcin es la copia, manteniendo inalterada la variable original. o 108 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. b) Por referencia. Se le pasa la direccin de memoria de los parmetros. La funcin llamada o a o puede modificar el valor de tales variables. La misma funcin de la pgina 106 puede ser modificada para que el paso de parmetros o a a sea por referencia, modificando la declaracin: o int funcion(int &); int main() { int i = 3; cout << "El valor de la funcion es " << funcion(i) << endl; cout << "El valor del parametro es " << i << endl; return 0; } int funcion(int & i) { i+=4; return i; } En vez de traspasarle a funcion el valor del parmetro, se le entrega la direccin a o de memoria de dicha variable. Debido a ello, funcion puede modificar el valor de la variable. El resultado en pantalla del ultimo programa ser: a El valor de la funcion es 7 El valor del parametro es 7 Debido a que las variables dejan de ser locales, el paso de parmetros por referencia a debe ser usado con sabidur De hecho el ejemplo presentado es poco recomendable. ia. Peor an, el problema es no slo que las variables dejan de ser locales, sino que es u o imposible saber que no lo son desde el main. En efecto, el main en ambas versiones de funcion es el mismo. Lo unico que cambi es la declaracin de la funcin. Puesto que un o o o usuario normal usualmente no conoce la declaracin e implementacin de cada funcin o o o que desea usar (pues pueden haber sido hechas por otros programadores), dejamos al usuario en la indefensin. o Por otro lado, hay al menos dos situaciones en que el paso de referencia es la unica opcin viable para entregar los parmetros. Un caso es cuando hay que cuidar el uso o a de la memoria. Supongamos que una funcin necesita un parmetros que es una matriz o a de 10 millones de filas por 10 millones de columnas. Seguramente estaremos llevando al l imite los recursos de nuestra mquina, y ser una torpeza pasarle la matriz por valor: a ia ello involucrar primero, duplicar la memoria utilizada, con el consiguiente riesgo de ia, que nuestro programa se interrumpa; y segundo, har el programa ms lento, porque ia a la funcin necesitar llenar su versin local de la matriz elemento por elemento. Es o ia o decir, nada de eficiente. En esta situacin, el paso por referencia es lo adecuado. o 4.3. FUNCIONES. 109 Un segundo caso en que el paso por referencia es recomendable es cuando efectivamente nuestra intencin es cambiar el valor de las variables. El ejemplo t o ipico es el intercambio de dos variables entre s digamos a1=1 y a2=3. Luego de ejecutar la funcin queremos i, o que a1=3 y a1=1. El siguiente cdigo muestra la definicin y el uso de una funcin para o o o esta tarea, y por cierto requiere el paso de parmetros por referencia: a #include <iostream> void swap(int &,int &); using namespace std; int main(){ int i = 3, k=10; swap(i,k); cout << "Primer argumento: " << i << endl; cout << "Segundo argumento: " << k << endl; return 0 ; } void swap(int & j,int & p){ int temp = j; j = p; p = temp; } El output es: Primer argumento: 10 Segundo argumento: 3 En el ejemplo de la matriz anterior, ser interesante poder pasar el parmetro por refeia a rencia, para ahorrar memoria y tiempo de ejecucin, pero sin correr el riesgo de que nuestra o matriz gigantesca sea modificada por accidente. Afortunadamente existe el modo de hacerlo, usando una palabra que ya hemos visto antes: const. En el siguiente cdigo: o int f5(const int &); int main(){...} int f5(const int & i){...}; f5 recibir su unico argumento por referencia, pero, debido a la presencia del modificador a const, el compilador avisar si se intenta modificar el argumento en medio del cdigo de la a o funcin. o 4.3.4. Parmetros por defecto. a C++ permite que omitamos algunos parmetros de la funcin llamada, la cual reema o plaza los valores omitidos por otros predeterminados. Tomemos por ejemplo la funcin o 110 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. int funcion(int); de la subseccin 4.3.3, y modifiqumosla de modo que si no le entregao e mos parmetros, asuma que el nmero entregado fue 5: a u int funcion(int i = 5){ i+=4; return i; } int main(){ cout << "El resultado default es " << funcion() << endl; int i = 3; cout << "Cuando el parametro vale " << i << " el resultado es " << funcion(i) << endl; return 0; } El output correspondiente es: El resultado default es 9 Cuando el parametro vale 3 el resultado es 7 Separando declaracin e implementacin: o o int funcion(int = 5); main(){...} int funcion(int i){ i+=4; return i; } Si una funcin tiene n argumentos, puede tener m n argumentos opcionales. La unica o restriccin es que, en la declaracin e implementacin de la funcin, los parmetros opcionales o o o o a ocupen los ultimos m lugares: void f1(int,int = 4); int f2(double,int = 4, double = 8.2); double f3(int = 3,double = 0.0, int = 0); En este caso, f1(2), f1(2,8), f2(2.3,5), f3(3), f3(), y muchas otras, son todas llamadas vlidas de estas funciones. Cada vez, los parmetros no especificados son reemplazados por a a sus valores predeterminados. 4.3.5. Ejemplos de funciones: ra cuadrada y factorial. iz Ra cuadrada. iz Con lo visto hasta ahora, ya podemos escribir un programa que calcule la ra cuadrada iz de una funcin. Para escribir una funcin, debemos tener claro qu se espera de ella: cuntos o o e a 4.3. FUNCIONES. 111 y de qu tipo son los argumentos que recibir, qu tipo de valor de retorno deber tener, e a e a y, por cierto, un nombre adecuado. Para la ra cuadrada, es claro que el argumento es un iz nmero. Pero ese nmero podr ser un entero o un real, y eso al compilador no le da lo u u ia mismo. En este punto nos aprovechamos del cast impl icito: en realidad, basta definir la ra iz cuadrada con argumento double; de este modo, si se llama la funcin con un argumento int, o el compilador convertir automticamente el int en double y nada fallar. En cambio, si la a a a definiramos para int y la llamamos con argumento double, el compilador se quejar de que e ia no sabe efectuar la conversin. Si el argumento es double, evidentemente esperamos que el o valor de retorno de la funcin sea tambin un double. Llamando a la funcin raiz, tenemos o e o la declaracin: o double raiz(double); Debido a la naturaleza de la funcin ra cuadrada, raiz() no tendr sentido, y por tanto o iz ia no corresponde declararla con un valor default. Ahora debemos pensar en cmo calcular la ra cuadrada. Usando una variante del mtodo o iz e de Newton-Raphson, se obtiene que la secuencia xn+1 = 1 2 xn + a xn converge a a cuando n . Por tanto, podemos calcular la ra cuadrada con aproximaiz ciones sucesivas. El clculo terminar en el paso N , cuando la diferencia entre el cuadrado a a de la aproximacin actual, xN , y el valor de a, sea menor que un cierto nmero peque~o: o u n 1. El valor de determinar la precisin de nuestro clculo. Un ejemplo de a o a | x2 - a | < N cdigo lo encontramos a continuacin: o o #include <iostream> #include <cmath> using namespace std; double raiz(double); int main(){ double r; cout.precision(20); cout << "Ingrese un numero: " << endl; cin >> r; cout << raiz(r) << endl; return 0 ; } double raiz(double a){ double x =a/2.0 ; // para comenzar double dx = 1e3, epsilon = 1e-8; 112 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. while (fabs(dx)>epsilon){ x = (x + a/x)/2; dx = x*x - a; cout << "x = " << x << ", precision = " << dx << endl; } return x; } Luego de la declaracin de la funcin raiz, est main, y al final la implementacin de o o a o raiz. En main se pide al usuario que ingrese un nmero, el cual se aloja en la variable r, u y se muestra en pantalla el valor de su ra cuadrada. La instruccin cout.precision(20) iz o permite que la salida a pantalla muestre el resultado con 20 cifras significativas. En la implementacin de la funcin hay varios aspectos que observar. Se ha llamado x a la o o variable que contendr las sucesivas aproximaciones a la ra Al final del ciclo, x contendr el a iz. a valor (aproximado) de la ra cuadrada. dx contiene la diferencia entre el cuadrado de x y el iz valor de a, epsilon es el nmero (peque~o) que determina si la aproximacin es satisfactoria u n o o no. El ciclo est dado por una instruccin while, y se ejecuta mientras dx>epsilon, es decir, a o termina cuando dx es suficientemente peque~o. El valor absoluto del real dx se obtiene con la n funcin matemtica fabs, disponible en el header cmath incluido al comienzo del programa. o a Observar que inicialmente dx=1e3, esto es un valor muy grande; esto permite que la condicin o del while sea siempre verdadera, y el ciclo se ejecuta al menos una vez. Dentro del ciclo, se calcula la nueva aproximacin, y se env a pantalla un mensaje con o ia la aproximacin actual y la precisin alcanzada (dada por dx). Eventualmente, cuando la o o aproximacin es suficientemente buena, se sale del ciclo y la funcin entrega a main el valor o o de x actual, que es la ultima aproximacin calculada. o Factorial. Otro ejemplo util es el clculo del factorial, definido para nmeros naturales: a u n! = n (n - 1) 2 1 , 0! 1 . La estrategia natural es utilizar un ciclo for, determinado por una variable entera i, que va desde 1 a n, guardando los resultados en una variable auxiliar que contiene el producto de todos los nmeros naturales desde 1 hasta i: u #include <iostream> using namespace std; int factorial(int); int main(){ int n=5 ; cout << "El factorial de " << n << " es: " << factorial(n) << endl; 4.3. FUNCIONES. return 0 ; } int factorial(int i) { int f =1; for (int j=1;j<=i;j++){ f = f*j; } return f; } 113 Observar que la variable auxiliar f, que contiene el producto de los primeros i nmeros u naturales, debe ser inicializada a 1. Si se inicializara a 0, factorial(n) ser 0 para todo n. ia Esta funcin no considera el caso n=0, pero al menos para el resto de los naturales funo cionar bien. a 4.3.6. Alcance, visibilidad, tiempo de vida. Con el concepto de funcin hemos apreciado que es posible que coexistan variables con el o mismo nombre en puntos distintos del programa, y que signifiquen cosas distintas. Conviene entonces tener en claro tres conceptos que estn ligados a esta propiedad: a Alcance (scope) La seccin del cdigo durante la cual el nombre de una variable puede ser o o usado. Comprende desde la declaracin de la variable hasta el final del cuerpo de la o funcin donde es declarada. o Si la variable es declarada dentro de una funcin es local . Si es definida fuera de todas o las funciones (incluso fuera de main), la variable es global. Visibilidad Indica cules de las variables, actualmente al alcance, pueden ser accesadas. En a u a nuestros ejemplos (subseccin 4.3.3), la variable i en main an est al alcance dentro o de la funcin funcion, pero no es visible, y por eso es posible reutilizar el nombre. o Tiempo de vida Indica cundo las variables son creadas y cundo destruidas. En general a a este concepto coincide con el alcance (las variables son creadas cuando son declaradas y destruidas cuando la funcin dentro de la cual fueron declaradas termina), salvo porque o es posible definir: (a) variables dinmicas, que no tienen alcance, sino slo tiempo de a o vida; (b) variables estticas, que conservan su valor entre llamadas sucesivas de una a funcin (estas variables tienen tiempo de vida mayor que su alcance). Para declarar o estas ultimas se usa un modificador static. El efecto del modificador static se aprecia en el siguiente ejemplo: #include <iostream> int f(); 114 using namespace std; int main(){ cout << f() << endl; cout << f() << endl; return 0; } int f(){ int x=0; x++; return x; } CAP ITULO 4. UNA BREVE INTRODUCCION A C++. La funcin f simplemente toma el valor inicial de x y le suma 1. Como cada vez que la o funcin es llamada la variable local x es creada e inicializada, el resultado de este programa o es siempre un 1 en pantalla: 1 1 Ahora modifiquemos la funcin, haciendo que x sea una variable esttica: o a #include <iostream> int f(); using namespace std; int main(){ cout << f() << endl; cout << f() << endl; return 0 ; } int f(){ static int x=0; x++; return x; } Ahora, al llamar a f por primera vez, la variable x es creada e inicializada, pero no destruida cuando la funcin termina, de modo que conserva su valor cuando es llamada por o segunda vez: 1 2 4.3. FUNCIONES. Veamos un ejemplo de una variable esttica en el clculo del factorial: a a int factorial2(int i=1){ static int fac = 1; fac*=i; return fac ; } int main (){ int n=5; int m=n; while(n>0) factorial2(n--); cout << "El factorial de "<< m << " es = " << factorial2() << endl; return 0 ; } 115 La idea, si se desea calcular el factorial de 5, por ejemplo, es llamar a la funcin factorial2 o una vez, con argumento n = 5, y despus disminuir n en 1. Dentro de la funcin, una variable e o esttica (fac) aloja el valor 1 5 = 5. Luego se llama nuevamente con n = 4, con lo cual a fac=1*5*4, y as sucesivamente, hasta llegar a n = 1, momento en el cual fac=1*5*4*3*2*1. i Al disminuir n en 1 una vez ms, la condicin del while es falsa y se sale del ciclo. Al llamar a o una vez ms a factorial2, esta vez sin argumentos, el programa asume que el argumento a tiene el valor predeterminado 1, y as el resultado es 1*5*4*3*2*1*1, es decir 5!. i Observemos el uso del operador de decremento en este programa: factorial2(n--) llama a la funcin con argumento n y despus disminuye n en 1. Esto es porque el operador de o e decremento est actuando como sufijo, y es equivalente a las dos instrucciones: a factorial2(n); n--; Si fuera un prefijo [factorial2(n--)], primero disminuir n en 1, y llamar luego a factorial2 ia ia con el nuevo valor de n Este ejemplo de clculo del factorial ilustra el uso de una variable esttica, que aloja los a a productos parciales de los nmeros enteros, pero no es un buen ejemplo de una funcin que u o calcule el factorial, porque de hecho esta funcin no lo calcula: es main quien, a travs de o e sucesivas llamadas a factorial2, calcula el factorial, pero la funcin en s no. o i 4.3.7. Recursin. o C++ soporta un tipo especial de tcnica de programacin, la recursin, que permite que e o o una funcin se llame a s misma (esto es no trivial, por cuanto si definimos, digamos, una o i funcin f, dentro del cuerpo de la implementacin no hay ninguna declaracin a una funcin o o o o f, y por tanto en principio no se podr usar f porque dicho nombre no estar en scope; ia ia C++ permite soslayar este hecho). La recursin permite definir de modo muy compacto una o funcin que calcule el factorial de un nmero entero n. o u 116 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. int factorial3(int n){ return (n<2) ? 1: n * factorial3(n-1); } int main(){ int n=5; cout << "El factorial de "<< n << " es = " << factorial3(n) << endl; return 0; } En este tercer ejemplo, el factorial de n es definido en funcin del factorial de n - 1. o Se ha usado la expresin condicional (operador ?) para compactar an ms el cdigo. Por o u a o ejemplo, al pedir el factorial de 5 la funcin se pregunta si 5 < 2. Esto es falso, luego, la o funcin devuelve a main el valor 5*factorial3(4). A su vez, factorial3(4) se pregunta si o 4 < 2; siendo falso, devuelve a la funcin que la llam (es decir, a factorial3(5)), el valor o o 4*factorial3(3). El proceso sigue hasta que factorial(2) llama a factorial3(1). En ese momento, 1 < 2, y la funcin factorial3(1), en vez de llamar nuevamente al factorial, o devuelve a la funcin que la llam el valor 1. No hay ms llamadas a factorial3, y el o o a proceso de recursin se detiene. El resultado final es que main recibe el valor factorial3(5) o = 5*factorial3(4) = = 5*4*3*2*factorial3(1) = 5*4*3*2*1= 120. Este tercer cdigo para el clculo del factorial s considera el caso n = 0, y adems es ms o a i a a eficiente, al ser ms compacto. a La recursin debe ser empleada con cuidado. Es importante asegurarse de que existe o una condicin para la cual la recursin se detenga, de otro modo, caer o o iamos en una recursin o infinita que har intil nuestro programa. En el caso del factorial, pudimos verificar que dicha ia u condicin existe, por tanto el programa es finito. En situaciones ms complicadas puede no o a ser tan evidente, y es responsabilidad del programador --como siempre-- revisar que todo est bajo control. e 4.3.8. Funciones internas. Existen muchas funciones previamente implementadas en C++ almacenadas en distintas bibliotecas. Una de las bibliotecas importante es la matemtica. Para usarla uno debe incluir a el archivo de header <cmath> y luego al compilar agregar al final del comando de compilacin o -lm: g++ -Wall -o <salida> <fuente>.cc -lm si se desea crear un ejecutable <salida> a partir del cdigo en <fuente>.cc. o Veamos algunas de estas funciones: 4.4. PUNTEROS. pow(x,y) fabs(x) sqrt(x) sin(x) cos(x) tan(x) atan(x) atan2(y, x) exp(x) log(x) log10(x) floor(x) ceil(x) fmod(x,y) Eleva a potencia, xy Valor absoluto Ra cuadrada iz Seno y coseno Tangente Arcotangente de x en [-, ] Arcotangente de y/x en [-, ] Exponencial Logaritmo natural y logaritmo en base 10 Entero ms cercano hacia abajo (e.g. floor(3.2)=3) a Entero ms cercano hacia arriba (e.g. ceil(3.2)=4) a El resto de x/y (e.g. fmod(7.3, 2)=1.3) 117 Para elevar a potencias enteras, es ms conveniente usar la forma expl a icita en vez de la funcin pow, i.e. calcular x^3 como x*x*x es ms eficiente computacionalmente que pow(x,3), o a debido a los algoritmos que usa pow para calcular potencias. Estos son ms convenientes a cuando las potencias no son enteras, en cuyo caso no existe una forma expl icita en trminos e de productos. 4.4. Punteros. Una de las ventajas de C++ es permitir el acceso directo del programador a zonas de memoria, ya sea para crearlas, asignarles un valor o destruirlas. Para ello, adems de los tipos a de variables ya conocidos (int, double, etc.), C++ proporciona un nuevo tipo: el puntero. El puntero no contiene el valor de una variable, sino la direccin de memoria en la cual dicha o variable se encuentra. Un peque~o ejemplo nos permite ver la diferencia entre un puntero y la variable a la cual n ese puntero "apunta": int main(){ int i = 42; int * p = &i; cout << "El valor del puntero es: " << p << endl; cout << "Y apunta a la variable: " << *p << endl; return 0; } En este programa definimos una variable i entera. Al crear esta variable, el programa reserv un espacio adecuado en algn sector de la memoria. Luego pusimos, en esa direccin o u o de memoria, el valor 42. En la siguiente l inea creamos un puntero a i, que en este caso denominamos p. Los punteros no son punteros a cualquier cosa, sino punteros a un tipo particular de variable. Ello es manifiesto en la forma de la declaracin: int * p. En la o misma l inea asignamos a este puntero un valor. Ese valor debe ser tambin una direccin de e o memoria, y para eso usamos &i, que es la direccin de memoria donde est i. Ya hemos visto o a antes el uso de & para entregar una direccin de memoria, al estudiar paso de parmetros a o a funciones por referencia (4.3.3). 118 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. Al ejecutar este programa vemos en pantalla los mensajes: El valor del puntero es: 0xbffff9d8 Y apunta a la variable: 42 Primero obtenemos un nmero hexadecimal imposible de determinar a priori , y que corresu ponde a la direccin de memoria donde qued ubicada la variable i. La segunda l o o inea nos da el valor de la variable que est en esa direccin de memoria: 42. Puesto que * aplicado a o a un puntero entrega el contenido de esa direccin de memoria, se le denomina operador de o desreferenciacin. o En este ejemplo, hemos creado un puntero que contiene la direccin de memoria de una o variable preexistente: declaramos una variable, esa variable queda en alguna direccin de o memoria, y despus asignamos esa direccin de memoria a un puntero. En este caso, podemos e o referirnos a la variable tanto por su nombre (i) como por su puntero asociado (p_i). Tambin es posible crear directamente una direccin de memoria, sin necesidad de crear e o una variable antes. En este caso, la unica forma de manipular este objeto es a travs de su e puntero, porque no existe ninguna variable y por tanto ningn nombre asociado a l. Esto se u e hace con el operador new. El mismo ejemplo anterior puede ser reescrito usando slo punteros: o int main(){ int * p = new int; *p = 42; cout << "El valor del puntero es: " << p << endl; cout << "Y apunta a la variable: " << *p << endl; delete p; return 0; } La primera l inea crea un nuevo puntero a int llamado p. new verifica que haya suficiente memoria para alojar un nuevo int, y si es as reserva ese espacio de memoria. En p queda la i direccin de la memoria reservada. Esto es equivalente a la declaracin int i; del programa o o anterior, salvo que ahora la unica manera de accesar esa direccin de memoria es a travs o e del puntero p. A continuacin se coloca dentro de esa direccin (observar la presencia del o o operador de desreferenciacin *) el nmero 42. El programa manda a pantalla la misma o u informacin que la versin anterior, salvo que seguramente el valor de p ser distinto. o o a Finalmente, ya que el puntero no volver a ser usado, la direccin de memoria debe ser a o liberada para que nuestro u otros programas puedan utilizarla. Ello se realiza con el operador delete. Todo puntero creado con new debe ser, cuando ya no se utilice, borrado con delete. Ello evitar desagradables problemas en nuestro programa debido a fuga de memoria (memory a leak ). Los punteros tienen gran importancia cuando de manejar datos dinmicos se trata, es a decir, objetos que son creados durante la ejecucin del programa, en nmero imposible de o u predecir al momento de compilar. Por ejemplo, una aplicacin X-windows normal que crea o una, dos, tres, etc. ventanas a medida que uno abre archivos. En este caso, cada ventana es un objeto dinmico, creado durante la ejecucin, y la unica forma de manejarlo es a travs a o e de un puntero a ese objeto, creado con new cuando la ventana es creada, y destruido con delete cuando la ventana es cerrada. 4.5. MATRICES O ARREGLOS. 119 4.5. 4.5.1. Matrices o arreglos. Declaracin e inicializacin. o o Podemos declarar (e inicializar inmediatamente) matrices de enteros, reales de doble precisin, caracteres, etc., segn nuestras necesidades. o u int a[5]; double r[3] = {3.5, 4.1, -10.8}; char palabra[5]; Una vez declarada la matriz (digamos a[5]), los valores individuales se accesan con a[i], con i desde 0 a 4. Por ejemplo, podemos inicializar los elementos de la matriz as i: a[0] = 3; a[3] = 5; ... o si queremos ingresarlos desde el teclado: for (i = 0; i < 5; i++){ cin >> a[i]; } Y si deseamos escribirlos en pantalla: for (i = 0; i < 5; i++){ cout << a[i] ; } 4.5.2. Matrices como parmetros de funciones. a Si deseamos, por ejemplo, dise~ar una funcin que mande los elementos de una matriz n o a pantalla, necesitamos entregarle como parmetro la matriz que va a utilizar. Para ello se a agrega luego del nombre de la variable, para indicar que se trata de una matriz: void PrintMatriz(int, double ); int main(){ double matriz[5] = {3.5, 5.2, 2.4, -0.9, -10.8}; PrintMatriz(5, matriz); return 0; } void PrintMatriz(int i, double a){ for (int j = 0; j < i; j++){ cout << "Elemento " << j << " = " << a[j] << endl; } } 120 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. Observemos que la funcin debe recibir dos parmetros, uno de los cuales es la dimensin o a o de la matriz. Esto se debe a que cuando las matrices son usadas como parmetros la infora macin de su dimensin no es traspasada, y debe ser comunicada independientemente. Una o o ligera optimizacin al programa anterior es modificar main a: o int main() { int dim = 5; double matriz[dim] = {3.5, 5.2, 2.4, -0.9, -10.8}; PrintMatriz(dim, matriz); return 0; } De este modo, si eventualmente cambiamos de opinin y deseamos trabajar con matrices o de longitud distinta, slo hay que modificar una l o inea de cdigo (la primera) en todo el o programa, el cual puede llegar a ser bastante largo por cierto. (En el ejemplo, tambin habr e ia que cambiar la l inea de inicializacin de la matriz, porque asume que la matriz requiere slo 5 o o elementos, pero de todos modos deber ser clara la enorme conveniencia.) Podemos reescribir ia este programa con un comando de preprocesador para hacer la definicin de la dimensin: o o #include <iostream> #define DIM 5 using namespace std; int main(){ double matriz[DIM] = {3.5, 5.2, 2.4, -0.9, -10.8}; PrintMatriz(DIM, matriz); return 0; } 4.5.3. Asignacin dinmica. o a La reserva de memoria para la matriz podemos hacerla en forma dinmica ocupando el a operador new que pedir al sistema la memoria necesaria, si est disponible el sistema se a a la asignar. Como con cualquier puntero, una vez desocupado el arreglo debemos liberar la a memoria con el comando delete. #include <iostream> using namespace std; int main() { cout<<"Ingrese la dimension deseada :" ; int dim ; cin >> dim ; double * matriz = new double[dim] ; // Reserva la memoria for(int i=0; i < dim; i++) { 4.5. MATRICES O ARREGLOS. cout << "Ingrese elemento "<< i <<" : "; cin >> matriz[i] ; } for (int i=0;i<dim;i++){ cout << matriz[i] << ", "; } cout << endl; delete matriz; return 0; } // Libera la memoria reservada 121 Este ejemplo permite apreciar una gran ventaja del uso de punteros, al permitirnos liberarnos de definir la dimensin de una matriz como una constante. Aqu dim es simplemente un int. o i, La asignacin dinmica permite definir matrices cuya dimensin se determina recin durante o a o e la ejecucin. o Observemos finalmente que la liberacin de memoria, en el caso de arreglos, se hace con o el operador delete , no delete como en los punteros usuales. 4.5.4. Matrices multidimensionales. Es fcil declarar e inicializar matrices de ms de una dimensin: a a o double array[10][8]; int array[2][3] = {{1, 2, 3}, {4, 5, 6}}; Una operacin usual es definir primero las dimensiones de la matriz, y luego llenar sus o elementos uno por uno (o desplegarlos en pantalla), recorriendo la matriz ya sea por filas o por columnas. Hay que tener cuidado del orden en el cual uno realiza las operaciones. En el siguiente cdigo, definimos una matriz de 10 filas y 3 columnas, la llenamos con ceros o elemento por elemento, y luego inicializamos tres de sus elementos a nmeros distintos de u cero. Finalmente desplegamos la matriz resultante en pantalla: #include <iostream> using namespace std; int main(){ int dimx=3, dimy=10; double a[dimy][dimx]; for (int i=0;i<dimy;i++){ for (int j=0;j<dimx;j++){ a[i][j]=0; 122 } } a[0][0]=1; a[3][2]=2; a[9][2]=3; CAP ITULO 4. UNA BREVE INTRODUCCION A C++. for (int i=0;i<dimy;i++){ for (int j=0;j<dimx;j++){ cout << a[i][j] << ", "; } cout << endl; } return 0; } Inicializar los elementos a cero inicialmente es particularmente relevante. Si no, la matriz se llenar con elementos aleatorios. Veamos un ejemplo a continuacin que ilustra el paso de ia o arreglos multidimensionales como un parmetro a una funcin y la necesidad de inicializar a a o cero los elementos de un arreglo #include <iostream> #define NROWS 3 #define NCOLUMNS 2 using namespace std; void f(int, int, int [NCOLUMNS]); int main() { int array[NROWS][NCOLUMNS]; f(NROWS, NCOLUMNS, array); for(int i=0;i<NROWS;i++) { for(int j=0;j<NCOLUMNS;j++) array[i][j]=0; } f(NROWS, NCOLUMNS, array); return 0; } void f(int n, int m, int a[NCOLUMNS]) { for(int i=0;i<n;i++) { for(int j=0;j<m;j++) cout <<a[i][j]<<" "; cout << endl; } } 4.5. MATRICES O ARREGLOS. 123 4.5.5. Matrices de caracteres: cadenas (strings). Una palabra, frase o texto ms largo es representado internamente por C++ como una a matriz de chars. A esto se le llama "cadena" (string). Sin embargo, esto ocasiona un problema, pues las matrices deben ser definidas con dimensin constante (a menos que sean definidas o dinmicamente), y las palabras pueden tener longitud arbitraria. La convencin de C++ para a o resolver el problema es aceptar que una cadena tiene longitud arbitraria, pero debe indicar dnde termina. Esto se hace con el char nulo: '\0'. As para asignar a la variable palabra o i, el valor "Hola", debe definirse como una matriz de dimensin 5 (una ms que el nmero de o a u letras): char palabra[5] = {'H', 'o', 'l', 'a', '\0'}; Para escribir "Hola" en pantalla basta recorrer los elementos de palabra uno a uno: for (i = 0; i < 5; i++) { cout << palabra[i]; } Si tuviramos que hacer esto cada vez que queremos escribir algo a pantalla no ser muy e ia cmodo. Por ello, tambin podemos escribir "Hola" en pantalla simplemente con cout << "Hola", o e y de hecho se fue el primer ejemplo de este cap e itulo. De hecho, la declaracin de palabra o podr haberse escrito: ia char palabra[5] = "Hola"; Esto ya es bastante ms cmodo, aunque persiste la inconsistencia de definir palabra con a o dimensin 5, cuando en realidad al lado derecho de la asignacin hay un objeto con slo 4 o o o elementos (visibles). Este y otros problemas asociados con el manejo convencional de cadenas en C++ se resuelven incluyendo el header string. Usando string. El cdigo anterior se puede reescribir: o #include <iostream> #include <string> using namespace std; int main(){ string palabra = "Hola"; cout << palabra << endl; return 0; } 124 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. Observar que la l inea a incluir es #include <string>, sin la extensin ".h". Al incluir o string, las cadenas pueden ser declaradas como objetos tipo string en vez de arreglos de char. El hecho de que ya no tengamos que definir a priori la dimensin de la cadena o es una gran ventaja. De hecho, permite ingresar palabras desde el teclado trivialmente, sin preocuparse de que el input del usuario sea demasiado grande (tal que supere la dimensin del o arreglo que podamos haber declarado inicialmente) o demasiado corto (tal que se traduzca en un despilfarro de memoria por reservar ms memoria para el arreglo de la que realmente a se necesita): #include <iostream> #include <string> using namespace std; int main(){ string palabra; cin >> palabra; return 0; } Adems, este nuevo tipo string permite acceder a un sin nmero de funciones adicionales a u que facilitan enormemente el manejo de cadenas. Por ejemplo, las cadenas se pueden sumar, donde la suma de cadenas a y b est definida (siguiendo la intuicin) como la cadena que a o resulta de poner b a continuacin de a: o #include <iostream> #include <string> using namespace std; int main(){ string texto1 = "Primera palabra"; string texto2 = "Segunda palabra"; cout << texto1 << endl << texto2 << endl; cout << texto1 + ", " + texto2 << endl; // La ultima linea es equivalente a: // string texto3 = texto1 + ", " + texto2; // cout << texto3 << endl; return 0 ; } El output de este programa ser: a Primera palabra Segunda palabra Primera palabra, Segunda palabra 4.6. MANEJO DE ARCHIVOS. Ingreso con espacios. 125 Dijimos que es muy fcil ingresar una cadena desde el teclado, pues no es necesario a definir la dimensin desde el comienzo. Sin embargo, el cdigo anterior, usando cin, no o o es muy general, porque el input termina cuando el usuario ingresa el primer cambio de l inea o el primer espacio. Esto es muy cmodo cuando queremos ingresar una serie de vao lores (por ejemplo, para llenar un arreglo), pues podemos ingresarlos ya sea en la forma: 1<Enter> 2<Enter> 3<Enter>, etc., o 1 2 3, etc, pero no es ptimo cuando deseamos ino gresar texto, que podr constar de ms de una palabra y, por tanto, necesariamente incluir ia a ia espacios (por ejemplo, al ingresar el nombre y apellido de una persona). Sin explicar demasiado por qu, digamos que la solucin a este problema es utilizar una funcin asociada a cin e o o llamada get, y leer desde el teclado hasta que el usuario d el primer cambio de l e inea. Un ejemplo simple lo encontramos en el siguiente cdigo: o #include <iostream> #include <string> using namespace std; int main(){ string texto1 = "El resultado es: " ; string texto2 =""; char ch; cout << "Entre un string:" << endl; while( ( ch = cin.get() ) != '\n' ) cout << texto1 + texto2 << endl; return 0; } Observamos que cin.get() no necesita argumento y devuelve un char el cual es primero comparado con el caracter de fin de l inea y luego acumulado en texto2. texto2 = texto2 + ch; 4.6. Manejo de archivos. Una operacin usual en todo tipo de programas es la interaccin con archivos. Ya sea que o o el programa necesite conocer ciertos parmetros de configuracin, hacer anlisis estad a o a istico sobre un gran nmero de datos generados por otro programa, entregar las coordenadas de u los puntos de una trayectoria para graficarlos posteriormente, etc., lo que se requiere es un modo de ingresar datos desde, o poner datos en, archivos. En C++ ello se efecta incluyendo u el header fstream. 4.6.1. Archivos de salida. Observemos el siguiente programa: 126 #include <iostream> #include <fstream> using namespace std; CAP ITULO 4. UNA BREVE INTRODUCCION A C++. int main(){ ofstream nombre_logico("nombre_fisico.dat"); int i = 3, j; cout << i << endl; nombre_logico << i << endl; cout << "Ingrese un numero entero: "; cin >> j; cout << j << endl; nombre_logico << j << endl; nombre_logico.close(); return 0; } La primera l inea de main define un objeto de tipo ofstream (output file stream). Esto corresponde a un archivo de salida. Dentro de main este archivo ser identificado por a una variable llamada nombre_logico, y corresponder a un archivo en el disco duro llamaa do nombre_fisico.dat. Naturalmente, el identificador nombre_logico puede ser cualquier nombre de variable vlido para C++, y nombre_fisico.dat puede ser cualquier nombre de a archivo vlido para el sistema operativo. En particular, se pueden tambin dar nombres que a e incluyan paths absolutos o relativos: ofstream nombre_logico_1("/home/vmunoz/temp/nombre_fisico.dat"); ofstream nombre_logico_2("../nombre_fisico.dat"); Cuando creamos un objeto del tipo archivo, sin importar si es de salida o de entrada, podemos inicializarlo con un nombre de archivo f isico. Este nombre lo podemos almacenar previamente en una variable de string, llamemosla mi_nombre_archivo. En este caso, cuando creamos el objeto ofstream debemos usar un mtodo del objeto string que devuelve un e puntero a char, para poder inicializar el objeto ofstream. Veamos la sintxis expl a icitamente string mi_nombre_archivo=''archivo.txt''; ofstream nombre_logico_1( mi_nombre_archivo.c_str()); Las l ineas tercera y sexta de main env ian a nombre_logico (es decir, escribe en nombre_fisico.dat), las variables i y j. Observar la analog que existe entre estas operaia ciones y las que env la misma informacin a pantalla.4 Si ejecutamos el programa y en ian o el teclado ingresamos el nmero 8, al finalizar la ejecucin el archivo nombre_fisico.dat u o tendr los dos nmeros escritos: a u 3 8 Esta analog no es casual y se entiende con el concepto de clases (Sec. 4.8). fstream e iostream definen ia clases que heredan sus propiedades de un objeto abstracto base, comn a ambas, y que en el caso de iostream u se concreta en la salida estndar --pantalla--, y en el de fstream en un archivo. a 4 4.6. MANEJO DE ARCHIVOS. 127 Finalmente, el archivo creado debe ser cerrado (nombre_logico.close()). Si esta ultima operacin se omite en el cdigo, no habr errores de compilacin, y el programa se encaro o a o gar de cerrar por s solo los archivos abiertos durante su ejecucin, pero un buen programador a i o debiera tener cuidado de cerrarlos expl icitamente. Por ejemplo, un mismo programa podr ia desear utilizar un mismo archivo ms de una vez, o varios programas podr querer acceder a ian al mismo archivo, y si no se ha insertado un close en el punto adecuado esto podr provocar ia problemas. El archivo indicado al declarar la variable de tipo ofstream tiene modo de escritura, para permitir la salida de datos hacia l. Si no existe un archivo llamado nombre_fisico.dat es e creado; si existe, los contenidos antiguos se pierden y son reemplazados por los nuevos. No siempre deseamos este comportamiento. A veces deseamos agregar la salida de un programa a un archivo de texto ya existente. En ese caso la declaracin del archivo es diferente, para o crear el archivo en modo "append": #include <iostream> #include <fstream> using namespace std; int main(){ ofstream nombre_logico("nombre_fisico.dat",ios::app); int i = 3; nombre_logico << i << endl; nombre_logico.close(); return 0; } Si ejecutamos este programa y el archivo nombre_fisico.dat no existe, ser creado. El a resultado ser un archivo con el nmero 3 en l. Al ejecutarlo por segunda vez, los datos se a u e ponen a continuacin de los ya existentes, resultando el archivo con el contenido: o 3 3 La l inea del tipo ofstream a("b") es equivalente a una del tipo int i=3, declarando una variable (a/i) de un cierto tipo (ofstream/int) y asignndole un valor simultneamente a a "b"/3. Como para los tipos de variables predefinidos de C++, es posible separar declaracin o y asignacin para una variable de tipo ofstream: o ofstream a; a.open("b"); es equivalente a ofstream a("b"). Esto tiene la ventaja de que podr iamos usar el mismo nombre lgico para identificar dos archivos f o isicos distintos, usados en distintos momentos del programa: 128 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. ofstream a; a.open("archivo1.txt"); // Codigo en que "archivo1.txt" es utilizado a.close(); a.open("archivo2.txt"); // Ahora "archivo2.txt" es utilizado a.close(); Observar la necesidad del primer close, que permitir liberar la asociacin de a a un nombre a o f isico dado, y reutilizar la variable lgica en otro momento. o En los ejemplos hemos escrito solamente variables de tipo int en los archivos. Esto por cierto no es restrictivo. Cualquiera de los tipos de variables de C++ --float, double, char, etc.-- se puede enviar a un archivo del mismo modo. Dicho esto, en el resto de esta seccin o seguiremos usando como ejemplo el uso de int. 4.6.2. Archivos de entrada. Ya sabemos que enviar datos a un archivo es tan fcil como enviarlos a pantalla. Cmo a o hacemos ahora la operacin inversa, de leer datos desde un archivo? Como es de esperar, es tan o fcil como leerlos desde el teclado. Para crear un archivo en modo de lectura, basta declararlo a de tipo ifstream (input file stream). Por ejemplo, si en nombre_logico.dat tenemos los siguientes datos: 3 6 9 12 el siguiente programa, #include <iostream> #include <fstream> using namespace std; int main(){ ifstream nombre_logico("nombre_fisico.dat"); int i, j,k,l; nombre_logico >> i >> j >> k >> l; cout << i << "," << j << "," << k << "," << l << endl; nombre_logico.close(); return 0; } 4.6. MANEJO DE ARCHIVOS. 129 ser equivalente a asignar i=3, j=6, k=9, l=12, y luego enviar los datos a pantalla. Observar a que la sintaxis para ingresar datos desde un archivo, nombre_logico >> i, es idntica a e cin >> i, para hacerlo desde el teclado. Al igual que cin, espacios en blanco son equivalentes a cambios de l inea, de modo que el archivo podr haber sido tambin: ia e 3 6 9 12 Por cierto, el ingreso de datos desde un archivo se puede hacer con cualquier tcnica, por e ejemplo, usando un for: ifstream nombre_logico("nombre_fisico.dat"); int i; for (int j=0;j<10;j++){ nombre_logico >> i; cout << i << ","; } nombre_logico.close(); } Como con ofstream, es posible separar declaracin e implementacin: o o ifstream a; a.open("b"); a.close(); 4.6.3. Archivos de entrada y salida. Ocasionalmente nos encontraremos con la necesidad de usar un mismo archivo, en el mismo programa, a veces para escribir datos, y otras veces para leer datos. Por ejemplo, podr iamos tener una secuencia de datos en un archivo, leerlos, y de acuerdo al anlisis de a esos datos agregar ms datos a continuacin del mismo archivo, o reemplazar los datos ya a o existentes con otros. Necesitamos entonces un tipo de variable flexible, que pueda ser usado como entrada y salida. Ese tipo es fstream. Todo lo que hemos dicho para ofstream y ifstream por separado es cierto simultneamente para fstream.5 Para especificar si el archivo a debe ser abierto en modo de escritura o lectura, open contiene el argumento ios::out o ios::in, respectivamente. Por ejemplo, el siguiente cdigo escribe el nmero 4 en un archivo, o u y luego lo lee desde el mismo archivo: #include <iostream> #include <fstream> using namespace std; int main(){ fstream nombre_logico; Nuevamente, este hecho se debe al concepto de clases que subyace a las definiciones de estos tres tipos de variables; fstream es una clase derivada a la vez de ofstream y de ifstream, heredando las propiedades de ambas. 5 130 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. nombre_logico.open("nombre_fisico.dat",ios::out); int i = 4,j; nombre_logico << i << endl; nombre_logico.close(); nombre_logico.open("nombre_fisico.dat",ios::in); nombre_logico >> j; cout << j << endl; nombre_logico.close(); return 0; } Las dos primeras l ineas de main separan declaracin y asignacin, y son equivalentes a o o fstream nombre_logico("nombre_fisico.dat",ios::out);, pero lo hemos escrito as pai ra hacer evidente la simetr entre el uso del archivo como salida primero y como entrada ia despus. e De lo anterior, se deduce que: fstream archivo_salida("salida.dat",ios::out); fstream archivo_entrada("entrada.dat",ios::in); es equivalente a ofstream archivo_salida("salida.dat"); ifstream archivo_entrada("entrada.dat"); 4.7. main como funcin. o Para ejecutar un programa compilado en C++, escribimos su nombre en el prompt: [email protected]:~/$ programa Si el mismo usuario desea ejecutar alguno de los comandos del sistema operativo, debe hacer lo mismo: [email protected]:~/$ ls Sin embargo, ls es en realidad el nombre de un archivo ejecutable en el directorio /bin, de modo que en realidad no hay diferencias entre nuestro programa y un comando del sistema operativo en ese sentido. Sin embargo, stos pueden recibir argumentos y opciones. Por e ejemplo, para ver todos los archivos que comienzan con l en el directorio local basta con darle a ls el argumento l*: ls l*. Si queremos ordenar los archivos en orden inverso de modificacin, basta dar otro argumento, en forma de opcin: ls -tr l*. Se ve entonces que o o los argumentos de un archivo ejecutable permiten modificar el comportamiento del programa de modos espec ificos. 4.7. MAIN COMO FUNCION. 131 Es posible hacer lo mismo con archivos ejecutables hechos por el usuario? La respuesta es s y para eso se usan los argumentos del main. Recordemos que main es una funcin, i, o pero hasta el momento no hemos aprovechado esa caracter istica. Simplemente sabemos que el programa empieza a ejecutarse en la l inea donde est la funcin main. Adems, siempre a o a hemos escrito esa l inea como main(). Sin embargo, main, como cualquier funcin, es capaz de o aceptar argumentos. Espec ificamente, acepta dos argumentos, el primero es un entero (que cuenta el nmero de argumentos que main recibi), y el segundo es un puntero a un arreglo u o de caracteres (que contiene los distintos argumentos, en forma de cadenas de caracteres, que se le entregaron). Por ejemplo: #include <iostream> using namespace std; int main( int argc, char * argv) { for(int i = 0; i < argc; i++) { cout << argv[i] << endl ; } return 0; } Si llamamos a este programa argumentos, obtenemos distintas salidas al llamarlo con distintos argumentos: [email protected]:~/$ argumentos argumentos [email protected]:~/$ argumentos ap k 5 argumentos ap k 5 user@host:~/$ argumentos -t -s 4 arg1 argumentos -t -s 4 arg1 Observar que el primer argumento del programa es siempre el nombre del propio programa. Naturalmente, ste es un ejemplo muy simple. Es tarea del programador decidir cmo manejar e o cada una de las opciones o argumentos que se le entregan al programa desde la l inea de comandos, escribiendo el cdigo correspondiente. o 132 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. 4.7.1. Tipo de retorno de la funcin main. o Un segundo aspecto con el cual no hemos sido sistemticos es que main, como toda funcin, a o tiene un tipo de retorno. En el caso de main, ese tipo debe ser int. Este int es entregado al sistema operativo, y puede servir para determinar si el programa se ejecut con normalidad o o si ocurri algo anormal. Podr o iamos hacer ese valor de retorno igual a 0 o 1, respectivamente. As la siguiente estructura es correcta: i, int main(){ // Codigo return 0; } En este caso, el programa entrega siempre el valor 0 al sistema operativo. Los cdigos del tipo: o main(){ // Codigo } o void main(){ // Codigo } tambin compilan, pero el compilador emite una advertencia si es llamado con la opcin e o -Wall (Warning all ). En el primer caso, la advertencia es: warning: ANSI C++ forbids declaration `main' with no type En el segundo: return type for `main' changed to `int' En general, siempre es conveniente compilar con la opcin -Wall, para lograr que nuestro o cdigo est realmente correcto (g++ -Wall <archivo>.cc -o <archivo>). o e 4.8. CLASES. 133 4.8. Clases. C++ dispone de una serie de tipos de variables con las cuales nos est permitido operar: a int, double, char, etc. Creamos variables de estos tipos y luego podemos operar con ellas: int x = y = int x, y; 3; 6; z = x + y; No hay, sin embargo, en C++, una estructura predefinida que corresponda a nmeros u complejos, vectores de dimensin n o matrices, por ejemplo. Y sin embargo, nos agradar o ia disponer de nmeros complejos que pudiramos definir como u e z = (3,5); w = (6,8); y que tuvieran sentido las expresiones a b c d e f = = = = = = z + w; z * w; z / w; z + 3; modulo(z); sqrt(z); Todas estas expresiones son completamente naturales desde el punto de vista matemtico, a y ser bueno que el lenguaje las entendiera. Esto es imposible en el estado actual, pues, por ia ejemplo, el signo + es un operador que espera a ambos lados suyos un nmero. Sumar cualquier u cosa con cualquier cosa no significa nada necesariamente, as que slo est permitido operar i o a con nmeros. Pero los humanos sabemos que los complejos son nmeros. Cmo dec u u o irselo al computador? Cmo convencerlo de que sumar vectores o matrices es tambin posible o e matemticamente, y que el mismo signo + deber servir para todas estas operaciones? a ia La respuesta es: a travs del concepto de clases. Lo que debemos hacer es definir una clase e de nmeros complejos. Llammosla Complejo. Una vez definida correctamente, Complejo u e ser un tipo ms de variable que el compilador reconocer, igual que int, double, char, etc. a a a Y ser tan fcil operar con los Complejos como con todos los tipos de variables preexistentes. a a Esta facilidad es la base de la extensibilidad de que es capaz C++, y por tanto de todas las propiedades que lo convierten en un lenguaje muy poderoso. Las clases responden a la necesidad del programador de construir objetos o tipos de datos que respondan a sus necesidades. Si necesitamos trabajar con vectores de 5 coordenadas, ser natural definir una clase que corresponda a vectores con 5 coordenadas; si se trata de a un programa de administracin de personal, la clase puede corresponder a un empleado, con o sus datos personales como elementos. Si bien es cierto uno puede trabajar con clases en el contexto de orientacin al procedio miento, las clases muestran con mayor propiedad su potencial con la orientacin al objeto, o donde cada objeto corresponde a una clase. Por ejemplo, para efectuar una aplicacin para o X-windows, la ventana principal, las ventanas de los archivos abiertos, la barra de men, las u cajas de dilogo, los botones, etc., cada uno de estos objetos estar asociado a una clase. a a 134 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. 4.8.1. Definicin. o Digamos que queremos una clase para representar a los empleados de una empresa. Llammosla Persona. La convencin aceptada es que los nombres de las clases comiencen e o con mayscula. Esto es porque las clases, recordemos, correspondern a tipos de variables u a tan vlidos como los internos de C++ (int, char, etc.). Al usar nombres con mayscula a u distinguimos visualmente los nombres de un tipo de variable interno y uno definido por el usuario. La estructura m inima de la definicin de la clase Persona es: o class Persona { }; Todas las caracter isticas de la clase se definen entre los parntesis cursivos. e 4.8.2. Miembros. Se denomina miembros de una clase a todas las variables y funciones declaradas dentro de una clase. Por ejemplo, para personas, es natural caracterizarlas por su nombre y su edad. Y si se trata de empleados de una empresa, es natural tambin tener una funcin que entregue e o su sueldo: class Persona { string nombre; fecha nacimiento; int rut; double edad(); }; Los miembros de una clase pueden tener cualquier nombre, excepto el nombre de la propia clase dentro de la cual se definen, ese nombre est reservado. a 4.8.3. Miembros p blicos y privados. u Una clase distingue informacin (datos o funciones) privada (accesible slo a otros miemo o bros de la misma clase) y pblica (accesible a funciones externas a la clase). La parte privada u corresponde a la estructura interna de la clase, y la parte pblica a la implementacin (t u o ipicamente funciones), que permite la interaccin de la clase con el exterior. o Consideremos ahora nuestro deseo de tener una clase que represente nmeros complejos. u Un nmero complejo tiene dos nmeros reales (parte real e imaginaria), y sos son elementos u u e privados, es decir, parte de su estructura interna. Sin embargo, nos gustar poder modificar ia y conocer esas cantidades. Eso slo puede hacerse a travs de funciones pblicas. o e u 4.8. CLASES. class Complejo { private: double real, imaginaria; public: void setreal(double); void setimag(double); double getreal(); double getimag(); }; 135 En este ejemplo, los miembros privados son slo variables, y los miembros pblicos son slo o u o funciones. Este es el caso t ipico, pero puede haber variables y funciones de ambos tipos. 4.8.4. Operador de seleccin (.). o Hemos definido una clase de nmeros complejos y funciones que nos permiten conocer u y modificar las partes real e imaginaria. Cmo se usan estos elementos? Consideremos el o siguiente programa de ejemplo: using namespace std; class Complejo { private: double real, imaginaria; public: void setreal(double); void setimag(double); double getreal(); double getimag(); }; int main() { Complejo z, w; z.setreal(3); z.setimag(2.8); w.setreal(1.5); w.setimag(5); cout << "El primer numero complejo es: " << z.getreal() << " + i*" << z.getimag() << endl; cout << "El segundo es: " << w.getreal() << " + i*" << z.getimag() << endl; return 0; } 136 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. Vemos en la primera l inea de main cmo la clase Complejo se usa del mismo modo que o usar iamos int o double. Ahora Complejo es un tipo de variable tan vlido como los tipos a predefinidos por C++. Una vez definida la variable, el operador de seleccin (.) permite o acceder a las funciones pblicas correspondientes a la clase Complejo, aplicadas a la variable u particular que nos interesa: z.setreal(3) pone en la parte real del Complejo z el nmero u 3, y w.setreal(1.5) hace lo propio con w. 4.8.5. Implementacin de funciones miembros. o Ya sabemos cmo declarar funciones miembros en el interior de la clase y cmo usarlas. o o Ahora veamos cmo se implementan. o void Complejo::setreal(double x) { real = x; } void Complejo::setimag(double x) { imaginaria = x; } double Complejo::getreal() { return real; } double Complejo::getimag() { return imaginaria; } Como toda funcin, primero va el tipo de la funcin (void o double en los ejemplos), luego o o el nombre de la funcin y los argumentos. Finalmente la implementacin. Lo diferente es que o o el nombre va precedido del nombre de la clase y el operador "::" . 4.8.6. Constructor. Al declarar una variable, el programa crea el espacio de memoria suficiente para alojarla. Cuando se trata de variables de tipos predefinidos en C++ esto no es problema, pero cuando son tipos definidos por el usuario, C++ debe saber cmo construir ese espacio. La funcin o o que realiza esa tarea se denomina constructor. El constructor es una funcin pblica de la clase, que tiene el mismo nombre que ella. o u Agreguemos un constructor a la clase Complejo: class Complejo 4.8. CLASES. { private: double real,imaginaria; public: Complejo(double,double); void setreal(double); void setimag(double); double getreal(); double getimag(); }; Complejo::Complejo (double x, double y) : real(x), imaginaria(y) {} 137 Definir el constructor de esta manera nos permite crear en nuestro programa variables de tipo Complejo y asignarles valores sin usar setreal() o setimag(): Complejo z (2, 3.8); Complejo w = Complejo(6.8, -3); En el constructor se inicializan las variables internas que nos interesa inicializar al momento de crear un objeto de esta clase. Si una de las variables internas a inicializar es una cadena de caracteres, hay que inicializarla de modo un poco distinto. Por ejemplo, si estamos haciendo una clase OtraPersona que slo tenga el nombre de una persona, entonces podemos definir la clase y su constructor o en la forma: class OtraPersona { private: char nombre[20]; public: Persona(char ); }; Persona::Persona(char a) { strcpy(nombre,a); } Si uno no especifica el constructor de una clase C++ crea uno default, pero en general ser insuficiente para cualquier aplicacin realmente prctica. Es una mala costumbre ser a o a descuidado y dejar estas decisiones al computador. 4.8.7. Destructor. As como es necesario crear espacio de memoria al definir una variable, hay que deshacerse i de ese espacio cuando la variable deja de ser necesaria. En otras palabras, la clase necesita 138 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. tambin un destructor . Si la clase es Complejo, el destructor es una funcin pblica de ella, e o u llamada ~Complejo. class Complejo { private: double real, imaginaria; public: Complejo(double,double); ~Complejo(); void setreal(double); void setimag(double); double getreal(); double getimag(); }; Complejo::Complejo (double x, double y): real(x), imaginaria(y) { } Complejo::~Complejo() { } Como con los constructores, al omitir un destructor C++ genera un default, pero es una mala costumbre. . . , etc. 4.8.8. Arreglos de clases. Una clase es un tipo de variable como cualquier otra de las predefinidas en C++. Es posible construir matrices con ellas, del mismo modo que uno tiene matrices de enteros o caracteres. La unica diferencia con las matrices usuales es que no se pueden slo declarar, o sino que hay que inicializarlas simultneamente. Por ejemplo, si queremos crear una matriz a que contenga 2 nmeros complejos, la l u inea Complejo z[2]; es incorrecta, pero s es aceptable la l i inea Complejo z[2] = {Complejo(3.5,-0.8), Complejo(-2,4)}; 4.9. Sobrecarga. Para que la definicin de nuevos objetos sea realmente util, hay que ser capaz de hacer o con ellos muchas acciones que nos ser naturales. Como ya comentamos al introducir el ian concepto de clase, nos gustar sumar nmeros complejos, y que esa suma utilizara el mismo ia u 4.9. SOBRECARGA. 139 signo + de la suma usual. O extraerles la ra cuadrada, y que la operacin sea tan fcil iz o a como escribir sqrt(z). Lo que estamos pidiendo es que el operador + o la funcin sqrt() o sean polimrficos, es decir, que acten de distinto modo segn el tipo de argumento que o u u se entregue. Si z es un real, sqrt(z) calcular la ra de un nmero real; si es complejo, a iz u calcular la ra de un nmero complejo. a iz u La tcnica de programacin mediante la cual podemos definir funciones polimrficas se e o o llama sobrecarga. 4.9.1. Sobrecarga de funciones. Digamos que la ra cuadrada de un nmero complejo a + ib es (a/2) + i(b/2). (Es ms iz u a complicado en realidad, pero no queremos escribir las frmulas ahora.) o Para sobrecargar la funcin sqrt() de modo que acepte nmeros complejos basta definirla o u as i: Complejo sqrt(Complejo z) { return Complejo (z.getreal()/2, z.getimag()/2); } Observemos que definimos una funcin sqrt que acepta argumentos de tipo Complejo, y que o entrega un nmero del mismo tipo. Cuando pidamos la ra de un nmero, el computador u iz u se preguntar si el nmero en cuestin es un int, double, float o Complejo, y segn eso a u o u escoger la versin de sqrt que corresponda. a o Con la definicin anterior podemos obtener la ra cuadrada de un nmero complejo o iz u simplemente con las instrucciones: Complejo z(1,3); Complejo raiz = sqrt(z); 4.9.2. Sobrecarga de operadores. Cmo le decimos al computador que el signo + tambin puede aceptar nmeros compleo e u jos? La respuesta es fcil, porque para C++ un operador no es sino una funcin, y la accin a o o de sobrecargar que ya vimos sirve en este caso tambin. La sintaxis es: e Complejo operator + (Complejo z, Complejo w) { return Complejo (z.getreal() + w.getreal(), z.getimag() + w.getimag()); } 4.9.3. Coercin. o Sabemos definir a + b, con a y b complejos. Pero qu pasa si a o b son enteros? O reales? e Pareciera que tendr iamos que definir no slo o 140 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. Complejo operator + (Complejo a, Complejo b); sino tambin todas las combinaciones restantes: e Complejo operator + (Complejo a, int b); Complejo operator + (Complejo a, float b); Complejo operator + (int a, Complejo b); etctera. e En realidad esto no es necesario. Por cierto, un nmero real es un nmero complejo con u u parte imaginaria nula, y es posible hacerle saber esto a C++, usando la posibilidad de definir funciones con parmetros default. Basta declarar (en el interior de la clase) el constructor de a los nmeros complejos como u Complejo (double, double = 0); Esto permite definir un nmero complejo con la instruccin: u o Complejo c = Complejo(3.5); resultando el nmero complejo 3.5 + i 0. Y si tenemos una l u inea del tipo: Complejo c = Complejo(3,2.8) + 5; el computador convertir impl a icitamente el entero 5 a Complejo (sabe cmo hacerlo porque o el constructor de nmeros complejos acepta tambin un solo argumento en vez de dos), y u e luego realizar la suma entre dos complejos, que es entonces la unica que es necesario definir. a 4.10. Herencia. Herencia es el mecanismo mediante el cual es posible definir clases a partir de otras, preservando parte de las propiedades de la primera y agregando o modificando otras. Por ejemplo, si definimos la clase Persona, toda Persona tendr una variable miembro a que sea su nombre. Si definimos una clase Hombre, tambin ser Persona, y por tanto deber e a ia tener nombre. Pero adems puede tener esposa. Y ciertamente no toda Persona tiene esposa. a Slo un Hombre. o C++ provee mecanismos para implementar estas relaciones lgicas y poder definir una o clase Hombre a partir de Persona. Lo vemos en el siguiente ejemplo: class Persona { private: string nombre; public: Persona(string = ""); ~Persona(); string getname(); } 4.11. EJEMPLO: LA CLASE DE LOS COMPLEJOS. 141 class Hombre : public Persona { private: string esposa; public: Hombre(string a) : Persona(a) { }; string getwife(); void setwife(string); }; Primero definimos una clase Persona que tiene nombre. Luego definimos una clase Hombre a partir de Persona (con la l inea class Hombre : public Persona). Esto permite de modo automtico que Hombre tenga tambin una variable nombre. Y finalmente, dentro de la clase a e Hombre, se definen todas aquellas caracter isticas adicionales que una Persona no tiene pero un Hombre s esposa, y funciones miembros para modificar y obtener el nombre de ella. i: Un ejemplo de uso de estas dos clases: Persona cocinera("Maria"); Hombre panadero("Claudio"); panadero.setwife("Estela"); cout << cocinera.getname() << endl; cout << panadero.getname() << endl; cout << panadero.getwife() << endl; Observemos que panadero tambin tiene una funcin getname(), a pesar de que la clase e o Hombre no la define expl icitamente. Esta funcin se ha heredado de la clase de la cual Hombre o se ha derivado, Persona. 4.11. Ejemplo: la clase de los complejos. A continuacin, una clase de complejos ms completa. Primero el archivo de headers o a complejos.h, con las definiciones: #ifndef _complejos_ #define _complejos_ #include <iostream> #include <cmath> class Complejo { private: double real, imaginaria; 142 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. public: Complejo(); Complejo(double,double=0); ~Complejo(); void setreal(double); void setimag(double); double getreal(); double getimag(); double getmodule(); double getmodule2(); double getphase(); }; Complejo operator + (Complejo,Complejo); Complejo operator - (Complejo,Complejo); Complejo operator * (Complejo,Complejo); Complejo operator / (Complejo,Complejo); Complejo conjugate(Complejo); Complejo inverse(Complejo); Complejo sqrt(Complejo); Complejo log(Complejo); bool operator == (Complejo,Complejo); bool operator != (Complejo,Complejo); std::ostream & operator << (std::ostream &, Complejo); #endif y la implementacin de lo anterior o #include "complejos.h" Complejo::Complejo(double x, double y) :real(x), imaginaria(y) {} Complejo::Complejo() :real(0), imaginaria(0) {} Complejo::~Complejo() {} void Complejo::setreal(double x) { real = x; 4.11. EJEMPLO: LA CLASE DE LOS COMPLEJOS. } void Complejo::setimag(double x) { imaginaria = x; } double Complejo::getreal() { return real; } double Complejo::getimag() { return imaginaria; } double Complejo::getmodule() { return sqrt(real*real+imaginaria*imaginaria); } double Complejo::getmodule2() { return real*real+imaginaria*imaginaria; } double Complejo::getphase() { return atan2(real,imaginaria); } 143 Complejo operator + (Complejo z,Complejo w) { return Complejo(z.getreal()+w.getreal(), z.getimag()+w.getimag()); } Complejo operator - (Complejo z,Complejo w) { return Complejo(z.getreal()-w.getreal(), z.getimag()-w.getimag()); } Complejo operator * (Complejo z,Complejo w) { 144 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. return Complejo(z.getreal()*w.getreal()- z.getimag()*w.getimag(), z.getreal()*w.getimag()+ z.getimag()*w.getreal()); } Complejo operator / (Complejo z,Complejo w) { return z*inverse(w); } Complejo conjugate(Complejo z) { return Complejo(z.getreal(), -z.getimag()); } Complejo inverse(Complejo z) { return Complejo(z.getreal()/z.getmodule2(), -z.getimag()/z.getmodule2()); } Complejo sqrt(Complejo z) { return Complejo(sqrt(z.getmodule())*cos(z.getphase()/2.0), sqrt(z.getmodule())*sin(z.getphase()/2.0)) ; } Complejo log(Complejo z) { return Complejo(log(z.getmodule()), z.getphase()); } bool operator == (Complejo z,Complejo w) { return bool(z.getreal()==w.getreal() && z.getimag()==w.getimag()); } bool operator != (Complejo z,Complejo w) { return bool(z.getreal()!=w.getreal() || z.getimag()!=w.getimag()); } std::ostream & operator << (std::ostream & os , Complejo z) { os << z.getreal(); if(z.getimag() !=0) os << " + i*"<< z.getimag(); return os; } 4.12. COMPILACION Y DEBUGGING. 145 4.12. 4.12.1. Compilacin y debugging. o Compiladores. El comando para usar el compilador de lenguaje C es gcc, para usar el compilador de C++ es g++ y para usar el compilador de fortran 77 es g77. Centrmosnos en el compilador e de C++, los dems funcionan en forma muy similar. Su uso ms elemental es: a a g++ filename.cc Esto compila el archivo filename.cc y crea un archivo ejecutable que se denomina a.out por omisin. Existen diversas opciones para el compilador, slo comentaremos una pocas. o o -c realiza slo la compilacin pero no el link: o o g++ -c filename.cc genera el archivo filename.o que es cdigo objeto. o -o exename define el nombre del ejecutable creado, en lugar del por defecto a.out. g++ -o outputfile filename.cc -lxxx incluye la biblioteca /usr/lib/libxxx.a en la compilacin. o g++ filename.cc -lm En este caso se compila con la biblioteca matemtica libm.a. a -g permite el uso de un debugger posteriormente. -On optimizacin de grado n que puede tomar valores de 1 (por defecto) a 3. El objetivo o inicial del compilador es reducir el tiempo de la compilacin. Con -On, el compilador o trata de reducir el tama~o del ejecutable y el tiempo de ejecucin, con n se aumenta el n o grado de optimizacin. o -Wall notifica todos los posibles warnings en el cdigo que est siendo compilado. o a -L/path1 -I/path2/include incluye en el camino de bsqueda /path1/ para las biu bliotecas y /path2/include para los archivos de cabecera (headers). El compilador gcc (the GNU C compiler) es compatible ANSI. 146 CAP ITULO 4. UNA BREVE INTRODUCCION A C++. Cap itulo 5 Grfica. a versin 4.12, 24 de Octubre del 2003 o En este cap itulo quisiramos mostrar algunas de las posibilidades grficas presentes en Lie a nux. Nuestra intensin es cubrir temas como la visualizacin, conversin, captura y creacin o o o o de archivos grficos. Slo mencionaremos las aplicaciones principales en cada caso centrndoa o a nos en sus posibilidades ms que en su utilizacin espec a o ifica, ya que la mayor posee una ia interfase sencilla de manejar y una amplia documentacin. o 5.1. Visualizacin de archivos grficos. o a Si disponemos de un archivo grfico conteniendo algn tipo de imagen lo primero que es a u importante determinar es en qu tipo de formato grfico est codificada. Existe un nmero e a a u realmente grande de diferentes tipos de codificaciones de imgenes, cada una de ellas se a considera un formato grfico. Por razones de reconocimiento inmediato del tipo de formato a grfico se suelen incluir en el nombre del archivo, que contiene la imagen, un tr de letras a io finales, conocidas como la extensin, que representan el formato. Por ejemplo: bmp, tiff, jpg, o ps, eps, fig, gif entre muchas otras, si uno quiere asegurarse puede dar el comando: jrogan@huelen:~$file mono.jpg mono.jpg: JPEG image data, JFIF standard 1.01, resolution (DPCM), 72 x 72 De qu herramientas disponemos en Linux para visualizar estas imgenes? La respuesta e a es que en Linux disponemos de variadas herramientas para este efecto. Si se trata de archivos de tipo PostScript o Encapsulated PostScript, identificados por la extensin ps o eps, existen las aplicaciones gv, gnome-gv o kghostview, todos programas que o nos permitirn visualizar e imprimir este tipo de archivos. Si los archivos son tipo Portable a Document Format, con extensin pdf, tenemos las aplicaciones gv, acroread o xpdf, Con o todas ellas podemos ver e imprimir dicho formato. Una mencin especial requieren los archivos o DeVice Independent con extensin dvi ya que son el resultado de la compilacin de un o o A X, para este tipo de archivo existen las aplicaciones xdvi, advi, gxdvi documento TEX o L TE y kdvi por nombrar las principales. La aplicacin xdvi slo permite visualizar estos archivos o o y no imprimirlos, la mayor de las otras permiten imprimirlo directamente. Si usa xdvi y ia desea imprimir el documento debe transformar a ps v dvips y luego se imprime como ia cualquier otro Postscript. Para la gran mayor de formatos grficos ms conocidos y usualmente usados para alia a a macenar fotos existen otra serie se programas especializados en visualizacin que son capaces o 147 148 CAP ITULO 5. GRAFICA. de entender la mayor de los formatos ms usados. Entre estos programas podemos mencioia a nar: Eye of Gnome (eog), Electric Eyes (eeyes), kview o display. Podemos mencionar que aplicaciones como display entienden sobre ochenta formatos grficos distintos entre los que a se encuentran la mayor de los formatos conocidos ms otros como ps, eps, pdf, fig, html, ia a entre muchos otros. Una mencin especial merece el utilitario gthumb que nos permite hacer o un preview de un directorio con muchas imagenes de manera muy fcil. a 5.2. Modificando imgenes a Si queremos modificaciones como rotaciones, ampliaciones, cortes, cambios de paleta de colores, filtros o efectos sencillos, display es la herramienta precisa. Pero si se desea intervenir la imagen en forma profesional, el programa gimp es el indicado. El nombre gimp viene de GNU Image Manipulation Program. Se puede usar esta aplicacin para editar y manipular o imgenes. Pudiendo cargar y salvar en una variedad de formatos, lo que permite usarlo para a convertir entre ellos. La aplicacin gimp puede tambin ser usado como programa de pintar, o e de hecho posee una gran variedad de herramientas en este sentido, tales como brocha de aire, lpiz clonador, tijeras inteligentes, curvas bezier, etc. Adems, permite incluir plugins a a que realizan gran variedad de manipulaciones de imagen. Como hecho anecdtico podemos o mencionar que la imagen oficial de Tux, el pingino mascota de Linux, fue creada en gimp. Sin u embargo, si gimp le parece muy profesional o usted slo necesita un programa para dibujar o en el cual se entretenga su hermano menor tuxpaint es la alternativa. 5.3. Conversin entre formatos grficos. o a El problema de transformar de un formato a otro es una situacin usual en el trabajo con o archivos grficos. Muchos softwares tienen salidas muy restringidas en formato o bien usan a formatos arcaicos (gif) por ejemplo. De ah que se presenta la necesidad de convertir estos i archivos de salida en otros formatos que nos sean ms manejables o prcticos. Como ya se a a mencion, gimp puede ser usado para convertir entre formatos grficos. Tambin display o a e permite este hecho. Sin embargo, en ambos casos la conversin es v mens, lo cual lo o ia u hace engorroso para un gran nmero de conversiones e imposible para conversiones de tipo u automtico. Existe un programa llamado convert que realiza conversiones desde la l a inea de comando. Este programa junto con display, import y varios otros forman la suite grfica a ImageMagick, una de las ms importantes en unix, en general, y en especial en Linux y que a ya ha sido migrada a otras plataformas. Adems, de la clara ventaja de automatizacin que a o proporciona convert, posee otro aspecto interesante, puede convertir un grupo de imgenes a asociadas en una secuencia de animacin o pel o icula. Veamos la sintaxis para este programa: user@host:~/imagenes$convert cockatoo.tiff cockatoo.jpg user@host:~/secuencias$convert -delay 20 dna*.png dna.mng En el primer caso convierte el archivo cockatoo de formato tiff a formato jpg. En el segundo, a partir de un conjunto de archivos con formato png llamados dna ms un nmero a u 5.4. CAPTURA DE PANTALLA. 149 correlativo, crea una secuencia animada con imgenes que persisten por 20 centsimas de a e segundos en un formato conocido como mng. 5.4. Captura de pantalla. A menudo se necesita guardar imgenes que slo se pueden generar a tiempo de ejecucin, a o o es decir, mientras corre nuestro programa genera la imagen pero no tiene un mecanismo propio para exportarla o salvarla como imagen. En este caso necesitamos capturar la pantalla y poderla almacenar en un archivo para el cual podamos elegir el formato. Para estos efectos existe un programa, miembro tambin de la suite ImageMagick, llamado import que nos e permite hacer el trabajo. La sintaxis del comando es import figure.eps import -window root root.jpg En el primer caso uno da el comando en un terminal y queda esperando hasta que uno toque alguna de las ventanas, la cual es guardada en este caso en un archivo figure.eps en formato PostScript. La extensin le indica al programa qu formato usar para almacenar la imagen. o e En el segundo caso uno captura la pantalla completa en un archivo root.jpeg. Este comando puede ser dado desde la consola de texto para capturar la imagen completa en la pantalla grfica. a 5.5. Creando imgenes. a Para imgenes art a isticas sin duda la alternativa es gimp, todo le que se dijo respecto a sus posibilidades para modificar imgenes se aplica tambin en el caso de crearlas. En el caso a e de necesitar imgenes ms bien tcnicas como esquemas o diagramas o una ilustracin para a a e o aclarar un problema las alternativas pueden ser xfig, sodipodi o sketch todas herramientas vectoriales muy poderosa. Este tipo de programas son manejados por medio de mens y u permiten dibujar y manipular objetos interactivamente. Las imgenes pueden ser salvadas, a en formato propios y posteriormente editadas. La gran ventaja de estos programas es que trabaja con objetos y no con bitmaps. Adems, puede exportar las imgenes a otros formatos: a a PostScript o Encapsulated PostScript o bien gif o jpeg. Habitualmente los dibujos necesarios para ilustrar problemas en F isica en tareas, pruebas y apuntes son realizados con software de este tipo, principalmente xfig, luego exportados A a PostScript e inclu idos en los respectivos archivos L TEX. Tambin existe una herramienta e extremadamente util que permite convertir un archivo PostScript, generado de cualquier manera, a un archivo fig que puede ser editado y modificado. Esta aplicacin que transforma o se llama pstoedit y puede llegar a ser realmente prctica. Otra herramienta interesante es a autotrace que permite pasar una figura en bitmap a forma vectorial. Una aparente limitacin de este tipo de software es que se podr pensar que no podemos o ia incluir curvas anal iticas, es decir, si necesitamos ilustrar una funcin gaussiana no podemos o pretender "dibujarla" con las herramientas de que disponen. Sin embargo, este problema puede ser resuelto ya que software que grafica funciones anal iticas, tales como gnuplot, 150 CAP ITULO 5. GRAFICA. permite exportar en formato que entienden los programas vectoriales (fig, por ejemplo) luego podemos leer el archivo y editarlo. Adems, xfig permite importar e incluir imgenes a a del tipo bitmap, agregando riqueza a los diagramas que puede generar. Una caracter istica importante de este tipo de programas es que trabajen por capas, las cuales son tratadas independientemente, uno puede poner un objeto sobre otro o por debajo de otro logrando diferentes efectos. Algunos programas de presentacin grficos basados en o a A X y pdf estn utilizando esta capacidad en xfig para lograr animaciones de imgenes. L TE a a Finalmente el programa xfig permite construir una biblioteca de objetos reutilizables ahorrando mucho trabajo. Por ejemplo, si uno dibuja los elementos de un circuito elctrico y e los almacena en el lugar de las bibliotecas de imgenes podr incluir estos objetos en futuros a a trabajos. El programa viene con varias bibliotecas de objetos listas para usar. 5.6. Graficando funciones y datos. Existen varias aplicaciones que permiten graficar datos de un archivo, entre las ms popua lares estn: gnuplot, xmgrace y SciGraphica. La primera est basada en la l a a inea de comando y permite grficos en 2 y 3 dimensiones, pudiendo adems, graficar funciones directamente a a sin pasar por un archivo de datos. Las otras dos son aplicaciones basadas en mens que u permiten un resultado final de mucha calidad y con mltiples variantes. La debilidad en el u caso de xmgrace es que slo hace grficos bidimensionales. o a El programa gnuplot se invoca de la l inea de comando y da un prompt en el mismo terminal desde el cual se puede trabajar, veamos una sesin de gnuplot: o jrogan@huelen:~$ gnuplot G N U P L O T Version 3.7 patchlevel 2 last modified Sat Jan 19 15:23:37 GMT 2002 System: Linux 2.4.19 Copyright(C) 1986 - 1993, 1998 - 2002 Thomas Williams, Colin Kelley and many others Type `help` to access the on-line reference manual The gnuplot FAQ is available from http://www.gnuplot.info/gnuplot-faq.html Send comments and requests for help to <info-gnuplot@dartmouth.edu> Send bugs, suggestions and mods to <bug-gnuplot@dartmouth.edu> Terminal gnuplot> gnuplot> gnuplot> type set to 'x11' plot sqrt(x) set xrange[0:5] set xlabel" eje de las x" 5.7. GRAFICANDO DESDE NUESTROS PROGRAMAS. 151 gnuplot> replot gnuplot> set terminal postscript Terminal type set to 'postscript' Options are 'landscape noenhanced monochrome dashed defaultplex "Helvetica" 14' gnuplot> set output "mygraph.ps" gnuplot> replot gnuplot> set terminal X Terminal type set to 'X11' Options are '0' gnuplot> set xrange[-2:2] gnuplot> set yrange[-2:2] gnuplot> splot exp(-x*x-y*y) gnuplot> plot "myfile.dat" w l gnuplot> exit jrogan@huelen:~$ En el caso de xmgrace y SciGraphica mucho ms directo manejarlo ya que est baa a sado en mens. Adems, existe abundante documentacin de ambos softwares. El software u a o SciGraphica es una aplicacin de visualizacin y anlisis de data cient o o a ifica que permite el despliegue de grficos en 2 y 3 dimensiones, adems, exporta los resultados a formato a a PostScript. Realmente esta aplicacin naci como un intento de clonar el programa comercial o o origen no disponible para Linux. 5.7. Graficando desde nuestros programas. Finalmente para poder graficar desde nuestro propio programa necesitamos alguna biblioteca grfica, en nuestro caso usaremos la biblioteca iglu, hecha completamente en casa. La a pgina de iglu est en : http://aristoteles.ciencias.uchile.cl/homepage/iglu/iglu.html a a El comando de compilacin incluido en un script, que llamaremos iglu_compila, y que cono tiene las siguientes l ineas: #!/bin/bash g++ -Wall -O3 -o $1 $1.cc -I. -I$HOME/iglu/ \ -L/usr/X11R6/lib/ -L$HOME/iglu/ -liglu -lX11 -lm Veamos algunos ejemplos: /* Ejemplo: sen(x) */ #include ``iglu.h'' #include <cmath> int main() { IgluDibujo v(``Funcion Seno''); const int N=100; double x[N], y[N]; 152 v.map_coordinates(0,2*M_PI,-1.2,1.2); double dx = 2*M_PI/(N-1); for (int i=0;i<N;i++){ x[i] = i*dx; y[i] = sin(x[i]); } v.plot_line(x,y,N); v.wait(); return 0; } CAP ITULO 5. GRAFICA. Este programa grafica la funcin seno con un nmero de puntos dado. o u Otro caso, una primitiva animacin o // Ejemplo sen(x-vt) #include "iglu.h" #include <cmath> int main(){ IgluDibujo v(``Pelicula''); const int N=100, Nt=100; double x[N], y[N]; v.map_coordinates(0,2*M_PI,-1.2,1.2); double dx = 2*M_PI/(N-1), dt = 1, t=0; for (int j=0;j<Nt;j++){ v.clean(); t += dt; for (int i=0;i<N;i++){ x[i] = i*dx; y[i] = sin(x[i]-.1*t); } v.plot_line(x,y,N); v.wait(.03); v.flush(); } v.wait(); return 0; } Cap itulo 6 El sistema de preparacin de o documentos TEX . versin 5.0, 30 de Julio del 2003 o 6.1. Introduccin. o TEX es un procesador de texto o, mejor dicho, un avanzado sistema de preparacin de o documentos, creado por Donald Knuth, que permite el dise~o de documentos de gran calin dad, conteniendo textos y frmulas matemticas. A~os despus, L TEX fue desarrollado por o a n e A Leslie Lamport, facilitando la preparacin de documentos en TEX, gracias a la definicin de o o "macros" o conjuntos de comandos de fcil uso. a A A L TEX tuvo diversas versiones hasta la 2.09. Actualmente, L TEX ha recibido importantes A modificaciones, siendo la distribucin actualmente en uso y desarrollo L TEX 2 , una versin o o A A transitoria en espera de que algn d se llegue a la nueva versin definitiva de L TEX, L TEX3. u ia o A A En estas pginas cuando digamos L TEX nos referiremos a la versin actual, L TEX 2 . Cuana o do queramos hacer referencia a la versin anterior, que deber quedar progresivamente en o ia A desuso, diremos expl icitamente L TEX 2.09. 6.2. Archivos. A El proceso de preparacin de un documento L TEX consta de tres pasos: o 1. Creacin de un archivo con extensin tex con algn editor. o o u 2. Compilacin o del archivo tex, con un comando del tipo latex <archivo>.tex o latex <archivo>. Esto da por resultado tres archivos adicionales, con el mismo nombre del archivo original, pero con extensiones distintas: a) dvi. Es el archivo procesado que podemos ver en pantalla o imprimir. Una vez compilado, este archivo puede ser enviado a otro computador, para imprimir en otra impresora, o verlo en otro monitor, independiente de la mquina (de donde a su extensin dvi, device independent). o 153 154 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . b) log. Aqu se encuentran todos los mensajes producto de la compilacin, para i o consulta si es necesario (errores encontrados, memoria utilizada, mensajes de advertencia, etc.). c) aux. Contiene informacin adicional que, por el momento, no nos interesa. o 3. Visin en pantalla e impresin del archivo procesado a travs de un programa anexo o o e (xdvi o dvips, por ejemplo), capaz de leer el dvi. 6.3. 6.3.1. Input bsico. a Estructura de un archivo. En un archivo no pueden faltar las siguientes l ineas: \documentclass[12pt]{article} \begin{document} \end{document} Haremos algunas precisiones respecto a la primera l inea ms tarde. Lo importante es que a una l inea de esta forma debe ser la primera de nuestro archivo. Todo lo que se encuentra antes de \begin{document} se denomina prembulo. El texto que queramos escribir va entre a \begin{document} y \end{document}. Todo lo que se encuentre despus de \end{document} e es ignorado. 6.3.2. Caracteres. Pueden aparecer en nuestro texto todos los caracteres del cdigo ASCII no extendido o (teclado ingls usual): letras, nmeros y los signos de puntuacin: e u o . : ; , ? ! ` ' ( ) [ ] / * @ Los caracteres especiales: # $ % & ~ _ ^ \ { } A tienen un significado espec ifico para L TEX. Algunos de ellos se pueden obtener anteponindoe les un backslash: # \# $ \$ % \% & \& { \{ } \} Los caracteres + = | < > 6.3. INPUT BASICO. 155 generalmente aparecen en frmulas matemticas, aunque pueden aparecer en texto normal. o a Finalmente, las comillas dobles (") casi nunca se usan. A Los espacios en blanco y el fin de l inea son tambin caracteres (invisibles), que L TEX e considera como un mismo carcter, que llamaremos espacio, y que simbolizaremos ocasionala mente como . Para escribir en castellano requeriremos adems algunos signos y caracteres especiales: a n ~ \~n a \'a i \'{\i} u \"u !` ?` 6.3.3. Comandos. Todos los comandos comienzan con un backslash, y se extienden hasta encontrar el primer carcter que no sea una letra (es decir, un espacio, un nmero, un signo de puntuacin o a u o matemtico, etc.). a 6.3.4. Algunos conceptos de estilo. A L TEX es consciente de muchas convenciones estil isticas que quizs no apreciamos cuando a leemos textos bien dise~ados, pero las cuales es bueno conocer para aprovecharlas. n a) Observemos la siguiente palabra: fino. Esta palabra fue generada escribiendo simplemente fino, pero observemos que las letras `f' e `i' no estn separadas, sino que unidas a art isticamente. Esto es una ligadura, y es considerada una prctica estticamente prea e A X sabe esto e inserta este peque~ o efecto tipogrfico sin que nos demos ferible. L TE n a cuenta. b) Las comillas de apertura y de cierre son distintas. Por ejemplo: `insigne' (comillas simples) o "insigne" (comillas dobles). Las comillas de apertura se hacen con uno o con dos acentos graves (`), para comillas simples o dobles, respectivamente, y las de cierre con acentos agudos ('): `insigne', ``insigne''. No es correcto entonces utilizar las comillas dobles del teclado e intentar escribir "insigne" (el resultado de esto es el poco esttico "insigne"). e c) Existen tres tipos de guiones: Corto (entre palabras, corte en s ilabas al final de la l inea) Medio pginas 12 a -(rango de nmeros) u Largo un ejemplo --como ste --- (puntuacin, parntesis) e o e A d) L TEX inserta despus de un punto seguido un peque~o espacio adicional respecto al e n espacio normal entre palabras, para separar sutilmente frases. Pero, cmo saber que o un punto termina una frase? El criterio que utiliza es que todo punto termina una frase cuando va precedido de una minscula. Esto es cierto en la mayor de los casos, u ia as como es cierto que generalmente cuando un punto viene despus de una mayscula i e u no hay fin de frase: Saint-Exupry e 156 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . China y U.R.S.S. estuvieron de acuerdo. Sin embargo. . . Pero hay excepciones: En la pg. 11 encontraremos noticias desde la U.R.S.S. Estas fueron entregaa das. . . Cuando estas excepciones se producen, nosotros, humanos, tenemos que ayudarle al computador, dicindole que, aunque hay un punto despus de la "g", no hay un fin de e e frase, y que el punto despus de la ultima "S" s termina frase. Esto se consigue as e i i: En la p\'ag.\ 11 encontraremos noticias desde la U.R.S.S\@. \'Estas fueron entregadas... d) Enfasis de texto: Este es un texto enfatizado. \'Este es un texto {\em enfatizado}. Otro texto \emph{enfatizado}. Otro texto enfatizado. Al enfatizar, pasamos temporalmente a un tipo de letra distinto, la itlica. Esta letra es a ligeramente inclinada hacia adelante, lo cual puede afectar el correcto espaciado entre palabras. Comparemos, por ejemplo: Quiero hoy mi recompensa. Quiero hoy mi recompensa. Quiero hoy mi recompensa. Quiero {\em hoy} mi recompensa. Quiero {\em hoy\/} mi recompensa. Quiero \emph{hoy} mi recompensa. La segunda y tercera frase tienen un peque~o espacio adicional despus de "hoy", n e para compensar el espacio entre palabras perdido por la inclinacin de la itlica. Este o a peque~o espacio se denomina correccin itlica, y se consigue usando \emph, o, si se n o a usa \em, agregando \/ antes de cerrar el parntesis cursivo. La correccin itlica es e o a A innecesaria cuando despus del texto enfatizado viene un punto o una coma. L TEX e advierte esto y omite el espacio adicional aunque uno lo haya sugerido. 6.3.5. Notas a pie de pgina. a Insertemos una nota a pie de p\'agina.\footnote{Como \'esta.} A L TEX colocar una nota a pie de pgina1 en el lugar apropiado. a a 1 Como sta. e 6.3. INPUT BASICO. 157 6.3.6. Frmulas matemticas. o a A L TEX distingue dos modos de escritura: un modo de texto, en el cual se escriben los textos usuales como los ya mencionados, y un modo matemtico, dentro del cual se escriben a las frmulas. Cualquier frmula debe ser escrita dentro de un modo matemtico, y si algn o o a u s imbolo matemtico aparece fuera del modo matemtico el compilador acusar un error. a a a Hay tres formas principales para acceder al modo matemtico: a a) $x+y=3$ b) $$xy=8$$ c) \begin{equation} x/y=5 \end{equation} Estas tres opciones generan, respectivamente, una ecuacin en el texto: x + y = 3, una o ecuacin separada del texto, centrada en la pgina: o a xy = 8 y una ecuacin separada del texto, numerada: o x/y = 5 (6.1) Es importante notar que al referirnos a una variable matemtica en el texto debemos a escribirla en modo matemtico: a Decir que la incgnita es x es o incorrecto. No: la incgnita es o x. Decir que la inc{\'o}gnita es x es incorrecto. No: la inc{\'o}gnita es $x$. 6.3.7. Comentarios. Uno puede hacer que el compilador ignore parte del archivo usando %. Todo el texto desde este carcter hasta el fin de la l a inea correspondiente ser ignorado (incluyendo el fin de l a inea). Un peque~o comentario. n Un peque{\~n}o co% mentario. Texto ignorado 6.3.8. Estilo del documento. Las caracter isticas generales del documento estn definidas en el prembulo. Lo ms a a a importante es la eleccin del estilo, que determina una serie de parmetros que al usuario o a normal pueden no importarle, pero que son bsicas para una correcta presentacin del texto: a o Qu mrgenes dejar en la pgina? Cunto dejar de sangr Tipo de letra? Distancia e a a a ia? entre l ineas? Dnde poner los nmeros de pgina? Y un largo etctera. o u a e Todas estas decisiones se encuentran en un archivo de estilo (extensin cls). Los archivos o standard son: article, report, book y letter, cada uno adecuado para escribir art iculos cortos (sin cap itulos) o ms largos (con cap a itulos), libros y cartas, respectivamente. 158 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . La eleccin del estilo global se hace en la primera l o inea del archivo:2 \documentclass{article} Esta l inea ser aceptada por el compilador, pero nos entregar un documento con un a a tama~o de letra peque~o, tcnicamente llamado de 10 puntos 10pt (1pt = 1/72 pulgadas). n n e o Existen tres tama~os de letra disponibles: 10, 11 y 12 pt. Si queremos un tama~o de letra n n ms grande, como el que tenemos en este documento, se lo debemos indicar en la primera a l inea del archivo: \documentclass[12pt]{article} Todas las decisiones de estilo contenidas dentro del archivo cls son modificables, existiendo tres modos de hacerlo: a) Modificando el archivo cls directamente. Esto es poco recomendable, porque dicha modificacin (por ejemplo, un cambio de los mrgenes) se har extensible a todos los o a ia archivos compilados en nuestro computador, y esto puede no ser agradable, ya sea que nosotros seamos los unicos usuarios o debamos compartirlo. Por supuesto, podemos deshacer los cambios cuando terminemos de trabajar, pero esto es tedioso. b) Introduciendo comandos adecuados en el prembulo. Esta es la opcin ms recomena o a dable y la ms usada. Nos permite dominar decisiones espec a ificas de estilo vlidas slo a o para el archivo que nos interesa. c) Creando un nuevo archivo cls. Esto es muy recomendable cuando las modificaciones de estilo son abundantes, profundas y deseen ser reaprovechadas. Se requiere un poco de A experiencia en L TEX para hacerlo, pero a veces puede ser la unica solucin razonable. o En todo caso, la opcin a usar en la gran mayor de los casos es la b) (Sec. 6.9). o ia 6.3.9. Argumentos de comandos. Hemos visto ya algunos comandos que requieren argumentos. Por ejemplo: \begin{equation}, \documentclass[12pt]{article}, \footnote{Nota}. Existen dos tipos de argumentos: 1. Argumentos obligatorios. Van encerrados en parntesis cursivos: \footnote{Nota}, e por ejemplo. Es obligatorio que despus de estos comandos aparezcan los parntesis. A e e veces es posible dejar el interior de los parntesis vac pero en otros casos el compilador e io, reclamar incluso eso (\footnote{} no genera problemas, pero \documentclass{} s es a i un gran problema). A Una propiedad muy general de los comandos de L TEX es que las llaves de los argumentos obligatorios se pueden omitir cuando dichos argumentos tienen slo un carcter. Por o a ejemplo, \~n es equivalente a \~{n}. Esto permite escribir ms fcilmente muchas a a expresiones, particularmente matemticas, como veremos ms adelante. a a A En L TEX 2.09 esta primera l inea debe ser \documentstyle[12pt]article, y el archivo de estilo tiene A extensin sty. Intentar compilar con L TEX 2.09 un archivo que comienza con \documentclass da un error. o A Por el contrario, la compilacin con L TEX 2 de un archivo que comienza con \documentstyle no genera un o A A error, y L TEX entra en un modo de compatibilidad . Sin embargo, interesantes novedades de L TEX 2 respecto A a L TEX 2.09 se pierden. 2 6.3. INPUT BASICO. 159 2. Argumentos opcionales. Van encerrados en parntesis cuadrados. Estos argumentos e son omitibles, \documentclass[12pt]... . Ya dijimos que \documentclass{article} es aceptable, y que genera un tama~o de letra de 10pt. Un argumento en parntesis n e cuadrados es una opcin que modifica la decisin default del compilador (en este caso, o o lo obliga a usar 12pt en vez de sus instintivos 10pt). 6.3.10. T itulo. Un t itulo se genera con: \title{Una breve introducci\'on} \author{V\'{\i}ctor Mu\~noz} \date{30 de Junio de 1998} \maketitle \title, \author y \date pueden ir en cualquier parte (incluyendo el prembulo) ana tes de \maketitle. \maketitle debe estar despus de \begin{document}. Dependiendo de e nuestras necesidades, tenemos las siguientes alternativas: a) Sin t itulo: \title{} b) Sin autor: \author{} c) Sin fecha: \date{} d) Fecha actual (en ingls): omitir \date. e e) Ms de un autor: a \author{Autor_1 \and Autor_2 \and Autor_3} A Para art iculos cortos, L TEX coloca el t itulo en la parte superior de la primera pgina a del texto. Para art iculos largos, en una pgina separada. a 160 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . 6.3.11. Secciones. Los t itulos de las distintas secciones y subsecciones de un documento (numerados adecuadamente, en negrita, como en este texto) se generan con comandos de la forma: \section{Una secci\'on} \subsection{Una subsecci\'on} Los comandos disponibles son (en orden decreciente de importancia): \part \chapter \section \subsection \subsubsection \paragraph \subparagraph Los ms a usados son \chapter, \section, \subsection \subsubsection. \chapter slo est disponible en los estilos report y book. o a y 6.3.12. Listas. Los dos modos usuales de generar listas: a) Listas numeradas (ambiente enumerate): \begin{enumerate} \item Nivel 1, \'{\i}tem \item Nivel 1, \'{\i}tem \begin{enumerate} \item Nivel 2, \'{\i}tem \begin{enumerate} \item Nivel 3, \'{\i}tem \end{enumerate} \end{enumerate} \item Nivel 1, \'{\i}tem \end{enumerate} 1. Nivel 1, item 1. 2. Nivel 1, item 2. a) Nivel 2, item 1. 1) Nivel 3, item 1. 3. Nivel 1, item 3. 1. 2. 1. 1. 3. b) Listas no numeradas (ambiente itemize): Nivel 1, item 1. Nivel 1, item 2. Nivel 2, item 1. Nivel 3, item 1. Nivel 1, item 3. \begin{itemize} \item Nivel 1, {\'\i}tem \item Nivel 1, {\'\i}tem \begin{itemize} \item Nivel 2, {\'\i}tem \begin{itemize} \item Nivel 3, {\'\i}tem \end{itemize} \end{itemize} \item Nivel 1, {\'\i}tem \end{itemize} 1. 2. 1. 1. 3. 6.3. INPUT BASICO. 161 Es posible anidar hasta tres niveles de listas. Cada uno usa tipos distintos de rtulos, o segn el ambiente usado: nmeros arbes, letras y nmeros romanos para enumerate, y u u a u puntos, guiones y asteriscos para itemize. Los rtulos son generados automticamente por o a cada \item, pero es posible modificarlos agregando un parmetro opcional: a a) Nivel 1, item 1. b) Nivel 1, item 2. \begin{enumerate} \item[a)] Nivel 1, \'{\i}tem 1. \item[b)] Nivel 1, \'{\i}tem 2. \end{enumerate} \item es lo primero que debe aparecer despus de un \begin{enumerate} o \begin{itemize}. e 6.3.13. Fonts. Tipos de letras. A Los fonts disponibles por default en L TEX son: roman boldface sans serif italic slanted Small Caps typewriter Los siguientes modos de cambiar fonts son equivalentes: texto texto texto texto texto Texto texto {\rm {\bf {\sf {\it {\sl {\sc {\tt texto} texto} texto} texto} texto} Texto} texto} \textrm{texto} \textbf{texto} \textsf{texto} \textit{texto} \textsl{texto} \textsc{texto} \texttt{texto} \rm es el default para texto normal; \it es el default para texto enfatizado; \bf es el default para t itulos de cap itulos, secciones, subsecciones, etc. \textrm, \textbf, etc., slo permiten cambiar porciones definidas del texto, contenido o entre los parntesis cursivos. Con \rm, \bf, etc. podemos, omitiendo los parntesis, cambiar e e el font en todo el texto posterior: Un cambio local de fonts y uno global, interminable e infinito. . . Un cambio {\sf local} de fonts \sl y uno global, interminable e infinito... Tambin es posible tener combinaciones de estos fonts, por ejemplo, bold italic, pero no e sirven los comandos anteriores, sino versiones modificadas de \rm, \bf, etc.: \rmfamily \sffamily \ttfamily \mdseries 162 \bfseries \upshape \itshape \slshape \scshape CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Por ejemplo: texto texto Texto texto texto {\bfseries\itshape texto} {\bfseries\upshape texto} (= {\bf texto}) {\ttfamily\scshape texto} {\sffamily\bfseries texto} {\sffamily\mdseries texto} (= {\sf texto}) Para entender el uso de estos comandos hay que considerar que un font tiene tres atributos: family (que distingue entre rm, sf y tt), series (que distingue entre md y bf), y shape (que distingue entre up, it, sl y sc). Cada uno de los comandos \rmfamily, \bfseries, etc., cambia slo uno de estos atributos. Ello permite tener versiones mixtas de los fonts, como o un slanted sans serif, imposible de obtener usando los comandos \sl y \sf. Los defaults para el texto usual son: \rmfamily, \mdseries y \upshape. Tama~ o. n Los tama~os de letras disponibles son: n texto \tiny \scriptsize \footnotesize \small texto \normalsize \large \Large texto \LARGE \huge \Huge texto texto texto texto texto texto texto Se usan igual que los comandos de cambio de font \rm, \sf, etc., de la seccin 6.3.13. o \normalsize es el default para texto normal; \scriptsize para sub o supra indices; \footnotesize para notas a pie de pgina. a 6.3.14. Acentos y s imbolos. A L TEX provee diversos tipos de acentos, que se muestran en la Tabla 6.1 (como ejemplo consideramos la letra "o", pero cualquiera es posible, por supuesto). (Hemos usado ac el a hecho de que cuando el argumento de un comando consta de un carcter, las llaves son a omitibles.) Otros s imbolos especiales y caracteres no ingleses disponibles se encuentran en la Tabla 6.2. 6.3. INPUT BASICO. o o ` o ^ o \'o \`o \^o \"o o ~ o o o \~o \=o \. o \u o o o oo o \v o \H o \t{oo} \r o o \c o o \d o . o \b o 163 Cuadro 6.1: Acentos. c a \dag \ddag \S \P \copyright \textcircled a \textvisiblespace \pounds oe OE a A \oe \OE \ae \AE \aa \AA \o \O l L SS \l \L \ss \SS ?` !` Cuadro 6.2: S imbolos especiales y caracteres no ingleses. 6.3.15. Escritura de textos en castellano. A L TEX emplea slo los caracteres ASCII bsicos, que no contienen s o a imbolos castellanos como , , n, etc. Ya hemos visto que existen comandos que permiten imprimir estos caracteres, ~ y por tanto es posible escribir cualquier texto en castellano (y otros idiomas, de hecho). Sin embargo, esto no resuelve todo el problema, porque en ingls y castellano las palabras e se cortan en "s ilabas" de acuerdo a reglas distintas, y esto es relevante cuando se debe cortar el A texto en l ineas. L TEX tiene incorporados algoritmos para cortar palabras en ingls y, si se ha e A X en nuestro computador, tambin en castellano u otros hecho una instalacin especial de L TE o e A idiomas (a travs del programa babel, que es parte de la distribucin standard de L TEX 2 ). e o En un computador con babel instalado y configurado para cortar en castellano basta incluir el comando \usepackage[spanish]{babel} en el prembulo para poder escribir en castellano a cortando las palabras en s ilabas correctamente.3 A Sin embargo, ocasionalmente L TEX se encuentra con una palabra que no sabe cortar, en cuyo caso no lo intenta y permite que ella se salga del margen derecho del texto, o bien A toma decisiones no ptimas. La solucin es sugerirle a L TEX la silabacin de la palabra. Por o o o ejemplo, si la palabra conflictiva es matem\'aticas (generalmente hay problemas con las palabras acentuadas), entonces basta con reescribirla en la forma: ma\-te\-m\'a\-ti\-cas. A Con esto, le indicamos a L TEX en qu puntos es posible cortar la palabra. El comando \- no e tiene ningn otro efecto, de modo que si la palabra en cuestin no queda al final de la l u o inea, A L TEX por supuesto ignora nuestra sugerencia y no la corta. Consideremos el siguiente ejemplo: Esto resuelve tambin otro problema: los encabezados de cap e itulos o indices, por ejemplo, son escritos Indice", en vez de "Chapter" e "Index", y cuando se usa el comando \date, la fecha aparece "Cap itulo" e " en castellano. 3 164 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Podemos escribir matem\'aticas. O matem\'aticas. Podemos escribir ma\-te\-m\'a\-ti\-cas. O ma\-te\-m\'a\-ti\-cas. Podemos escribir matemtia cas. O matemticas. a Podemos escribir matemtia cas. O matemticas. a A En el primer caso, L TEX decidi por s mismo dnde cortar "matemticas". Como es una o i o a palabra acentuada tuvo problemas y no lo hizo muy bien, pues qued demasiado espacio o A entre palabras en esa l inea. En el segundo prrafo le sugerimos la silabacin y L TEX pudo a o tomar una decisin ms satisfactoria. En el mismo prrafo, la segunda palabra "matemticas" o a a a tambin tiene sugerencias de corte, pero como no qued al final de l e o inea no fueron tomadas en cuenta. 6.4. Frmulas matemticas. o a Hemos mencionado tres formas de ingresar al modo matemtico: $...$ (frmulas dentro a o del texto), $$...$$ (frmulas separadas del texto, no numeradas) y \begin{equation} ... o \end{equation} (frmulas separadas del texto, numeradas). Los comandos que revisaremos o en esta seccin slo pueden aparecer dentro del modo matemtico. o o a 6.4.1. x2y x2y Sub y supra indices. x^{2y} x_{2y} xy x y1 2 x^{y^{2}} ( x^{y^2}) o x^{y_{1}} ( x^{y_1}) o xy 1 x^y_1 ( x_1^y) o \textsuperscript permite obtener supra indices fuera del modo matemtico: a La 3a es la vencida. La 3\textsuperscript{a} es la vencida. 6.4.2. Fracciones. a) Horizontales n/2 n/2 b) Verticales 1 2 x= y + z/2 y2 + 1 x+y y 1 + z+1 \frac{1}{2}, \frac 1{2}, \frac{1}2 \frac 12 o x = \frac{y + z/2}{y^2+1} \frac{x+y}{1 + \frac y{z+1}} 6.4. FORMULAS MATEMATICAS. 165 La forma a) es ms adecuada y la preferida para fracciones dentro del texto, y la sea 1 gunda para frmulas separadas. \frac puede aparecer en frmulas dentro del texto ( 2 con o o $\frac 12$), pero esto es inusual y poco recomendable estticamente, salvo estricta necesie dad. 6.4.3. Ra ices. n \sqrt{n} o \sqrt n a2 + b2 n 2 \sqrt{a^2 + b^2} \sqrt[n]{2} 6.4.4. a) Puntos suspensivos. ... \ldots Para frmulas como o a1 a2 . . . an b) \cdots a_1 a_2 \ldots a_n Entre s imbolos como +, -, = : x1 + + xn c) . . . \vdots x1 . . . xn d) ... \ddots Inn = 1 0 0 0 1 0 . ... . . . . . 0 0 ... 1 x_1 + \cdots + x_n \ldots puede ser usado tambin en el texto usual: e Arturo quiso salir. . . pero se detuvo. Arturo quiso salir\ldots pero se detuvo. No corresponde usar tres puntos seguidos (...), pues el espaciado entre puntos es incorrecto. 166 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Minsculas u \alpha \beta \gamma \delta \epsilon \varepsilon \zeta \eta \theta \vartheta \iota \kappa \lambda \mu \nu \xi o o \pi \varpi \rho \varrho \sigma \varsigma \tau \upsilon \phi \varphi \chi \psi \omega Maysculas u \Gamma \Delta \Theta \Lambda \Xi \Pi \Sigma \Upsilon \Phi \Psi \Omega Cuadro 6.3: Letras griegas. 6.4.5. Letras griegas. Las letras griegas se obtienen simplemente escribiendo el nombre de dicha letra (en ingls): e \gamma. Para la mayscula correspondiente se escribe la primera letra con mayscula: \Gamma. u u 4 La lista completa se encuentra en la Tabla 6.3. No existen s imbolos para , , , etc. maysculas, pues corresponden a letras romanas u (A, B, E, etc.). 6.4.6. Letras caligrficas. a Letras caligrficas maysculas A, B, . . . , Z se obtienen con \cal. \cal se usa igual que a u los otros comandos de cambio de font (\rm, \it, etc.). Sea F una funcin con o F(x) > 0. Sea $\cal F$ una funci\'on con ${\cal F}(x) > 0$. No son necesarios los parntesis cursivos la primera vez que se usan en este ejemplo, e porque el efecto de \cal est delimitado por los $. a 6.4.7. S imbolos matemticos. a A L TEX proporciona una gran variedad de s imbolos matemticos (Tablas 6.4, 6.5, 6.6, 6.7). a La negacin de cualquier s o imbolo matemtico se obtiene con \not: a x<y aM 4 x \not < y a \not \in {\cal M} Un ejemplo del uso de variantes de letras griegas, en el idioma griego se usa dentro de una palabra y se usa al finalizar una palabra. El nombre Felipe en griego, es Felips, y se escribe de la forma: o. El o nombre Jos, ser algo como Josu en griego: Io o la palabra F e ia e isica: 6.4. FORMULAS MATEMATICAS. 167 \pm \mp \times \div \ast \star \circ \bullet \cdot \cap \cup \uplus \sqcap \sqcup \lor \land \ \setminus \wr \diamond \bigtriangleup \bigtriangledown \triangleleft \triangleright \bigcirc \dagger \ddagger \amalg \oplus \ominus \otimes \oslash \odot Cuadro 6.4: S imbolos de operaciones binarias. \leq \prec \preceq \ll \subset \subseteq \smile \frown \vdash \geq \succ \succeq \gg \supset \supseteq \sqsubseteq \in \dashv \equiv \sim \simeq \asymp \approx \cong = \sqsupseteq \ni |= \models \perp | \mid \parallel \bowtie = \neq . = \doteq \propto Cuadro 6.5: S imbolos relacionales. \gets \Leftarrow \to \Rightarrow \Leftrightarrow \mapsto \hookleftarrow \leftharpoonup \leftharpoondown \rightleftharpoons - = - = - \longleftarrow \Longleftarrow \longrightarrow \Longrightarrow \Longleftrightarrow \longmapsto \hookrightarrow \rightharpoonup \rightharpoondown \uparrow \Uparrow \downarrow \Downarrow \Updownarrow \nearrow \searrow \swarrow \nwarrow Cuadro 6.6: Flechas 168 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . \aleph \hbar i \imath \jmath \ell \wp \Re \Im \prime \emptyset \nabla \surd \top \bot \| \angle \forall \exists \lnot \flat \natural \sharp \ \backslash \partial \infty \triangle \clubsuit \diamondsuit \heartsuit \spadesuit Cuadro 6.7: S imbolos varios. \sum \prod \coprod \int \oint \bigcap \bigcup \biguplus \bigvee \bigwedge \bigsqcup \bigodot \bigotimes \bigoplus Cuadro 6.8: S imbolos de tama~o variable. n [Notemos, s en la Tabla 6.5, que existe el s i, imbolo = (\neq).] Algunos s imbolos tienen tama~o variable, segn aparezcan en el texto o en frmulas n u o separadas del texto. Se muestran en la Tabla 6.8. Estos s imbolos pueden tener indices que se escriben como sub o supra indices. Nuevamente, la ubicacin de estos o indices depende de si la frmula est dentro del texto o separada de l: o a e n 1 xi = i=1 n i=1 xi 0 f = 1 0 f $$\sum_{i=1}^n x_i = \int_0^1 f $$ $\sum_{i=1}^n x_i = \int_0^1 f $ 6.4.8. Funciones tipo logaritmo. Observemos la diferencia entre estas dos expresiones: x = logy x = log y $x $x = log y$ = \log y$ A En el primer caso L TEX escribe el producto de cuatro cantidades, l, o, g e y. En el segundo, representa correctamente nuestro deseo: el logaritmo de y. Todos los comandos de la Tabla 6.9 generan el nombre de la funcin correspondiente, en letras romanas. o Algunas de estas funciones pueden tener indices: n l xn = 0 im $$\lim_{n\to\infty} x_n = 0 $$ 6.4. FORMULAS MATEMATICAS. \arccos \arcsin \arctan \arg \cos \cosh \cot \coth \csc \deg \det \dim \exp \gcd \hom \inf \ker \lg \lim \liminf \limsup \ln \log \max \min \Pr \sec \sin \sinh \sup \tan \tanh 169 Cuadro 6.9: Funciones tipo logaritmo l n xn = 0 im $\lim_{n\to\infty} x_n = 0 $ 6.4.9. Matrices. Ambiente array. Se construyen con el ambiente array. Consideremos, por ejemplo: a + b + c uv 27 a+b u+v 134 a 3u + vw 2.978 La primera columna est alineada al centro (c, center); la segunda, a la izquierda (l, left); la a tercera, a la derecha (r, right). array tiene un argumento obligatorio, que consta de tantas letras como columnas tenga la matriz, letras que pueden ser c, l o r segn la alineacin u o que queramos obtener. Elementos consecutivos de la misma l inea se separan con & y l ineas consecutivas se separan con \\. As el ejemplo anterior se obtiene con: i, \begin{array}{clr} a+b+c & uv & 27 \\ a+b & u + v & 134 \\ a & 3u+vw & 2.978 \end{array} Delimitadores. Un delimitador es cualquier s imbolo que acte como un parntesis, encerrando una exu e presin, apareciendo a la izquierda y a la derecha de ella. La Tabla 6.10 muestra todos los o delimitadores posibles. Para que los delimitadores tengan el tama~o correcto para encerrar la expresin corresponn o diente hay que anteponerles \left y \right. Podemos obtener as expresiones matriciales: i a b c d \left(\begin{array}{cc} a&b\\ c&d \end{array}\right) v = \left(\begin{array}{c} 1\\ 2\\ 3 \end{array}\right) 1 v= 2 3 170 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . ( ( [ [ { \{ \lfloor \lceil \langle / / | | ) ) ] ] } \} \rfloor \rceil \rangle \ \backslash \| Cuadro 6.10: Delimitadores \uparrow \downarrow \updownarrow \Uparrow \Downarrow \Updownarrow = a11 a12 a21 a22 \Delta = \left|\begin{array}{cc} a_{11} & a_{12}\\ a_{21} & a_{22} \end{array}\right| \left y \right deben ir de a pares, pero los delimitadores no tienen por qu ser los e mismos: a b \left(\begin{array}{c} a\\ b \end{array}\right[ Tampoco es necesario que los delimitadores encierren matrices. Comparemos, por ejemplo: (A + B) = ( dF )x=a dx (\vec A + \vec B) = ( \frac{d \vec F}{dx} )_{x=a} A+B = dF dx x=a \left(\vec A + \vec B\right) = \left( \frac{d \vec F}{dx} \right)_{x=a} El segundo ejemplo es mucho ms adecuado estticamente. a e Algunas expresiones requieren slo un delimitador, a la izquierda o a la derecha. Un punto o (.) representa un delimitador invisible. Los siguientes ejemplos son t ipicos: b dx a df = f (x) dx b a \left. \int_a^b dx \frac{df}{dx} = f(x) \right |_a^b f(x) = \left\{ \begin{array}{cl} 0 & x<0 \\ 1 & x>0 \end{array} \right. f (x) = 0 x<0 1 x>0 6.4. FORMULAS MATEMATICAS. a \hat a ^ a \check a a \breve a a \acute a a \grave a ` a \tilde a ~ a \bar a a \vec a a \dot a a \ddot a 171 Cuadro 6.11: Acentos matemticos a Frmulas de ms de una l o a inea. eqnarray ofrece una manera de ingresar a modo matemtico (en reemplazo de $, $$ o a equation) equivalente a un array con argumentos {rcl}: x = a+b+c+ d+e \begin{eqnarray*} x& = & a + b + c +\\ && d + e \end{eqnarray*} El asterisco impide que aparezcan nmeros en las ecuaciones. Si deseamos que numere u cada l inea como una ecuacin independiente, basta omitir el asterisco: o x = 5 a + b = 60 (6.2) (6.3) \begin{eqnarray} x& = & 5 \\ a + b&= & 60 \end{eqnarray} Si queremos que solamente algunas l ineas aparezcan numeradas, usamos \nonumber: x = a+b+c+ d+e (6.4) \begin{eqnarray} x& = & a + b + c + \nonumber\\ && d + e \end{eqnarray} El comando \eqnarray es suficiente para necesidades sencillas, pero cuando se requiere escribir matemtica de modo intensivo sus limitaciones comienzan a ser evidentes. Al agrea gar al prembulo de nuestro documento la l a inea \usepackage{amsmath} quedan disponibles muchos comandos mucho ms utiles para textos matemticos ms serios, como el ambiente a a a equation*, \split, \multline o \intertext. En la seccin 6.8.2 se encuentra una descripo cin de estos y otros comandos. o 6.4.10. Acentos. Dentro de una frmula pueden aparecer una serie de "acentos", anlogos a los de texto o a usual (Tabla 6.11). Las letras i y j deben perder el punto cuando son acentuadas: i es incorrecto. Debe ser i. \imath y \jmath generan las versiones sin punto de estas letras: i+ ^ \vec \imath + \hat \jmath 172 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . 6.4.11. Vcr itico Texto en modo matemtico. a V_{\mbox{\scriptsize cr\'{\i}tico}} Para insertar texto dentro de modo matemtico empleamos \mbox: a Bastante ms ptimo es utilizar el comando \text, disponible a travs de amsmath (seccin a o e o 6.8.2). 6.4.12. Espaciado en modo matemtico. a TEX ignora los espacios que uno escribe en las frmulas y los determina de acuerdo a sus propios o criterios. A veces es necesario ayudarlo para hacer ajustes finos. Hay cuatro comandos que agregan peque~os espacios dentro de modo matemtico: n a \, \! espacio peque~o n espacio peque~o (negativo) n \: \; espacio medio espacio grueso Algunos ejemplos de su uso: 2x \sqrt 2 \, x en vez de n/log n n / \!\log n en vez de f dx \int f \, dx en vez de 2x n/ log n f dx El ultimo caso es quizs el ms frecuente, por cuanto la no insercin del peque~o espacio adicional a a o n entre f y dx hace aparecer el integrando como el producto de tres variables, f , d y x, que no es la idea. 6.4.13. Fonts. Anlogamente a los comandos para texto usual (Sec. 6.3.13), es posible cambiar los fonts dentro a del modo matemtico: a (A, x) (A, x) (A, B) (A, x) (A, x) (A, x) (A, x ) \mathrm{(A,x)} \mathnormal{(A,x)} \mathcal{(A,B)} \mathbf{(A,x)} \mathsf{(A,x)} \mathtt{(A,x)} \mathit{(A,x)} (Recordemos que la letras tipo \cal slo existen en maysculas.) o u Las declaraciones anteriores permiten cambiar los fonts de letras, d igitos y acentos, pero no de los otros s imbolos matemticos: a ~ A1 \mathbf{\tilde A \times 1} Como en todo ambiente matemtico, los espacios entre caracteres son ignorados: a Hola \mathrm{H o l a} Finalmente, observemos que \mathit corresponde al font itlico, en tanto que \mathnormal al a font matemtico usual, que es tambin itlico. . . o casi: a e a 6.5. TABLAS. dif f erent dif f erent different different $different$ $\mathnormal{different}$ $\mathit{different}$ \textit{different} 173 6.5. Tablas. array nos permiti construir matrices en modo matemtico. Para tablas de texto existe tabular, o a que funciona de la misma manera. Puede ser usado tanto en modo matemtico como fuera de l. a e Nombre Edad Profesin o : : : Juan Prez e 26 Estudiante \begin{tabular}{lcl} Nombre&:&Juan P\'erez\\ Edad&:&26\\ Profesi\'on&:&Estudiante \end{tabular} Si deseamos agregar l ineas verticales y horizontales para ayudar a la lectura, lo hacemos insertando | en los puntos apropiados del argumento de tabular, y \hline al final de cada l inea de la tabla: Item Vasos Botellas Platos Total Gastos $ 500 $ 1300 $ 500 $ 2300 \begin{tabular}{|l|r|}\hline Item&Gastos\\ \hline Vasos& \$ 500 \\ Botellas & \$ 1300 \\ Platos & \$ 500 \\ \hline Total& \$ 2300 \\ \hline \end{tabular} 6.6. Referencias cruzadas. Ecuaciones, secciones, cap itulos y pginas son entidades que van numeradas y a las cuales a podemos querer referirnos en el texto. Evidentemente no es ptimo escribir expl o icitamente el nmero u correspondiente, pues la insercin de una nueva ecuacin, cap o o itulo, etc., su eliminacin o cambio de o orden del texto podr alterar la numeracin, obligndonos a modificar estos nmeros dispersos en ia o a u el texto. Mucho mejor es referirse a ellos de modo simblico y dejar que TEX inserte por nosotros o los nmeros. Lo hacemos con \label y \ref. u La ecuacin de Euler o ei + 1 = 0 (6.5) La ecuaci\'on de Euler \begin{equation} \label{euler} e^{i\pi} + 1 = 0 \end{equation} re\'une los n\'umeros m\'as importantes. La ecuaci\'on (\ref{euler}) es famosa. rene los nmeros ms imporu u a tantes. La ecuacin (6.5) es fao mosa. El argumento de \label (reiterado luego en \ref) es una etiqueta simblica. Ella puede ser o cualquier secuencia de letras, d igitos o signos de puntuacin. Letras maysculas y minsculas son o u u 174 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . diferentes. As euler, eq:euler, euler_1, euler1, Euler, etc., son etiquetas vlidas y distintas. i, a Podemos usar \label dentro de equation, eqnarray y enumerate. Tambin podemos referenciar pginas con \pageref: e a Ver pgina 174 para ms dea a talles. [Texto en pg. 174] a El significado de la vida. . . Ver p\'agina \pageref{significado} para m\'as detalles. ... El significado \label{significado} de la vida... A L TEX puede dar cuenta de las referencias cruzadas gracias al archivo aux (auxiliar) generado durante la compilacin. o Al compilar por primera vez el archivo, en el archivo aux es escrita la informacin de los \label o A X lee el archivo aux e incorpora esa informacin al encontrados. Al compilar por segunda vez, L TE o dvi. (En realidad, tambin lo hizo la primera vez que se compil el archivo, pero el aux no exist e o ia entonces o no ten informacin util.) ia o Por tanto, para obtener las referencias correctas hay que compilar dos veces, una para generar el aux correcto, otra para poner la informacin en el dvi. Toda modificacin en la numeracin o o o tendr efecto slo despus de compilar dos veces ms. Por cierto, no es necesario preocuparse de a o e a estos detalles a cada momento. Seguramente compilaremos muchas veces el archivo antes de tener A la versin final. En todo caso, L TEX avisa, tras cada compilacin, si hay referencias inexistentes o o u otras que pudieron haber cambiado, y sugiere compilar de nuevo para obtener las referencias correctas. (Ver Sec. 6.14.2.) 6.7. Texto centrado o alineado a un costado. Los ambientes center, flushleft y flushright permiten forzar la ubicacin del texto respecto o a los mrgenes. L a ineas consecutivas se separan con \\: Una l inea centrada, otra y otra ms. a Ahora el texto contina u alineado a la izquierda y finalmente dos l ineas alineadas a la derecha. \begin{center} Una l\'{\i}nea centrada,\\ otra\\ y otra m\'as. \end{center} Ahora el texto contin\'ua \begin{flushleft} alineado a la izquierda \end{flushleft} y finalmente \begin{flushright} dos l\'{\i}neas\\ alineadas a la derecha. \end{flushright} 6.8. ALGUNAS HERRAMIENTAS IMPORTANTES 175 6.8. Algunas herramientas importantes A Hasta ahora hemos mencionado escencialmente comandos disponibles en L TEX standard. Sin A X, se vuelven insuficientes cuando embargo, stos, junto con el resto de los comandos bsicos de L TE e a se trata de ciertas aplicaciones demasiado espec ificas, pero no inimaginables: si queremos escribir A un texto de alta matemtica, o usar L TEX para escribir partituras, o para escribir un archivo .tex a A en un teclado croata. . . . Es posible que con los comandos usuales L TEX responda a las necesidades, pero seguramente ello ser a un costo grande de esfuerzo por parte del autor del texto. Por esta a A razn, las distribuciones modernas de L TEX incorporan una serie de extensiones que hacen la vida o un poco ms fcil a los eventuales autores. En esta seccin mencionaremos algunas extensiones muy a a o utiles. Muchas otras no estn cubiertas, y se sugiere al lector consultar la documentacin de su a o distribucin para saber qu otros paquetes se encuentran disponibles. o e A En general, las extensiones a L TEX vienen contenidas en paquetes ("packages", en ingls), en e archivos .sty. As cuando mencionemos el paquete amsmath, nos referimos a caracter i, isticas disponibles en el archivo amsmath.sty. Para que los comandos de un paquete <package>.sty estn e disponibles, deben ser cargados durante la compilacin, incluyendo en el prembulo del documento o a la l inea: \usepackage{<package>} Si se requiere cargar ms de un paquete adicional, se puede hacer de dos formas: a \usepackage{<package1>,<package2>} o \usepackage{<package1>} \usepackage{<package2>} Algunos paquetes aceptan opciones adicionales (del mismo modo que la clase article acepta la opcin 12pt): o \usepackage[option1,option2]{<package1>} Revisemos ahora algunos paquetes utiles. 6.8.1. babel Permite el procesamiento de textos en idiomas distintos del ingls. Esto significa, entre otras e cosas, que se incorporan los patrones de silabacin correctos para dicho idioma, para cortar adecuao damente las palabras al final de cada l inea. Adems, palabras claves como "Chapter", "Index", "List a of Figures", etc., y la fecha dada por \date, son cambiadas a sus equivalentes en el idioma escogido. A La variedad de idiomas disponibles es enorme, pero cada instalacin de L TEX tiene slo algunos de o o ellos incorporados. (Esta es una decisin que toma el administrador del sistema, de acuerdo a las o necesidades de los usuarios. Una configuracin usual puede ser habilitar la compilacin en ingls, o o e castellano, alemn y francs.) a e Ya sabemos como usar babel para escribir en castellano: basta incluir en el prembulo la l a inea \usepackage[spanish]{babel} 176 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . A AMS-LTEX 6.8.2. El paquete amsmath permite agregar comandos para escritura de textos matemticos profea sionales, desarrollados originalmente por la American Mathematical Society. Si un texto contiene abundante matemtica, entonces seguramente incluir la l a inea correspondiente en el prembulo: a \usepackage{amsmath} aliviar mucho la tarea. He aqu algunas de las caracter a i isticas adicionales disponibles con AMSA L TEX. Ambientes para ecuaciones Con equation* generamos una ecuacin separada del texto, no numerada: o x = 2y - 3 \begin{equation*} x = 2y - 3 \end{equation*} multline permite dividir una ecuacin muy larga en varias l o ineas, de modo que la primera l inea quede alineada con el margen izquierdo, y la ultima con el margen derecho: 15 = 1 + 2 + 3 + 4 + 5+ i=1 6 + 7 + 8 + 9 + 10+ 11 + 12 + 13 + 14 + 15 (6.6) \begin{multline} \sum_{i=1}^{15} = 1 +2+3+4+5+\\ 6+7+8+9+10+\\ 11+12+13+14+15 \end{multline} align permite reunir un grupo de ecuaciones consecutivas alinendolas (usando &, igual que la a alineacin vertical de tabular y array). gather hace lo mismo, pero centrando cada ecuacin en o o la pgina independientemente. a a1 = b1 + c1 a2 = b2 + c2 - d2 + e2 (6.7) (6.8) \begin{align} a_1 &= b_1 + c_1 \\ a_2 &= b_2 + c_2 - d_2 + e_2 \end{align} \begin{gather} a_1 = b_1 + c_1 \\ a_2 = b_2 + c_2 - d_2 + e_2 \end{gather} a1 = b1 + c1 a2 = b2 + c2 - d2 + e2 (6.9) (6.10) Con multline*, align* y gather* se obtienen los mismos resultados, pero con ecuaciones no numeradas. split permite escribir una sola ecuacin separada en l o ineas (como multline), pero permite alinear las l ineas con & (como align). split debe ser usado dentro de un ambiente como equation, align o gather (o sus equivalentes con asterisco): 6.8. ALGUNAS HERRAMIENTAS IMPORTANTES 177 a1 = b1 + c1 = b2 + c2 - d2 + e2 (6.11) \begin{equation} \begin{split} a_1& = b_1 + c_1 \\ & = b_2 + c_2 - d_2 + e_2 \end{split} \end{equation} Espacio horizontal \quad y \qquad insertan espacio horizontal en ecuaciones: x>y , xz , x A z B \begin{gather*} x > y \ , \quad \forall\, x \in A \\ x \leq z \ , \qquad \forall\, z \in B \end{gather*} Texto en ecuaciones Para agregar texto a una ecuacin, usamos \text: o x = 2n - 1 , con n entero \begin{equation*} x = 2^n - 1 \ , \quad \text{con $n$ entero} \end{equation*} \text se comporta como un buen objeto matemtico, y por tanto se pueden agregar sub a indices textuales ms fcilmente que con \mbox (ver seccin 6.4.11): a a o Vcr itico $V_{\text{cr\'{\i}tico}}$ Referencia a ecuaciones \eqref es equivalente a \ref, salvo que agrega los parntesis automticamente: e a La ecuacin (6.5) era la de Euo ler. La ecuaci\'on \eqref{euler} era la de Euler. Ecuaciones con casos Esta es una construccin usual en matemticas: o a f(x)= \begin{cases} 1&\text{si $x<0$} \\ 0&\text{si $x>0$} \end{cases} f (x) = 1 si x < 0 0 si x > 0 Notar cmo es ms simple que el ejemplo con los comandos convencionales en la seccin 6.4.9. o a o 178 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Texto insertado entre ecuaciones alineadas Otra situacin usual es insertar texto entre ecuaciones alineadas, preservando la alineacin: o o x1 = a + b + c , x2 = d + e , y por otra parte x3 = f + g + h . \begin{align*} x_1 &= a + b + c \ , \\ x_2 &= d + e \ , \\ \intertext{y por otra parte} x_3 &= f + g + h \ . \end{align*} Matrices y coeficientes binomiales La complicada construccin de matrices usando array (seccin 6.4.9), se puede reemplazar con o o ambientes como pmatrix y vmatrix, y comandos como \binom. a b c d \begin{pmatrix} a&b\\ c&d \end{pmatrix} \Delta = \begin{vmatrix} a_{11} & a_{12}\\ a_{21} & a_{22} \end{vmatrix} v = \binom{k}{2} a a = 11 12 a21 a22 k 2 v= Podemos observar que el espaciado entre los parntesis y el resto de la frmula es ms adecuado e o a que el de los ejemplos en la seccin 6.4.9. o Flechas extensibles Las flechas en la tabla 6.6 vienen en ciertos tama~os predefinidos. amsmath proporciona flen chas extensibles \xleftarrow y \xrightarrow, para ajustar sub o super indices demasiado anchos. Adems, tienen un argumento opcional y uno obligatorio, para colocar material sobre o bajo ellas: a A - - B -- C - D -- -- T U n+-1 ni-1 A \xleftarrow{n+\mu-1} B \xrightarrow[T]{n\pm i-1} C \xrightarrow[U]{} D Uso del paquete amssymb Este paquete contiene s imbolos matemticos muy estticos a la hora de referirse a los conjuntos a e de nmeros: u \mathbb{C} \mathbb{R} \mathbb{Z} para los nmeros complejos u para los nmeros reales u para los nmeros enteros u \mathbb{I} \mathbb{Q} \mathbb{N} para los nmeros imaginarios u para los nmeros racionales u para los nmeros naturales u C R Z I Q N 6.8. ALGUNAS HERRAMIENTAS IMPORTANTES Otro siimbolo interesante es: (\therefore) para "por lo tanto". 179 6.8.3. fontenc A Ocasionalmente, L TEX tiene problemas al separar una palabra en s ilabas. T ipicamente, eso ocurre con palabras acentuadas, pues, debido a la estructura interna del programa, un carcter a como la "" en "matemticas" no es tratado igual que los otros. Para solucionar el problema, y a a poder cortar en s ilabas palabras que contengan letras acentuadas (adems de acceder a algunos a caracteres adicionales), basta incluir el paquete fontenc: \usepackage[T1]{fontenc} Tcnicamente, lo que ocurre es que la codificacin antigua para fonts es la OT1, que no contiene e o fonts acentuados, y que por lo tanto es util slo para textos en ingls. La codificacin T1 aumenta los o e o fonts disponibles, permitiendo que los caracteres acentuados sean tratados en igual pie que cualquier otro. 6.8.4. enumerate A enumerate.sty define una muy conveniente extensin al ambiente enumerate de L TEX. El o comando se usa igual que siempre (ver seccin 6.3.12), con un argumento opcional que determina o el tipo de etiqueta que se usar para la lista. Por ejemplo, si queremos que en vez de nmeros se a u usen letras maysculas, basta usar \begin{enumerate}[A]: u A Primer item. B Segundo item. Si queremos etiquetas de la forma "1.-", \begin{enumerate}[1.-]: 1.- Primer item. 2.- Segundo item. Si deseamos insertar un texto que no cambie de una etiqueta a otra, hay que encerrarlo entre parntesis cursivos (\begin{enumerate}[{Caso} A:]): e Caso A: Primer item. Caso B: Segundo item. 6.8.5. Color. A A travs de PostScript es posible introducir color en documentos L TEX. Para ello, incluimos en e el prembulo el paquete color.sty: a \usepackage{color} 180 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . De este modo, est disponible el comando \color, que permite especificar un color, ya sea por a nombre (en el caso de algunos colores predefinidos), por su cdigo rgb (red-green-blue) o cdigo o o cmyk (cian-magenta-yellow-black). Por ejemplo: Un texto en azul Un texto en un segundo color Un texto en un tercer color Un texto en {\color{blue} azul} Un texto en un {\color[rgb]{1,0,1} segundo color} Un texto en un {\color[cmyk]{.3,.5,.75,0} tercer color} Los colores ms frecuentes (azul, amarillo, rojo, etc.) se pueden dar por nombre, como en este a ejemplo. Si se da el cdigo rgb, se deben especificar tres nmeros entre 0 y 1, que indican la cantidad o u de rojo, verde y azul que constituyen el color deseado. En el ejemplo, le dimos mxima cantidad de a rojo y azul, y nada de verde, con lo cual conseguimos un color violeta. Si se trata del cdigo cmyk los o nmeros a especificar son cuatro, indicando la cantidad de cian, magenta, amarillo y negro. En el u ejemplo anterior pusimos una cantidad arbitraria de cada color, y result un color caf. Es evidente o e que el uso de los cdigos rgb y cmyk permite explorar infinidad de colores. o Observar que \color funciona de modo anlogo a los comandos de cambio de font de la seccin a o 6.3.13, de modo que si se desea restringir el efecto a una porcin del texto, hay que encerrar dicho o texto entre parntesis cursivos. Anlogamente al caso de los fonts, existe el comando \textcolor, e a que permite dar el texto a colorear como argumento: Un texto en azul Un texto en un segundo color Un texto en un tercer color Un texto en \textcolor{blue}{azul} Un texto en un \textcolor[rgb]{1,0,1}{segundo color} Un texto en un \textcolor[cmyk]{.3,.5,.75,0}{tercer color} 6.9. Modificando el estilo de la pgina. a TEX toma una serie de decisiones por nosotros. Ocasionalmente nos puede interesar alterar el comportamiento normal. Disponemos de una serie de comandos para ello, los cuales revisaremos a continuacin. Todos deben aparecer en el prembulo, salvo en los casos que se indique. o a 6.9.1. Estilos de pgina. a a) Nmeros de pgina. u a Si se desea que los nmeros de pgina sean arbicos (1, 2, 3. . . ): u a a \pagenumbering{arabic} Para nmeros romanos (i, ii, iii,. . . ): u \pagenumbering{roman} 6.9. MODIFICANDO EL ESTILO DE LA PAGINA. arabic es el default. b) Estilo de pgina. a El comando \pagestyle determina dnde queremos que vayan los nmeros de pgina: o u a \pagestyle{plain} Nmeros de pgina en el extremo inferior, u a al centro de la pgina. (Default para estia los article, report.) Nmeros de pgina y otra informacin u a o (t itulo de seccin, etc.) en la parte suo perior de la pgina. (Default para estilo a book.) Sin nmeros de pgina. u a 181 \pagestyle{headings} \pagestyle{empty} 6.9.2. Corte de pginas y l a ineas. TEX tiene modos internos de decidir cundo cortar una pgina o una l a a inea. Al preparar la versin o final de nuestro documento, podemos desear coartar sus decisiones. En todo caso, no hay que hacer esto antes de preparar la versin verdaderamente final, porque agregar, modificar o quitar texto o puede alterar los puntos de corte de l ineas y pginas, y los cortes inconvenientes pueden resolverse a solos. Los comandos de esta seccin no van en el prembulo, sino en el interior del texto. o a Corte de l ineas. o inea en un punto deseado En la pgina 163 ya vimos un ejemplo de induccin de un corte de l a del texto, al dividir una palabra en s ilabas. Cuando el problema no tiene relacin con s o ilabas disponemos de dos comandos: \newline \linebreak Corta la l inea y pasa a la siguiente en el punto indicado. Lo mismo, pero justificando la l inea para adecuarla a los mrgenes. a Un corte de l\'{\i}nea\newline no justificado a los m\'argenes en curso. Un corte de l\'{\i}nea\linebreak justificado a los m\'argenes en curso. Un corte de l inea no justificado a los mrgenes a en curso. Un corte de l inea justificado a los mrgenes a en curso. Observemos cmo en el segundo caso, en que se usa \linebreak, la separacin entre palabras o o es alterada para permitir que el texto respete los mrgenes establecidos. a 182 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Corte de pginas. a Como para cortar l ineas, existe un modo violento y uno sutil: \newpage \clearpage Cambia de pgina en el punto indicado. Anlogo a a a \newline. Lo mismo, pero ajustando los espacios verticales en el texto para llenar del mejor modo posible la pgina. a \clearpage, sin embargo, no siempre tiene efectos visibles. Dependiendo de la cantidad y tipo de texto que quede en la pgina, los espacios verticales pueden o no ser ajustados, y si no lo son, a el resultado termina siendo equivalente a un \newpage. TEX decide en ultima instancia qu es lo e o ptimo. Adicionalmente, tenemos el comando: \enlargethispage{<longitud>} Cambia el tama~o de la pgina acn a tual en la cantidad <longitud>. (Las unidades de longitud que maneja TEX se revisan a continuacin.) o Unidades de longitud y espacios. a) Unidades. TEX reconoce las siguientes unidades de longitud: cm mm in pt em ex cent imetro mil imetro pulgada punto (1/72 pulgadas) ancho de una "M" en el font actual altura de una "x" en el font actual Las cuatro primeras unidades son absolutas; las ultimas dos, relativas, dependiendo del ta ma~o del font actualmente en uso. n Las longitudes pueden ser nmeros enteros o decimales, positivos o negativos: u 1cm 1.6in .58pt -3ex b) Cambio de longitudes. TEX almacena los valores de las longitudes relevantes al texto en comandos especiales: 6.9. MODIFICANDO EL ESTILO DE LA PAGINA. \parindent \textwidth \textheight \oddsidemargin \topmargin \baselineskip \parskip Sangr ia. Ancho del texto. Altura del texto. Margen izquierdo menos 1 pulgada. Margen superior menos 1 pulgada. Distancia entre la base de dos l ineas de texto consecutivas. Distancia entre prrafos. a 183 Todas estas variables son modificables con los comandos \setlength, que le da a una variable un valor dado, y \addtolength, que le suma a una variable la longitud especificada. Por ejemplo: \setlength{\parindent}{0.3em} \addtolength{\parskip}{1.5cm} (\parindent = 0.3 em.) (\parskip = \parskip + 1.5 cm.) Por default, el ancho y altura del texto, y los mrgenes izquierdo y superior, estn definidos a a de modo que quede un espacio de una pulgada ( 2.56 cm) entre el borde del texto y el borde de la pgina. a Un problema t ipico es querer que el texto llene un mayor porcentaje de la pgina. Por ejema plo, para que el margen del texto en los cuatro costados sea la mitad del default, debemos introducir los comandos: \addtolength{\textwidth}{1in} \addtolength{\textheight}{1in} \addtolength{\oddsidemargin}{-.5in} \addtolength{\topmargin}{-.5in} Las dos primeras l ineas aumentan el tama~o horizontal y vertical del texto en 1 pulgada. n Si luego restamos media pulgada del margen izquierdo y el margen superior, es claro que la distancia entre el texto y los bordes de la pgina sera de media pulgada, como desebamos. a a c) Espacios verticales y horizontales. Se insertan con \vspace y \hspace: \vspace{3cm} \hspace{3cm} Algunos ejemplos: Un primer prrafo de un pea que~o texto. n Un primer p\'arrafo de un peque\~no texto. \vspace{1cm} Y un segundo p\'arrafo separado del otro. Espacio vertical de 3 cm. Espacio horizontal de 3 cm. Y un segundo prrafo separaa do del otro. 184 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Tres palabras del resto. separadas Tres\hspace{.5cm}palabras \hspace{.5cm}separadas del resto. Si por casualidad el espacio vertical impuesto por \vspace debiese ser colocado al comienzo de una pgina, TEX lo ignora. Ser molesto visualmente que en algunas pginas el texto a ia a comenzara algunos cent imetros ms abajo que en el resto. Lo mismo puede ocurrir si el a espacio horizontal de un \hspace queda al comienzo de una l inea. Los comandos \vspace*{<longitud>} y \hspace*{<longitud>} permiten que el espacio en blanco de la <longitud> especificada no sea ignorado. Ello es util cuando invariablemente queremos ese espacio vertical u horizontal, aunque sea al comienzo de una pgina o una l a inea --por ejemplo, para insertar una figura. 6.10. Figuras. A Lo primero que hay que decir en esta seccin es que L TEX es un excelente procesador de texto, o tanto convencional como matemtico. Las figuras, sin embargo, son un problema aparte. a A X provee un ambiente picture que permite realizar dibujos simples. Dentro de la estrucL TE tura \begin{picture} y \end{picture} se pueden colocar una serie de comandos para dibujar l ineas, c irculos, valos y flechas, as como para posicionar texto. Infortunadamente, el proceso de o i ejecutar dibujos sobre un cierto umbral de complejidad puede ser muy tedioso para generarlo directamente. Existe software (por ejemplo, xfig) que permite superar este problema, pudindose e A X. Sin embargo, picture dibujar con el mouse, exportando el resultado al formato picture de L TE tiene limitaciones (no se pueden hacer l ineas de pendiente arbitraria), y por tanto no es una solucin o o ptima. Para obtener figuras de buena calidad es imprescindible recurrir a lenguajes grficos externos, y a A X da la posibilidad de incluir esos formatos grficos en un documento. De este modo, tanto el L TE a texto como las figuras sern de la ms alta calidad. Las dos mejores soluciones son utilizar Metafont a a o PostScript. Metafont es un programa con un lenguaje de programacin grfico propio. De hecho, o a A X fueron creados usando Metafont, y sus capacidades permiten hacer dibujos los propios fonts de L TE de complejidad arbitraria. Sin embargo, los dibujos resultantes no son trivialmente reescalables, y exige aprender un lenguaje de programacin espec o ifico. Una solucin mucho ms verstil, y adoptada como el estndar en la comunidad de usuarios o a a a A X, es el uso de PostScript. Como se mencion brevemente en la seccin 1.13, al imprimir, de L TE o o una mquina unix convierte el archivo a formato PostScript, y luego lo env a la impresora. Pero a ia PostScript sirve ms que para imprimir, siendo un lenguaje de programacin grfico completo, con a o a el cual podemos generar imgenes de gran calidad, y reescalables sin prdida de resolucin. Adems, a e o a muchos programas grficos permiten exportar sus resultados en formato PostScript. Por lo tanto, a podemos generar nuestras figuras en alguno de estos programas (xfig es un excelente software, que satisface la mayor parte de nuestras necesidades de dibujos simples; octave o gnuplot pueden ser usados para generar figuras provenientes de clculos cient a ificos, etc.), lo cual crear un archivo con a 5 Luego introducimos la figura en el extensin .ps (PostScript) o .eps (PostScript encapsulado). o A documento L TEX, a travs del paquete graphicx. e eps es el formato preferido, pues contiene informacin sobre las dimensiones de la figura, informacin o o A que es utilizada por L TEX para insertar sta adecuadamente en el texto. e 5 6.10. FIGURAS. 185 6.10.1. graphicx.sty Si nuestra figura est en un archivo figura.eps, la instruccin a utilizar es: a o \documentclass[12pt]{article} \usepackage{graphicx} \begin{document} ... Texto ... \includegraphics[width=w, height=h]{figura.eps} ... \end{document} Los parmetros width y height son opcionales y puede omitirse uno para que el sistema escale a de acuerdo al parmetro dado. Es posible variar la escala completa de la figura o rotarla usando a comandos disponibles en graphicx. Una figura aqu i: Una figura aqu\'{\i}: \begin{center} \includegraphics[height=3cm]{figura.eps} \end{center} puede hacer m\'as agradable el texto. puede hacer ms agradable el a texto. En este ejemplo, indicamos slo la altura de la figura (3cm). El ancho fue determinado de modo o que las proporciones de la figura no fueran alteradas. Si no se especifica ni la altura ni el ancho, la figura es insertada con su tama~o natural. n Observemos tambin que pusimos la figura en un ambiente center. Esto no es necesario, pero e normalmente uno desea que las figuras estn centradas en el texto. e 6.10.2. Ambiente figure. Insertar una figura es una cosa. Integrarla dentro del texto es otra. Para ello est el ambiente a figure, que permite: (a) posicionar la figura automticamente en un lugar predeterminado o espea cificado por el usuario; (b) numerar las figuras; y (c) agregar un breve texto explicativo junto a la figura. Coloquemos la misma figura de la seccin anterior dentro de un ambiente figure. El input: o \begin{figure}[h] \begin{center} \includegraphics[height=3cm]{figura.eps} \end{center} \caption{Un sujeto caminando.} \label{caminando} \end{figure} 186 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Figura 6.1: Un sujeto caminando. da como resultado: figure delimita lo que en TEX se denomina un objeto flotante, es decir, un objeto cuya posicin o no est determinada a priori, y se ajusta para obtener los mejores resultados posibles. TEX considera a (de acuerdo con la tradicin), que la mejor posicin para colocar una figura es al principio o al final o o de la pgina. Adems, lo ideal es que cada pgina tenga un cierto nmero mximo de figuras, a a a u a que ninguna figura aparezca en el texto antes de que sea mencionada por primera vez, y que, por supuesto, las figuras aparezcan en el orden en que son mencionadas. Estas y otras condiciones determinan la posicin que un objeto flotante tenga al final de la compilacin. Uno puede forzar la o o A decisin de L TEX con el argumento opcional de figure: o t b h p (top) (bottom) (here) (page of floats) extremo superior de la pgina a extremo inferior de la pgina a aqu en el punto donde est el comando i, a en una pgina separada al final del texto a El argumento adicional ! suprime, para ese objeto flotante espec ifico, cualquier restriccin que o exista sobre el nmero mximo de objetos flotantes en una pgina y el porcentaje de texto m u a a inimo que debe haber en una pgina. a Varios de estos argumentos se pueden colocar simultnemente, su orden dictando la prioridad. a Por ejemplo, \begin{figure}[htbp] ... \end{figure} indica que la figura se debe colocar como primera prioridad aqu mismo; si ello no es posible, al i comienzo de pgina (sta o la siguiente, dependiendo de los detalles de la compilacin), y as sucea e o i sivamente. Adems, figure numera automticamente la figura, colocando el texto "Figura N :", y \caption a a permite colocar una leyenda, centrada en el texto, a la figura. Puesto que la numeracin es automtio a ca, las figuras pueden ser referidas simblicamente con \label y \ref (seccin 6.6). Para que la o o referencia sea correcta, \label debe estar dentro del argumento de \caption, o despus, como e aparece en el ejemplo de la Figura 6.1 (\ref{caminando}!). Finalmente, notemos que la figura debi ser centrada expl o icitamente con center. figure no hace nada ms que tratar la figura como un objeto flotante, proporcionar numeracin y leyenda. El a o resto es responsabilidad del autor. 6.11. CARTAS. 187 6.11. Cartas. Para escribir cartas debemos emplear el estilo letter en vez del que hemos utilizado hasta ahora, article. Comandos especiales permiten escribir una carta, poniendo en lugares adecuados la direccin del remitente, la fecha, la firma, etc. o A modo de ejemplo, consideremos el siguiente input: \documentclass[12pt]{letter} \usepackage[spanish]{babel} \begin{document} \address{Las Palmeras 3425\\ \~Nu\~noa, Santiago} \date{9 de Julio de 1998} \signature{Pedro P\'erez \\ Secretario} \begin{letter}{Dr.\ Juan P\'erez \\ Las Palmeras 3425 \\ \~Nu\~noa, Santiago} \opening{Estimado Juan} A\'un no tenemos novedades. Parece incre\'{\i}ble, pero los recientes acontecimientos nos han superado, a pesar de nuestros esfuerzos. Esperamos que mejores tiempos nos aguarden. \closing{Saludos,} \cc{Arturo Prat \\ Luis Barrios} \end{letter} \end{document} El resultado se encuentra en la prxima pgina. o a 188 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Las Palmeras 3425 ~ n Nu~oa, Santiago 9 de Julio de 1998 Dr. Juan Prez e Las Palmeras 3425 ~ n Nu~oa, Santiago Estimado Juan An no tenemos novedades. u Parece incre ible, pero los recientes acontecimientos nos han superado, a pesar de nuestros esfuerzos. Esperamos que mejores tiempos nos aguarden. Saludos, Pedro Prez e Secretario Copia a: Arturo Prat Luis Barrios A 6.12. L TEX Y EL FORMATO PDF. 189 Observemos que el texto de la carta est dentro de un ambiente letter, el cual tiene un argua mento obligatorio, donde aparece el destinatario de la carta (con su direccin opcionalmente). o Los comandos disponibles son: \address{<direccion>} \signature{<firma>} \opening{<apertura>} \closing{<despedida>} \cc{<copias>} <direccion> del remitente. <firma> del remitente. Frmula de <apertura>. o Frmula de <despedida>. o Receptores de <copias> (si los hubiera). Uno puede hacer ms de una carta con distintos ambientes letter en un mismo archivo. Caa da una tomar el mismo remitente y firma dados por \address y \signature. Si deseamos que a \address o \signature valgan slo para una carta particular, basta poner dichos comandos entre o el \begin{letter} y el \opening correspondiente. Por ejemplo, la siguiente estructura: \documentclass[12pt]{letter} \begin{document} \address{<direccion remitente>} \date{<fecha>} \signature{<firma>} \begin{letter}{<destinatario 1>} \opening<apertura 1> ... \end{letter} \begin{letter}{<destinatario 2>} \address{<direccion remitente 2>} \signature{<firma 2>} \opening<apertura 2> ... \end{letter} \begin{letter}{<destinatario 3>} \opening<apertura 3> ... \end{letter} \end{document} dar origen a tres cartas con la misma direccin de remitente y firma, salvo la segunda. a o En todos estos comandos, l ineas sucesivas son indicadas con \\. 6.12. A LTEX y el formato pdf. Junto con PostScript, otro formato ampliamente difundido para la transmisin de archivos, o especialmente a travs de Internet, es el formato pdf (Portable Document Format). Para generar un e 190 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . A archivo pdf con L TEX es necesario compilarlo con pdflatex. As pdflatex <archivo> generar un i, a archivo <archivo>.pdf en vez del <archivo>.dvi generado por el compilador usual. Si nuestro documento tiene figuras, slo es posible incluirlas en el documento si estn tambin o a e en formato pdf. Por tanto, si tenemos un documento con figuras en PostScript, debemos introducir dos modificaciones antes de compilar con pdflatex: a) Cambiar el argumento de \includegraphics (seccin 6.10) de <archivo_figura>.eps o a <archivo_figura>.pdf. b) Convertir las figuras PostScript a pdf (con epstopdf, por ejemplo). Si tenemos una figura en el archivo <archivo_figura>.eps, entonces epstopdf <archivo_figura>.eps genera el archivo correspondiente <archivo_figura>.pdf. Observar que el mismo paquete graphicx descrito en la seccin 6.10 para incluir figuras o PostScript permite, sin modificaciones, incluir figuras en pdf. 6.13. A Modificando LTEX. Esta seccin se puede considerar "avanzada". Normalmente uno se puede sentir satisfecho con o A el desempe~o de L TEX, y no es necesaria mayor intervencin. A veces, dependiendo de la aplicacin n o o y del autor, nos gustar modificar el comportamiento default. Una alternativa es definir nuevos ia comandos que sean utiles para nosotros. Si esos nuevos comandos son abundantes, o queremos reu tilizarlos frecuentemente en otros documentos, lo conveniente es considerar crear un nuevo paquete o incluso una nueva clase. Examinaremos a continuacin los elementos bsicos de estas modificaciones. o a 6.13.1. Definicin de nuevos comandos. o El comando \newcommand Un nuevo comando se crea con: \newcommand{<comando>}{<accion>} El caso ms sencillo es cuando una estructura se repite frecuentemente en nuestro documento. a Por ejemplo, digamos que un sujeto llamado Cristbal no quiere escribir su nombre cada vez que o aparece en su documento: Mi nombre es S como oyes, i, Cristbal Loyola. o Cristbal. o Cristbal. o \newcommand{\nombre}{Crist\'obal} ... \begin{document} ... Mi nombre es \nombre. S\'{\i}, como oyes, \nombre. \nombre\ Loyola. Un \newcommand puede aparecer en cualquier parte del documento, pero lo mejor es que est en e el prembulo, de modo que sea evidente qu nuevos comandos estn disponibles en el presente a e a documento. Observemos adems que la definicin de un comando puede contener otros comandos a o (en este caso, \'). Finalmente, notamos que ha sido necesario agregar un espacio expl icito con \ , al escribir "Cristbal Loyola": recordemos que un comando comienza con un backslash y termina o A 6.13. MODIFICANDO L TEX. 191 con el primer carcter que no es letra. Por tanto, \nombre Loyola ignora el espacio al final de a \nombre, y el output ser "CristbalLoyola". ia o Tambin es posible definir comandos que funcionen en modo matemtico: e a Sea x la velocidad, de modo que x(t) > 0 si t < 0. \newcommand{\vel}{\dot x} Sea $\vel$ la velocidad, de modo que $ \vel(t)> 0$ si $t<0$. Como \vel contiene un comando matemtico (\dot), \vel slo puede aparecer en modo maa o temtico. a Podemos tambin incluir la apertura de modo matemtico en la definicin de \vel: e a o \newcommand{\vel}{$\dot x$}. De este modo, \vel (no $\vel$) da como output directamente x. Sin embargo, esta solucin no es ptima, porque la siguiente ocurrencia de \vel da un error. o o A En efecto, si \vel = $\dot x$, entonces $ \vel(t)>0$ = $ $\dot x$> 0$. En tal caso, L TEX ve que un modo matemtico se ha abierto y cerrado inmediatamente, conteniendo slo un espacio a o A X acusa un entremedio, y luego, en modo texto, viene el comando \dot, que es matemtico: L TE a error y la compilacin se detiene. o La solucin a este problema es utilizar el comando \ensuremath, que asegura que haya modo o matemtico, pero si ya hay uno abierto, no intenta volverlo a abrir: a Sea x la velocidad, de modo que x(t) > 0 si t < 0. \newcommand{\vel}{\ensuremath{\dot x}} Sea \vel\ la velocidad, de modo que $ \vel(t)> 0$ si $t<0$. Un caso especial de comando matemtico es el de operadores tipo logaritmo (ver Tabla 6.9). Si a queremos definir una traduccin al castellano de \sin, debemos usar el comando \DeclareMathOperator o disponible via amsmath: Ahora podemos escribir en castellano, sen x. \usepackage{amsmath} \DeclareMathOperator{\sen}{sen} ... Ahora podemos escribir en castellano, $\sen x$. A diferencia de \newcommand, \DeclareMathOperator slo puede aparecer en el prembulo del o a documento. Un nuevo comando puede tambin ser usado para ahorrar tiempo de escritura, reemplazando e A X: comandos largos de L TE 1. El primer caso. 2. Ahora el segundo. 3. Y el tercero. \newcommand{\be}{\begin{enumerate}} \newcommand{\ee}{\end{enumerate}} \be \item El primer caso. \item Ahora el segundo. \item Y el tercero. \ee 192 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Nuevos comandos con argumentos Podemos tambin definir comandos que acepten argumentos. Si el sujeto anterior, Cristbal, e o desea escribir cualquier nombre precedido de "Nombre:" en itlica, entonces puede crear el siguiente a comando: Nombre: Cristbal o Nombre: Violeta \newcommand{\nombre}[1]{\textit{Nombre:} #1} \nombre{Crist\'obal} \nombre{Violeta} Observemos que \newcommand tiene un argumento opcional, que indica el nmero de argumentos u que el nuevo comando va a aceptar. Esos argumentos se indican, dentro de la definicin del comando, o con #1, #2, etc. Por ejemplo, consideremos un comando que acepta dos argumentos: \newcommand{\fn}[2]{f(#1,#2)} f (x, y) + f (x3 , y) = 0 . $$ \fn{x}{y} + \fn{x_3}{y*} = 0 \ . $$ A En los casos anteriores, todos los argumentos son obligatorios. L TEX permite definir comandos con un (slo un) argumento opcional. Si el comando acepta n argumentos, el argumento opcional es o el #1, y se debe indicar, en un segundo parntesis cuadrado, su valor default. As podemos modificar e i, el comando \fn del ejemplo anterior para que el primer argumento sea opcional, con valor default x: \newcommand{\fn}[2][x]{f(#1,#2)} f (x, y) + f (x3 , y) = 0 . $$ \fn{y} + \fn[x_3]{y*} = 0 \ . $$ Redefinicin de comandos o Ocasionalmente no nos interesa definir un nuevo comando, sino redefinir la accin de un comando o preexistente. Esto se hace con \renewcommand: La antigua versin de ldots: o ... La nueva versin de ldots: o La antigua versi\'on de {\tt ldots}: \ldots \renewcommand{\ldots}{\textbullet \textbullet \textbullet} La nueva versi\'on de {\tt ldots}: \ldots Prrafos y cambios de l a inea dentro de comandos En el segundo argumento de \newcommand o \renewcommand puede aparecer cualquier comando A de L TEX, pero ocasionalmente la aparicin de l o ineas en blanco (para forzar un cambio de prrafo) a puede provocar problemas. Si ello ocurre, podemos usar \par, que hace exactamente lo mismo. Adems, la definicin del comando queda ms compacta: a o a A 6.13. MODIFICANDO L TEX. 193 \newcommand{\comandolargo}{\par Un nuevo comando que incluye un cambio de p\'arrafo, porque deseamos incluir bastante texto.\par \'Este es el nuevo p\'arrafo.\par} Observemos en acci\'on el comando: \comandolargo Listo. da como resultado: Observemos en accin el comando: o Un nuevo comando que incluye un cambio de prrafo, pora que deseamos incluir bastante texto. Este es el nuevo prrafo. a Listo. Un ejemplo ms util ocurre cuando queremos asegurar un cambio de prrafo, por ejemplo, para a a colocar un t itulo de seccin: o Observemos comando: en accin o el \newcommand{\seccion}[1]{\par\vspace{.5cm} {\bf Secci\'on: #1}\par\vspace{.5cm}} Observemos en acci\'on el comando: \seccion{Ejemplo} Listo. Seccin: Ejemplo o Listo. Adems de las l a ineas en blanco, los cambios de l inea pueden causar problemas dentro de la definicin de un nuevo comando. El ejemplo anterior, con el comando \seccion, es un buen ejemplo: o notemos que cuando se defini, pusimos un cambio de l o inea despus de \vspace{.5cm}. Ese cambio e de l inea es interpretado (como todos los cambios de l inea) como un espacio en blanco, y es posible que, bajo ciertas circunstancias, ese espacio en blanco produzca un output no deseado. Para ello basta utilizar sabiamente el carcter %, que permite ignorar todo el resto de la l a inea, incluyendo el cambio de l inea. Ilustremos lo anterior con los siguientes tres comandos, que subrayan (comando \underline) una palabra, y difieren slo en el uso de % para borrar cambios de l o inea: Notar la diferencia entre: Un texto de prueba , Un texto de prueba , y Un texto de prueba. \newcommand{\texto}{ Un texto de prueba } \newcommand{\textodos}{% Un texto de prueba } \newcommand{\textotres}{% Un texto de prueba% } Notar la diferencia entre: \underline{\texto}, \underline{\textodos}, y \underline{\textotres}. \texto conserva espacios en blanco antes y despus del texto, \textodos slo el espacio en e o 194 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . blanco despus del texto, y \textotres no tiene espacios en blanco alrededor del texto. e Nuevos ambientes A Nuevos ambientes en L TEX se definen con \newenvironment: \newenvironment{<ambiente>}{<comienzo ambiente>}{<final ambiente>} define un ambiente <ambiente>, tal que \begin{ambiente} ejecuta los comandos <comienzo ambiente>, y \end{ambiente} ejecuta los comandos <final ambiente>. Definamos un ambiente que, al comenzar, cambia el font a itlica, pone una l a inea horizontal (\hrule) y deja un espacio vertical de .3cm, y que al terminar cambia de prrafo, coloca XXX en a sans serif, deja un nuevo espacio vertical de .3cm, y vuelve al font roman: \newenvironment{na}{\it \hrule \vspace{.3cm}}{\par\sf XXX \vspace{.3cm}\rm} Entonces, con \begin{na} Hola a todos. Es un placer saludarlos en este d\'{\i}a tan especial. Nunca esper\'e una recepci\'on tan calurosa. \end{na} obtenemos: Hola a todos. Es un placer saludarlos en este d tan especial. ia Nunca esper una recepcin tan calurosa. e o XXX Los nuevos ambientes tambin pueden ser definidos de modo que acepten argumentos. Como con e \newcommand, basta agregar como argumento opcional a \newenvironment un nmero que indique u cuntos argumentos se van a aceptar: a \newenvironment{<ambiente>}[n]{<comienzo ambiente>}{<final ambiente>} Dentro de <comienzo ambiente>, se alude a cada argumento como #1, #2, etc. Los argumentos no pueden ser usados en los comandos de cierre del ambiente (<final ambiente>). Por ejemplo, modifiquemos el ambiente na anterior, de modo que en vez de colocar una l inea horizontal al comienzo, coloque lo que le indiquemos en el argumento: \newenvironment{na}[1]{\it #1 \vspace{.3cm}}{\par\sf XXX\hrule\vspace{.3cm}\rm} Ahora usmoslo dos veces, cada una con un argumento distinto: e A 6.13. MODIFICANDO L TEX. 195 El mismo ejemplo anterior, ahora es \begin{na}{\hrule} Hola a todos... \end{na} Pero podemos ahora cambiar el comienzo: \begin{na}{\it XXX} Hola a todos... \end{na} El mismo ejemplo anterior, ahora es Hola a todos. . . XXX Pero podemos ahora cambiar el comienzo: XXX Hola a todos. . . XXX 6.13.2. Creacin de nuevos paquetes y clases o Si la cantidad de nuevos comandos y/o ambientes que necesitamos en nuestro documento es suficientemente grande, debemos considerar crear un nuevo paquete o una nueva clase. Para ello hay que tener clara la diferencia entre uno y otro. En general, se puede decir que si nuestros comandos involucran alterar la apariencia general del documento, entonces corresponde crear una nueva clase (.cls). Si, por el contrario, deseamos que nuestros comandos funcionen en un amplio rango de circunstancias, para diversas apariencias del documento, entonces lo adecuado es un paquete (.sty). Consideremos por ejemplo la experiencia de los autores de estos apuntes. Para crear estos apuntes necesitamos bsicamente la clase book, con ciertas modificaciones: mrgenes ms peque~os, inclusin a a a n o automtica de los paquetes amsmath, babel y graphicx, entre otros, y definicin de ciertos ambientes a o espec ificos. Todo ello afecta la apariencia de este documento, cambindola de manera apreciable, a pero a la vez de un modo que en general no deseamos en otro tipo de documento. Por ello lo hemos compilado usando una clase adecuada, llamada mfm2.cls. Por otro lado, uno de los autores ha necesitado escribir muchas tareas, pruebas y controles de ayudant en su vida, y se ha convencido de que su trabajo es ms fcil creando una clase tarea.cls, ia a a que sirve para esos tres propsitos, definiendo comandos que le permiten especificar fcilmente la o a fecha de entrega de la tarea, o el tiempo disponible para una prueba, los nombres del profesor y el ayudante, etc., una serie de comandos espec ificos para sus necesidades. Sin embargo, tanto en este documento que usa mfm2.cls, como en las tareas y pruebas que A usan tarea.cls, se utilizan algunos comandos matemticos que no vienen con L TEX, pero que a son recurrentes, como \sen (la funcin seno en castellano), \modulo (el mdulo de un vector), o o o \TLaplace (la transformada de Laplace). Para que estos comandos estn disponibles en cualquier e tipo de documento, necesitamos reunirlos en un paquete, en este caso addmath.sty. De este modo, mfm2.cls, tarea.cls o cualquier otra clase pueden llamar a este paquete y utilizar sus comandos. Estructura bsica. a La estructura bsica de un paquete o una clase es: a a) Identificacin: Informacin general (nombre del paquete, fecha de creacin, etc.). (Obligatoria.) o o o b) Declaraciones preliminares: Opcionales, dependiendo del paquete o clase en cuestin. o c) Opciones: Comandos relacionados con el manejo de las opciones con las cuales el paquete o clase pueden ser invocados. (Opcional.) 196 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . d) Ms declaraciones: Aqu van los comandos que constituyen el cuerpo de la clase o paquete. a i (Obligatoria: si no hay ninguna declaracin, el paquete o clase no hace nada, naturalmente.) o La identificacin est consituida por las siguientes dos l o a ineas, que deben ir al comienzo del archivo: \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{<paquete>}[<fecha> <otra informacion>] A A La primera l inea indica a L TEX que ste es un archivo para L TEX 2 . La segunda l e inea especifica que se trata de un paquete, indicando el nombre del mismo (es decir, el nombre del archivo sin extensin) y, opcionalmente, la fecha (en formato YYYY/MM/DD) y otra informacin relevante. Por o o ejemplo, nuestro paquete addmath.sty comienza con las l ineas: \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{addmath}[1998/09/30 Macros matematicos adicionales (VM)] Si lo que estamos definiendo es una clase, usamos el comando \ProvidesClass. Para nuestra clase mfm2.cls: \NeedsTeXFormat{LaTeX2e} \ProvidesClass{mfm2}[2002/03/25 Estilo para apuntes MFM II (VM)] A continuacin de la identificacin vienen los comandos que se desean incorporar a travs de o o e este paquete o clase. Como hemos dicho, addmath.sty contiene muchos nuevos comandos matemticos que considea ramos necesario definir mientras escrib iamos estos apuntes. Veamos los contenidos de una versin o simplificada de dicho paquete: \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{addmath}[1998/09/30 Macros matematicos adicionales (VM)] \newcommand{\prodInt}[2]{\ensuremath \left(\, #1\, |\, #2\, \right ) } \newcommand{\promedio}[1]{\langle #1 \rangle} \newcommand{\intii}{\int_{-\infty}^{\infty}} \newcommand{\grados}{\ensuremath{^\circ}} \newcommand{\Hipergeometrica}[4]{{}_2F_1\left (#1, #2, #3\, ; #4\right )} ... De este modo, incluyendo en nuestro documento el paquete con \usepackage{addmath}, varios nuevos comandos estn disponibles: a (x|y) x \prodInt{x}{y} \promedio{x} dz f (z) ABC = 90 2 F1 (a, b, c ; d) - \intii dz\, f(z) \angle\, ABC = 90\grados \Hipergeometrica{a}{b}{c}{d} A 6.13. MODIFICANDO L TEX. 197 Incluyendo otros paquetes y clases Los comandos \RequirePackage y \LoadClass permiten cargar un paquete o una clase, respectivamente.6 . Esto es de gran utilidad, pues permite construir un nuevo paquete o clase aprovechando la funcionalidad de otros ya existentes. As nuestro paquete addmath.sty define bastantes comandos, pero nos gustar definir vai, ia A rios ms que slo pueden ser creados con las herramientas de AMS-L TEX. Cargamos entonces a o en addmath.sty el paquete amsmath y otros relacionados, y estamos en condiciones de crear ms a comandos: \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{addmath}[1998/09/30 Macros matematicos adicionales (VM)] \RequirePackage{amsmath} \RequirePackage{amssymb} \RequirePackage{euscript} ... \newcommand{\norma}[1]{\ensuremath \left\lVert\, #1 \,\right\rVert} \newcommand{\intC}{{\sideset{^*}{}\int}} \DeclareMathOperator{\senh}{senh} ... Por ejemplo: x \norma{x} dz f (z) \intC dz \, f(z) \senh (2y) senh(2y) La posibilidad de basar un archivo .sty o .cls en otro es particularmente importante para una clase, ya que contiene una gran cantidad de comandos y definiciones necesarias para compilar el documento exitosamente. Sin embargo, un usuario normal, aun cuando desee definir una nueva clase, estar interesado en modificar slo parte del comportamiento. Con \LoadClass, dicho usuario a o puede cargar la clase sobre la cual se desea basar, y luego introducir las modificaciones necesarias, facilitando enormemente la tarea. Por ejemplo, al preparar este documento fue claro desde el comienzo que se necesitaba esencialmente la clase book, ya que ser un texto muy extenso, pero tambin era claro que se requer ia e ian ciertas modificaciones. Entonces, en nuestra clase mfm2.cls lo primero que hacemos es cargar la clase book, ms algunos paquetes necesarios (incluyendo nuestro addmath), y luego procedemos a a modificar o a~adir comandos: n \NeedsTeXFormat{LaTeX2e} \ProvidesClass{mfm2}[2002/03/25 Estilo para apuntes MFM II (VM)] \LoadClass[12pt]{book} \RequirePackage[spanish]{babel} Estos comandos slo se pueden usar en un archivo .sty o .cls Para documentos normales, la manera o de cargar un paquete es \usepackage, y para cargar una clase es \documentclass. 6 198 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . \RequirePackage{enumerate} \RequirePackage{addmath} En un archivo .sty o un .cls se pueden cargar varios paquetes con \RequirePackage. \LoadClass, en cambio, slo puede aparecer en un .cls, y slo es posible usarlo una vez (ya que normalmente o o clases distintas son incompatibles entre s i). Manejo de opciones En el ultimo ejemplo anterior, la clase mfm2 carga la clase book con la opcin 12pt. Esto significa o que si nuestro documento comienza con \documentclass{mfm2}, ser compilado de acuerdo a la a clase book, en 12 puntos. No es posible cambiar esto desde nuestro documento. Ser mejor que ia pudiramos especificar el tama~o de letra fuera de la clase, de modo que \documentclass{mfm2} e n d un documento en 10 puntos, y \documentclass[12pt]{mfm2} uno en 12 puntos. Para lograr e esto hay que poder pasar opciones desde la clase mfm2 a book. El modo ms simple de hacerlo es con \LoadClassWithOptions. Si mfm2.cls ha sido llamada a con opciones <opcion1>,<opcion2>, etc., entonces book ser llamada con las mismas opciones. a Por tanto, basta modificar en mfm2.cls la l inea \LoadClass[12pt]{book} por: \LoadClassWithOptions{book} \RequirePackageWithOptions es el comando anlogo para paquetes. Si una clase o un paquete a llaman a un paquete <paquete_base> y desean pasarle todas las opciones con las cuales han sido invocados, basta indicarlo con: \RequirePackageWithOptions{<paquete_base>} El ejemplo anterior puede ser suficiente en muchas ocasiones, pero en general uno podr llamar ia a nuestra nueva clase, mfm2, con opciones que no tienen nada que ver con book. Por ejemplo, podr iamos llamarla con opciones spanish,12pt. En tal caso, deber pasarle spanish a babel, y ia 12pt a book. Ms an, podr a u iamos necesitar definir una nueva opcin, que no existe en ninguna de o las clases o paquetes cargados por book, para modificar el comportamiento de mfm2.cls de cierta manera espec ifica no prevista. Estas dos tareas, discriminar entre opciones antes de pasarla a algn u paquete determinado, y crear nuevas opciones, constituyen un manejo ms avanzado de opciones. a A continuacin revisaremos un ejemplo combinado de ambas tareas, extraido de la clase con la cual o compilamos este texto, mfm2.cls. La idea es poder llamar a mfm2 con una opcin adicional keys, que permita agregar al dvi o informacin sobre las etiquetas (dadas con \label) de ecuaciones, figuras, etc., que aparezcan en o el documento (veremos la utilidad y un ejemplo de esto ms adelante). Lo primero es declarar una a nueva opcin, con: o \DeclareOption{<opcion>}{<comando>} <opcion> es el nombre de la nueva opcin a declarar, y <comando> es la serie de comandos que se o ejecutan cuando dicha opcin es especificada. o As nuestro archivo mfm2.cls debe ser modificado: i, \NeedsTeXFormat{LaTeX2e} \ProvidesClass{mfm2}[2002/03/25 Estilo para apuntes MFM II (VM)] ... \DeclareOption{keys}{...} A 6.13. MODIFICANDO L TEX. 199 ... \ProcessOptions\relax ... Observamos que despus de declarar la o las opciones (en este caso keys), hay que procesarlas, e con \ProcessOptions.7 Las l ineas anteriores permiten que \documentclass{mfm2} y \documentclass[keys]{mfm2} sean ambas vlidas, ejecutndose o no ciertos comandos dependiendo de la forma utilizada. a a Si ahora queremos que \documentclass[keys,12pt]{mfm2} sea una l inea vlida, dea bemos procesar keys dentro de mfm2.cls, y pasarle a book.cls las opciones restantes. El siguiente es el cdigo definitivo: o \NeedsTeXFormat{LaTeX2e} \ProvidesClass{mfm2}[2002/03/25 Estilo para apuntes MFM II (VM)] \newif\ifkeys\keysfalse \DeclareOption{keys}{\keystrue} \DeclareOption*{\PassOptionsToClass{\CurrentOption}{book}} \ProcessOptions\relax \LoadClass{book} \RequirePackage[spanish]{babel} \RequirePackage{amsmath} \RequirePackage{theorem} \RequirePackage{epsfig} \RequirePackage{ifthen} \RequirePackage{enumerate} \RequirePackage{addmath} \ifkeys\RequirePackage[notref,notcite]{showkeys}\fi <nuevos comandos de la clase mfm2.cls> Sin entrar en demasiados detalles, digamos que la opcin keys tiene el efecto de hacer o que una cierta variable lgica \ifkeys, sea verdadera (cuarta l o inea del cdigo). La siguieno te l inea (\DeclareOption*...) hace que todas las opciones que no han sido procesadas (12pt, por ejemplo) se pasen a la clase book. A continuacin se procesan las opciones con o \ProcessOptions, y finalmente se carga la clase book. Las l ineas siguientes cargan todos los paquetes necesarios, y finalmente se encuentran todos los nuevos comandos y definiciones que queremos incluir en mfm2.cls. Observemos que la forma particular en que se carga el paquete showkeys. Esa es precisamente la funcin de la opcin keys que definimos: showkeys.sty se carga con ciertas o o opciones slo si se da la opcin keys. o o Cul es su efecto? Consideremos el siguiente texto de ejemplo, en que mfm2 ha sido a llamada sin la opcin keys: o \relax es un comando de TEX que, esencialmente, no hace nada, ni siquiera introduce un espacio en blanco, y es util incluirlo en puntos cr iticos de un documento, como en este ejemplo. 7 200 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . \documentclass[12pt]{mfm2} \begin{document} La opci\'on \verb+keys+ resulta muy \'util cuando tengo objetos numerados autom\'aticamente, como una ecuaci\'on: \begin{equation} \label{newton} \vec F = m \vec a \ . \end{equation} y luego quiero referirme a ella: Ec.\ \eqref{newton}. En el primer caso, se ha compilado sin la opcin keys, y en el segundo con ella. El efecto o es que, si se usa un \label en cualquier parte del documento, aparece en el margen derecho una caja con el nombre de dicha etiqueta (en este caso, newton). Esto es util para cualquier tipo de documentos, pero lo es especialmente en textos como estos apuntes, muy extensos y con abundantes referencias. En tal caso, tener un modo visual, rpido, de saber los nombres a de las ecuaciones sin tener que revisar trabajosamente el archivo fuente es una gran ayuda. As versiones preliminares pueden ser compiladas con la opcin keys, y la versin final sin i, o o ella, para no confesar al lector nuestra mala memoria o nuestra comodidad. A 6.13. MODIFICANDO L TEX. 201 Caso 1: \documentclass[12pt]{mfm2} La opcin keys resulta muy util cuando tengo objetos numeo rados automticamente, como una ecuacin: a o F = ma . y luego quiero referirme a ella: Ec. (1). (1) Caso 2: \documentclass[keys,12pt]{mfm2} La opcin keys resulta muy util cuando tengo objetos numeo rados automticamente, como una ecuacin: a o F = ma . y luego quiero referirme a ella: Ec. (1). (1) newton 202 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . 6.14. 6.14.1. Errores y advertencias. Errores. Un mensaje de error t ipico tiene la forma: LaTeX error. See LaTeX manual for explanation. Type H <return> for immediate help. ! Environment itemie undefined. \@latexerr ...or immediate help.}\errmessage {#1} \endgroup l.140 \begin{itemie} ? A La primera l inea nos comunica que L TEX ha encontrado un error. A veces los errores tienen que ver con procesos ms internos, y son encontrados por TEX. Esta l a inea nos informa quin encontr el error. e o La tercera l inea comienza con un signo de exclamacin. Este es el indicador del error. Nos o dice de qu error se trata. e Las dos l ineas siguientes describen el error en trminos de comandos de bajo nivel. e La l inea 6 nos dice dnde ocurri el error: la l o o inea 140 en este caso. Adems nos informa a del texto conflictivo: \begin{itemie}. A En realidad, el mensaje nos indica dnde L TEX advirti el error por primera vez, que no o o es necesariamente el punto donde el error se cometi. Pero la gran mayor de las veces la o ia indicacin es precisa. De hecho, es fcil darse cuenta, con la tercera l o a inea (Environment itemie undefined) y la sexta (\begin{itemie}) que el error consisti en escribir itemie en vez de itemize. La o A X es clara en este caso y nos dice correctamente qu ocurri y dnde. informacin de L TE o e o o A Luego viene un ?. L TEX est esperando una respuesta de nosotros. Tenemos varias altera nativas. Comentaremos slo cuatro, t o ipicamente usadas: (a) h <Enter> Solicitamos ayuda. TEX nos explica brevemente en qu cree l que consiste el error y/o e e nos da alguna recomendacin. o (b) x <Enter> Abortamos la compilacin. Deberemos volver al editor y corregir el texto. Es la opcin o o ms t a ipica cuando uno tiene ya cierta experiencia, pues el mensaje basta para reconocer el error. (c) <Enter> Ignoramos el error y continuamos la compilacin. TEX hace lo que puede. En algunos o casos esto no tiene consecuencias graves y podremos llegar hasta el final del archivo sin mayores problemas. En otros casos, ignorar el error puede provocar que ulteriores comandos --perfectamente vlidos en principio-- no sean reconocidos y, as acumular a i, 6.14. ERRORES Y ADVERTENCIAS. 203 muchos errores ms. Podemos continuar con <Enter> sucesivos hasta llegar al final de a la compilacin. o (d) q <Enter> La accin descrita en el punto anterior puede llegar a ser tediosa o infinita. q hace o ingresar a TEX en batchmode, modo en el cual la compilacin prosigue ignorando todos o los errores hasta el final del archivo, sin enviar mensajes a pantalla y por ende sin que debamos darle infinitos <Enter>. Las opciones (c) y (d) son utiles cuando no entendemos los mensajes de error. Como TEX seguir compilando haciendo lo mejor posible, al mirar el dvi puede que veamos ms a a claramente dnde comenzaron a ir mal las cosas y, por tanto, por qu. o e A Como dijimos, L TEX indica exactamente dnde encontr el error, de modo que hemos de o o ponerle atencin. Por ejemplo, si tenemos en nuestro documento la l o inea: ... un error inesperado\fotnote{En cualquier punto.} puede decidir... generar el mensaje de error: ia ! Undefined control sequence. l.249 ...un error inesperado\fotnote {En cualquier punto.} ? En la l inea de localizacin, L TEX ha cortado el texto justo despus del comando inexiso A e A X no slo indica la l tente. L TE o inea en la cual detect el error, sino el punto de ella donde ello o ocurri. (En realidad, hizo lo mismo --cortar la l o inea para hacer resaltar el problema-- en el o i caso expuesto en la pg. 202, pero ello ocurri en medio de comandos de bajo nivel, as que a no era muy informativo de todos modos.) Errores ms comunes. a Los errores ms comunes son: a a) Comando mal escrito. b) Parntesis cursivos no apareados. e c) Uso de uno de los caracteres especiales #, $, %, &, _, {, }, ~, ^, \ como texto ordinario. d) Modo matemtico abierto de una manera y cerrado de otra, o no cerrado. a e) Ambiente abierto con \begin... y cerrado con un \end... distinto. f) Uso de un comando matemtico fuera de modo matemtico. a a g) Ausencia de argumento en un comando que lo espera. h) L inea en blanco en ambiente matemtico. a 204 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Algunos mensajes de error. A A continuacin, una peque~a lista de errores (de L TEX y TEX) en orden alfabtico, y sus o n e posibles causas. * Falta \end{document}. (Dar Ctrl-C o escribir \end{document} para salir de la compilacin.) o ! \begin{...} ended by \end{...} Error e) de la Sec. 6.14.1. El nombre del ambiente en \end{...} puede estar mal escrito, sobra un \begin o falta un \end. ! Double superscript (o subscript). Una expresin como x^2^3 o x_2_3. Si se desea obtener x2 (x23 ), escribir {x^2}^3 ({x_2}_3). o ! Environment ... undefined. \begin{...} con un argumento que corresponde a un ambiente no definido. ! Extra alignment tab has been changed. En un tabular o array sobra un &, falta un \\, o falta una c, l r en el argumento o obligatorio. ! Misplaced alignment tab character &. Un & aparece fuera de un tabular o array. ! Missing $ inserted. Errores c), d), f), h) de la Sec. 6.14.1. ! Missing { (o }) inserted. Parntesis cursivos no apareados. e ! Missing \begin{document}. Falta \begin{document} o hay algo incorrecto en el prembulo. a ! Missing number, treated as zero. A Falta un nmero u donde L TEX \setlength{\textwidth}{a}, etc. 3 lo espera: \hspace{}, \vspace cm, ! Something's wrong -- perhaps a missing \item. Posiblemente la primera palabra \begin{itemize} no es \item. ! Undefined control sequence. Aparece una secuencia \<palabra>, donde <palabra> no es un comando. despus e de un \begin{enumerate} o 6.14. ERRORES Y ADVERTENCIAS. 205 6.14.2. Advertencias. A La estructura de una advertencia de L TEX es: LaTeX warning. <mensaje>. Algunos ejemplos: Label `...' multiply defined. Dos \label tienen el mismo argumento. Label(s) may have changed. Rerun to get cross-references right. Los nmeros impresos por \ref y \pageref pueden ser incorrectos, pues los valores corresu pondientes cambiaron respecto al contenido del aux generado en la compilacin anterior. o Reference `...' on page ... undefined. El argumento de un \ref o un \pageref no fue definido por un \label. TEX tambin env advertencias. Se reconocen porque no comienzan con TeX warning. e ia Algunos ejemplos. Overfull \hbox ... TEX no encontr un buen lugar para cortar una l o inea, y puso ms texto en ella que lo a conveniente. Overfull \vbox ... TEX no encontr un buen lugar para cortar una pgina, y puso ms texto en ella que lo o a a conveniente. Underfull \hbox ... TEX construy una l o inea con muy poco material, de modo que el espacio entre palabras puede ser excesivo. Underfull \vbox ... TEX construy una pgina con muy poco material, de modo que los espacios verticales (entre o a prrafos) pueden ser excesivos. a A Las advertencias de L TEX siempre deben ser atendidas. Una referencia doblemente definiA da, o no compilar por segunda vez cuando L TEX lo sugiere, generar un resultado incorrecto a en el dvi. Una referencia no definida, por su parte, hace aparecer un signo ?? en el texto final. Todos resultados no deseados, por cierto. Las advertencias de TEX son menos decisivas. Un overfull o underfull puede redundar en que alguna palabra se salga del margen derecho del texto, que el espaciado entre palabras en una l inea sea excesivo, o que el espacio vertical entre prrafos sea demasiado. Los estndares a a de calidad de TEX son altos, y por eso env advertencias frecuentemente. Pero generalmente ia los defectos en el resultado final son imperceptibles a simple vista, o por lo menos no son suficientes para molestarnos realmente. A veces s por supuesto, y hay que estar atentos. i, Siempre conviene revisar el texto y prestar atencin a estos detalles, aunque ello slo tiene o o sentido al preparar la versin definitiva del documento. o 206 CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . Parte II Mtodos Numricos. e e 207 Cap itulo 7 Preliminares. versin 4.1, 6 de Noviembre del 2007 1 . o 7.1. Programas y funciones. En esta seccin nosotros escribiremos algunos programas simples usando Python, C++ y o Octave. En nuestro primer ejemplo, llamado orthog, probaremos si dos vectores son ortogonales calculando su producto punto. Este simple programa lo bosquejamos a continuacin o Inicializamos los vectores a y b. Evaluamos el producto punto como a b = a1 b1 + a2 b2 + a3 b3 . Imprimir el producto punto y establecer si los vectores son ortogonales. Programa de ortogonalidad en Python. Escribimos una clase en Python de vectores en tres dimensiones en el archivo vector3d.py, el constructor y sobrecargamos la multiplicacin y la impresin o o from math import sqrt class Vec3: def __init__(self, x=0, y=0, z=0): self.x = x self.y = y self.z = z def __mul__(self,new): return self.x*new.x+self.y*new.y+self.z*new.z def __repr__(self): return ``(%1.5f,%1.5f,%1.5f)'' % (self.x,self.y,self.z) Este cap itulo est basado en el primer cap a itulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall 1 209 210 CAP ITULO 7. PRELIMINARES. Escribimos el programa, orthog, usando la clase anterior #!/usr/bin/env python from vector3d import * def main(): x1=input(``Ingrese la primera coordenada del 1er vector : ``) x2=input(``Ingrese la segunda coordenada del 1er vector : ``) x3=input(``Ingrese la tercera coordenada del 1er vector : ``) c=Vec3(x1,x2,x3) x1=input(``Ingrese la primera coordenada del 2do vector : ``) x2=input(``Ingrese la segunda coordenada del 2do vector : ``) x3=input(``Ingrese la tercera coordenada del 2do vector : ``) d=Vec3(x1,x2,x3) if c*d==0: print ``Los vectores ingresados son ortogonales'' else: print ``Los vectores ingresados no son ortogonales'' if __name__ == `__main__': main() Primero cambiamos los permisos del archivo orthog.py para que sea ejecutable y luego usamos el programa jrogan@huelen:~/programas_metodos_numericos/pyhton$ chmod 744 orthog.py%$ jrogan@huelen:~/programas_metodos_numericos/pyhton$ orthog.py%$ Ingrese la primera coordenada del 1er vector : 1 Ingrese la segunda coordenada del 1er vector : 0 Ingrese la tercera coordenada del 1er vector : 0 Ingrese la primera coordenada del 2do vector : 0 Ingrese la segunda coordenada del 2do vector : 1 Ingrese la tercera coordenada del 2do vector : 0 Los vectores ingresados son ortogonales Programa de ortogonalidad en C++. Ahora consideremos la versin en C++ del programa orthog, el cual prueba si dos vectores o son ortogonales mediante el clculo de su producto punto. Primero escribiremos una clase a muy bsica de vectores en tres dimensiones. a 7.1. PROGRAMAS Y FUNCIONES. Las declaraciones estn en vector3d.h a #ifndef _vector_3d_h #define _vector_3d_h // // Clase basica de vectores 3d // #include <iostream> class Vector{ private: double c_x; double c_y; double c_z; public: Vector():c_x(0),c_y(0),c_z(0) {} ; Vector(double x, double y, double z):c_x(x),c_y(y),c_z(z) {} ; ~Vector() {} ; double x() const {return c_x;}; double y() const {return c_y;}; double z() const {return c_z;}; }; double operator * (const Vector &, const Vector &) ; istream & operator >> (istream &, Vector &) ; #endif 211 La peque~a implementacin necesaria para esta clase la escribimos en vector3d.cc el cual n o es listado a continuacin o #include "vector3d.h" double operator * (const Vector & v1, const Vector &v2) { return v1.x()*v2.x()+v1.y()*v2.y()+ v1.z()*v2.z() ; } istream & operator >> (istream & is, Vector & v) { double x,y,z ; is >> x >> y>>z ; v= Vector(x,y,z) ; return is; } Ahora estamos en condiciones de escribir el programa propiamente tal. Las primeras l ineas son 212 CAP ITULO 7. PRELIMINARES. // orthog - Programa para probar si un par de vectores es ortogonal. // Supondremos vectores en 3D. #include ``vector3d.h'' using namespace std; Las primeras l ineas son comentarios que nos recuerdan lo que el programa hace. La l inea siguiente incluye las definiciones de nuestra recin creada clase. Luego inclu e imos una l inea dice que vamos a usar el namespace std. A continuacin comienza el programa o // // orthog - Programa para probar si un par de vectores es ortogonal. Usaremos vectores en 3D. #include "vector3d.h" using namespace std; int main() { Vector a, b; cout << "Ingrese el primer vector : "; cin >> a ; cout << "Ingrese el segundo vector : "; cin >> b ; if(a*b==0) { cout <<"Son ortogonales" << endl; } else { cout << "No son ortogonales"<< endl ; } return 0; } Declaramos dos objetos tipo Vector, a y b para almacenar los vectores que entran. La instruccin de salida despliega sobre la pantalla: o Ingrese el primer vector : La instruccin de entrada lee el Vector en a y luego, de la misma manera, el Vector b. Las o prximas l o ineas hacen el trabajo if(a*b==0) { cout <<"Son ortogonales" << endl; } else { cout << "No son ortogonales"<< endl ; } y despliega el resultados. Aqu los comandos de compilacin y una salida t i o ipica del programa. 7.1. PROGRAMAS Y FUNCIONES. jrogan@pucon:~$ g++ -Wall -o orthog orthog.cc vector3d.cc jrogan@pucon:~$ orthog Ingrese el primer vector : 1 0 0 Ingrese el segundo vector : 0 1 0 Son ortogonales Programa de ortogonalidad en Octave. 213 Primero consideremos la versin en Octave del programa que llamaremos orthog.m. Las o primeras l ineas de orthog son: % orthog - Programa para probar si un par de vectores es ortogonal. % Supondremos vectores en 3D. clear all; % Borra la memoria Las primeras dos l ineas son comentarios; si tipeamos help orthog desde la l inea de comandos, Octave desplegar estas l a ineas. El comando clear all en la tercera l inea borra la memoria. Las prximas l o ineas del programa %* Inicializa los vectores a y b a= input('Entre el primer vector: '); b= input('Entre el segundo vector: '); Los vectores entran usando el comando input en estas l ineas. Los comentarios que comienzan con %* son aquellos que corresponden al bosquejo del programa que hicimos. En las l ineas siguientes se evala el producto punto. u %* Evalua el producto punto como la suma sobre el producto de los elementos adotb=0; for i=1:3 adotb=adotb+a(i)*b(i); end El ciclo for, usando el indice i, recorre las componentes de los vectores. Una manera hbil a de hacer lo mismo podr ser usar ia %* Evalua el producto punto como el producto de dos vectores adotb=a*b' ; En este caso, hemos usado la multiplicacin de matrices de Octave para calcular el producto o punto como el producto vectorial del vector fila a y el columna b' (donde hemos usado el operador Herm itico conjugado '). Las ultimas l ineas del programa %* Imprime el producto punto y si los vectores son ortogonales if(adotb==0) disp('Los vectores son ortogonales'); else disp('Los vectores no son ortogonales'); printf('Producto punto = %g \n', adotb); end 214 CAP ITULO 7. PRELIMINARES. De acuerdo al valor de adotb el programa despliega una de las dos posibles respuestas. A continuacin la salida al ejecutar el help del programa o octave> help orthog orthog is the file: /home/jrogan/orthog.m orthog - Programa para probar si un par de vectores es ortogonal. Supondremos vectores en 3D. Additional help for builtin functions, operators, and variables is available in the on-line version of the manual. Use the command `help -i <topic>' to search the manual index. Help and information about Octave is also available on the WWW at http://www.che.wisc.edu/octave/octave.html and via the help-octave@bevo.che.wisc.edu mailing list. Ahora ejecutamos el programa con diferentes vectores. octave> orthog Entre el primer vector: [1 1 1] Entre el segundo vector: [1 -2 1] Los vectores son ortogonales octave> orthog Entre el primer vector: [1 1 1] Entre el segundo vector: [2 2 2] Los vectores no son ortogonales Producto punto = 6 Interpolacin. o Es bien sabido que dados tres pares (x, y), se puede encontrar una cuadrtica que pasa a por los puntos deseados. Hay varias maneras de encontrar el polinomio y varias maneras de escribirlo. La forma de Lagrange del polinomio es (x - x1 )(x - x3 ) (x - x1 )(x - x2 ) (x - x2 )(x - x3 ) y1 + y2 + y3 , (7.1) p(x) = (x1 - x2 )(x1 - x3 ) (x2 - x1 )(x2 - x3 ) (x3 - x1 )(x3 - x2 ) donde (x1 , y1 ), (x2 , y2 ), (x3 , y3 ), son los tres puntos por los que queremos pasar. Comnmente u tales polinomios son usados para interpolar entre los puntos dados. A continuacin el bosquejo o de un programa simple de interpolacin, que llamaremos interp o Inicializa los puntos (x1 , y1 ), (x2 , y2 ) y (x3 , y3 ) para ser ajustados por el polinomio. Establece el intervalo de la interpolacin (desde xm hasta xmx ) o in a Encuentra y para los valores deseados de x , usando la funcin intrpf. o Finalmente, podemos graficar la curva dada por (x , y ), y marcar los puntos originales para comparar. 7.1. PROGRAMAS Y FUNCIONES. Programa de interpolacin en Python. o Las primeras l ineas de la versin en Python del programa interp son o #!/usr/bin/env python # -*- coding: iso-8859-1 -*# interp - Programa para interpolar datos usando # el polinomio de Lagrange cuadratico para tres puntos dados. # Importa un modulo que permite graficar. from pylab import * # Definicion de la funcion que evalua el polinomio. def intrpf(x,x_i,y_i): t0=y_i[0]*(x-x_i[1])*(x-x_i[2])/((x_i[0]-x_i[1])*(x_i[0]-x_i[2])) t1=y_i[1]*(x-x_i[0])*(x-x_i[2])/((x_i[1]-x_i[0])*(x_i[1]-x_i[2])) t2=y_i[2]*(x-x_i[0])*(x-x_i[1])/((x_i[2]-x_i[0])*(x_i[2]-x_i[1])) return t0+t1+t2 def main(): # Se ingresan los tres puntos y se almacenan en dos listas x_i e y_i x_i= y_i= print "Ingrese tres puntos (x,y)" x0=input("Coordenada x, primer punto : ") y0=input("Coordenada y, primer punto : ") x1=input("Coordenada x, segundo punto : ") y1=input("Coordenada y, segundo punto : ") x2=input("Coordenada x, tercer punto : ") y2=input("Coordenada y, tercer punto : ") x_i.append(x0) x_i.append(x1) x_i.append(x2) y_i.append(y0) y_i.append(y1) y_i.append(y2) # Se ingresa el intervalo donde se evaluara el polinomio print "Ingrese intervalo para hacer la interpolacion" x_min=input("Coordenada x minimo : ") x_max=input("Coordenada x maximo : ") # Grafica t=arange(x_min,x_max,(x_max-x_min)/100.0) plot(x_i, y_i,'ro',t, intrpf(t,x_i,y_i)) title("Polinomio de interpolacion de Lagrange") grid(True) show() if __name__=='__main__': main() 215 216 Usando el programa CAP ITULO 7. PRELIMINARES. jrogan@huelen:~/programas_metodos_numericos/pyhton$ interp.py Ingrese tres puntos (x,y) Coordenada x, primer punto : 0.5 Coordenada y, primer punto : 0.25 Coordenada x, segundo punto : 1 Coordenada y, segundo punto : 1 Coordenada x, tercer punto : 2 Coordenada y, tercer punto : 4 Ingrese intervalo para hacer la interpolacion Coordenada x minimo : -3 Coordenada x maximo : 3 El uso de las instruccin plot en el programa levanta una ventana independiente con el o siguiente grfico: a Figura 7.1: Salida grfica del programa interp. a 7.1. PROGRAMAS Y FUNCIONES. Programa de interpolacin en C++. o Las primeras l ineas de la versin en C++ del programa interp son o // interp - Programa para interpolar datos usando // el polinomio de Lagrange cuadratico para tres puntos dados. #include "NumMeth.h" double intrpf(double xi, double x, double y); int main() { 217 Comentarios ms una instruccin para incluir el archivo de encabezamiento NumMeth.h, lisa o tado a continuacin o #include #include #include #include <iostream> <fstream> <cmath> <cstdlib> using namespace std; La declaracin double intrpf(..) afirma que el programa pretende llamar una funcin o o intrpf, la cual tiene tres argumentos de tipo double y devuelve un double. Las prximas o l ineas del programa // Inicializa los puntos a ser ajustados con una cuadratica double x[3], y[3] ; cout << "Entre los puntos como pares x,y (e.g., [1 2])" << endl ; for(int i=0; i<3; i++) { cout << "x["<<i<<"] = "; cin>> x[i]; cout << "y["<<i<<"] = "; cin >> y[i]; } // Establece el intervalo de interpolacion (desde x_min a x_max) double xmin, xmax; cout <<"Entre el valor minimo de x: "; cin >> xmin ; cout <<"Entre el valor maximo de x: "; cin >> xmax ; El programa pregunta por los puntos para ajustar el polinomio de Lagrange (7.1) y por el intervalo de interpolacin. Lo siguiente, los arreglos xi y yi son declarados: o // Encontrar yi para los valores deseados de interpolacion xi // usando la funcion intrpf int nplot= 100; // Numero de puntos para la curva interpolada double * xi = new double[nplot] ; // Reserva memoria para double * yi = new double[nplot] ; // estos arreglos. 218 Estas l ineas tambin podr reemplazarse por e ian CAP ITULO 7. PRELIMINARES. int nplot = 100; // Numero de puntos para la curva interpolada double xi[nplot], yi[nplot] ; En ambos casos hay asignamiento dinmico de memoria, nplot podr ser una entrada del a ia programa. Los valores interpolados son calculados en un for for(int i=0; i<nplot;i++) { xi[i] = xmin+(xmax-xmin)*double(i)/double(nplot-1); yi[i] = intrpf(xi[i], x, y); // Usando intrpf para interpolar } Notemos que xi[1]=xm , xi[nplot]=xmx , con valores equiespaciados entre ellos. Los vain a lores de yi (y = p(x )) son evaluados usando la ecuacin (7.1) en la funcin intrpf. La o o salida del programa // Imprime las variables para graficar: x, y, xi, yi ofstream xOut("x.txt"), yOut("y.txt"), xiOut("xi.txt"), yiOut("yi.txt"); for(int i =0; i <3; i++) { xOut << x[i] << endl; yOut << y[i] << endl; } for(int i =1; i <=nplot; i++) { xiOut << xi[i] << endl; yiOut << yi[i] << endl; } xOut.close() ; yOut.close() ; xiOut.close(); yiOut.close() ; Estos cuatro archivos de datos (x.txt, y.txt, etc.) son creados. Desgraciadamente, C++ carece de una biblioteca grfica estndar, as que necesitamos a a i una aplicacin grfica adicional para graficar la salida. Tambin podemos usar un peque~o o a e n script en Octave: #!/usr/bin/octave load x.txt; load y.txt; load xi.txt; load yi.txt; %* Grafica la curva dada por (xi,yi) y marca los puntos originales xlabel('x'); ylabel('y'); title('Interpolacion de tres puntos'); gset nokey; plot(x,y, '*',xi,yi,'-'); pause Al cual, incluso, podemos llamar desde el mismo programa mediante system( "grafica.m" ) ; 7.1. PROGRAMAS Y FUNCIONES. Interpolacion de tres puntos 9 8 7 6 5 y 4 3 2 1 0 -3 -2 -1 0 x 1 2 3 219 Figura 7.2: Salida grfica del programa interp. a La ultima l inea del programa delete xi, yi ; // Libera la memoria pedida con "new" return 0; } Esta l inea no es absolutamente necesaria, por que al salir el programa liberar la memoria a de todas maneras. Sin embargo, se considera como buen estilo de programacin, limpiar uno o la memoria que requiri durante la ejecucin del programa. o o La funcin intrpf, la cual evala el polinomio de Lagrange, comienza por las siguientes o u l ineas double intrpf( double xi, double x, double y) { // Funcion para interpolar entre puntos // usando polinomio de Lagrange (cuadratico) // Entradas // x Vector de las coordenadas x de los puntos dados (3 valores) // y Vector de las coordenadas y de los puntos dados (3 valores) // Salida // yi El polinomio de interpolacion evaluado en xi Especifica los argumentos de llamada y lo que devuelve. Todas las variables dentro de la funcin son locales. El C++ pasa las variables por valor, por defecto, la funcin recibe una o o copia que se destruye cuando termina la funcin, si se desea pasar una variable double a o por referencia debemos anteponerle el signo &, es decir, pasarla como double &a. De esta manera la funcin puede modificar el valor que ten la variable en el programa principal. o ia El resto de la funcin o 220 CAP ITULO 7. PRELIMINARES. //* Calcula yi=p(xi) usando Polinomio de Lagrange double yi = (xi-x[2])*(xi-x[3])/((x[1]-x[2])*(x[1]-x[3]))*y[1] + (xi-x[1])*(xi-x[3])/((x[2]-x[1])*(x[2]-x[3]))*y[2] + (xi-x[1])*(xi-x[2])/((x[3]-x[1])*(x[3]-x[2]))*y[3]; return yi ; Estas l ineas evalan el polinomio. Inicialmente pondremos esta funcin en el mismo archivo, u o luego la podemos separar en otro archivo y escribir un Makefile que genere el ejecutable. Programa de interpolacin en Octave. o Las primeras l ineas del programa % interp - Programa para interpolar datos usando % el polinomio de Lagrange cuadratico para tres puntos dados. clear all; %* Inicializa los puntos a ser ajustados con una cuadratica disp('Entre los puntos como pares x,y (e.g., [1 2])'); for i=1:3 temp =input('Ingrese el punto: '); x(i)=temp(1); y(i)=temp(2) ; end %* Establece el intervalo de interpolacion (desde x_min a x_max) xr = input ('Ingrese el intervalo de valores de x como [x_min x_max]: '); Aqu el programa lee los tres pares (x, y) y el intervalo de valores entre los cuales ser interi a polado. Los valores interpolados y = p(x ) son calculados por la funcin intrpf desde x = xm o in a x = xmx . Estos valores de y (yi) son calculados en el ciclo. a %* Encontrar yi para los valores deseados de interpolacion xi % usando la funcion intrpf nplot= 100; % Numero de puntos para la curva interpolada for i=1:nplot xi(i) = xr(1)+(xr(2)-xr(1))*(i-1)/(nplot-1); yi(i) = intrpf(xi(i), x, y); % Usando intrpf para interpolar end Finalmente, los resultados son graficados usando las funciones grficas de Octave. a %* Grafica la curva dada por (xi,yi) y marca los puntos originales xlabel('x'); ylabel('y'); title('Interpolacion de tres puntos'); gset nokey; plot(x,y, '*',xi,yi,'-'); 7.2. ERRORES NUMERICOS. 221 Los puntos de la interpolacin (x , y ) son graficados con l o inea segmentada y los datos originales con c irculos, ver figura (7.2). El trabajo real es hecho por la funcin intrpf. Un o bosquejo de lo que queremos que haga esta funcin a continuacin. o o Entrada: x = [x1 x2 x3 ], y = [y1 y2 y3 ], y x . Salida: y . Clculo de y = p(x ) usando el polinomio de Lagrange (7.1). a Las funciones en Octave estn implementadas como en la mayor de los lenguajes, excepto a ia que aqu cada funcin tiene que ir en un archivo separado. El nombre del archivo debe i o coincidir con el nombre de la funcin (la funcin intrpf est en el archivo intrpf.m). o o a function yi=intrpf(xi,x,y) % Funcion para interpolar entre puntos % usando polinomio de Lagrange (cuadratico) % Entradas % x Vector de las coordenadas x de los puntos dados (3 valores) % y Vector de las coordenadas y de los puntos dados (3 valores) % Salida % yi El polinomio de interpolacion evaluado en xi La funcin intrpf tiene tres argumentos de entrada y uno de salida. El resto de la funcin o o o o es directa, slo evala el polinomio definido en (7.1). El cuerpo de la funcin a continuacin o u yi = (xi-x(2))*(xi-x(3))/((x(1)-x(2))*(x(1)-x(3)))*y(1) ... + (xi-x(1))*(xi-x(3))/((x(2)-x(1))*(x(2)-x(3)))*y(2) ... + (xi-x(1))*(xi-x(2))/((x(3)-x(1))*(x(3)-x(2)))*y(3); return; 7.2. 7.2.1. Errores numricos. e Errores de escala. Un computador almacena nmeros de punto flotante usando slo una peque~a cantidad u o n de memoria. T ipicamente, a una variable de precisin simple (un float en C++) se le o asignan 4 bytes (32 bits) para la representacin del nmero, mientras que una variable de o u doble precisin (double en C++, por defecto en Python y Octave) usa 8 bytes. Un nmero de o u punto flotante es representado por su mantisa y su exponente (por ejemplo, para 6.62510-27 la mantisa decimal es 6.625 y el exponente es -27). El formato IEEE para doble precisin o usa 53 bits para almacenar la mantisa (incluyendo un bit para el signo) y lo que resta, 11 bit para el exponente. La manera exacta en que el computador maneja la representacin de o los nmeros no es tan importante como saber el intervalo mximo de valores y el nmero de u a u cifras significativas. El intervalo mximo es el l a imite sobre la magnitud de los nmeros de punto flotante u impuesta por el nmero de bit usados para el exponente. Para precisin simple un valor u o 222 CAP ITULO 7. PRELIMINARES. t ipico es 2127 1038 ; para precisin doble es t o ipicamente 21024 10308 . Exceder el intervalo de la precisin simple no es dif o icil. Consideremos, por ejemplo, la evaluacin del o radio de Bohr en unidades SI, a0 = 40 2 5.3 10-11 [m] . 2 me e (7.2) Mientras sus valores caen dentro del intervalo de un nmero de precisin simple, el intervalo u o 2 -78 2 es excedido en el clculo del numerador (40 1.24 10 a [kg C m]) y del denominador (me e2 2.34 10-68 [kg C2 ]). La mejor solucin para lidiar con este tipo de dificultades de o intervalo es trabajar en un conjunto de unidades naturales al problema (e.g. para problemas atmicos se trabaja en las distancias en ngstroms y la carga en unidades de la carga del o A electrn). o Algunas veces los problemas de intervalo no son causados por la eleccin de las unidao des, sino porque los nmeros en el problema son inherentemente grandes. Consideremos un u importante ejemplo, la funcin factorial. Usando la definicin o o n! = n (n - 1) (n - 2) . . . 3 2 1 , es fcil evaluar n! en Python, a nFactorial=1; for i in range(1,n+1): nFactorial *=i o en C++, double nFactorial=1; for(int i=1; i <=n; i++) nFactorial *=i ; donde n es un nmero dado. u En Octave, usando el operador dos puntos este clculo puede ser realizado como a nFactorial = prod(1:n); donde prod(x) es el producto de los elementos del vector x y 1:n=[1,2. . . , n]. Infortunadamente, debido a problemas de intervalo, no podemos calcular n! para n > 170 usando estos mtodos directos de evaluacin (7.3). e o Una solucin comn para trabajar con nmeros grandes es usar su logaritmo. Para el o u u factorial log(n!) = log(n) + log(n - 1) + . . . + log(3) + log(2) + log(1) . (7.4) En Octave, esto puede ser evaluado como log_nFactorial = sum( log(1:n) ) ; donde sum(x) es la suma de los elementos del vector x. Sin embargo, este esquema es computacionalmente pesado si n es grande. Una mejor estrategia es combinar el uso de logaritmos con la frmula de Stirling2 o 1 1 n! = 2nnn e-n 1 + + + (7.5) 12n 288n2 2 (7.3) M. Abramowitz and I. Stegun, Handbook of Mathematical Functions ( New York: Dover 1972). 7.2. ERRORES NUMERICOS. o log(n!) = 1 1 1 log(2n) + n log(n) - n + log 1 + + + 2 12n 288n2 . 223 (7.6) Esta aproximacin puede ser usada cuando n es grande (n > 30), de otra manera es preferible o la definicin original. o Finalmente, si el valor de n! necesita ser impreso, podemos expresarlo como n! = (mantisa) 10(exponente) , (7.7) donde el exponente es la parte entera de log10 (n!), y la mantisa es 10a donde a es la parte fraccionaria de log10 (n!). Recordemos que la conversin entre logaritmo natural y logaritmo o en base 10 es log10 (x) = log10 (e) log(x). 7.2.2. Errores de redondeo. Supongamos que deseamos calcular numricamente f (x), la derivada de una funcin e o conocida f (x). En clculo se aprendi que la frmula para la derivada es a o o f (x) = f (x + h) - f (x) , h (7.8) en el l imite en que h 0. Qu sucede si evaluamos el lado derecho de esta expresin, e o poniendo h = 0?. Como el computador no entiende que la expresin es vlida slo como un o a o l imite, la divisin por cero tiene varias posibles salidas. El computador puede asignar el valor, o Inf, el cual es un nmero de punto flotante especial reservado para representar el infinito. Ya u que el numerador es tambin cero el computador podr evaluar el cociente siendo indefinido e ia (Not-a-Number), NaN, otro valor reservado. O el clculo podr parar y arrojar un mensaje a ia de error. a Claramente, poniendo h = 0 para evaluar (7.8) no nos dar nada util, pero si le ponemos -300 a h un valor muy peque~o, digamos h = 10 n , usamos doble precisin? La respuesta an o u ser incorrecta debido a la segunda limitacin sobre la representacin de nmeros con punto a o o u flotante: el nmero de d u igitos en la mantisa. Para precisin simple, el nmero de d o u igitos significantes es t ipicamente 6 o 7 d igitos decimales; para doble precisin es sobre 16 d o igitos. As en doble precisin, la operacin 3 + 10-20 retorna una respuesta 3 por el redondeo; i, o o usando h = 10-300 en la ecuacin (7.8) casi con seguridad regresar 0 cuando evaluemos el o a numerador. La figura 7.3 ilustra la magnitud del error de redondeo en un clculo t a ipico de derivada. Definimos el error absoluto (h) = f (x) - f (x + h) - f (x) h . (7.9) Notemos que (h) decrece cuando h se hace ms peque~o, lo cual es esperado, dado que a n la ecuacin (7.8) es exacta cuando h 0. Por debajo de h = 10-10 , el error comienza a o incrementarse debido a efectos de redondeo. En valores menores de h el error es tan grande 224 CAP ITULO 7. PRELIMINARES. 10 0 10 -2 (h) 10 -4 10 -6 10 -8 10 -10 10 -20 10 -16 10 -12 10 -8 10 -4 10 0 h Figura 7.3: Error absoluto (h), ecuacin (7.9), versus h para f (x) = x2 y x = 1. o que la respuesta carece de sentido. Volveremos en el prximo cap o itulo a la pregunta de cmo o mejorar el clculo de la derivada numricamente. a e Para testear la tolerancia del redondeo, definimos como el ms peque~o nmero que, a n u cuando es sumado a uno, regresa un valor distinto de 1. En Octave, la funcin integrada o eps devuelve 2.22 10-16 . En C++, el archivo de encabezamiento <cfloat> define DBL_EPSILON (2.2204460492503131e-16) como para doble precisin. o Debido a los errores de redondeo la mayor de los clculos cient ia a ificos usan doble precisin. o Las desventajas de la doble precisin son que requieren ms memoria y que algunas veces (no o a siempre) es ms costosa computacionalmente. Los procesadores modernos estn construidos a a para trabajar en doble precisin, tanto que puede ser ms lento trabajar en precisin simple. o a o Usar doble precisin algunas veces slo desplaza las dificultades de redondeo. Por ejemplo, el o o clculo de la inversa de una matriz trabaja bien en simple precisin para matrices peque~as a o n de 50 50 elementos, pero falla por errores de redondeo para matrices ms grandes. La a doble precisin nos permite trabajar con matrices de 100 100, pero si necesitamos resolver o sistemas an ms grandes debemos usar un algoritmo diferente. La mejor manera de trabajar u a es usar algoritmos robustos contra el error de redondeo. Cap itulo 8 Ecuaciones diferenciales ordinarias: Mtodos bsicos. e a versin 4.0, 6 de Noviembre del 20071 . o En este cap itulo resolveremos uno de los primeros problemas abordados por un estudiante de f isica: el vuelo de un proyectil y, en particular, el de una pelota de baseball. Sin la resistencia del aire el problema es fcil de resolver. Sin embargo, incluyendo un arrastre realista, nosotros a necesitamos calcular la solucin numricamente. Para analizar este problema definiremos o e primero la diferenciacin numrica. De hecho antes de aprender f o e isica uno aprende clculo a as que no debemos sorprendernos si este es nuestro punto de partida. En la segunda mitad del i cap itulo nos ocuparemos de otro viejo conocido, el pndulo simple, pero sin la aproximacin a e o a ngulos peque~os. Los problemas oscilatorios, tales como el pndulo, nos revelarn una falla n e a fatal en algunos de los mtodos numricos de resolver ecuaciones diferenciales ordinarias. e e 8.1. 8.1.1. Movimiento de un proyectil. Ecuaciones bsicas. a Consideremos el simple movimiento de un proyectil, digamos un pelota de baseball. Para describir el movimiento, nosotros debemos calcular el vector posicin r(t) y el vector velocidad o v(t) del proyectil. Las ecuaciones bsicas de movimiento son a dv 1 = Fa (v) - g y , ^ dt m dr =v , dt (8.1) donde m es la masa del proyectil. La fuerza debido a la resistencia del aire es Fa (v), la aceleracin gravitacional es g, e y es un vector unitario en la direccin y. El movimiento es o ^ o bidimensional, tal que podemos ignorar la componente z y trabajar en el plano xy. La resistencia del aire se incrementa con la velocidad del objeto, y la forma precisa para Fa (v) depende del flujo alrededor del proyectil. Comnmente, esta fuerza es aproximada por u 1 Fa (v) = - Cd A | v | v , 2 1 (8.2) Este cap itulo est basado en el segundo cap a itulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall 225 226 CAP ITULO 8. EDO: METODOS BASICOS. donde Cd es el coeficiente de arrastre, es la densidad del aire, y A es el rea de la seccin a o transversal del proyectil. El coeficiente de arrastre es un parmetro adimensional que depende a de la geometr del proyectil, entre ms aerodinmico el objeto, el coeficiente es menor. ia a a Para una esfera suave de radio R movindose lentamente a travs del fluido, el coeficiente e e de arrastre es dado por la Ley de Stokes, Cd = 12 24 = , Rv Re (8.3) donde es la viscosidad del fluido ( 1.5 10-5 [m2 /s] para el aire) y Re = 2Rv/ es el adimensional nmero de Reynolds. Para un objeto del tama~o de una pelota de baseball u n movindose a travs del aire, la ley de Stokes es vlida slo si la velocidad es menor que e e a o 0.2~ [mm/s] (Re 1). A velocidades altas (sobre 20 [cm/s], Re> 103 ), la estela detrs de la esfera desarrolla a vrtices y el coeficiente de arrastre es aproximadamente constante (Cd 0.5) para un amplio o intervalo de velocidades. Cuando el nmero de Reynolds excede un valor cr u itico, el flujo en la estela llega a ser turbulento y el coeficiente de arrastre cae dramticamente. Esta reduccin a o ocurre porque la turbulencia rompe la regin de bajas presiones en la estela detrs de la o a esfera2 . Para una esfera suave este nmero cr u itico de Reynolds es aproximadamente 3 105 . Para una pelota de baseball, el coeficiente de arrastre es usualmente ms peque~o que el de a n una esfera suave, porque las costuras rompen el flujo laminar precipitando el inicio de la turbulencia. Nosotros podemos tomar Cd = 0.35 como un valor promedio para el intervalo de velocidades t ipicas de una pelota de baseball. Notemos que la fuerza de arrastre, ecuacin (8.2), var como el cuadrado de la magnitud o ia 2 de la velocidad (Fa v ) y, por supuesto, acta en la direccin opuesta a la velocidad. La u o masa y el dimetro de una pelota de baseball son 0.145 [kg] y 7.4 [cm]. Para una pelota de a baseball, el arrastre y la fuerza gravitacional son iguales en magnitud cuando v 40 [m/s]. Nosotros sabemos cmo resolver las ecuaciones de movimiento si la resistencia del aire es o despreciable. La trayectoria es 1 ^ (8.4) r(t) = r1 + v1 t - gt2 y , 2 donde r1 r(0) y v1 v(0) son la posicin y la velocidad inicial. Si el proyectil parte del o origen y la velocidad inicial forma un ngulo con la horizontal, entonces a xmx = a 2 2v1 sen cos , g ymx = a 2 v1 sen2 , 2g (8.5) son el alcance horizontal y la altura mxima. El tiempo de vuelo es a tf l = 2v1 sen . g (8.6) Nuevamente estas expresiones son vlidas slo cuando no hay resistencia con el aire. a o Es fcil demostrar que el mximo alcance horizontal se obtiene cuando la velocidad forma a a un ngulo de 45 con la horizontal. Deseamos mantener esta informacin en mente cuando a o construyamos nuestra simulacin. Si se sabe la solucin exacta para un caso especial, se debe o o comparar constantemente que el programa trabaje bien para este caso. 2 D.J. Tritton, Physical Fluid Dynamics, 2d ed. (Oxford: Clarendon Press, 1988). 8.1. MOVIMIENTO DE UN PROYECTIL. 227 8.1.2. Derivada avanzada. e e Para resolver las ecuaciones de movimiento (8.1) necesitamos un mtodo numrico para evaluar la primera derivada. La definicin formal de la derivada es o f (t + ) - f (t) , (8.7) 0 donde es el incremento temporal o paso en el tiempo. Como ya vimos en el cap itulo pasado esta ecuacin debe ser tratada con cuidado. La figura 7.3 ilustra que el uso de un valor o extremadamente peque~o para causa un gran error en el clculo de (f (t + ) - f (t))/ . n a Espec ificamente, los errores de redondeo ocurren en el clculo de t + , en la evaluacin de la a o funcin f y en la sustraccin del numerador. Dado que no puede ser elegido arbitrariamente o o peque~o, nosotros necesitamos estimar la diferencia entre f (t) y (f (t + ) - f (t))/ para un n finito. Para encontrar esta diferencia usaremos una expansin de Taylor. Como f o isicos usualmente vemos las series de Taylor expresadas como f (t) l im 2 f (t) + . . . (8.8) 2 donde el s imbolo (. . . ) significa trminos de ms alto orden que son usualmente despreciados. e a Una alternativa, forma equivalente de la serie de Taylor usada en anlisis numrico es a e f (t + ) = f (t) + f (t) + 2 f () . (8.9) 2 donde es un valor entre t y t + . No hemos botado ningn trmino, esta expansin tiene u e o un nmero finito de trminos. El teorema de Taylor garantiza que existe algn valor para u e u a el cual (8.9) es cierto, pero no sabemos cul valor es este. La ecuacin previa puede ser rescrita o f (t + ) = f (t) + f (t) + f (t + ) - f (t) 1 - f () , (8.10) 2 donde t t + . Esta ecuacin es conocida como la frmula de la derivada derecha o o o derivada adelantada. El ultimo trmino de la mano derecha es el error de truncamiento; este e error es introducido por cortar la serie de Taylor. o En otras palabras, si mantenemos el ultimo trmino en (8.10), nuestra expresin para e f (t) es exacta. Pero no podemos evaluar este trmino porque no conocemos , todo lo que e conocemos es que yace en algn lugar entre t y t + . As despreciamos el trmino f () u i e (truncamos) y decimos que el error que cometemos por despreciar este trmino es el error de e truncamiento. No hay que confundir ste con el error de redondeo discutido anteriormente. El e error de redondeo depende del hardware, el error de truncamiento depende de la aproximacin o usada en el algoritmo. Algunas veces veremos la ecuacin (8.10) escrita como o f (t) = f (t + ) - f (t) + O( ) (8.11) donde el error de truncamiento es ahora especificado por su orden en , en este caso el error de truncamiento es lineal en . En la figura 7.3 la fuente de error predominante en estimar f (x) como [f (x + h) - f (x)]/h es el error de redondeo cuando h < 10-10 y es el error de truncamiento cuando h > 10-10 . f (t) = 228 CAP ITULO 8. EDO: METODOS BASICOS. 8.1.3. Mtodo de Euler. e Las ecuaciones de movimiento que nosotros deseamos resolver numricamente pueden ser e escritas como: dr dv = a(r, v) , =v , (8.12) dt dt donde a es la aceleracin. Notemos que esta es la forma ms general de las ecuaciones. En o a el movimiento de proyectiles la aceleracin es slo funcin de v (debido al arrastre), en otros o o o problemas (e.g., rbitas de cometas) la aceleracin depender de la posicin. o o a o Usando la derivada adelantada (8.11), nuestras ecuaciones de movimiento son v(t + ) - v(t) + O( ) = a(r(t), v(t)) , r(t + ) - r(t) + O( ) = v(t) , o bien v(t + ) = v(t) + a(r(t), v(t)) + O( 2 ) , r(t + ) = r(t) + v(t) + O( 2 ) . (8.15) (8.16) (8.13) (8.14) notemos que O( ) = O( 2 ). Este esquema numrico es llamado el mtodo de Euler. Antes de e e discutir los mritos relativos de este acercamiento, veamos cmo ser usado en la prctica. e o ia a Primero, introducimos la notacin o fn = f (tn ) , tn = (n - 1) , n = 1, 2, . . . (8.17) tal que f1 = f (t = 0). Nuestras ecuaciones para el mtodo de Euler (despreciando el trmino e e del error) ahora toma la forma vn+1 = vn + an , rn+1 = rn + vn , donde an = a(rn , vn ). El clculo de la trayectoria podr proceder as a ia i: 1. Especifique las condiciones iniciales, r1 y v1 . 2. Elija un paso de tiempo . 3. Calcule la aceleracin dados los actuales r y v. o 4. Use las ecuaciones (8.18) y (8.19) para calcular los nuevos r y v. 5. Vaya al paso 3 hasta que suficientes puntos de trayectoria hayan sido calculados. El mtodo calcula un conjunto de valores para rn y vn que nos da la trayectoria, al menos e en un conjunto discreto de valores. La figura 8.1 ilustra el clculo de la trayectoria para un a unico paso de tiempo. (8.18) (8.19) 8.1. MOVIMIENTO DE UN PROYECTIL. 229 an vn x vn vn vn+1 an rn rn+1 y Figura 8.1: Trayectoria de una part icula despus de un unico paso de tiempo con el mtodo e e de Euler. Slo para efectos ilustrativos es grande. o 8.1.4. Mtodos de Euler-Cromer y de Punto Medio. e Una simple (y por ahora injustificada) modificacin del mtodo de Euler es usar las o e siguientes ecuaciones: vn+1 = vn + an , rn+1 = rn + vn+1 . (8.20) (8.21) Notemos el cambio sutil: La velocidad actualizada es usada en la segunda ecuacin. Esta o 3 frmula es llamada mtodo de Euler-Cromer . El error de truncamiento es an del orden o e u 2 de O( ), no parece que hemos ganado mucho. Veremos que esta forma es marcadamente superior al mtodo de Euler en algunos casos. e En el mtodo del punto medio usamos e vn+1 = vn + an , vn+1 + vn rn+1 = rn + . 2 (8.22) (8.23) Notemos que hemos promediado las dos velocidades. Usando la ecuacin para la velocidad o en la ecuacin de la posicin, vemos que o o 1 rn+1 = rn + vn + an 2 , 2 (8.24) lo cual realmente hace esto lucir atractivo. El error de truncamiento es an del orden de u 2 en la ecuacin velocidad, pero para la posicin el error de truncamiento es ahora 3 . o o Realmente, para el movimiento de proyectiles este mtodo trabaja mejor que los otros dos. e Infortunadamente, en otros sistemas f isicos este mtodo da pobres resultados. e 8.1.5. Errores locales, errores globales y eleccin del paso de tiemo po. Para juzgar la precisin de estos mtodos necesitamos distinguir entre errores de truno e camiento locales y globales. Hasta ahora, el error de truncamiento que hemos discutido ha 3 A. Cromer, "Stable solutions using the Euler approximation", Am. J. Phys., 49 455-9 (1981). 230 CAP ITULO 8. EDO: METODOS BASICOS. sido el error local, el error cometido en un unico paso de tiempo. En un problema t ipico nosotros deseamos evaluar la trayectoria desde t = 0 a t = T . El nmero de pasos de tiempo u es NT = T / ; notemos que si reducimos , debemos tomar ms pasos. Si el error local es a O( n ), entonces estimamos el error global como error global NT (error local) T = NT O( n ) = O( n ) = T O( n-1 ) . (8.25) Por ejemplo, el mtodo de Euler tiene un error local de truncamiento de O( 2 ), pero un error e global de truncamiento de O( ). Por supuesto, este anlisis nos da slo una estimacin ya que a o o no sabemos si los errores locales se acumularn o se cancelarn (i.e. interferencia constructiva a a o destructiva). El verdadero error global para un esquema numrico es altamente dependiente e del problema que se est estudiando. a Una pregunta que siempre aparece es cmo elegir el ? Tratemos de responderla. Primero, o supongamos que los errores de redondeo son despreciables tal que slo debemos preocuparnos o por los errores de truncamiento. Desde (8.10) y (8.16), el error local de truncamiento en el clculo de la posicin usando el mtodo de Euler es aproximadamente 2 r = 2 a. Usando a o e slo estimaciones del orden de magnitud, tomamos a 10 [m/s2 ], el error en un solo paso o en la posicin es de 10-1 [m], cuando = 10-1 [s]. Si el tiempo de vuelo T 100 [s], o entonces el error global es del orden de metros. Si un error de esta magnitud es inaceptable entonces debemos disminuir el paso en el tiempo. Finalmente usando un paso de tiempo 10-1 [s] no introducir iamos ningn error significativo de redondeo dada la magnitud de los u otros parmetros del problema. a En el mundo real, a menudo no podemos hacer un anlisis tan elegante por una variedad a de razones (ecuaciones complicadas, problemas con el redondeo, flojera, etc.). Sin embargo, a menudo podemos usar la intuicin f o isica. Respndase usted mismo "en qu escala de o e tiempo el movimiento es casi lineal?". Por ejemplo, para la trayectoria completa de una pelota de baseball que es aproximadamente parablica, el tiempo en el aire son unos pocos o segundos, entonces el movimiento es aproximadamente lineal sobre una escala de tiempo de unos pocos centsimos de segundo. Para revisar nuestra intuicin, nosotros podemos comparar e o -1 -2 los resultados obtenidos usando = 10 [s] y = 10 [s] y, si ellos son suficientemente cercanos, suponemos que todo est bien. A veces automatizamos la prueba de varios valores a de ; el programa es entonces llamado adaptativo (construiremos un programa de este tipo ms adelante). Como con cualquier mtodo numrico, la aplicacin ciega de esta tcnica es a e e o e poco recomendada, aunque con slo un poco de cuidado sta puede ser usada exitosamente. o e 8.1.6. Programa de la pelota de baseball. e La tabla 8.1 bosqueja un simple programa, llamado balle, que usa el mtodo de Euler para calcular la trayectoria de una pelota de baseball. Antes de correr el programa, establezcamos algunos valores razonables para tomar como entradas. Una velocidad inicial de | v1 | =15 [m/s] nos da una pelota que le han pegado dbilmente. Partiendo del origen y e despreciando la resistencia del aire, el tiempo de vuelo es de 2.2 [s], y el alcance horizontal es sobre los 23 [m] cuando el ngulo inicial = 45 . A continuacin, mostramos la salida a a o pantalla del programa balle en C++ cuando es corrido bajo estas condiciones: 8.1. MOVIMIENTO DE UN PROYECTIL. 231 Fijar la posicin inicial r1 y la velocidad inicial v1 de la pelota de baseball. o Fijar los parmetros f a isicos ( m, Cd , etc.). Iterar hasta que la bola golpe en el piso o el mximo nmero de pasos sea completado. e a u Grabar posicin (calculada y terica) para graficar. o o Calcular la aceleracin de la pelota de baseball. o Calcular la nueva posicin y velocidad, rn+1 y vn+1 , Usando el mtodo de Euler, o e (8.18) y (8.19). Si la pelota alcanza el suelo (y < 0) para la iteracin. o Imprimir el alcance mximo y el tiempo de vuelo. a Graficar la trayectoria de la pelota de baseball. Cuadro 8.1: Bosquejo del programa balle, el cual calcula la trayectoria de una pelota de baseball usando el mtodo de Euler. e Movimiento de Proyectil Mtodo de Euler Teora (sin aire) 6 Altura [m] 4 2 0 0 5 10 15 20 25 Alcance [m] Figura 8.2: Salida del programa balle para una altura inicial de 0 [m], una velocidad inicial de 15 [m/s], y un paso de tiempo =0.1 [s]. No hay resistencia del aire. La l inea continua es la terica y los puntos son los calculados, la diferencia se debe a errores de truncamiento. o jrogan@huelen:~/programas$ balle Ingrese la altura inicial [m] : 0 Ingrese la velocidad inicial [m/s]: 15 Ingrese angulo inicial (grados): 45 232 CAP ITULO 8. EDO: METODOS BASICOS. Ingrese el paso en el tiempo, tau en [s]: 0.1 Tiempo de vuelo: 2.2 Alcance: 24.3952 La salida en Octave debiera ser muy similar. La trayectoria calculada por el programa es mostrada en la figura 8.2. Usando un paso de = 0.1 [s], el error en el alcance horizontal es sobre un metro, como esperbamos del a error de truncamiento. A velocidades bajas los resultados no son muy diferentes si incluimos la resistencia con el aire, ya que |Fa (v1 )|/m g/7. Ahora tratemos de batear un cuadrangular. Consideremos una velocidad inicial grande | v1 | = 50 [m/s]. Debido a la resistencia, encontramos que el alcance es reducido a alrededor de 125 [m], menos de la mitad de su mximo terico. La trayectoria es mostrada figura 8.3, a o notemos cmo se aparta de la forma parablica. o o En nuestras ecuaciones para el vuelo de una pelota de baseball no hemos incluido todos los factores en el problema. El coeficiente de arrastre no es constante sino ms bien una a complicada funcin de la velocidad. Adems, la rotacin de la pelota ayuda a levantar la o a o pelota (efecto Magnus). Movimiento de Proyectil Mtodo de Euler Teora (sin aire) 60 Altura [m] 40 20 0 0 50 100 150 200 250 Alcance [m] Figura 8.3: Salida del programa balle para una altura inicial de 1 [m], una velocidad inicial de 50 [m/s], y un paso de tiempo =0.1 [s]. Con resistencia del aire. 8.2. 8.2.1. Pndulo simple. e Ecuaciones bsicas. a El movimiento de los pndulos ha fascinado a f e isicos desde que Galileo fue hipnotizado por la lmpara en la Catedral de Pisa. El problema es tratado en los textos de mecnica a a bsica pero antes de apresurarnos a calcular con el computador, revisemos algunos resultados a 8.2. PENDULO SIMPLE. 233 bsicos. Para un pndulo simple es ms conveniente describir la posicin en trminos del a e a o e desplazamiento angular, (t). La ecuacin de movimiento es o d2 g = - sen , 2 dt L (8.26) donde L es la longitud del brazo y g es la aceleracin de gravedad. En la aproximacin para o o a ngulo peque~o, sen , la ecuacin (8.26) se simplifica a n o d2 g =- . 2 dt L Esta ecuacin diferencial ordinaria es fcilmente resuelta para obtener o a (t) = C1 cos 2t + C2 Ts , (8.28) (8.27) donde las constantes C1 y C2 estn determinadas por los valores iniciales de y = d/dt. a El per iodo para ngulos peque~os, Ts es a n Ts = 2 L . g (8.29) Esta aproximacin es razonablemente buena para oscilaciones con amplitudes menores o o iguales a 20 . Sin la aproximacin para ngulos peque~os, la ecuacin de movimiento es ms dif de o a n o a icil resolver. Sin embargo, sabemos de la experiencia que el movimiento es todav peridico. En ia o efecto, es posible obtener una expresin para el per o iodo sin resolver expl icitamente (t). La energ total es ia 1 (8.30) E = mL2 2 - mgL cos , 2 donde m es la masa de la lenteja. La energ total es conservada e igual a E = -mgL cos m , ia donde m es el ngulo mximo. De lo anterior, tenemos a a 1 mL2 2 - mgL cos = mgL cos m , 2 o 2 = Ya que = d/dt, dt = d 2g (cos - cos m ) L . (8.33) 2g (cos - cos m ) . L (8.31) (8.32) En un per iodo el pndulo se balancea de = m a = -m y regresa a = m . As en medio e i, per iodo el pndulo se balancea desde = m a = -m . Por ultimo, por el mismo argumento, e 234 CAP ITULO 8. EDO: METODOS BASICOS. en un cuarto de per iodo el pndulo se balancea desde = m a = 0, as integrando ambos e i lados de la ecuacin (8.33) o T = 4 L 2g m 0 d (cos - cos m ) . (8.34) Esta integral podr ser reescrita en trminos de funciones especiales usando la identidad ia e 2 cos 2 = 1 - 2 sen , tal que T =2 L g m 0 d (sen2 m /2 - sen2 /2) . (8.35) Introduciendo K(x), la integral el iptica completa de primera especie,4 /2 K(x) 0 dz , 1 - x2 sen2 z (8.36) podr iamos escribir el per iodo como T =4 L K(sen m /2) , g (8.37) usando el cambio de variable sen z = sen(/2)/ sen(m /2). Para valores peque~os de m , n podr iamos expandir K(x) para obtener T = 2 L g 1+ 1 2 + ... 16 m . (8.38) Note que el primer trmino es la aproximacin para ngulo peque~o (8.29). e o a n 8.2.2. Frmulas para la derivada centrada. o Antes de programar el problema del pndulo miremos un par de otros esquemas para e calcular el movimiento de un objeto. El mtodo de Euler est basado en la formulacin de la e a o derivada derecha para df /dt dado por (8.7). Una definicin equivalente para la derivada es o f (t) = l im 0 f (t + ) - f (t - ) . 2 (8.39) Esta frmula se dice centrada en t. Mientras esta frmula parece muy similar a la ecuacin o o o (8.7), hay una gran diferencia cuando es finito. Nuevamente, usando la expansin de Taylor, o 1 1 f (t + ) = f (t) + f (t) + 2 f (t) + 3 f (3) (+ ) , 2 6 1 2 1 f (t - ) = f (t) - f (t) + f (t) - 3 f (3) (- ) , 2 6 4 (8.40) (8.41) I.S. Gradshteyn and I.M. Ryzhik, Table of Integral, Series and Products (New York: Academic Press, 1965) 8.2. PENDULO SIMPLE. 235 donde f (3) es la tercera derivada de f (t) y es un valor ente t y t . Restando las dos ecuaciones anteriores y reordenando tenemos, f (t) = f (t + ) - f (t - ) 1 2 (3) - f () , 2 6 (8.42) donde f (3) () = (f (3) (+ ) + f (3) (- ))/2 y t - t + . Esta es la aproximacin en la o primera derivada centrada. El punto clave es que el error de truncamiento es ahora cuadrtico a en , lo cual es un gran progreso sobre la aproximacin de las derivadas adelantadas que tiene o un error de truncamiento O( ). Usando las expansiones de Taylor para f (t + ) y f (t - ) podemos construir una frmula o centrada para la segunda derivada. La que tiene la forma f (t) = f (t + ) + f (t - ) - 2f (t) 1 - 2 f (4) () , 2 12 (8.43) donde t - t + . De nuevo, el error de truncamiento es cuadrtico en . La mejor a manera de entender esta frmula es pensar que la segunda derivada est compuesta de una o a derivada derecha y de una derivada izquierda, cada una con incrementos de /2. Usted podr pensar que el prximo paso ser preparar frmulas ms complicadas que ia o ia o a tengan errores de truncamiento an ms peque~os, quizs usando ambas f (t ) y f (t 2 ). u a n a Aunque tales frmulas existen y son ocasionalmente usadas, las ecuaciones (8.10), (8.42) y o (8.43) sirven como el "caballo de trabajo" para calcular las derivadas primera y segunda. 8.2.3. Mtodos del "salto de la rana" y de Verlet. e Para el pndulo, las posiciones y velocidades generalizadas son y , pero para mantener e la misma notacin anterior trabajaremos con r y v. Comenzaremos de las ecuaciones de o movimiento escritas como dv = a(r(t)) , dt dr = v(t) . dt (8.44) (8.45) Note que expl icitamente escribimos la aceleracin dependiente solamente de la posicin. Diso o cretizando la derivada temporal usando la aproximacin de derivada centrada da, o v(t + ) - v(t - ) + O( 2 ) = a(r(t)) , 2 (8.46) para la ecuacin de la velocidad. Note que aunque los valores de velocidad son evaluados en o t + y t - , la aceleracin es evaluada en el tiempo t. o Por razones que pronto sern claras, la discretizacin de la ecuacin de posicin estar cena o o o a trada entre t + 2 y t, r(t + 2 ) - r(t) + O( 2 ) = v(t + ) . (8.47) 2 236 CAP ITULO 8. EDO: METODOS BASICOS. De nuevo usamos la notacin fn f (t = (n - 1) ), en la cual las ecuaciones (8.47) y (8.46) o son escritas como, vn+1 - vn-1 + O( 2 ) = a(rn ) , 2 rn+2 - rn + O( 2 ) = vn+1 . 2 Reordenando los trminos para obtener los valores futuros a la izquierda, e vn+1 = vn-1 + 2 a(rn ) + O( 3 ) , rn+2 = rn + 2 vn+1 + O( 3 ) . (8.50) (8.51) (8.48) (8.49) Este es el mtodo del "salto de la rana" (leap frog). Naturalmente, cuando el mtodo es usado e e 3 en un programa, el trmino O( ) no va y por lo tanto constituye el error de truncamiento e para el mtodo. e El nombre "salto de la rana" es usado ya que la solucin avanza en pasos de 2 , con la o posicin evaluada en valores impares (r1 , r3 , r5 , . . . ), mientras que la velocidad est calculada o a en los valores pares (v2 , v4 , v6 , . . . ). Este entrelazamiento es necesario ya que la aceleracin, o la cual es una funcin de la posicin, necesita ser evaluada en un tiempo que est centrado o o a entre la velocidad nueva y la antigua. Algunas veces el esquema del "salto de la rana" es formulado como vn+1/2 = vn-1/2 + a(rn ) , rn+1 = rn + vn+1/2 , (8.52) (8.53) con vn1/2 v(t = (n - 1 1/2) ). En esta forma, el esquema es funcionalmente equivalente al mtodo de Euler-Cromer. e Para el ultimo esquema numrico de este cap e itulo tomaremos una aproximacin diferente o y empezaremos con, dr = v(t) , dt d2 r = a(r) . dt2 (8.54) (8.55) Usando las frmulas diferenciales centradas para la primera y segunda derivada, tenemos o rn+1 - rn-1 + O( 2 ) = vn , 2 rn+1 + rn-1 - 2rn + O( 2 ) = an , 2 donde an a(rn ). Reordenando trminos, e vn = rn+1 - rn-1 + O( 2 ) , 2 (8.58) (8.59) (8.56) (8.57) rn+1 = 2rn - rn-1 + 2 an + O( 4 ) . 8.2. PENDULO SIMPLE. 237 Estas ecuaciones, conocidas como el mtodo de Verlet 5 , podr parecer extra~as a prie ian n mera vista, pero ellas son fciles de usar. Suponga que conocemos r0 y r1 ; usando la ecuacin a o (8.59), obtenemos r2 . Conociendo r1 y r2 podr iamos ahora calcular r3 , luego usando la ecuai cin (8.58) obtenemos v2 , y as sucesivamente. o Los mtodos del "salto de la rana" y de Verlet tienen la desventaja que no son "autoinie ciados". Usualmente tenemos las condiciones iniciales r1 = r(t = 0) y v1 = v(t = 0), pero no v0 = v(t = - ) [necesitado por el "salto de la rana" en la ecuacin (8.50)] o r0 = r(t = - ) o [necesitado por Verlet en la ecuacin (8.59)]. Este es el precio que hay que pagar para los o esquemas centrados en el tiempo. Para lograr que estos mtodos partan, tenemos una variedad de opciones. El mtodo de e e Euler-Cromer, usando la ecuacin (8.53), toma v1/2 = v1 , lo cual es simple pero no muy o preciso. Una alternativa es usar otro esquema para lograr que las cosas partan, por ejemplo, en el "salto de la rana" uno podr tomar un paso tipo Euler para atrs, v0 = v1 - a1 . ia a Algunas precauciones deber ser tomadas en este primer paso para preservar la precisin ian o del mtodo; usando e 2 r0 = r1 - v1 + a(r1 ) , (8.60) 2 es una buena manera de comenzar el mtodo de Verlet. e Adems de su simplicidad, el mtodo del "salto de la rana" a menudo tiene propiedades a e favorables (e.g. conservacin de la energ cuando resuelve ciertos problemas. El mtodo de o ia) e Verlet tiene muchas ventajas. Primero, la ecuacin de posicin tiene un error de truncamiento o o menor que otros mtodos. Segundo, si la fuerza es solamente una funcin de la posicin y si e o o nos preocupamos slo de la trayectoria de la part o icula y no de su velocidad (como en muchos problemas de mecnica celeste), podemos saltarnos completamente el clculo de velocidad. a a El mtodo es popular para el clculo de las trayectorias en sistemas con muchas part e a iculas, por ejemplo, el estudio de fluidos a nivel microscpico. o 8.2.4. Programa de pndulo simple. e Las ecuaciones de movimiento para un pndulo simple son e d = () dt d = , dt (8.61) donde la aceleracin angular () = -g sen /L. El mtodo de Euler para resolver estas o e ecuaciones diferenciales ordinarias es iterar las ecuaciones: n+1 = n + n , n+1 = n + n . (8.62) (8.63) Si estamos interesados solamente en el ngulo y no la velocidad, el mtodo de Verlet slo usa a e o la ecuacin o n+1 = 2n - n-1 + 2 n . (8.64) L.Verlet, "Computer experiments on classical fluid I. Thermodynamical properties of Lennard-Jones molecules", Phys. Rev. 159, 98-103 (1967). 5 238 CAP ITULO 8. EDO: METODOS BASICOS. Seleccionar el mtodo a usar: Euler o Verlet. e Fijar la posicin inicial 1 y la velocidad 1 = 0 del pndulo. o e Fijar los parmetros f a isicos y otras variables. Tomar un paso para atrs para partir Verlet; ver ecuacin (8.60). a o Iterar sobre el nmero deseado de pasos con el paso de tiempo y mtodo numrico dado. u e e Grabar ngulo y tiempo para graficar. a Calcular la nueva posicin y velocidad usando el mtodo de Euler o de Verlet. o e Comprobar si el pndulo a pasado a travs de = 0; si es as usar el tiempo e e i transcurrido para estimar el per iodo. Estima el per iodo de oscilacin, incluyendo barra de error. o Graficar las oscilaciones como versus t. Cuadro 8.2: Bosquejo del programa pndulo, el cual calcula el tiempo de evolucin de un e o pndulo simple usando el mtodo de Euler o Verlet. e e En vez de usar las unidades SI, usaremos las unidades adimensionales naturales del problema. Hay solamente dos parmetros en el problema, g y L y ellos siempre aparecen en la a razn g/L. Fijando esta razn a la unidad, el per o o iodo para peque~as amplitudes Ts = 2. n En otras palabras, necesitamos solamente una unidad en el problema: una escala de tiempo. Ajustamos nuestra unidad de tiempo tal que el per iodo de peque~as amplitudes sea 2. n La tabla 8.2 presenta un bosquejo del programa pendulo, el cual calcula el movimiento de un pndulo simple usando o el mtodo de Euler o el de Verlet. El programa estima el e e per iodo por registrar cuando el ngulo cambia de signo; esto es verificar si n y n+1 tienen a signos opuestos probando si n n+1 < 0. Cada cambio de signo da una estimacin para el o ~k = 2 (nk+1 - nk ), donde nk es el paso de tiempo en el cual el k-simo cambio de per iodo, T e signo ocurre. El per iodo estimado de cada inversin de signo es registrado, y el valor medio o calculado como M 1 ~ ~ T = Tk , (8.65) M k=1 ~ donde M es el nmero de veces que T es evaluado. La barra de error para esta medicin del u o per iodo es estimada como = s/ M , donde s= 1 M -1 M ~ ~ Tk - T k=1 2 , (8.66) ~ es la desviacin estndar de la muestra T . Note que cuando el nmero de medidas se increo a u 8.2. PENDULO SIMPLE. 239 menta, la desviacin estndar de la muestra tiende a una constante, mientras que la barra o a de error estimado decrece. Para comprobar el programa pendulo, primero tratamos con ngulos iniciales peque~os, a n m , ya que conocemos el per iodo T 2. Tomando = 0.1 tendremos sobre 60 puntos por oscilacin; tomando 300 pasos deber o iamos tener como cinco oscilaciones. Para m = 10 , ~ el mtodo de Euler calcula un per e iodo estimado de T = 6.375 0.025 sobre un 1.5 % mayor que el esperado T = 2(1.002) dado por la ecuacin (8.38). Nuestro error estimado o ~ para el per iodo es entorno a en cada medida. Cinco oscilaciones son 9 medidas de T , as que nuestro error estimado para el per i iodo deber ser ( /2)/ 9 0.02. Notemos que la ia estimacin est en buen acuerdo con los resultados obtenidos usando la desviacin estndar. o a o a Hasta aqu todo parece razonable. i 40 30 20 Angulo [grados] 10 0 -10 -20 -30 -40 -50 0 5 10 15 20 25 30 Tiempo Figura 8.4: Salida del programa pndulo usando el mtodo de Euler. El ngulo inicial es e e a m = 10 , el paso en el tiempo es = 0.1, y 300 iteraciones fueron calculadas. Infortunadamente si miramos el grfico 8.4 nos muestra los problemas del mtodo de Euler. a e La amplitud de oscilacin crece con el tiempo. Ya que la energ es proporcional al ngulo o ia a mximo, esto significa que la energ total se incrementa en el tiempo. El error global de a ia truncamiento en el mtodo de Euler se acumula en este caso. Para pasos de tiempos peque~os e n = 0.05 e incrementos en el nmero de pasos (600) podemos mejorar los resultados, ver figura u 8.5, pero no eliminamos el error. El mtodo del punto medio tiene la misma inestabilidad e numrica. e Usando el mtodo de Verlet con m = 10 , el paso en el tiempo = 0.1 y 300 iteraciones e obtenemos los resultados graficados en 8.5. Estos resultados son mucho mejores; la amplitud ~ de oscilacin se mantiene cerca de los 10 y T = 6.275 0.037. Afortunadamente el mtodo o e de Verlet, el del "salto de rana" y el de Euler-Cromer no sufren de la inestabilidad numrica e encontrada al usar el mtodo de Euler. e Para m = 90 , la primera correccin para la aproximacin de ngulo peque~o, ecuacin o o a n o (8.38), da T = 7.252. Usando el mtodo de Verlet, el programa da un per e iodo estimado de ~ T = 7.414 0.014, lo cual indica que (8.38) es una buena aproximacin (alrededor de un o 240 20 CAP ITULO 8. EDO: METODOS BASICOS. 15 10 Angulo [grados] 5 0 -5 -10 -15 -20 -25 0 5 10 15 20 25 30 Tiempo Figura 8.5: Salida del programa pndulo usando el mtodo de Euler. El ngulo inicial es e e a m = 10 , el paso en el tiempo es = 0.05 y 600 iteraciones fueron calculadas. 15 10 Angulo [grados] 5 0 -5 -10 -15 0 5 10 15 20 25 30 Tiempo Figura 8.6: Salida del programa pndulo usando el mtodo de Verlet. El ngulo inicial es e e a m = 10 , el paso en el tiempo es = 0.1 y 300 iteraciones fueron calculadas. 2 % de error), an para ngulos grandes. Para el ngulo muy grande de m = 170 , vemos u a a la trayectoria en la figura 8.6. Notemos como la curva tiende a aplanarse en los puntos de ~ retorno. En este caso el per iodo estimado es T = 15.3333 0.0667, mientras que (8.38) da T = 9.740, indicando que esta aproximacin para (8.37) deja de ser vlida para este ngulo o a a tan grande. 8.3. LISTADO DE LOS PROGRAMAS EN PYTHON. 200 241 150 100 Angulo [grados] 50 0 -50 -100 -150 -200 0 5 10 15 20 25 30 Tiempo Figura 8.7: Salida del programa pndulo usando el mtodo de Verlet. El ngulo inicial es e e a m = 170 , el paso en el tiempo es = 0.1 y 300 iteraciones fueron calculadas. 8.3. 8.3.1. Listado de los programas en python. balle.py #!/usr/bin/env python # -*- coding: iso-8859-1 -*import math from pylab import * Cd=0.35 rho=1.293 radio=0.037 A=math.pi*radio*radio m=0.145 g=9.8 a=-Cd*rho*A/(2.0*m) # [kg/m^3] # [m] # [kg] # [m/s^2] def main(): salida=open("salida.txt", "w") salidaT=open("salidaT.txt", "w") x0=0 y0=input("Ingrese la altura inicial [m] :") v0=input("Ingrese la velocidad inicial [m/s]:") theta0=input("Ingrese el angulo inicial (grados):") 242 CAP ITULO 8. EDO: METODOS BASICOS. flagRA=2 while flagRA !=0 and flagRA !=1: flagRA=input("Con resistencia del aire, Si=1, No=0: ") tau=input("Ingrese el paso en el tiempo, tau en [s]: ") vxn=v0*math.cos(math.pi*theta0/180.0) vyn=v0*math.sin(math.pi*theta0/180.0) xn=x0 yn=y0 tiempo = -tau l_xT= l_yT= l_xn= l_yn= while yn >= y0: tiempo = tiempo+tau l_xT.append(x0+v0*math.cos(math.pi*theta0/180.0)*tiempo) l_yT.append(y0+v0*math.sin(math.pi*theta0/180.0)*tiempo-g*tiempo*tiempo/2.0) print >> salidaT,x0+v0*math.cos(math.pi*theta0/180)*tiempo, print >> salidaT,y0+v0*math.sin(math.pi*theta0/180)*tiempo-g*tiempo*tiempo/2.0 l_xn.append(xn) l_yn.append(yn) print >> salida, xn, yn if flagRA==0: a=0.0 v=math.sqrt(vxn*vxn + vyn*vyn) axn=a*v*vxn ayn=a*v*vyn - g xnp1 = xn + tau * vxn ynp1 = yn + tau * vyn vxnp1 = vxn + tau*axn vynp1 = vyn + tau*ayn vxn=vxnp1 vyn=vynp1 xn=xnp1 yn=ynp1 print "Tiempo de vuelo: ",tiempo print "Alcance: ",xn 8.3. LISTADO DE LOS PROGRAMAS EN PYTHON. salida.close() salidaT.close() plot(l_xn, l_yn,'ro',l_xT, l_yT,linewidth=1.0) title("Trayectoria de balle") grid(True) show() # if __name__=='__main__': main() 243 8.3.2. pendulo.py #!/usr/bin/env python # -*- coding: iso-8859-1 -*import math from matplotlib import rc from pylab import * rc('text', usetex=True) def main(): respuesta = 2 while respuesta !=0 and respuesta != 1: respuesta = input("Elija el metodo Euler=0 o Verlet=1 : ") omega1=0 theta1=input("Ingrese el angulo inicial (en grados) : ") theta1*=math.pi/180.0 tau = input("Ingrese el paso del tiempo : ") pasos = input("Ingrese el numero de pasos : ") periodo = salida = open("salidaPendulo.txt", "w") theta0=theta1-tau*omega1-tau*tau*math.sin(theta1) thetaNm1=theta0 thetaN=theta1 omegaN=omega1 nK=1 M=0 244 CAP ITULO 8. EDO: METODOS BASICOS. l_t= l_theta= for i in range(1,pasos): alphaN=-math.sin(thetaN) if respuesta==0: # Euler thetaNp1=thetaN+tau*omegaN omegaNp1=omegaN+tau*alphaN else: # Verlet thetaNp1=2.0*thetaN-thetaNm1+tau*tau*alphaN omegaNp1=0.0 #solo por completitud l_t.append((i-1)*tau) l_theta.append(thetaNp1*180/math.pi) print >> salida, (i-1)*tau,thetaNp1*180/math.pi if thetaNp1*thetaN<0: if M==0: M+=1 periodo.append(0.0) nK=i else: M+=1 periodo.append(2.0*tau*(i-nK)) nK=i thetaNm1=thetaN thetaN=thetaNp1 omegaN=omegaNp1 Tprom=0 for i in range(1,M): Tprom += periodo[i] Tprom /= float(M-1) ssr=0 for i in range(1,M): ssr+=(periodo[i]-Tprom)*(periodo[i]-Tprom) ssr/=float(M-2) sigma=math.sqrt(ssr/float(M-1)) print "Periodo = ", Tprom, "+/-", sigma salida.close() plot(l_t, l_theta,'ro') xlabel(r'\textbf{\Large Tiempo (s)}') ylabel(r'\textbf{\Large\'Angulo (grados)}') title(r'\textbf{\Huge P\'endulo no lineal}') 8.4. LISTADO DE LOS PROGRAMAS EN C++. grid(True) show() # if __name__=='__main__': main() 245 8.4. 8.4.1. Listado de los programas en c++. balle.cc #include "NumMeth.h" int main() { const double Cd=0.35; const double rho=1.293; // [kg/m^3] const double radio=0.037; // [m] double A= M_PI*radio*radio ; double m=0.145; // [kg] double g=9.8; // [m/s^2] double a = -Cd*rho*A/(2.0e0*m) ; double v0, theta0, tau; ofstream salida ("salida.txt") ; ofstream salidaT ("salidaT.txt") ; double x0, y0; x0=0.0e0 ; cout << "Ingrese la altura inicial [m] : "; cin >> y0; cout << "Ingrese la velocidad inicial [m/s]: "; cin >> v0; cout <<"Ingrese angulo inicial (grados): "; cin >> theta0; int flagRA = 2 ; while (flagRA!=0 && flagRA !=1) { cout <<"Con resistencia del aire, Si= 1, No= 0: "; cin >> flagRA; } cout <<"Ingrese el paso en el tiempo, tau en [s]: "; cin >> tau ; double vxn=v0*cos(M_PI*theta0/180.0) ; 246 CAP ITULO 8. EDO: METODOS BASICOS. double vyn=v0*sin(M_PI*theta0/180.0) ; double xn=x0 ; double yn=y0 ; double tiempo = -tau; while( yn >= y0) { tiempo +=tau ; salidaT << x0+v0*cos(M_PI*theta0/180.0) *tiempo <<" " ; salidaT << y0+v0*sin(M_PI*theta0/180.0) *tiempo -g*tiempo*tiempo/2.0e0<< endl; salida << xn << " " << yn << endl; if(flagRA==0) a=0.0e0 ; double v=sqrt(vxn*vxn+vyn*vyn) ; double axn= a*v*vxn ; double ayn= a*v*vyn -g ; double xnp1 = xn + tau*vxn ; double ynp1 = yn + tau*vyn ; double vxnp1 = vxn + tau*axn; double vynp1 = vyn + tau*ayn; vxn=vxnp1; vyn=vynp1; xn=xnp1 ; yn=ynp1 ; } cout << "Tiempo de vuelo: " << tiempo<< endl; cout << "Alcance: " << xn<<endl; salida.close(); salidaT.close(); return 0; } 8.4.2. pendulo.cc #include "NumMeth.h" int main() { int respuesta=2 ; while(respuesta != 0 && respuesta !=1 ) { cout << "Elija el metodo: Euler=0 y Verlet=1 : " ; cin >> respuesta ; } double theta1 ; double omega1 = 0.0e0; cout << "Ingrese el angulo inicial (grados): "; cin >> theta1 ; theta1*=M_PI/180.0e0 ; 8.4. LISTADO DE LOS PROGRAMAS EN C++. double tau ; cout << "Ingrese el paso de tiempo: "; cin >> tau ; int pasos ; cout << "Ingrese el numero de pasos: "; cin >> pasos ; double * periodo = new double[pasos] ; ofstream salida ("salidaPendulo.txt"); double theta0= theta1-tau*omega1-tau*tau*sin(theta1) ; double thetaNm1=theta0 ; double thetaN=theta1 ; double omegaN=omega1; double thetaNp1, omegaNp1 ; int nK=1; int M=0 ; for(int i=1; i< pasos; i++) { double alphaN=-sin(thetaN); if(respuesta==0) { // Euler thetaNp1=thetaN+tau*omegaN ; omegaNp1=omegaN+tau*alphaN ; } else { thetaNp1=2.0e0*thetaN-thetaNm1+tau*tau*alphaN ; } salida << (i-1)*tau<<" " <<thetaNp1*180/M_PI<< endl ; if (thetaNp1*thetaN<0) { if(M==0) { periodo[M++]=0.0e0; nK=i ; } else { periodo[M++] = 2.0e0*tau*double(i-nK); nK=i ; } } thetaNm1=thetaN ; thetaN=thetaNp1 ; omegaN=omegaNp1 ; } 247 248 CAP ITULO 8. EDO: METODOS BASICOS. double Tprom=0.0e0; for (int i=1; i < M; i++) Tprom+=periodo[i] ; Tprom/=double(M-1) ; double ssr=0.0 ; for (int i=1; i < M; i++) ssr+=(periodo[i]-Tprom)* (periodo[i]-Tprom); ssr/=double(M-2); double sigma =sqrt(ssr/double(M-1)) ; cout <<" Periodo = "<< Tprom << "+/-"<< sigma << endl ; salida.close() ; delete periodo; return 0; } Cap itulo 9 Ecuaciones Diferenciales Ordinarias II: Mtodos Avanzados. e versin 3.2 16 Diciembre 20031 o En el cap itulo anterior aprendimos cmo resolver ecuaciones diferenciales ordinarias usano do algunos mtodos simples. En este cap e itulo haremos algo de mecnica celeste bsica comena a zando con el problema de Kepler. Al calcular la rbita de un satlite peque~o alrededor de o e n un cuerpo masivo (e.g un cometa orbitando el Sol), descubriremos que mtodos mucho ms e a sofisticados son necesarios para manipular sistemas simples de dos cuerpos. 9.1. 9.1.1. Orbitas de cometas. Ecuaciones bsicas. a Considere el problema de Kepler en el cual un peque~o satlite, tal como un cometa, orbita n e el Sol. Usamos un sistema de coordenadas Copernicano y fijamos el Sol en el origen. Por ahora, consideremos solamente la fuerza gravitacional entre el cometa y el Sol, y despreciemos todas las otras fuerzas (e.g., fuerzas debidas a los planetas, viento solar). La fuerza sobre el cometa es GmM r, (9.1) F =- | r |3 donde r es la posicin del cometa, m es su masa, M = 1.99 1030 [kg] es la masa del Sol, y o -11 G = 6.67 10 [m3 /kg s2 ] es la constante gravitacional. Las unidades naturales de longitud y tiempo para este problema no son metros ni segundos. Como unidad de distancia usaremos la unidad astronmica [AU], 1 AU=1.4961011 [m], o la cual es igual a la distancia media de la Tierra al Sol. La unidad de tiempo ser el [a~o] a n AU (el per iodo de una rbita circular de radio 1 [AU]). En estas unidades, el producto o GM = 4 2 [AU3 /a~o2 ]. Tomaremos la masa del cometa, m, como la unidad; en unidades n MKS la masa t ipica de un cometa es 10153 [kg]. Ahora tenemos suficiente para ensamblar nuestro programa, pero antes hagamos una rpida revisin de lo que sabemos de rbitas. Para un tratamiento completo podemos recurrir a o o Este cap itulo est basado en el tercer cap a itulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall. 1 249 250 CAP ITULO 9. EDO II: METODOS AVANZADOS. a algunos textos de mecnica estndar, tales como Symon2 o Landau y Lifshitz3 . La energ a a ia total del satlite es e 1 GM m E = mv 2 - , (9.2) 2 r donde r = | r | y v = | v |. Esta energ total es conservada, tal como el momento angular, ia L = r (mv) . (9.3) Ya que este problema es bidimensional, consideraremos el movimiento en el plano x-y. El unico componente distinto de cero del momento angular est en la direccin z. a o Cuando la rbita es circular, en el sistema de referencia que gira con el satlite, la fuerza o e centr ifuga es compensada por la fuerza gravitacional, GM m mv 2 = , r r2 o GM . (9.5) r Por colocar algunos valores, en una rbita circular en r = 1 [AU] la velocidad orbital es v = 2 o ia [AU/a~o] (cerca de 30.000 [km/h]). Reemplazando la ecuacin (9.5) en (9.2), la energ total n o en una rbita circular es o GM m E=- . (9.6) 2r En una rbita el o iptica, los semiejes mayores y menores, a y b, son desiguales (figura 9.1). La v= (9.4) y q 2b r Q 2a Figura 9.1: Orbita el iptica alrededor del Sol. excentricidad, e, est definida como a e= 2 3 x 1- b2 . a2 (9.7) K. Symon, Mechanics (Reading Mass.: Addison-Wesley, 1971). L. Landau and E. Lifshitz, Mechanics (Oxford: Pergamon, 1976). 9.1. ORBITAS DE COMETAS. Nombre del Cometa Encke Biela Schwassmann-Wachmann 1 Halley Grigg-Mellish Hale-Bopp T [a~os] n 3.30 6.62 16.10 76.03 164.3 2508.0 e q [AU] i 0.847 0.339 12.4 0.756 0.861 12.6 0.132 5.540 9.5 0.967 0.587 162.2 0.969 0.923 109.8 0.995 0.913 89.4 Primera pasada 1786 1772 1925 239 a.c. 1742 1995 251 Cuadro 9.1: Datos orbitales de algunos cometas. La excentricidad de la Tierra es e = 0.017, por lo tanto esta rbita est muy cercana de ser o a circular. La distancia del Sol al perihelio (punto de mayor aproximacin) es q = (1 - e)a; la o distancia del Sol al afelio es Q = (1 + e)a. La ecuacin (9.6) tambin se mantiene para una rbita el o e o iptica, si reemplazamos el radio con el semieje mayor; por lo tanto la energ total es ia E=- GM m . 2a (9.8) Note que E 0. De las ecuaciones (9.2) y (9.8), encontramos que la velocidad orbital como funcin de la distancia radial es o v= GM 2 1 - r a . (9.9) La velocidad es mxima en el perihelio y m a inima en el afelio, la razn entre las velocidades o est dada por Q/q. Finalmente, usando la conservacin de momento angular, podr a o iamos derivar la tercera ley de Kepler, 4 2 3 a , (9.10) T2 = GM donde T es el per iodo de la rbita. o Los datos orbitales para unos pocos cometas bien conocidos estn dados en la tabla 9.1. a La inclinacin, i, es el ngulo entre el plano orbital del cometa y el plano ecl o a iptico (el plano de la rbita de los planetas). Cuando la inclinacin es menor que los 90 , se dice que la rbita o o o es directa, cuando es mayor que 90 , se dice que la rbita es retrgrada (i.e., orbita el Sol en o o la direccin opuesta a la de los planetas). o 9.1.2. Programa orbita. Un programa simple, llamado orbita, que calcula las rbitas para el problema de Kepler o usando varios mtodos numricos es propuesto en la tabla 9.2. El mtodo de Euler, descrito e e e en el cap itulo anterior, calcula la trayectoria del cometa como rn+1 = rn + vn , vn+1 = vn + a(rn ) , (9.11) (9.12) 252 CAP ITULO 9. EDO II: METODOS AVANZADOS. Fijar la posicin y velocidad inicial del cometa. o Fijar los parmetros f a isicos (m, G, etc.). Iterar sobre el nmero deseado de pasos usando el mtodo numrico especificado. u e e Grabar posicin y la energ para graficar. o ia Calcular la nueva posicin y velocidad usando: o Mtodo e Mtodo e Mtodo e Mtodo e de Euler (9.11), (9.12) o; de Euler-Cromer (9.13), (9.14) o; Runge-Kutta de cuarto orden (9.30), (9.31) o; de Runge-Kutta adaptativo. Graficar la trayectoria del cometa. Graficar la energ del cometa versus el tiempo. ia Cuadro 9.2: Bosquejo del programa orbita, el cual calcula la trayectoria de un cometa usando varios mtodos numricos. e e donde a es la aceleracin gravitacional. De nuevo, discretizamos el tiempo y usamos la notao cin fn f (t = (n - 1) ), donde es el paso tiempo. o El caso de prueba ms simple es una rbita circular. Para un radio orbital de 1 [AU], la a o ecuacin (9.5) da una velocidad tangencial de 2 [AU/a~o]. Unos 50 puntos por revolucin o n o orbital nos dar una suave curva, tal que = 0.02 [a~os] (o cercano a una semana) es ia n un paso de tiempo razonable. Con esos valores, el programa orbita usando el mtodo de e o Euler, da los resultados mostrados en la figura 9.2. Inmediatamente vemos que la rbita no es circular, pero una espiral hacia fuera. La razn es clara desde el grfico de energ en vez de o a ia; ser constante, la energ total aumenta continuamente. Este tipo de inestabilidad se observa, ia tambin, en el mtodo de Euler para el pndulo simple. Afortunadamente hay una solucin e e e o simple a este problema: el mtodo Euler-Cromer para calcular la trayectoria e vn+1 = vn + a(rn ) , rn+1 = rn + vn+1 . (9.13) (9.14) Note que el slo cambio del mtodo de Euler en que primero calculamos la nueva velocidad, o e vn+1 , y luego la usamos en el clculo de la nueva posicin. Para las mismas condiciones a o iniciales y paso de tiempo, el mtodo de Euler-Cromer da resultados mucho mejores, como e los mostrados en la figura 9.3. La rbita es casi circular, y la energ total se conserva. o ia Las energ potencial y cintica no son constantes, pero este problema podr ser mejorado ias e ia usando un paso de tiempo peque~o. El programa rbita tambin da la opcin de usar el n o e o mtodo de Runge-Kutta, el cual es descrito en las prximas dos secciones. e o Aunque el mtodo de Euler-Cromer hace un buen trabajo para bajas excentricidades, e tiene problemas con rbitas ms el o a ipticas, como se muestra en la figura 9.4. Note que si la 9.1. ORBITAS DE COMETAS. 90 o 30 Energa Cintica Energa Potencial Energa Total 253 Energa [M AU*AU/ao*ao] 20 10 0 180o 0o -10 -20 -30 -40 3 2 1 Distancia [AU] 270o 0 1 2 3 0 0.5 1 1.5 2 2.5 3 3.5 4 Tiempo [aos] Figura 9.2: Grfico de la trayectoria y la energ desde el programa orbita usando el mtodo a ia e de Euler. La distancia radial inicial es 1 [AU] y la velocidad tangencial inicial es 2 [AU/a~o]. n El paso en el tiempo es = 0.02 [a~os]; y 200 pasos son calculados. Los resultados estn en n a desacuerdo con la prediccin terica de una rbita circular con energ total constante. o o o ia energ llega a ser positiva; el satlite alcanza la velocidad de escape. Si bajamos el paso de ia e tiempo desde = 0.02 [a~os] a = 0.005 [a~os] obtenemos mejores resultados, como los n n mostrados en la figura 9.5. Estos resultados no son del todo perfectos; la rbita puede ser o una elipse cerrada, pero todav tiene una notable deriva espria. ia u En este punto usted se podr estar preguntando, "Por qu estamos estudiando este ia e problema?, si la solucin anal o itica es bien conocida". Es verdad que hay problemas mecnicos a celestes ms interesantes (e.g., el efecto de perturbaciones sobre la rbita, problema de tres a o cuerpos). Sin embargo, antes de hacer los casos complicados podr iamos, siempre, chequear los algoritmos de problemas conocidos. Suponga que introducimos una peque~a fuerza de n arrastre sobre el cometa. Podr iamos pecar de inocentes creyendo que la precisin de la figura o 9.5 fue un fenmeno f o isico ms que un artefacto numrico. a e Claramente, el mtodo de Euler-Cromer hace un trabajo inaceptable de rastreo de las e o rbitas ms el a ipticas. Los resultados mejoran si achicamos el paso de tiempo, pero entonces slo podemos rastrear unas pocas rbitas. Suponga que deseamos rastrear cometas para o o posibles impactos con la Tierra. Un gran cometa impactando sobre la Tierra ser ms desia a tructivo que una guerra nuclear. Muchos cometas tienen rbitas extremadamente el o ipticas y per iodos de cientos de a~os. Esta amenaza desde el espacio exterior motiva nuestro estudio n de mtodos ms avanzados para resolver ecuaciones diferenciales ordinarias. e a 254 90 o CAP ITULO 9. EDO II: METODOS AVANZADOS. 30 Energa [M AU*AU/ao*ao] 20 Energa Cintica Energa Potencial Energa Total 0 10 180o 0o -10 -20 -30 -40 -50 1.5 1 0.5 0 0.5 1 1.5 0 0.5 1 1.5 2 2.5 3 3.5 4 Distancia [AU] 270o Tiempo [aos] Figura 9.3: Grfico de la trayectoria y la energ desde el programa orbita usando el mtodo a ia e de Euler-Cromer. Los parmetros son los mismos que en la figura 9.2. Los resultados estn en a a un acuerdo cualitativo al menos con la prediccin terica de una rbita circular con energ o o o ia total constante. 90o Energa [M AU*AU/aos*aos] 200 100 0 -100 -200 0 1 Energa Cintica Energa Potencial Energa Total 180 o 0o 30 20 10 Distancia [AU] 270 o 0 10 20 30 2 Tiempo [aos] 3 4 Figura 9.4: Grfico de la trayectoria y la energ desde el programa orbita usando el mtodo a ia e de Euler-Cromer. La distancia radial inicial es 1 [AU] y la velocidad tangencial inicial es [AU/a~o]. El paso en el tiempo es = 0.02 [a~os]; y 200 pasos son calculados. Debido al n n error numrico el cometa alcanza la velocidad de escape, la posicin final es 35 [AU] y la e o energ total es positiva. ia 9.2. METODOS DE RUNGE-KUTTA. 90 o Energa [M AU*AU/aos*aos] 300 200 100 0 Energa Cintica Energa Potencial Energa Total 255 180o 0o -100 -200 -300 270o 1 0.5 Distancia [AU] 0 0.5 1 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Tiempo [aos] Figura 9.5: Grfico de la trayectoria y la energ desde el programa orbita usando el mtodo a ia e de Euler-Cromer. Los parmetros son los mismos que en la figura 9.4 excepto que el paso de a tiempo es ms peque~o = 0.005 [a~os]. Los resultados son mejores, pero an presenta una a n n u precesin espria. o u 9.2. 9.2.1. Mtodos de Runge-Kutta. e Runge-Kutta de segundo orden. Ahora miremos uno de los mtodos ms populares para resolver numricamente las ecuae a e ciones diferenciales ordinarias: Runge-Kutta. Primero trabajaremos las frmulas generales de o Runge-Kutta y luego las aplicaremos espec ificamente a nuestro problema del cometa. De esta manera ser fcil usar el mtodo Runge-Kutta para otros sistemas f a a e isicos. Nuestra ecuacin o diferencial ordinaria general toma la forma dx = f (x(t), t) , dt (9.15) donde el vector de estado x(t) = [x1 (t), x2 (t), . . . xN (t)] es la solucin deseada. En el problema o de Kepler tenemos x(t) = [rx (t), ry (t), vx (t), vy (t)] , (9.16) y f (x(t), t) = drx dry dvx dvy , , , , dt dt dt dt = [vx (t), vy (t), Fx (t)/m, Fy (t)/m] , (9.17) donde rx , vx , y Fx son las componentes x de la posicin, la velocidad y la fuerza respectivao mente (y lo mismo para la componente y). Note que en el problema de Kepler, la funcin f o no depende expl icitamente del tiempo sino que slo depende de x(t). o 256 CAP ITULO 9. EDO II: METODOS AVANZADOS. Nuestro punto de partida es el mtodo simple de Euler; en forma vectorial podr ser e ia escrito como x(t + ) = x(t) + f (x, t) . (9.18) Consideremos la primera frmula de Runge-Kutta: o x(t + ) = x(t) + f donde 1 x t + 2 1 ,t + 2 , (9.19) 1 1 x t + x(t) + f (x, t) . (9.20) 2 2 Para ver de dnde viene esta frmula, consideremos por el momento el caso de una o o variable. Sabemos que la expansin de Taylor o x(t + ) = x(t) + dx() , dt = x(t) + f (x(), ) , (9.21) es exacta para algn valor de entre t y t + , como se vio en la ecuacin (8.10). La frmula u o o de Euler toma = t; Euler-Cromer usa = t en la ecuacin de velocidad y = t + en la o 1 ecuacin de posicin. Runge-Kutta usa = t+ 2 , lo cual pareciera ser una mejor estimacin. o o o 1 Sin embargo, x t + 2 no es conocida, podemos aproximarla de la manera simple: usando 1 o un paso de Euler calculamos x t + 1 y usando esta como nuestra estimacin de x t + 2 . 2 A continuacin un ejemplo simple usando la frmula Runge-Kutta. Consideremos la ecuao o cin o dx = -x , x(t = 0) = 1 . (9.22) dt La solucin de la ecuacin (9.22) es x(t) = e-t . Usando el mtodo de Euler con un paso de o o e tiempo de = 0.1, tenemos x(0.1) = 1 + 0.1(-1) = 0.9 , x(0.2) = 0.9 + (0.1)(-0.9) = 0.81 , x(0.3) = 0.81 + 0.1(-0.81) = 0.729 , x(0.4) = 0.729 + 0.1(-0.729) = 0.6561 . Ahora tratemos con Runge-Kutta. Para hacer una correcta comparacin usaremos un paso o de tiempo mayor para Runge-Kutta = 0.2 porque hace el doble de evaluaciones de f (x). Por la frmula de Runge-Kutta presentada arriba, o x (0.1) = 1 + 0.1(-1) = 0.9 , x(0.2) = 1 + 0.2(-0.9) = 0.82 , x (0.3) = 0.82 + 0.1(-0.82) = 0.738 x(0.4) = 0.82 + 0.2(-0.738) = 0.6724 . Podemos comparar esto con la solucin exacta x(0.4) = exp(-0.4) 0.6703. Claramente, o Runge-Kutta lo hace mucho mejor que Euler; los errores porcentuales absolutos son 0.3 % y 2.1 % respectivamente. 9.2. METODOS DE RUNGE-KUTTA. 257 9.2.2. Frmulas generales de Runge-Kutta. o La frmula discutida arriba no es la unica posible para un Runge-Kutta de segundo orden. o Aqu hay una alternativa: i 1 x(t + ) = x(t) + [f (x(t), t) + f (x (t + ), t + )] , 2 donde x (t + ) x(t) + f (x(t), t) . (9.24) (9.23) Para entender este esquema, consideremos nuevamante el caso en una variable. En nuestra frmula original, estimamos que f (x(), ) como 1 [f (x, t) + f (x (t + ), t + )]. o 2 Estas expresiones pueden ser deducidas usando la expansin de Taylor con dos variables, o f (x + h, t + ) = n=0 1 n! h + x t n f (x, t) , (9.25) donde todas las derivadas son evaluadas en (x, t). Para una frmula general de Runge-Kutta o de segundo orden queremos obtener una expresin de la siguiente forma o x(t + ) = x(t) + w1 f (x(t), t) + w2 f (x , t + ) , donde x x(t) + f (x(t), t) . (9.27) (9.26) Hay cuatro coeficientes no especificados: , , w1 y w2 . Note que cubrimos las ecuaciones (9.19) y (9.20) eligiendo los valores w1 = 0 , w2 = 1 = 1 , 2 = 1 , 2 (9.28) y las ecuaciones (9.23) y (9.24) eligiendo w1 = 1 , 2 w2 = 1 , 2 =1, =1. (9.29) Deseamos seleccionar cuatro coeficientes tal que tengamos una precisin de segundo orden; o esto es deseamos calzar la serie de Taylor a travs de los trminos de la segunda derivada. e e Los detalles del clculo se proponen como un ejercicio, pero cualquier grupo de coeficientes a satisfacen las relaciones siguientes w1 + w2 = 1, w2 = 1/2 y = darn un esquema a Runge-Kutta de segundo orden. El error de truncamiento local es O( 3 ), pero la expresin o expl icita no tiene una forma simple. No est claro que un esquema sea superior al otro ya a que el error de truncamiento, siendo una funcin complicada de f (x, t), variar de problema o a a problema. 258 CAP ITULO 9. EDO II: METODOS AVANZADOS. 9.2.3. Runge-Kutta de cuarto orden. Presentamos las frmulas de Runge-Kutta de segundo orden porque es fcil de comprender o a su construccin. En la prctica, sin embargo, el mtodo ms comnmente usado es la siguiente o a e a u frmula de cuarto orden: o 1 x(t + ) = x(t) + F1 + 2F2 + 2F3 + F4 6 donde F1 = f (x, t) , F2 = f F3 = f 1 x + F1 , t + 2 1 x + F2 , t + 2 1 2 1 2 , (9.31) , , (9.30) F4 = f (x + F3 , t + ) . El siguiente extracto del Numerical Recipes4 resume mejor el estado que las frmulas de o arriba tienen en el mundo del anlisis numrico: a e Para muchos usuarios cient ificos, el mtodo de Runge-Kutta de cuarto orden no es e slo la primera palabra en esquemas de integracin para ecuaciones diferenciales o o ordinarias, si no que es la ultima tambin. De hecho, usted puede ir bastante lejos e con este viejo caballito de batalla, especialmente si los combina con un algor itmo de paso adaptativo. . . Bulirsch-Stoer o los mtodos predictor-corrector pueden ser e mucho ms eficientes para problemas donde se require una alta precisin. Estos a o mtodos son los finos caballos de carrera mientras que Runge-Kutta es el fiel e caballo de tiro. Usted se preguntar, por qu frmulas de cuarto orden y no de orden superior? Bien, los a e o mtodos de orden superior tienen un error de truncamiento mejor, pero tambin requieren e e ms clculo, esto es, ms evaluaciones de f (x, t). Hay dos opciones, hacer ms pasos con un a a a a peque~o usando un mtodo de orden inferior o hacer pocos pasos con un ms grande usando n e a un mtodo de orden superior. Ya que los mtodos de Runge-Kutta de rdenes superiores son e e o muy complicados, el esquema de cuarto orden dado anteriormente es muy conveniente. Entre parntesis, el error de truncamiento local para Runge-Kutta de cuarto orden es O( 5 ). e Para implementar mtodos de cuarto orden para nuestro problema de la rbita, usaremos e o o la funcin rk4 (tabla 9.3). Esta funcin toma como datos: el estado actual del sistema, x(t); el o paso de tiempo para ser usado, ; el tiempo actual, t; la funcin f (x(t), t; ); donde es una o lista de parmetros usados por f . La salida es el nuevo estado del sistema, x(t + ), calculado a por el mtodo de Runge-Kutta. Usando Runge-Kutta de cuarto orden da los resultados e mostrados en la figura 9.6, la cual es mucho mejor que las obtenidas usando el mtodo de e Euler-Cromer (figura 9.5). W. Press, B. Flannery, S. Tukolsky and W. Vetterling, Numerical Recipes in fortran, 2nd ed. (Cambridge: Cambridge University Press 1992). 4 9.2. METODOS DE RUNGE-KUTTA. 259 Entradas: x(t), t, , f (x, t; ), y . Salidas: x(t + ). Evaluacin F1 , F2 , F3 y F4 usando ecuacin (9.31). o o Clculo de x(t + ) usando Runge-Kutta de cuarto orden, usando ecuacin (9.30). a o Cuadro 9.3: Bosquejo de la funcin rk4, la cual evala un paso simple usando el mtodo o u e Runge-Kutta de cuarto orden. Entradas: x(t), t (no se usa), GM . Salidas: dx(t)/dt. Evala la aceleracin a = -(GM r/ | r |3 ). u o Retorno: dx(t)/dt = [vx , vy , ax , ay ]. Cuadro 9.4: Bosquejo de la funcin gravrk, la cual es usada por la funcin Runge-Kutta para o o evaluar las ecuaciones de movimiento para el problema de Kepler. 9.2.4. Pasando funciones a funciones. La funcin de Runge-Kutta rk4 es muy simple, pero introduce un elemento de prograo macin que no hemos usado antes. La funcin f (x, t; ) est introducida como un parmetro o o a a de entrada a rk4. Esto nos permite usar rk4 para resolver diferentes problemas cambiando simplemente la definicin de f (como lo haremos en la ultima seccin). Para el problema de o o Kepler, la funcin gravrk (tabla 9.4) define la ecuacin de movimiento devolviendo dx/dt, o o ecuacin (9.17). o En C++ el puntero a la funcin f (x, t; ) es pasado como parmetro a rk4. El programa o a orbita llama a rk4 como rk4( state, nState, time, tau, gravrk, param) ; donde el vector de estado es x = [rx , ry , vx , vy ]. En el inicio del archivo, la funcin gravrk es o declarada con el prototipo void gravrk( double * x, double t, double param, double * deriv ); La primera l inea de rk4 es void rk4(double * x, int nX, double t, double tau, void (*derivsRK) (double *, double, double, double *) , double param) 260 90 o CAP ITULO 9. EDO II: METODOS AVANZADOS. 300 Energa [M AU*AU/aos*aos] 200 Energa Cintica Energa Potencial Energa Total 100 180o 0o 0 -100 -200 1 0.5 0 Distancia [AU] 270 o 0.5 1 -300 0 0.2 0.4 0.6 0.8 1.0 Tiempo [aos] Figura 9.6: Grfico de la trayectoria y la energ desde el programa orbita usando el mtodo a ia e de Runge-Kutta. La distancia radial inicial es 1 [AU] y la velocidad tangencial inicial es [AU/a~o]. El paso en el tiempo es = 0.005 [a~os]; y 200 pasos son calculados. Comparemos n n con la figura 9.5. Cuando es llamado por orbita, esta funcin recibe un puntero a gravrk en la variable o derivsRK. Dentro de rk4, la sentencia (*derivsRK)( x, t, param, F1 ) ; es equivalente a gravrk( x, t, param, F1 ) ; ya que dervsRK apunta a gravrk. 9.3. 9.3.1. Mtodos adaptativos e Programas con paso de tiempo adaptativo. Ya que el mtodo de Runge-Kutta de cuarto orden es ms preciso (errores de truncamiento e a peque~os), hace un mejor trabajo dentro de una rbita altamemente el n o iptica. An para una u distancia inicial al afelio de 1 [AU] y una velocidad inicial en el afelio de /2 [AU/a~o] usando n 1 un paso tiempo tan peque~o como = 0.0005 [a~os] ( 4 2 [hrs]), la energ total var sobre n n ia ia el 7 % por rbita. Si pensamos la f o isica, llegamos a que realizar una integracin con un paso o peque~o es slo necesaria cuando el cometa haga su acercamiento ms prximo, punto en el n o a o cual su velocidad es mxima. Cualquier error peque~o en la trayectoria cuando rodea al Sol a n causa una gran desviacin en la energ potencial. o ia La idea ahora es dise~ar un programa que use un paso de tiempo peque~o cuando el comen n ta est cerca del Sol y pasos de tiempo grande cuando est lejos. Tal como est, normalmente a a a 9.3. METODOS ADAPTATIVOS 261 tenemos slo una idea aprximada de lo que pudiera ser; ahora tenemos que seleccionar un o o m y un mx y una manera de intercambiar entre ellos. Si tenemos que hacer esto por prueba in a y error manual, podr ser peor que hacindolo por la fuerza bruta calculando con un paso ia e de tiempo peque~o toda la trayectoria. Idealmente, deseamos estar completamente liberados n de tener que especificar un paso de tiempo. Deseamos tener una trayectoria calculada de la misma posicin inicial hasta algn tiempo final con la seguridad de que la solucin es correcta o u o a una precisin especificada o Los programas adaptativos continuamente monitorean la solucin y modifican el paso de o tiempo para asegurar que se mantenga la precisin especificada por el usuario. Esos programas o pueden hacer algunos clculos extras para optimizar la eleccin de , en muchos casos este a o trabajo extra vale la pena. Aqu est una manera para implementar esta idea: dado el estado i a actual x(t), el programa calcula x(t + ) como siempre, y luego repite el clculo haciendolo a en dos pasos, cada uno con paso de tiempo 2 . Visualmente, esto es paso grande x (t) paso pequeo x (t+/2) paso pequeo x b(t+ ) x s (t+ ) La diferencia entre las dos respuestas, xb (t+ ) y xs (t+ ), estima el error de truncamiento local. Si el error es tolerable, el valor calculado es aceptado y un valor mayor de es usado en la prxima iteracin. Por otra parte, si el error es muy grande, la respuesta es rebotada, el o o paso de tiempo es reducido y el procedimiento es repetido hasta que se obtenga una respuesta aceptable. El error de truncamiento estimado para el actual paso de tiempo puede guiarnos en seleccionar en nuevo paso de tiempo para la prxima iteracin. o o 9.3.2. Funcin adaptativa de Runge-Kutta. o Aqu mostramos cmo una iteracin adaptativa puede ser implementada para un esquema i o o de Runge-Kutta de cuarto orden: llamemos al error de truncamiento; sabemos que 5 para un esquema Runge-Kutta de cuarto orden. Supongamos que el paso de tiempo actual ant da un error de c = | xb - xs |; esta es nuestra estimacin para el error de truncamiento. o Dado que deseamos que el error sea menor o igual que el error ideal especificado por el usuario, le llamamos i ; luego, el nuevo paso de tiempo estimado es est i = c 1/5 . (9.32) Ya que esto es slo una estimacin, el nuevo paso de tiempo es nuevo = S1 est , donde S1 < 1. o o Esto nos hace sobreestimar el cambio cuando disminuimos y subestimar el cambio cuando lo aumentamos. Malogramos los esfuerzos computacionales cada vez que rebotamos una respuesta y necesitamos reducir el paso de tiempo, por lo tanto es mejor ajustar nuevo < est . Podr iamos poner un segundo factor de seguridad, S2 < 1, para asegurarse que el programa no sea demasiado entusiasta en aumentar o disminuir precipitadamente el paso de tiempo. 262 CAP ITULO 9. EDO II: METODOS AVANZADOS. Con ambas precauciones, el nuevo paso de tiempo es S2 ant si S1 est > S2 ant nuevo = /S2 si S1 est < ant /S2 . S1 est en otro caso (9.33) Entradas: x(t), t, , i , f (x, t; ), y . Salidas: x(t ), t , nuevo . Fijar las variables iniciales Iterar sobre el nmero deseado de intentos para satisfacer el error l u imite. Tomar dos peque~os pasos de tiempo. n Tomar un unico paso grande de tiempo. Calcule el error de truncamiento estimado. Estime el nuevo valor de (incluyendo factores de seguridad). Si el error es aceptable, regresar los valores calculados. Mostrar un mensaje de error si el error l imite nunca es satisfecho. Cuadro 9.5: Bosquejo de la funcin rka, la cual evala un unico paso usando un mtodo o u e adaptativo de Runge-Kutta de cuarto orden. Esto obliga a asegurar que nuestro nueva estimacin para nunca aumente o decrezca o por ms que un factor S2 . Por supuesto, este nuevo podr ser insuficientemente peque~o, a ia n y tendr iamos que continuar reduciendo el paso de tiempo; pero al menos sabr iamos que no ocurrir de un modo incontrolado. a Este procedimiento no es "a prueba de balas", los errores de redondeo llegan a ser significativos en pasos de tiempos muy peque~os. Por esta razn la iteracin adaptativa podr n o o ia fallar para encontrar un paso de tiempo que de la precisin deseada. Debemos mantener esta o limitacin en mente cuando especifiquemos el error aceptable. Una funcin de Runge-Kutta o o adaptativa, llamada rka, es esbozada en la tabla 9.5. Note que los datos de entrada en la secuencia de llamada son los mismos que para rk4, excepto por la suma de i , el error ideal especificado. Las salidas del rka son el nuevo estado del sistema, x(t ); el tiempo nuevo, t y el nuevo paso de tiempo, nuevo, el cual podr ser usado la prxima vez que sea llamada ia o la rka. Usando el mtodo de Runge-Kutta adaptativo, el programa orbita da los resultados en e la figura 9.7 para una rbita altamente el o iptica. Notemos que el programa toma muchos ms a pasos en el perihelio que en el afelio. Podemos comparar con los resultados usando el mtodo e de Runge-Kutta no adaptativo (figura 9.6) en el cual los pasos en el perihelio son ampliamente 9.3. METODOS ADAPTATIVOS 90 o 1500 263 Energa [M AU*AU/aos*aos] Energa Cintica Energa Potencial Energa Total 1000 500 180 o 0o 0 -500 -1000 270 1 0.5 0 o 0.5 1 -1500 0 0.05 0.1 0.15 0.2 0.25 Distancia [AU] Tiempos [aos] Figura 9.7: Grfico de la trayectoria y la energ desde el programa orbita usando el mtodo a ia e de Runge-Kutta adaptativo. La distancia radial inicial es 1 [AU] y la velocidad tangencial inicial es /2 [AU/a~o]. El paso inicial en el tiempo es = 0.1 [a~os]; y 40 pasos son n n calculados. 0.1 0.01 Tau [aos] 0.001 0.0001 0.01 0.1 Distancia [Au] 1 Figura 9.8: Paso de tiempo como funcin de la distancia radial desde el programa orbita o usando el mtodo de Runge-Kutta adaptativo. Los paramtros son los mismos de la figura e e 9.7. espaciados. Una grfica de los pasos de tiempo versus la distancia radial (figura 9.8) muestra a que var casi tres rdenes de magnitud. ia o Interesantemente esta grfica revela una relacin a o 3 . Por supuesto esta dependencia nos recuerda exponencial aproximada de la forma r la tercera ley de Kepler, ecuacin (9.10). Esperamos alguna dispersin en los puntos, ya que o o nuestra rutina adaptada solamente estima el paso de tiempo ptimo. o 264 CAP ITULO 9. EDO II: METODOS AVANZADOS. 9.4. 9.4.1. Listados del programa. orbita.cc #include "NumMeth.h" const double GM=4.0e0*M_PI*M_PI ; const double masaCometa = 1.0e0 ; const double adaptErr = 1.0e-3; void rk4(double * x, int nX, double t, double tau, void(*derivsRK)(double *, double, double, double *), double param) { double * F1=new double [nX] ; double * F2=new double [nX] ; double * F3=new double [nX] ; double * F4=new double [nX] ; double * xtemp=new double [nX] ; // Evaluemos F1=f(x,t) (*derivsRK) (x, t, param, F1) ; double half_tau = tau/2.0e0; double t_half = t+half_tau ; double t_full = t+tau ; // Evaluamos F2=f(x+tau*F1/2, t+tau/2) for(int i=0; i<nX; i++) xtemp[i]=x[i]+half_tau*F1[i] ; (*derivsRK) (xtemp, t_half, param, F2) ; // Evaluamos F3=f(x+tau*F2/2, t+tau/2) for(int i=0; i<nX; i++) xtemp[i]=x[i]+half_tau*F2[i] ; (*derivsRK) (xtemp, t_half, param, F3) ; // Evaluamos F4=f(x+tau*F3, t+tau) for(int i=0; i<nX; i++) xtemp[i]=x[i]+tau*F3[i] ; (*derivsRK) (xtemp, t_full, param, F4) ; // Retornamos x(t+tau) for(int i=0; i<nX; i++) x[i] += tau*(F1[i]+F4[i]+2.0e0*(F2[i]+F3[i]))/6.0e0 ; delete F1; delete F2; delete F3; delete F4; delete xtemp ; 9.4. LISTADOS DEL PROGRAMA. } void rka ( double * x, int nX, double & t, double & tau, double erro, void(*derivsRK)(double *, double, double, double *), double param) { double tSave = t ; double safe1 = 0.9, safe2 = 4.0 ; //factores de seguridad double * xSmall = new double[nX] ; double * xBig = new double[nX] ; int maxTray=100 ; for (int iTray=0; iTray<maxTray; iTray++) { // Tomemos dos peque{\~n}os pasos en el tiempo double half_tau = 0.5*tau ; for (int i =0; i < nX; i++) xSmall[i]=x[i] ; rk4( xSmall, nX, tSave, half_tau, derivsRK, param) ; t= tSave + half_tau ; rk4( xSmall, nX, t, half_tau, derivsRK, param) ; // Tomemos un solo tiempo grande for (int i =0; i < nX; i++) xBig[i]=x[i] ; rk4( xBig, nX, tSave, tau, derivsRK, param) ; // Calculemos el error de truncamiento estimado double erroRatio = 0.0e0 ; double eps = 1.0e-16 ; for (int i = 0 ; i < nX; i++) { double scale = erro * (fabs(xSmall[i]) + fabs(xBig[i]))/2.0e0 ; double xDiff = xSmall[i] - xBig[i] ; double ratio = fabs(xDiff)/(scale+eps) ; erroRatio = (erroRatio > ratio ) ? erroRatio:ratio ; } // Estimamos el nuevo valor de tau (incluyendo factores de seguridad) double tau_old= tau ; tau = safe1*tau_old*pow(erroRatio, -0.20) ; tau = (tau > tau_old/safe2) ? tau:tau_old/safe2 ; tau = (tau < safe2*tau_old) ? tau:safe2*tau_old ; // Si el error es aceptable regrese los valores computados if ( erroRatio < 1 ) { for (int i =0 ; i < nX; i++) x[i]=xSmall[i] ; return ; } } cout << "Error: Runge-Kutta adaptativo fallo" << endl ; 265 266 exit(-1) ; } CAP ITULO 9. EDO II: METODOS AVANZADOS. void gravrk( double * x, double t, double param, double * deriv) { double gm=param ; double rX=x[0], rY=x[1]; double vX=x[2], vY=x[3] ; double mod_r= sqrt(rX*rX+rY*rY) ; double aX= -gm*rX/(mod_r*mod_r*mod_r) ; double aY= -gm*rY/(mod_r*mod_r*mod_r) ; // Retorna la derivada deriv[0] deriv[1] deriv[2] deriv[3] } int main() { ofstream salidaO ("Orbita.txt") ; ofstream salidaE ("Energia.txt") ; ofstream salidaT ("Tau.txt") ; double r0 ; cout << "Ingrese la distancia radial inicial [AU]: " ; cin >> r0 ; double vT ; cout << "Ingrese la velocidad tangencial inicial [AU/a{\~n}os]: " ; cin >> vT ; double x0=r0 ; double y0=0.0e0; double vx0=0.0e0 ; double vy0=vT; // // Suponemos angulo inicial nulo // int metodo = 0 ; while( metodo < 1|| metodo > 4 ) { cout << "Ingrese el m{\'e}todo num{\'e}rico a usar :" << endl ; cout << "\t Metodo de Euler \t\t\t[1]" << endl; cout << "\t Metodo de Euler-Cromer \t\t[2]" << endl; = = = = vX; vY; aX; aY; 9.4. LISTADOS DEL PROGRAMA. cout << "\t Metodo de Runge-Kutta 4 orden \t\t[3]" << endl; cout << "\t Metodo de Runge-Kutta adaptativo \t[4]" << endl; cout << "elija: " ; cin >> metodo ; } double tau ; cout << "Ingrese paso en el tiempo: " ; cin >> tau ; int numPasos ; cout << "Ingrese el numero de pasos: " ; cin >> numPasos ; double param=GM ; const int dimX= 4; double * x = new double[dimX] ; double double double double double double xN= x0; yN= y0; vxN=vx0; vyN=vy0; vxNp1, vyNp1, xNp1, yNp1; tiempo = 0.0e0 ; 267 for(int pasos=0; pasos < numPasos; pasos++) { double r =sqrt(xN*xN+yN*yN) ; double v2 =vxN*vxN+vyN*vyN ; double theta= atan2(yN, xN) ; salidaO << theta << " " << r << endl ; double Ep = -GM*masaCometa/r ; double Ek = masaCometa*v2/2.0e0 ; double ET= Ep+Ek ; salidaE<< tiempo << " " << Ek<< " " << Ep<<" " << ET << endl ; double modr3=pow(xN*xN+yN*yN, 3.0e0/2.0e0) ; double axN= -GM*xN/modr3 ; double ayN= -GM*yN/modr3 ; switch( metodo ) { case 1: { // Euler vxNp1=vxN+tau*axN ; vyNp1=vyN+tau*ayN ; xNp1= xN+tau* vxN ; yNp1= yN+tau* vyN ; tiempo += tau ; 268 CAP ITULO 9. EDO II: METODOS AVANZADOS. } break ; case 2: { // Euler-Cromer vxNp1=vxN+tau*axN ; vyNp1=vyN+tau*ayN ; xNp1= xN+tau* vxNp1 ; yNp1= yN+tau* vyNp1 ; tiempo += tau ; } break ; case 3: { // Runge-Kutta 4to Orden x[0] = xN; x[1] = yN; x[2] = vxN; x[3] = vyN; rk4( x, dimX, tiempo, tau, gravrk, param); xNp1=x[0] ; yNp1=x[1]; vxNp1=x[2]; vyNp1=x[3]; tiempo += tau ; } break ; case 4: { x[0] = xN; x[1] = yN; x[2] = vxN; x[3] = vyN; rka( x, dimX, tiempo, tau, adaptErr, gravrk, param); double distancia = sqrt( x[0]*x[0]+x[1]*x[1]) ; salidaT<< distancia << " " <<tau << endl ; xNp1=x[0] ; yNp1=x[1]; vxNp1=x[2]; vyNp1=x[3]; } } xN=xNp1 ; yN=yNp1 ; vxN=vxNp1 ; vyN=vyNp1 ; } salidaO.close() ; salidaE.close() ; salidaT.close() ; 9.4. LISTADOS DEL PROGRAMA. delete x; return 0; } 269 270 CAP ITULO 9. EDO II: METODOS AVANZADOS. Cap itulo 10 Resolviendo sistemas de ecuaciones. versin final 2.20-0304071 o En este cap itulo aprenderemos a cmo resolver sistemas de ecuaciones de ambos tipos, o lineal y no lineal. Ya conocemos los algoritmos bsicos para los sistemas lineales: eliminar a variables hasta que tengamos una sola ecuacin con una sola incgnita. Para sistemas noo o lineales desarrollamos un esquema iterativo que en cada paso resuelve una versin linealizada o de estas ecuaciones. Para mantener la continuidad, la discusin ser motivada por el clculo o a a del estado estacionario, un importante tema en ecuaciones diferenciales ordinarias. 10.1. 10.1.1. Sistemas de ecuaciones lineales. Estado estacionario de EDO. En el cap itulo pasado, nosotros vimos cmo resolver ecuaciones diferenciales ordinarias o de la forma dx = f (x, t) , (10.1) dt donde x = [x1 , x2 , . . . , xN ]. Dada una condicin inicial para las N variables xi (t) = 0, nosotros o podemos calcular la serie de tiempo xi (t) por una variedad de mtodos (e.g. Runge-Kutta). e Los ejemplos que hemos estudiado hasta aqu han sido aquellos conocidos como sistemas i autnomos donde f (x, t) = f (x), esto es, f no depende expl o icitamente del tiempo. Para sistemas autnomos, a menudo existe una importante clase de condiciones iniciales para las o cuales xi (t) = xi (0) para todo i y t. Estos puntos, en el espacio N -dimensional de nuestras variables, son llamados estado estacionario. Si nosotros partimos de un estado estacionario nos quedamos ah para siempre. Localizar los estados estacionarios para ecuaciones diferenciales i ordinarias es importante, ya que ellos son usados en el anlisis de bifurcaciones.2 a Es fcil ver que x = [x1 , x2 , . . . , xN ] es un estado estacionario si y slo si a o f (x ) = 0 , o fi (x , x , . . . , x ) = 0 , 1 2 N 1 (10.2) para todo i, (10.3) Este cap itulo est basado en el cuarto cap a itulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall. 2 R. Seydel, From Equilibrium to Chaos, Practical Bifurcation and Stability Analysis (New York: Elsevier, 1988). 271 272 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. ya que esto implica que dx /dt = 0. Localizar los estados estacionarios se reduce al problema de resolver N ecuaciones con N incgnitas xi . Este problema es tambin llamado "encontrar o e las raices de f (x)". Como un ejemplo, consideremos el pndulo simple; el estado est descrito por el ngulo e a a y la velocidad angular . Los estados estacionarios se encuentran al resolver las ecuaciones no lineales g - sen = 0 , = 0 . (10.4) L Las raices son = 0, , 2, . . . y = 0. Por supuesto que no todos los sistemas son tan fciles de resolver. a Deber ser claro que encontrar raices tiene muchas ms aplicaciones que calcular los ia a estados estacionario. En este cap itulo consideraremos una variedad de maneras para resolver ambos sistemas lineales y sistemas no lineales. En esta seccin y en la prxima consideraremos o o sistemas lineales, dejando los sistemas no lineales para la parte final del cap itulo. 10.1.2. Eliminacin Gaussiana. o El problema de resolver fi ({xj }) = 0 se divide en dos importantes clases. En esta seccin o consideramos el caso fcil cuando fi ({xj }) es una funcin lineal. El problema en ese caso se a o reduce a resolver un sistema de N ecuaciones con N incgnitas. o a11 x1 + a12 x2 + . . . + a1N xN - b1 = 0 a21 x1 + a22 x2 + . . . + a2N xN - b2 = 0 . . . . . . . . . . . . aN 1 x1 + aN 2 x2 + . . . + aN N xN - bN = 0 , o en forma matricial Ax - b = 0 , donde a11 a12 . . . A = a21 a22 . . . , . . .. . . . . . x1 x2 x= , . . . b1 b2 b= . . . . (10.6) (10.5) (10.7) Sabemos cmo resolver este conjunto de ecuaciones. Combinando las ecuaciones para o eliminar variables hasta que tengamos una sola ecuacin con una sola incgnita. Hagamos o o un ejemplo simple para revisar cmo el procedimiento trabaja. Tomemos las ecuaciones o x1 + x2 + x3 = 6 , -x1 + 2x2 = 3, 2x1 + x3 = 5 . (10.8) Deseamos eliminar x1 de la segunda y de la tercera ecuacin. Para llevar a cabo esto, primero o sumamos la primera y la segunda y despus restamos dos veces la primera a la tercera. Esto e nos da x1 + x2 + x3 = 6, 3x2 + x3 = 9, (10.9) -2x2 - x3 = -7 . 10.1. SISTEMAS DE ECUACIONES LINEALES. 273 Ahora, eliminamos x2 de la ultima ecuacin multiplicando la segunda ecuacin por - 2 y la o o 3 restamos de la tercera, dndonos a x1 + x2 + 3x2 + x3 = 6, x3 = 9, 1 - 3 x3 = -1 . (10.10) Este procedimiento es llamado eliminacin hacia adelante. Si se tienen N ecuaciones, elimio namos x1 de las ecuaciones 2 hasta la N , luego eliminamos x1 y x2 de las ecuaciones 3 hasta la N , y as sucesivamente. La ultima ecuacin slo contendr la variable xN . i o o a Volviendo al ejemplo, es ahora trivial resolver la tercera ecuacin resultando x3 = 3. o Podemos ahora sustituir este valor en la segunda ecuacin obteniendo 3x2 + 3 = 9, tal que o x2 = 2. Finalmente, introduciendo los valores de x2 y x3 en la primera ecuacin obtenemos o x1 = 1. Este segundo procedimiento es llamado sustitucin hacia atrs. Deber ser claro o a ia cmo esto trabaja con sistemas grandes de ecuaciones. Usando la ultima ecuacin obtenemos o o xN , ste es usado en la penltima ecuacin para obtener xN -1 y as seguimos. e u o i Este mtodo de resolver sistemas de ecuaciones lineales por eliminacin hacia adelante e o 3 y luego sustitucin hacia atrs es llamado eliminacin Gaussiana. Esta es una secuencia o a o rutinaria de pasos que es simple para un computador realizar sistemticamente. Para N a ecuaciones con N incgnitas, el tiempo de computacin para eliminacin Gaussiana va como o o o N 3 . Afortunadamente, si el sistema es esparcido o ralo4 (la mayor de los coeficientes son ia cero), el tiempo de clculo puede ser considerablemente reducido. a 10.1.3. Pivoteando. La eliminacin Gaussiana es un procedimiento simple, sin embargo, se debe estar conciente o de sus riesgos. Para ilustrar la primera fuente de problemas, consideremos el conjunto de ecuaciones x 1 + x2 + x3 = 5 , x1 + x2 = 3, (10.11) x1 + x3 = 4 . En el l imite 0 la solucin es x1 = 1, x2 = 2, x3 = 3. Para estas ecuaciones, el primer o paso de la eliminacin hacia adelante podr partir por multiplicar la primera ecuacin por o ia o (1/ ) y sustrayndola de la segunda y tercera ecuaciones, lo que da e x1 + x2 + x3 = 5, (1 - 1/ )x2 - (1/ )x3 = 3 - 5/ , -(1/ )x2 + (1 - 1/ )x3 = 4 - 5/ . (10.12) Por supuesto, si = 0 tenemos grandes problemas, ya que el factor 1/ estalla. An si = 0, u pero es peque~o, vamos a tener serios problemas de redondeo. Supongamos que 1/ es tan n G.E. Forsythe and C.B. Moler, Computer Solution of Linear Algebraic System (Upper Saddle River, N.J.: Prentice-Hall, 1967). 4 sparse 3 274 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. grande que (C - 1/ ) -1/ , donde C es del orden de la unidad. Nuestras ecuaciones, despus del redondeo, llegan a ser e x1 + x2 + x3 = 5, -(1/ )x2 - (1/ )x3 = -5/ , -(1/ )x2 - (1/ )x3 = -5/ . (10.13) En este punto est claro que no podemos proceder ya que la segunda y la tercera ecuacin en a o (10.13) son ahora idnticas; no tenemos ms que tres ecuaciones independientes. El prximo e a o paso de eliminacin ser transformar la tercera ecuacin en (4.13) en la tautolog 0 = 0. o ia o ia Afortunadamente, hay una solucin simple: intercambiar el orden de las ecuaciones antes o de realizar la eliminacin. Cambiando las ecuaciones primera y segunda en (10.11), o x1 + x2 = 3, x 1 + x2 + x3 = 5 , x1 + x3 = 4 . El primer paso de la eliminacin hacia adelante nos da las ecuaciones o x1 + x2 = 3, (1 - )x2 + x3 = 5 - 3 , -x2 + x3 = 4 - 3 . (10.14) (10.15) El redondeo elimina los trminos proporcionales a , dando e x1 + x2 = 3, x2 + x3 = 5 , -x2 + x3 = 1 . (10.16) El segundo paso de eliminacin hacia adelante elimina x2 de la tercera ecuacin en (10.16) o o usando la segunda ecuacin, o x1 + x2 x2 + = 3, x3 = 5 , 2x3 = 6 . (10.17) Se puede comprobar fcilmente que la sustitucin hacia atrs da x1 = 1, x2 = 2, y x3 = 3, la a o a cual es la respuesta correcta en el l imite 0. Los algoritmos que reordenan las ecuaciones cuando ellas sitan elementos peque~os en la u n diagonal son llamados pivotes. A menudo si todos los elementos de una matriz son inicialmente de una magnitud comparable, el procedimiento de eliminacin hacia adelante podr producir o ia peque~os elementos sobre la diagonal principal. El precio de pivotear es slo un par de l n o ineas extras en el programa, pero es esencial usar pivoteo para todas, no slo para las matrices ms o a peque~as. An con el pivoteo, no podemos garantizar estar a salvo de problemas de redondeo n u si se trata de matrices muy grandes. 10.1. SISTEMAS DE ECUACIONES LINEALES. 275 10.1.4. Determinantes. Es fcil obtener el determinante de una matriz usando la eliminacin Gaussiana. Despus a o e de completar la eliminacin hacia adelante, uno simplemente calcula el producto de los coeo ficientes de los elementos diagonales. Tomamos nuestro ejemplo original, ecuacin (10.8). La o matriz es 1 1 1 (10.18) A = -1 2 0 . 2 0 1 Completada la eliminacin hacia adelante, ecuacin (10.10), el producto de los coeficientes de o o los elementos diagonales es (1)(3)(- 1 ) = -1, el cual, usted puede comprobar, es el determi3 nante de A. Este mtodo es sut e ilmente ms complicado cuando se usa el pivoteo. Si el nmero a u de pivoteos es impar, el determinante es el producto negativo de los coeficientes de los elementos de la diagonal. Ahora deber ser obvio que la regla de Cramer es computacionalmente ia una manera ineficiente para resolver el conjunto de ecuaciones lineales. 10.1.5. Eliminacin Gaussiana en Octave. o No necesitamos escribir un programa en Octave para realizar la eliminacin Gaussiana o con pivoteo. En vez de esto nosotros podemos usar las capacidades de manipulacin de o matrices que viene con Octave. En Octave, la eliminacin Gaussiana es una rutina primitiva, o tal como las funciones seno o ra cuadrada. Como con cualquier rutina "enlatada", usted iz deber entender, en general, como trabaja y reconocer posibles problemas, especialmente los ia computacionales (e.g., poner sqrt(-1) retorna un nmero imaginario o un error?). u Octave implementa la eliminacin de Gauss usando los operadores slash / y backslash \. o El sistema de ecuaciones lineales x A = b donde x y b son vectores fila, se resuelve usando El sistema de ecuaciones lineales A x = b donde x y b son el operador slash como x = b/A. vectores columna, se resuelve usando el operador backslash como x = b\A. Como un ejemplo, tomemos la ecuacin (10.11) con = 0, escrito en forma matricial o 5 0 1 1 x1 1 1 0 x2 = 3 (10.19) 4 1 0 1 x3 Usando Octave en forma interactiva la solucin es ilustrada a continuacin: o o octave> octave> octave> octave> 1 2 3 A=[0 1 1; 1 1 0; 1 0 1]; b=[5;3;4]; x=A\b; disp(x); Claramente, Octave usa pivoteo en este caso. Los operadores slash y backslash pueden ser usados de la misma manera en programas. El comando en Octave para el determinante de una matriz es det(A). 276 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. 10.1.6. Eliminacin Gaussiana con C++ de objetos matriciales. o El uso de arreglos multidimensionales en C++ no es del todo comodo. Las maneras usuales de declarar un arreglo de M N de nmeros con punto flotante en doble precisin son: u o const int M=3, N=3; double A[M][N] ; para asignacin esttica de memoria y o a int M, N . . . // Se fijan valores a M y N double * * A = new double * [M] ; // asignacion de un vector de punteros for(int i=0;i<M;i++) { A[i] = new double [N] ; // asignacion de memoria para cada fila } para un reserva dinmica (no olvide desasignar cada fila con un delete). Una asignacin a o esttica es simple pero r a igida, ya que las dimensiones son constantes fijas. Cuando el arreglo esttico es pasado a una funcin, esta funcin deber declarar algn arreglo con el mismo a o o ia u nmero de columnas de acuerdo al arreglo a ser indexado apropiadamente. Una asignacin u o dinmica es flexible pero es dif de manejar, aunque los detalles pueden ser escondidos a icil dentro de funciones separadas. Accesar elementos fuera de los contornos del arreglo es un error de programacin comn (bug) el cual es dif de rastrear con arreglos dinmicos. o u icil a C++ nos permite corregir estas deficiencias creando nuestros propios tipos de variables. Estas variables definidas por el usuario son llamadas clases de objetos. De aqu en adelante i usaremos la clase Matrix para declarar arreglos de una o dos dimensiones de nmeros de punto u flotante. Esta clase est enteramente declarada dentro del archivo de cabecera Matrix.h e a implementada dentro de Matrix.cc. Algunos ejemplos de declaracin de objetos de Matrix o son int M=3, N=2 ; Matrix A(M,N), b(N), x(3) ; Aunque esto se parece a una asignacin de arreglo esttico, note que las dimensiones no son o a constantes fijas. Tanto vectores unidimensionales como matrices bidimensionales pueden ser declarados; las anteriores son tratadas como matrices de una sola columna. Los valores en estas variables pueden ser fijados por la declaracin de asignamiento o A(0,0)=0; A(1,0)=1; A(2,0)=1; b(1)=5; A(0,1)=1; A(1,1)=1; A(2,1)=0; b(2)=3; A(0,2)=1; A(1,2)=0; A(2,2)=1; b(3)=4. El formato para el objeto Matrix es A(i, j) en vez de A[i][j], para distinguirlos de los arreglos C++ convencionales. Un objeto Matrix conoce sus dimensiones, y usted puede obtenerlas usando las funciones miembros nRow() y nCol(). Por ejemplo: 10.1. SISTEMAS DE ECUACIONES LINEALES. 277 Entradas: A, b. Salidas: x, det A. Fija el factor de escala, si = maxj (| Ai,j |) para cada fila. Itera sobre las filas k = 1, . . . , (N - 1). Selecciona la columna a pivotear a partir de maxj (| Ai,j |)/si . Realiza pivoteos usando la lista de indice de columnas. Realiza la eliminacin hacia adelante. o Calcula el determinante det A, como producto de los elementos de la diagonal. Realiza la sustitucin hacia atrs. o a Cuadro 10.1: Bosquejo de la funcin ge, la cual resuelve un sistema de ecuaciones lineales o x = b por eliminacin Gaussiana. La funcin tambin devuelve el determinante de A. A o o e int m = A.nRow(), n = A.nCol() ; asigna m y n a las dimensiones de A. La verificacin de los contornos se realiza cada vez que o un objeto Matrix es indexado. Las l ineas Matrix newA(3, 7) ; newA(4,5) = 0; // Una matriz no cuadrada de 3 por 7 // Fuera de los limites produce el mensage de error: Indice de fila fuera de los limites cuando el programa es corrido. Esto significa que al menos uno de los indices i no satisface la condicin 0 < i N . o Los objetos Matrix automticamente liberan la memoria que les fue asignada cuando ellos a exceden su alcance (scope), por lo tanto no es necesario invocar delete. Para asignar todos los elementos de un objeto Matrix a un valor dado usamos la funcin o miembro set(double x ), por ejemplo A.set(1.0). Una matriz entera puede ser asignada a otra del mismo tama~o (e.g., Matrix C(3,3); C=A;). Sin embargo, a diferencia de las matrin ces de Octave, operaciones aritmticas como 2*A no estn an implementadas. Operaciones e a u de este tipo deber ser llevadas a cabo elemento por elemento, t ian ipicamente usando ciclos for. La rutina de eliminacin Gaussiana ge, la cual usa los objetos tipo Matrix, es descrita o en la tabla 10.1. Declarando y asignando la matriz A y los vectores b y x como arriba, un programa puede llamar esta rutina como double determ = ge(A, b, x) ; // Eliminacion Gaussiana cout << x(1) << ", " << x(2) << ", " << x(3) << endl ; cout << "Determinante = " << determ << endl ; para resolver el sistema lineal A x = b y calcular el determinante de A. 278 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. 10.2. 10.2.1. Matriz inversa. Matriz inversa y eliminacin Gaussiana. o En la seccin previa hemos revisado cmo resolver un conjunto de ecuaciones simultneas o o a por eliminacin de Gauss. Sin embargo, si usted est familiarizado con el lgebra lineal, o a a probablemente podr escribir la solucin de ia o Ax = b , como x = A-1 b , (10.21) donde A-1 es la matriz inversa de A. No nos deber sorprender que el clculo de la matriz ia a inversa est relacionada al algoritmo para resolver un conjunto de ecuaciones lineales. Usuale mente la inversa de una matriz es calculada por aplicaciones repetidas de eliminaciones de Gauss (o una variante de descomposicin llamada LU). o La inversa de una matriz est definida por la ecuacin a o A A-1 = I , donde I es la matriz identidad 1 0 I = 0 . . . ... . . . . . . . .. . (10.22) (10.20) 0 1 0 . . . 0 0 1 . . . (10.23) Definiendo los vectores columna 1 0 e1 = 0 , ^ . . . 0 1 e2 = 0 , ^ . . . ... , . . . eN = 0 , ^ 0 1 (10.24) podr iamos escribir la matriz identidad como una vector fila de los vectores columna ^ ^ ^ I = e1 e2 . . . eN Si resolvemos el conjunto de ecuaciones lineales, A x1 = e1 . ^ (10.26) . (10.25) El vector solucin x1 es la primera columna de la inversa A-1 . Si procedemos de esta manera o con los otros e calcularemos todas las columnas de A-1 . En otras palabras, nuestra ecuacin ^ o -1 para la matriz inversa AA = I es resuelta escribindola como e ^ ^ ^ ^ ^ ^ A x1 x2 . . . xN = e1 e2 . . . eN . (10.27) 10.2. MATRIZ INVERSA. 279 Entradas: A. Salidas: A-1 , det A. Matriz es inicializada a la matriz identidad. b Fija el factor de escala, si = maxj (| Ai,j |) para cada fila. Itera sobre las filas k = 1, . . . , (N - 1). Selecciona la columna a pivotear a partir de maxj (| Ai,j |)/si . Realiza pivoteos usando la lista de indice de columnas. Realiza la eliminacin hacia adelante. o Calcula el determinante detA, como producto de los elementos de la diagonal. Realiza la sustitucin hacia atrs. o a Cuadro 10.2: Bosquejo de la funcin inv, la cual calcula el inverso de una matriz y su o determinante. Despus de calcular los x, construimos A-1 como e (x1 )1 (x1 )2 = . . . (x2 )1 (x2 )2 . . . . . . (xN )1 . . . (xN )2 . .. . . . . . . (xN )N ^ ^ ^ A-1 x1 x2 . . . xN (10.28) (x1 )N (x2 )N donde(xi )j es el elemento j de xi . o La tabla 10.2 muestra la funcin inv para calcular la inversa de una matriz. En Octave, inv(A) es una funcin internamente construida que regresa a la matriz inversa de A . Es o posible resolver un sistema de ecuaciones lineales usando la matriz inversa, pero hacer esto es usualmente sobrepasarse. Una excepcin podr ser el caso donde deseamos resolver un o ia nmero de problemas similares en el cual la matriz A es fija pero el vector b toma muchos u valores diferentes. Finalmente, aqu hay una frmula manual para tener presente: la inversa i o de una matriz 2 2 es A-1 = 1 a22 -a12 a11 a22 - a12 a21 -a21 a11 . (10.29) Para matrices mayores las frmulas rpidamente llegan a ser muy desordenadas. o a 280 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. 10.2.2. Matrices singulares y patolgicas. o Antes que regresemos a la F isica, discutamos otro posible riesgo en resolver sistemas de ecuaciones lineales. Consideremos las ecuaciones x1 + x2 = 1 . 2x1 + 2x2 = 2 (10.30) Note que realmente no tenemos dos ecuaciones independientes, ya que la segunda es slo el o doble de la primera. Estas ecuaciones no tienen una solucin unica. Si tratamos de hacer una o eliminacin hacia adelante, obtenemos o x1 + x2 = 1 , 0 = 0 y no se puede hacer nada ms. a Otra manera de mirar este problema es ver que la matriz 1 1 A= 2 2 (10.32) (10.31) no tiene inversa. Una matriz sin inversa se dice que es singular. Una matriz singular tambin tiene un determinante nulo. Las matrices singulares no siempre son evidentes. Podr e ia adivinar si esta matriz 1 2 3 4 5 6 7 8 9 es singular? Aqu est lo que pasa en Octave cuando tratamos de resolver (10.30) i a octave:1> A=[1 1; 2 2]; octave:2> b=[1; 2]; octave:3> x=A\b; warning: matrix singular to machine precision, rcond = 0 Dependiendo de su compilador, la rutina inv de C++ probablemente retorne infinito o arroje un mensage de error. En algunos casos la rutina calcula una inversa para una matriz singular, pero naturalmente la respuesta es espuria. Algunas veces la matriz no es singular pero est tan cerca de serlo que los errores de a redondeo podr "empujarla al abismo". Un ejemplo trivial ser ian ia 1+ 2 1 2 , (10.33) donde es un nmero muy peque~o. A una matriz se le dice patolgica cuando est muy u n o a cerca de ser singular. Si usted sospecha que est tratrando con una matriz patolgica cuando resuelve Ax = b, a o entonces calcule el error absoluto, Ax - b / b para comprobar si x es una solucin precisa. o 10.2. MATRIZ INVERSA. 281 Formalmente, la condicin numrica est definida como la "distancia" normalizada entre o e a una matriz y la matriz singular ms cercana5 . Hay una variedad de maneras para definir a la distancia, dependiendo del tipo de norma usada. La funcin de Octave cond(A) regresa o la condicin numrica de una matriz A. Una matriz con una gran condicin numrica es o e o e patolgica. Un peque~o determinante puede algunas veces advertirnos que la matriz podr o n ia ser patolgica, pero la condicin numrica es el criterio real.6 o o e 10.2.3. Osciladores armnicos acoplados. o En el comienzo de este cap itulo, discutimos el problema de encontrar los estados estacionarios de ecuaciones diferenciales ordinarias. Un ejemplo cannico de un sistema con o interacciones lineales es el caso de osciladores armnicos acoplados. Consideremos el sistema o mostrado en la figura 10.1; las constantes de resorte son k1 , . . . , k4 . La posicin de los bloo ques, relativas a la pared izquierda, son x1 , x2 y x3 . La distancia entre las paredes es LP , y las longitudes naturales de los resortes son L1 , . . . , L4 . Los bloques son de ancho despreciable. Lp x1 x2 Figura 10.1: Sistema de bloques acoplados por resortes anclados entre paredes. La ecuacin de movimiento para el bloque i es o dxi dvi 1 = vi , = Fi , (10.34) dt dt mi donde Fi es la fuerza neta sobre el bloque i. En el estado estacionario, las velocidades vi , son nulas y las fuerzas netas, Fi son cero. Esto es justo el caso de equilibrio esttico. Nuestro a trabajo ahora es encontrar las posiciones en reposo de las masas. Expl icitamente las fuerzas netas son F1 = -k1 (x1 - L1 ) + k2 (x2 - x1 - L2 ) F2 = -k2 (x2 - x1 - L2 ) + k3 (x3 - x2 - L3 ) (10.35) F3 = -k3 (x3 - x2 - L3 ) + k4 (Lp - x3 - L4 ) o en forma matricial, F1 -k1 - k2 k2 0 x1 -k1 L1 + k2 L2 . F2 = k2 -k2 - k3 k3 x2 - -k2 L2 + k3 L3 0 k3 k3 - k4 x3 -k3 L3 + k4 (L4 - Lp ) F3 5 6 (10.36) S. Conte and C. de Boor, Elementary Numerical Analysis (New York: McGraw-Hill, 1980). G.H. Golub and C.F. van Loan, Matrix computation 2d ed. (Baltimore Johns Hopkins University Press, 1989). 282 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. Por conveniencia, abreviaremos la ecuacin de arriba como F = Kx - b. En forma matricial o las simetr son claras, y vemos que no ser dif extender el problema a un sistema ms ias ia icil a grande de osciladores acoplados. En el estado de equilibrio esttico las fuerzas netas son a iguales a cero, as obtenemos el resto de las posiciones de las masas resolviendo Kx - b. i 10.3. 10.3.1. Sistemas de ecuaciones no lineales. Mtodo de Newton en una variable. e Ahora que sabemos cmo resolver sistemas de ecuaciones lineales, procederemos al caso o ms general (y ms desafiante) de resolver sistemas de ecuaciones no lineales. Este problema a a es dif tanto que consideraremos primero el caso de una variable. Deseamos resolver para icil, x tal que f (x ) = 0 . (10.37) donde f (x ) es ahora una funcin general. Hay un nmero de mtodos disponibles para o u e encontrar raices en una variable. Quizs usted conozca algunos mtodos como el de biseccin a e o o de la secante u otros algoritmos. Tambin hay algoritmos especializados para cuando f (x) e es un polinomio (e.g., funcin de roots en Octave). En vez de utilizar todos estos esquemas, o nos concentraremos en el ms simple y util de los mtodos para el caso general de N variables. a e 7 a o iz El mtodo de Newton est basado en la expansin de Taylor de f (x) entorno a la ra e x . Supongamos que hacemos una estimacin acerca de la localizacin de la ra llamamos o o iz; a esta estimacin x1 . Nuestro error podr ser escrito como x = x1 - x o x = x1 - x. o ia Escribiendo la expansin de Taylor de f (x ), o f (x ) = f (x1 - x) = f (x1 ) - x df (x1 ) + O(x2 ) . dx (10.38) Note que si x es una ra f (x ) = 0, as podemos resolver para x iz, i x = f (x1 ) + O(x2 ) . f (x1 ) (10.39) Despreciamos el trmino O(x2 ) (este ser nuestro error de truncamiento) y usamos la exe a presin resultante de x para corregir nuestra estimacin inicial. La nueva estimacin es o o o x2 = x1 - x = x1 - Este procedimiento podr ser iterado como ia xn+1 = xn - f (xn ) , f (xn ) (10.41) f (x1 ) . f (x1 ) (10.40) para mejorar nuestra estimacin hasta obtener la precisin deseada. o o El procedimiento iterativo descrito ms arriba puede entenderse mejor grficamente (figua a ra 10.2). Note que en cada paso usamos la derivada de f (x) para dibujar la l inea tangente a 7 F.S. Acton, Numerical Methods that Work (New York: Harper&Row, 1970). 10.3. SISTEMAS DE ECUACIONES NO LINEALES. 283 f(x) x2 x1 x3 x* x Figura 10.2: Representacin grfica del mtodo de Newton. o a e la funcin. Donde esta l o inea tangente intersecta el eje x es nuestra siguiente estimacin de la o ra Efectivamente, estamos linealizando f (x) y resolviendo el problema lineal. Si la funcin iz. o es bien comportada, pronto ser aproximadamente lineal en alguna vecindad cerca de la ra a iz x. Unas pocas notas acerca del mtodo de Newton: primero, cuando converge, encuentra una e ra muy rpidamente; pero, desafortunadamente, algunas veces diverge (e.g., f (xn ) 0) y iz a falla. Para funciones bien comportadas, este mtodo es garantizado que converger si estamos e suficientemente cerca de la ra Por esta razn algunas veces est combinada con un algoritmo iz. o a ms lento pero que asegura encontrar la ra tal como la biseccin. Segundo, si hay varias a iz, o raices, la ra a la cual el mtodo converge depende de la estimacin inicial (que podr no iz e o ia ser la ra deseada). Hay procedimientos (e.g., "deflation") para encontrar mltiples raices iz u usando el mtodo de Newton. Finalmente, el mtodo es ms lento cuando se encuentran e e a raices tangentes, tales como para f (x) = x2 . 10.3.2. Mtodo de Newton multivariable. e No es dif generalizar el mtodo de Newton a problemas de N variables. Ahora nuestra icil e incgnita x = [x1 , x2 , . . . , xN ] es un vector fila, y deseamos encontrar los ceros (raices) de o la funcin vector fila o f (x) = [f1 (x) , f2 (x) , . . . , fN (x)] . (10.42) De nuevo, hacemos una estimacin inicial para ubicar la ra llamamos a esta estimacin x1 . o iz, o Nuestro error podr ser esrito como x = x1 - x o x = x1 - x. Usando la expansin de ia o Taylor de f (x1 ), f (x ) = f (x1 - x) = f (x1 ) - x D(x1 ) + O(x 2 ) , donde D es el Jacobiano, definido como Dij (x) = fj (x) . xi (10.44) (10.43) 284 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. Ya que x es la ra f (x ) = 0, como antes podr iz, iamos resolverla para x. Despreciando el trmino de error, podemos escribir la ecuacin (10.43) como e o f (x1 ) = x D(x1 ) , o x = f (x1 ) D-1 (x1 ) . Nuestra nueva estimacin es o x2 = x1 - x = x1 - f (x1 ) D-1 (x1 ) . (10.47) (10.46) (10.45) Este procedimiento puede ser iterado para mejorar nuestra estimacin hasta que sea obtenida o la precisin deseada. Ya que D cambia en cada iteracin, podr ser desgastador calcular su o o ia inversa. En cambio, usamos la eliminacin Gaussiana sobre la ecuacin (10.45) para resolver o o para x, y calcular la nueva estimacin como x2 = x1 - x. o 10.3.3. Programa del mtodo de Newton. e Para demostrar el mtodo de Newton, lo usaremos para calcular estados estacionarios del e modelo de Lorenz. A principios de la dcada de 1960 el meteorlogo del MIT, Ed Lorenz, encontr que el clima e o o es intr insecamente impredecible, no por su complejidad, sino por la naturaleza no lineal de las ecuaciones que lo gobiernan. Lorenz formul un modelo simple del clima global, reduciendo el o problema a un sistema de ecuaciones diferenciales ordinarias de 12 variables. El observ que o este sistema ten un comportamiento aperidico y que era extremadamente sensible a las ia o condiciones iniciales. Estudiemos un modelo de Lorenz simplificado a tres variables dx = (y - x) , dt dy = rx - y - xz , dt dz = xy - bz , dt (10.48) donde , r y b son contantes positivas. Estas ecuaciones simples fueron originalmente desarrolladas como un modelo para un fluido con conveccin. La variable x mide la razn o o de conveccin, y y z miden los gradientes de temperaturas horizontales y verticales. Los o parmetros y b dependen de las propiedades del fluido y de la geometr del contenedor; a ia comnmente, los valores = 10 y b = 8/3 son usados. El parmetro r es proporcional al u a gradiente de temperatura aplicado. Un programa que encuentra las raices de este sistema de ecuaciones usando el mtodo e de Newton, al que llamamos newtn, es esbozado en la tabla 10.3. Este programa llama la funcin fnewt (tabla 10.4), la cual, dado un x = [x , y , z] regresa o (y - x) - 0 f = rx - y - xz , D = r - z -1 -x . (10.49) xy - bz y x -b 10.3. SISTEMAS DE ECUACIONES NO LINEALES. 285 Conjunto inicial de estimaciones x1 y parmetros k . a Itera sobre el nmero de pasos deseados. u Evala la funcin f (xn ; k ) y su Jacobiano D. u o Encuentra x por la eliminacin Gaussiana [ver (10.45)]. o Actualiza la estimacin para la ra usando xn+1 = xn - x. o iz Imprime la estimacin final de la ra o iz. Cuadro 10.3: Descripcin del programa newtn, el cual encuentra una ra para un conjunto o iz de ecuaciones. Para r = 28, = 10 y b = 8/3, las tres ra ices son [x, y, z] = [0, 0, 0], [6 2, 6 2, 27] y [-6 2, -6 2, 27]. Un ejemplo de la salida de newtn est dada ms abajo; note que el programa obtiene la a a ra [6 2, 6 2, 27]. iz octave:1> newtn newtn is the file: ~/cursos/MFM1.apuntes2/programas/newtn.m newtn - Programa para resolver un sistema de ecuaciones no lineales usando el metodo de Newton. Las ecuaciones estan definidas en fnewt Entre la estimacion inicial (vector columna): [50; 50; 50] Entre los parametros a: [28 10 8/3] Despues de 10 iteraciones la raiz es 8.4853 8.4853 27.0000 Otras condiciones iniciales convergen a otras raices. Por ejemplo, comenzando por 2, 2], [2, convergemos a la ra [0, 0, 0]; si comenzamos en [5, 5, 5], converge a [-6 2, -6 2, 27]. iz Comenzando por el punto [4, 4, 15], el mtodo converge a una ra slo despus de hacer e iz o e una excursin incre o iblemente distante del origen. 10.3.4. Continuacin. o La primera dificultad con el mtodo de Newton es la necesidad de dar una buena estimae cin inicial para la ra A menudo nuestro problema es de la forma o iz. f (x ; ) = 0 , (10.50) donde es algn parmetro en el problema. Supongamos que conocemos una ra x0 para el u a iz valor 0 pero necesitamos encontrar una ra para un valor diferente de a . Intuitivamente, iz si a 0 , entonces x0 deber ser una buena estimacin inicial para encontrar xa usando ia o 286 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. Entradas: x = [x, y, z], = [r, , b]. Salidas: f , D. Evala f por el modelo de Lorenz [(10.49)]. u Evala el Jacobiano D para el modelo de Lorenz. u Cuadro 10.4: Descripcin de la funcin fnewt, la cual es usada por newtn para encontrar los o o estados estables de la ecuacin de Lorenz. o el mtodo de Newton. Pero si a 0 , hay alguna manera para hacer uso de nuestra ra e iz conocida? La respuesta es s y la tcnica es conocida como continuacin. La idea es acercarse poco i e o a poco a a definiendo la siguiente secuencia de : i = 0 + (a - 0 ) i , N (10.51) para i = 1, . . . . . . ., N . Usando el mtodo de Newton, resolvemos f (x1 ; 1 ) = 0 con x0 e como la estimacin inicial. Si N es suficientemente grande, entonces 1 0 y el mtodo o e podr converger rpidamente. Luego usamos x1 como una estimacin inicial para resolver ia a o f (x2 ; 2 ) = 0; la secuencia contina hasta alcanzar nuestro valor deseado en a . La tcnica u e de continuacin tiene un beneficio adicional que podemos usar cuando estamos interesados o en conocer no slo una ra simple, sino conocer como x var con . o iz ia 10.4. LISTADOS DEL PROGRAMA. 287 10.4. 10.4.1. Listados del programa. Definicin de la clase Matrix. o // // Clase de Matrices doubles // #ifndef _Matrix_h #define _Matrix_h #include <iostream> #include <string> class Matrix { private: int nFilP ; int nColP ; int dimP ; double * dataP ; void copy(const Matrix &) ; public: Matrix() ; Matrix( int, int = 1, double = 0.0e0) ; Matrix( const Matrix &) ; ~Matrix() ; Matrix & operator = (const Matrix &) ; double & operator () (int, int =0) ; int nRow () const; int nCol () const ; void set(double) ; double maximoF(int) const ; void pivot(int,int) ; void multi(double, int, int ) ; }; ostream & operator << (ostream &, Matrix ); void error ( int, string="Error") ; Matrix operator * (Matrix, Matrix) ; Matrix operator + (Matrix, Matrix) ; Matrix operator - (Matrix, Matrix) ; #endif 288 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. 10.4.2. Implementacin de la clase Matrix. o // // Implementacion de la clase Matrix #include "Matrix.h" #include <cassert> #include <cstdlib> // Funcion privada de copia void Matrix::copy(const Matrix & mat) { nFilP=mat.nFilP ; nColP=mat.nColP ; dimP = mat.dimP ; dataP = new double[dimP] ; for(int i =0 ; i< dimP; i++) dataP[i]=mat.dataP[i] ; } // Constructor default Crea una matriz de 1 por 1 fijando su valor a cero Matrix::Matrix() { Matrix(1) ; } // Constructor normal Crea una // y fija sus valores a cero o Matrix::Matrix(int nF, int nC, error(nF>0 && nC >0, "Una de nFilP= nF ; nColP = nC ; dimP = nFilP*nColP ; dataP = new double[dimP] ; assert(dataP != 0) ; for (int i=0; i < dimP; i++) } matriz de N por M a un valor ingresado double v) { las dimensiones no es positiva" ) ; // Habia memoria para reservar dataP[i]=v ; // Constructor de copia Matrix::Matrix( const Matrix & mat) { this->copy(mat) ; // this permite acceder a la misma vartiable como un todo // *this representa la variable, y this un puntero a ella // -> nos permite elegir miembros de la clase pero cuando tenemos el puntero // a la variable y no su valor } // Destructor 10.4. LISTADOS DEL PROGRAMA. 289 Matrix::~Matrix() { delete dataP ; } // Libera la memoria // Operador Asignacion, sobrecarga del = para que funcione con Matrix Matrix & Matrix::operator= (const Matrix & mat) { if( this == &mat ) return *this ; // Si ambos lados son iguales no hace nada delete dataP ; // borra la data del lado izquierdo this-> copy(mat) ; return * this ; } // Funciones simples que retornan el numero de filas y de columnas // el const al final indica que no modifican ningun miembro de la clasa int Matrix::nRow() const {return nFilP; } int Matrix::nCol() const {return nColP;} // operador Parentesis // Permite accesar los valores de una matriz via el par (i,j) // Ejemplo a(1,1)=2*b(2,3) // Si no se especifica la columna la toma igual a 0 double & Matrix::operator() (int indF, int indC) { error(indF>-1 && indF< nFilP, "Indice de fila fuera de los limites") ; error(indC>-1 && indC<nColP, "Indice de columna fuera de los limites" ) ; return dataP[indC+nColP*indF] ; } void Matrix::set(double value) { for(int i=0; i<dimP; i++) dataP[i]=value ; } double Matrix::maximoF(int indF) const { error(indF>-1 && indF< nFilP, "Indice de fila fuera en maximoF") ; double max= dataP[nColP*indF]; for(int i=nColP*indF; i<nColP*(indF+1); i++ ) { max = (max > fabs(dataP[i]) ) ? max : fabs(dataP[i]) ; } return max ; } void Matrix::pivot(int indF1, int indF2) { error(indF1>-1 && indF1< nFilP, "Primer indice de fila fuera en Pivot") ; error(indF2>-1 && indF2< nFilP, "Segundo indice de fila fuera en Pivot") ; 290 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. if(indF1==indF2) return ; double paso ; int ind1, ind2 ; for (int i = 0; i < nColP; i++ ) { ind1 = nColP*indF1+i ; ind2 = nColP*indF2+i ; paso = dataP[ind1] ; dataP[ind1] = dataP[ind2] ; dataP[ind2] = paso ; } } void Matrix::multi(double fact, int indF1, int indF2 ) { int ind1, ind2 ; for (int i = 0; i < nColP; i++ ) { ind1 = nColP*indF1+i ; ind2 = nColP*indF2+i ; dataP[ind2] += fact*dataP[ind1] ; } } // // IOSTREAM << // ostream & operator << (ostream & os, Matrix mat ) { for(int indF=0; indF < mat.nRow(); indF++) { os << "| " ; for(int indC=0; indC<mat.nCol(); indC++) { os << mat(indF,indC) << " "; } os << "|"<<endl ; } return os ; } void error ( int i, string s) { if(i) return ; cout << s<<"\a" <<endl ; exit(-1); } Matrix operator * (Matrix A , Matrix B) { int nColA = A.nCol() ; int nColB = B.nCol() ; int nFilA = A.nRow() ; 10.4. LISTADOS DEL PROGRAMA. int nFilB = B.nRow() ; error(nColA == nFilB, "No se pueden multiplicar por sus dimensiones") ; Matrix R(nFilA , nColB ) ; for (int indF = 0; indF<nFilB; indF++){ for (int indC=0; indC<nColA; indC++){ double sum = 0.0 ; for (int k=0; k < nColA; k++ ) sum += A(indF, k) * B(k, indC) ; R(indF, indC) = sum ; } } return R ; } 291 Matrix operator + (Matrix A , Matrix B) { int nColA = A.nCol() ; int nColB = B.nCol() ; int nFilA = A.nRow() ; int nFilB = B.nRow() ; error(nFilA == nFilB && nColA== nColB, "tienen dimensiones distintas") ; Matrix R(nFilA , nColA ) ; for (int indF = 0; indF<nFilB; indF++){ for (int indC=0; indC<nColA; indC++){ R(indF, indC) = A( indF, indC) + B(indF, indC); } } return R ; } Matrix operator - (Matrix A , Matrix B) { int nColA = A.nCol() ; int nColB = B.nCol() ; int nFilA = A.nRow() ; int nFilB = B.nRow() ; error(nFilA == nFilB && nColA== nColB, "tienen dimensiones distintas") ; Matrix R(nFilA , nColA ) ; for (int indF = 0; indF<nFilB; indF++){ for (int indC=0; indC<nColA; indC++){ R(indF, indC) = A( indF, indC) - B(indF, indC); } } return R ; } 292 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. 10.4.3. Funcin de eliminacin Gaussiana ge. o o // // Eliminacion Gaussiana. // #include "NumMeth.h" #include "Matrix.h" double ge( Matrix A, Matrix { int nFil = A.nRow() ; int nCol = A.nCol() ; Matrix si (nFil) ; b, Matrix & x) for ( int indF= 0; indF < nFil ; indF++) si(indF)= A.maximoF(indF) ; double determinante=1.0e0 ; for (int indC= 0; indC< nCol-1; indC++) { // pivoteo double max = A(indC,indC)/si(indC) ; int indicePivot = indC ; for (int i = indC+1; i < nCol ; i++){ if( A(i, indC)/si(i) > max ) { max = A(i,indC)/si(i) ; indicePivot = i ; } } if(indicePivot != indC) { A.pivot(indC, indicePivot) ; b.pivot(indC, indicePivot) ; determinante *= -1.0e0 ; } double Ad= A(indC,indC) ; for (int indF=indC+1; indF< nFil; indF++ ) { double factor = - A(indF, indC)/Ad ; A.multi(factor, indC, indF); b.multi(factor, indC, indF); } } for (int indF= nFil-1; indF >=0; indF--) { double sum =0.0e0 ; for (int i = indF+1; i < nCol; i++) sum += A(indF, i)*x(i) ; x(indF) = b(indF)/A(indF, indF) - sum /A(indF, indF); } double determ = 1.0e0 ; 10.4. LISTADOS DEL PROGRAMA. for (int i = 0; i < nCol; i++) determ *= A(i,i) ; return determinante*determ } ; 293 10.4.4. Funcin para inversin de matrices inv. o o // // Invierte una matriz // #include "NumMeth.h" #include "Matrix.h" double inv( Matrix A, Matrix & invA) { int nFil = A.nRow() ; int nCol = A.nCol() ; error(nFil==nCol, "Matriz no es cuadrada"); Matrix e(nFil) ; Matrix x(nFil) ; double deter = 0.0e0 ; invA.set(0.0e0) ; for(int indC=0; indC < nCol; indC++) { e.set(0.0e0) ; e(indC) = 1.0e0; deter = ge( A, e, x) ; error(fabs(deter)>1.0e-10, " Determinante Singular" ); for (int indF=0; indF< nFil; indF++) invA(indF, indC) = x(indF) ; } return deter ; } 10.4.5. Programa newtn en Octave. % newtn - Programa para resolver un sistema de ecuaciones no lineales % usando el metodo de Newton. Las ecuaciones estan definidas en fnewt suppress_verbose_help_message=1; clear all; help newtn; x0=input('Entre la estimacion inicial (vector columna): '); x=x0; a=input('Entre los parametros a: '); nStep =10; 294 for iStep=1:nStep CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. [f D] = fnewt(x,a) ; dx=D\f ; x=x-dx; end fprintf('Despues de %g iteraciones la raiz es \n', nStep); disp(x'); Funcin fnewt en Octave. o function [f,D] = fnewt(x,a) f(1)=a(2)*(x(2)-x(1)); f(2)= a(1)*x(1)-x(2)-x(1)*x(3); f(3)=x(1)*x(2)-a(3)*x(3) ; D(1,1)=-a(2); D(2,1)=a(1)-x(3); D(3,1)=x(2); D(1,2)=a(2); D(2,2)=-1; D(3,2)=x(1); D(1,3)=0; D(2,3)=-x(1); D(3,3)=-a(3); return 10.4. LISTADOS DEL PROGRAMA. 295 10.4.6. Programa newtn en c++. #include <iostream> #include "NumMeth.h" #include "Matrix.h" void fnewt( Matrix & f, Matrix & D, Matrix xN, Matrix lambda ) { double r= lambda(0) ; double s= lambda(1) ; double b=lambda(2) ; double x=xN(0) ; double y=xN(1) ; double z=xN(2) ; f(0) = s*(y-x) ; f(1) = r*x-y-x*z ; f(2) = x*y-b*z ; D(0,0) = -s ; D(1,0) = r-z ; D(2,0) = y ; D(0,1) = s ; D(1,1)= -1.0e0 ; D(2,1) = x ; D(0,2)=0.0e0 ; D(1,2)= -x ; D(2,2) =-b ; } double ge( Matrix A, Matrix { int nFil = A.nRow() ; int nCol = A.nCol() ; Matrix si (nFil) ; b, Matrix & x) for ( int indF= 0; indF < nFil ; indF++) si(indF)= A.maximoF(indF) ; double determinante=1.0e0 ; for (int indC= 0; indC< nCol-1; indC++) { // pivoteo double max = A(indC,indC)/si(indC) ; int indicePivot = indC ; for (int i = indC+1; i < nCol ; i++){ if( A(i, indC)/si(i) > max ) { max = A(i,indC)/si(i) ; indicePivot = i ; } 296 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. } if(indicePivot != indC) { A.pivot(indC, indicePivot) ; b.pivot(indC, indicePivot) ; determinante *= -1.0e0 ; } double Ad= A(indC,indC) ; for (int indF=indC+1; indF< nFil; indF++ ) { double factor = - A(indF, indC)/Ad ; A.multi(factor, indC, indF); b.multi(factor, indC, indF); } } for (int indF= nFil-1; indF >=0; indF--) { double sum =0.0e0 ; for (int i = indF+1; i < nCol; i++) sum += A(indF, i)*x(i) ; x(indF) = b(indF)/A(indF, indF) - sum /A(indF, indF); } double determ = 1.0e0 ; for (int i = 0; i < nCol; i++) determ *= A(i,i) ; return determinante*determ } ; int main() { Matrix D(3,3) ; Matrix f(3) ; Matrix lambda(3), xN(3), xNp1(3), dx(3) ; cout <<"Ingrese r , Sigma, b : " ; cin >> lambda(0) >> lambda(1) >> lambda(2) ; cout << "Ingrese estimacion inicial : " ; cin>> xN(0) >> xN(1) >> xN(2) ; int iteraciones ; cout << "Ingrese numero de iteraciones : " ; cin >> iteraciones ; for (int itera = 0; itera < iteraciones; itera ++ ) { f.set(0.0e0) ; D.set(0.0e0) ; dx.set(0.0e0) ; fnewt(f, D, xN, lambda ) ; 10.4. LISTADOS DEL PROGRAMA. ge(D, f, dx) ; xNp1=xN-dx ; xN=xNp1 ; cout << xN(0)<< " " << xN(1) << " " << xN(2) << endl ; } cout << xN <<endl ; return 0; } 297 298 CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. Cap itulo 11 Anlisis de datos. a versin 3.0, 02 de Diciembre 20031 o A menudo se destaca que los sistemas f isicos simulados sobre un computador son similares al trabajo experimental. La razn de esta analog es hecha ya que la simulacin computacioo ia o nal produce datos en muchas maneras similares a los experimentos de laboratorio. Sabemos que en el trabajo experimental uno a menudo necesita analizar los resultados y esto es lo mismo que con la simulacin numrica. Este cap o e itulo cubre parcialmente algunos tpicos en o el anlisis de datos. a 11.1. 11.1.1. Ajuste de curvas. El calentamiento global. En el presente, parece que predicciones sobre el tiempo de largo alcance y precisas nunca se llevarn a cabo. La razn es a causa de las ecuaciones gobernantes que son altamente a o no lineales y sus soluciones son extremadamente sensibles a las condiciones iniciales (ver el modelo de Lorenz). Por otra parte, las predicciones generales acerca del clima terrestre son posibles. Se pueden predecir si habr o no condiciones de sequ en Africa en los prximos a ia o a~os, aunque no la cantidad de precipitaciones de un d en particular. n ia El calentamiento global es un importante tpico actualmente debatido en los foros de ino vestigacin sobre clima. El calentamiento es culpa de los gases de invernadero, tal como es el o dixido de carbono en la atmsfera. Estos gases calientan la Tierra porque son transparentes o o a la radiacin de onda corta que llega desde el Sol, pero opacas a la radiacin infrarroja desde o o la tierra. Cient ificos y legisladores todav estn debatiendo la amenaza del calentamiento ia a global. Sin embargo, nadie se pregunta qu concentraciones de gases invernadero estn en e a aumento. Espec ificamente, los niveles de dixido de carbono han estado firmemente aumeno tados desde la revolucin industrial. La figura 11.1 muestra el aumento en la concentracin o o de dixido de carbono durante los a~os ochenta, medidos en Mauna Loa, Hawai. o n El estudio del calentamiento global ha producido una vasta cantidad de datos, tanto mediciones prcticas, como datos de las simulaciones computacionales. En este cap a itulo estudiaremos algunas tcnicas bsicas para analizar y reducir tales conjuntos de datos. Por e a ejemplo, para los datos mostrados en la figura 11.1, cul es la razn estimada de crecimiento a o Este cap itulo est basado en el quinto cap a itulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall. 1 299 300 CAP ITULO 11. ANALISIS DE DATOS. 355 CO2 (ppm) 350 345 340 335 1982 1984 Ao 1986 1988 1990 Figura 11.1: Dixido de carbono (en partes por milln) medida en Mauna Loa, Hawai desde o o 1981 a 1990. Barra de error estimada es 0 = 0.16 [p.p.m.] . de la concentracin de CO2 por a~o?. Esta es la primera pregunta que motiva nuestro estudio o n de ajustes de curvas. 11.1.2. Teor general. ia El tipo ms simple de anlisis de datos es ajustar una curva. Suponga que tenemos un a a conjunto de datos de N puntos (xi , yi ). Deseamos ajustar estos datos a una funcin Y (x; {aj }), o donde {aj } es un conjunto de M parmetros ajustables. Nuestro objetivo es encontrar los a valores de esos parmetros, para los cuales la funcin ajusta mejor los datos. Intuitivamente, a o esperamos que si nuestro ajuste de la curva es bueno, un grfico del conjunto de datos (xi , yi ) a y la funcin Y (x; {aj }) mostrarn la curva pasando cerca de los puntos (ver figura 11.2). o a Podemos cuantificar esta sentencia midiendo la distancia entre un punto y la curva. i = Y (xi ; {aj }) - yi . (11.1) Nuestro criterio de ajuste para la curva ser que la suma de los cuadrados de los errores a sea un m inimo; esto es, necesitamos encontrar {aj } que minimice la funcin o N N D({aj }) = i=1 2 i = i=1 [Y (xi ; {aj}) - yi ]2 . (11.2) 11.1. AJUSTE DE CURVAS. 301 yi i i Y(x;{aj }) xi Figura 11.2: Ajuste de datos a una curva. Esta tcnica nos dar el ajuste de los cuadrados mnimos; esta no es la unica manera de e a i obtener un ajuste de la curva, pero es la ms comn. El mtodo de los m a u e inimos cuadrados fue el primero usado por Gauss para determinar las rbitas de los cometas a partir de los o datos observados. A menudo, nuestros datos tienen una barra de error estimada (o intervalo de seguridad), el cual escribimos como yi i . En este caso podr iamos modificar nuestro criterio de ajuste tanto como para dar un peso menor a los puntos con ms error. En este esp a iritu definimos N ({aj }) = i=1 2 i i 2 N = i=1 [Y (xi ; {aj }) - yi ]2 . 2 i (11.3) La funcin chi-cuadrado es la funcin de ajuste ms comnmente usada, porque si los errores o o a u son distribuidos gaussianamente, podemos hacer sentencias estad isticas concernientes a la virtud del ajuste. Antes de continuar, debemos destacar que discutiremos brevemente la validacin de la o curva de ajuste. Usted puede ajustar cualquier curva para cualquier conjunto de datos, pero esto no significa que los resultados sean significativos. Para establecer un significado tenemos que preguntarnos lo siguiente: cul es la probabilidad de que los datos, dado el error a experimental asociado con cada uno de los puntos, sean descritos por la curva?. Desafortunadamente, las hiptesis de prueba ocupan una porcin significativa de un curso estad o o istico y estn fuera de los objetivos de este libro.2 a 11.1.3. Regresin lineal. o Primero consideremos ajustar el conjunto de datos con una l inea recta, Y (x; {a1 , a2 }) = a1 + a2 x . 2 (11.4) W. Mendenhall, R.L. Scheaffer, and D.D. Wackerly, Mathematical Statistics with Applications (Boston: Duxbury Press, 1981). 302 CAP ITULO 11. ANALISIS DE DATOS. Este tipo de ajuste de curva es tambin conocido como regresin lineal. Deseamos determinar e o a1 y a2 tal que N 1 2 (a1 , a2 ) = (a1 + a2 xi - yi )2 , (11.5) 2 i i=1 es minimizada. El m inimo es encontrado diferenciando (11.5) y ajustando la derivada a cero: 2 =2 a1 =2 a2 o a1 S + a2 x - y = 0 a1 x + a2 x2 - xy = 0 , donde N 2 N i=1 N 1 (a1 + a2 xi - yi ) = 0 , 2 i 1 (a1 + a2 xi - yi ) xi = 0 , 2 i (11.6) (11.7) i=1 (11.8) (11.9) S i=1 N 1 , 2 i N x i=1 N xi , 2 i N y i=1 N yi , 2 i (11.10) x2 i=1 x2 i , 2 i y 2 i=1 2 yi , 2 i xy i=1 xi yi . 2 i Puesto que las sumas pueden ser calculadas directamente de los datos, ellas son constantes conocidas. De este modo tenemos un conjunto lineal de dos ecuaciones simultneas en las a incgnitas a1 y a2 . Estas ecuaciones son fciles de resolver: o a a1 = yx2 - xxy , Sx2 - (x)2 a2 = Sxy - xy . Sx2 - (x)2 (11.11) Note que si i es una constante, esto es, si el error es el mismo para todos los datos, los se a cancelan en las ecuaciones (11.11). En este caso, los parmetros, a1 y a2 , son independientes de la barra de error. Es comn que un conjunto de datos no incluya las barras de error u asociadas. Todav podr ia iamos usar las ecuaciones (11.11) para ajustar los datos si tenemos que los i son constantes (i =1 siendo la eleccin ms simple). o a Lo siguiente es obtener una barra de error asociado, aj , para el parmetro aj de la curva a 3 de ajuste. Usando la ley de la propagacin de errores, o N 2 aj = i=1 3 aj yi 2 i , (11.12) P. Bevington, Data Reduction an Error Analysis for the Physical Sciences 2d ed. (New York: McGrawHill, 1992). 11.1. AJUSTE DE CURVAS. e insertando las ecuaciones (11.11), despus de un poco de lgebra obtenemos e a x2 , Sx2 - (x)2 S . - (x)2 303 a1 = a2 = Sx2 (11.13) Note que aj es independiente de yi . Si las barras de error de los datos son constantes (i = 0 ), el error en los parmetros es a 0 a1 = N donde 1 x = N N x2 x2 - x 2 , 0 a2 = N x2 1 - x 2 , (11.14) xi , i=1 x 2 1 = N N x2 . i i=1 (11.15) Finalmente, si nuestro conjunto de datos no tiene un conjunto de barras de error asociadas, podr iamos estimar 0 a partir de la diferencia muestral de los datos, 2 0 s2 = 1 N -2 N [yi - (a1 + a2 xi )]2 , i=1 (11.16) donde s es la desviacin estndar de la muestra. Note que esta varianza muestral est noro a a malizada por N - 2, puesto que hemos extra dos parmetros a1 y a2 , de los datos. ido a Muchos problemas de ajuste de curva no lineales, pueden ser transformados en problemas lineales por un simple cambio de variable. Por ejemplo, Z(x; {, }) = ex , podr ser reescrita como las ecuaciones (11.4) usando el cambio de variable ia ln Z = Y , ln = a1 , = a2 . (11.18) (11.17) Similarmente, para ajustar una potencia de la forma Z(t; {, }) = t , usamos el cambio de variable ln Z = Y , ln t = x , ln = a1 , = a2 . (11.20) (11.19) Estas transformaciones deber ser familiares debido a que se usan para graficar datos en ian escala semi logar itmica o escalas log-log. 304 CAP ITULO 11. ANALISIS DE DATOS. 11.1.4. Ajuste general lineal de m inimos cuadrados. El procedimiento de ajuste de m inimos cuadrados es fcil de generalizar para funciones a de la forma M Y (x; {aj }) = a1 Y1 (x) + a2 Y2 (x) + . . . + aM YM (x) = j=1 aj Yj (x) . (11.21) Para encontrar los ptimos parmetros procedemos como antes encontrando el m o a inimo de 2 , 2 = aj aj o N N i=1 1 2 i M 2 ak Yk (x) - yi k=1 M =0, (11.22) i=1 1 Y (xi ) 2 j i M ak Yk (x) - yi k=1 N =0, (11.23) por lo tanto N i=1 k=1 Yj (xi )Yk (xi ) ak = 2 i i=1 Yj (xi )yi , 2 i (11.24) para j = 1, . . . , M . Este conjunto de ecuaciones es conocida como las ecuaciones normales del problema de los m inimos cuadrados. Las ecuaciones normales son ms fciles de trabajar en forma matricial. Primero, definaa a como mos la matriz de dise~o A, n Y1 (xi )/1 Y2 (xi )/1 . . . Yj (xi ) A = Y1 (xi )/2 Y2 (xi )/2 . . . , Aij = . (11.25) i . . .. . . . . . Note que la matriz de dise~o no depende de yi , los valores de datos, pero depende de xi , esto n es, sobre el dise~o del experimento (donde las mediciones son tomadas). Usando la matriz de n dise~o, podemos escribir (11.24) como n N M N Aij Aik ak = i=1 k=1 i=1 Aij yi , 2 i (11.26) o en forma matricial, (AT A)a = AT b , (11.27) donde el vector b est definido como bi = yi /i y AT es la traspuesta de la matriz de dise~o. a n Esta ecuacin es fcil de resolver para el parmetro vector a, o a a a = (AT A)-1 AT b . (11.28) Usando este resultado y la ley de propagacin de errores, en la ecuacin (11.12), encontramos o o que el error estimado en el parmetro aj es a aj = Cjj (11.29) 11.1. AJUSTE DE CURVAS. 305 donde C = (AT A)-1 . Una aplicacin comn de esta formulacin general lineal de ajuste de m o u o inimos cuadrados es el ajuste de los datos polinomiales, Y (x; {aj }) = a1 + a2 x + a3 x2 + . . . + aM xM -1 . (11.30) La matriz de dise~o tiene elementos Aij = aj xj-1 /i , el cual es un tipo de matriz de Vandern I monde. Desafortunadamente estas matrices son notoriamente patolgicas, por lo tanto sea o cuidadoso para M > 10. 11.1.5. Bondades del ajuste. Podemos fcilmente ajustar cada punto de dato si el nmero de parmetros, M , es igual a u a al nmero de puntos de datos, N . En este caso ya sea que hemos construido una teor trivial u ia o no hemos tomado suficientes datos. En vez de eso, supongamos el escenario ms comn en a u el cual N M . Porque cada dato de punto tiene un error, no esperemos que la curva pase exactamente a travs de los datos. Sin embargo, preguntemos, con las barras de error dadas, e cuan probable es que la curva en efecto describa los datos?. Por supuesto, si no se tienen barras de error no hay nada que se pueda decir acerca de la bondad del ajuste. El sentido comn sugiere que si el ajuste es bueno, entonces el promedio de la diferencia u deber ser aproximadamente igual a la barra de error, ia | yi - Y (xi ) | i . (11.31) Colocando esto dentro de nuestra definicin para 2 , la ecuacin (11.3), da 2 N . Sin o o embargo, sabemos que entre ms parmetros usamos, ms fcil es ajustar la curva; el ajuste a a a a puede ser perfecto si M = N . Esto sugiere que nuestra regla prctica para que un ajuste sea a bueno es 2 N - M . (11.32) Por supuesto, este es slo un crudo indicador, pero es mejor que una simple ojeada a la curva. o Un anlisis completo podr usar estad a ia istico para asignar una probabilidad de que los datos sean ajustados por la curva. Si encontramos que 2 N - M , entonces una de dos: no hemos usado una funcin o apropiada, Y (x), para nuestro ajuste de curva o las barras de errores, I , son demasiado peque~as. Por otra parte, si 2 n N - M , el ajuste es tan espectacularmente bueno que podemos esperar que las barras de error sean realmente demasiado grandes. Habitualmente la calidad de un ajuste se mide por el coeficiente de correlacin adimeno sional que es un nmero que var entre 0 y 1, correspondiendo a 1 un mejor ajuste. u ia r2 = S(a1 y - a2 xy) - ( S y 2 - ( y)2 y)2 . (11.33) 306 CAP ITULO 11. ANALISIS DE DATOS. Cap itulo 12 Integracin numrica bsica o e a versin 4.1, 4 de Diciembre del 2004 o En este cap itulo veremos algunos mtodos bsicos para realizar cuadraturas (evaluar e a integrales numricamente). e 12.1. Definiciones b Consideremos la integral I= a f (x) dx . (12.1) Nuestra estrategia para estimar I es evaluar f (x) en unos cuantos puntos, y ajustar una curva simple a travs de estos puntos. Primero, subdividamos el intervalo [a, b] en N subintervalos. e Definamos los puntos xi como x0 = a, xN = b, x0 < x1 < x2 < < xN -1 < xN . La funcin f (x) slo se evala en estos puntos, de modo que usamos la notacin fi f (xi ), o o u o ver figura 12.1. f(x) x0=a x1 x2 xi xN=b Figura 12.1: Subintervalos. 307 308 CAP ITULO 12. INTEGRACION NUMERICA BASICA 12.2. Regla trapezoidal El mtodo ms simple de cuadratura es la regla trapezoidal. Conectamos los puntos fi e a con l ineas rectas, y la funcin lineal formada por la sucesin de l o o ineas rectas es nuestra curva aproximante. La integral de esta funcin aproximante es fcil de calcular, pues es la suma de o a fi f(x) fi+1 Ti xi xi+1 x Figura 12.2: Sucesin de l o ineas rectas como curva aproximante. las reas de trapezoides. El rea de un trapezoide es a a 1 Ti = (xi+1 - xi )(fi+1 + fi ) . 2 La integral es entonces calculada como la suma de las reas de los trapezoides: a I IT = T0 + T1 + + TN -1 . Las expresiones son ms simples si tomamos puntos equidistantes. En este caso el espaa ciado entre cada par de puntos es b-a h= , N de modo que xi = a + ih. El rea de un trapezoide es entonces a 1 Ti = h(fi+1 + fi ) , 2 y la regla trapezoidal para puntos equiespaciados queda 1 1 IT (h) = hf0 + hf1 + hf2 + + hfN -1 + hfN 2 2 N -1 1 = h(f0 + fN ) + h fi 2 i=1 (12.2) 12.3. INTERPOLACION CON DATOS EQUIDISTANTES. 309 12.3. Interpolacin con datos equidistantes. o Para el caso de puntos xi = a + ih que estn igualmente espaciados podemos plantear a un formalismo ms general. Primero que todo, ajustemos un polinomio de grado N a un a conjunto de N + 1 datos xi , fi , no necesariamente equidistantes, de la forma: PN (x) = b0 + b1 (x - x0 ) + + bN (x - x0 )(x - x1 ) (x - xN -1 ) . Determinemos los coeficientes usando los datos: b0 = f0 = f (x0 ) f1 - f0 f [x1 , x0 ] b1 = x1 - x0 f2 - f1 f1 - f0 f [x2 , x1 ] - f [x1 , x0 ] b2 = - /(x2 - x0 ) = f [x2 , x1 , x0 ] x2 - x1 x1 - x0 x2 - x0 . . . bN = f [xN , xN -1 , xN -2 , . . . , x1 , x0 ] , donde hemos usado la definicin recurrente o f [xN , xN -1 , xN -2 , . . . , x1 , x0 ] f [xN , xN -1 , xN -2 , . . . , x1 ] - f [xN -1 , xN -2 , . . . , x1 , x0 ] . xN - x0 (12.3) La expresin anterior es conocida como la n-sima diferencia dividida finita. Usando estas o e definiciones podemos escribir el polinomio de interpolacin (12.3) de la siguiente manera: o PN (x) = f0 + f [x1 , x0 ](x - x0 ) + f [x2 , x1 , x0 ](x - x1 )(x - x0 ) + +f [xN , xN -1 , xN -2 , . . . , x1 , x0 ](x - x0 )(x - x1 ) (x - xN -1 ) , Este polinomio es conocido como el polinomio de interpolacin por diferencias divididas de o Newton. Analicemos estos f [. . .] para el caso equiespaciado, f [x1 , x0 ] = El segundo f2 - f1 f1 - f0 - f (x2 ) - 2f (x1 ) + f (x0 ) 2 f0 x - x1 x1 - x0 f [x2 , x1 , x0 ] = 2 = . = x2 - x0 2h2 2!h2 En general tenemos (puede probarse por induccin) que o n f0 . n!hn Luego podemos escribir la llamada frmula hacia adelante de Newton-Gregory, definiendo o = (x - x0 )/h de la siguiente manera f [xN , xN -1 , xN -2 , . . . , x1 , x0 ] = fN (x) = f (x0 ) + f (x0 ) + n f (x0 ) 2 f (x0 ) ( - 1) + + ( - 1) ( - n + 1) + RN , 2! n! (12.4) f1 - f0 f0 = . x1 - x0 1!h 310 CAP ITULO 12. INTEGRACION NUMERICA BASICA el error de truncamiento viene dado por RN = para algn [a, b]. u f (n+1) () n+1 h ( - 1)( - 2) ( - n) , (n + 1)! 12.4. Reglas de cuadratura La integral (12.1) puede ser evaluada separndola en una suma de integrales sobre pea que~os intervalos que contengan dos o tres puntos, luego usando el polinomio de interpolacin n o adecuado para el nmero de puntos escogidos podemos evaluar aproximadamente cada inteu gral. Para terminar el proceso debemos sumar todas las integrales parciales. Usemos slo dos o puntos, y entre esos dos puntos aproximamos la funcin por el polinomio de interpolacin de o o dos puntos, i.e. por una recta, figura 12.3 (a). xi+1 xi+1 Ii (h) = xi f (x) dx xi f (xi ) + f (xi ) x - xi h dx = f (xi )h + f (xi ) h2 , h 2 usando que f (xi ) = f (xi+1 ) - f (xi ) podemos dar una expresin para la integral o Ii (h) f (xi+1 ) + f (xi ) h. 2 (12.5) f(x) (a) f(x) (b) xi xi+1 xi xi+1 xi+2 Figura 12.3: Aproximaciones, (a) lineal, (b) cuadrtica. a Si consideramos intervalos que contengan tres puntos podemos usar la aproximacin a o segundo orden, es decir esta vez aproximamos nuestra funcin por un polinomio de segundo o grado, figura 12.3 (b). xi+2 xi+2 Ii (h) = xi f (x) dx xi f (xi ) + f (xi ) (x - xi ) 2 f (xi ) (x - xi ) (x - xi - h) + h 2 h h dx , 12.4. REGLAS DE CUADRATURA integrando obtenemos Ii (h) 2hf (xi ) + f (xi ) 4h2 2 f (xi ) + h 2 2h2 8h3 4h3 - 3 2 , 311 usando la expresin para f (xi ) = f (xi+1 )-f (xi ) y para 2 f (xi ) = f (xi+2 )-2f (xi+1 )+f (xi ) o tenemos h (12.6) Ii (h) (f (xi ) + 4f (xi+1 ) + f (xi+2 )) . 3 Se puede continuar encontrando expresiones usando aproximaciones de orden mayor, sin embargo, las frmulas (12.5) y (12.6) son, sin duda, las ms usadas. o a A continuacin, para evaluar la integral finita (12.1) debemos sumar las integrales paro ciales para ambos casos. Partamos sumando (12.5) b N -1 xi+1 N -1 I= a f (x) dx = i=0 xi f (x) dx i=0 f (xi+1 ) - f (xi ) h IT (h) , 2 haciendo la suma tenemos h IT (h) = [f (a) + f (b)] + h 2 N -1 f (xi ) , i=1 regla trapezoidal. (12.7) Ahora evaluemos la integral finita, (12.1), usando la descomposicin en integrales de tres o puntos ecuacin (12.6) o b N -2 xi+2 N -2 I= a f (x) dx = i=0 xi f (x) dx i=0 h [f (xi ) + 4f (xi+1 ) + f (xi+2 )] Is (h) , 3 haciendo la suma tenemos Is (h) = 2h f (a) f (b) + 2f (x1 ) + f (x2 ) + 2f (x3 ) + f (x4 ) + 2f (x5 ) + . . . + 3 2 2 . (12.8) La cual es conocida como la regla de Simpson. Notemos que se necesita un nmero impar de u puntos equiespaciados para aplicar esta regla. Se puede estimar el error cometido en cada caso integrando el trmino (12.3) que correse ponde al error de truncamiento de la expansin. Evaluemos el error para el caso trapezoidal o en que cortamos la expansin a primer orden, por lo tanto el error corresponde o xi+1 T (h) = xi d2 f () h2 (x - xi ) (x - xi - h) dx , dx2 2! h h haciendo el cambio de variable u = x - xi tenemos T (h) = 1 d2 f () 2 dx2 h u(u - h) du = 0 h3 h3 - 3 2 1 d2 f () h3 d2 f () =- 2 dx2 12 dx2 312 CAP ITULO 12. INTEGRACION NUMERICA BASICA este es el error en cada integral entre xi y xi+1 , para obtener el error total en la integral entre a y b tenemos que multiplicar por el nmero de intervalos (N ), u I - IT (h) = N T (h) = -N h3 d2 f () (b - a)h2 d2 f () h2 =- = - (f (b) - f (a)) . 12 dx2 12 dx2 12 La expresin para el error en el mtodo trapezoidal nos queda o e I - IT (h) = - 1 2 h [f (b) - f (a)] + O(h4 ) . 12 (12.9) Vemos que el error es proporcional a h2 , y que la regla trapezoidal tendr problemas cuando a b la derivada diverge en los extremos del intervalo. Por ejemplo, la integral 0 x dx es problemtica. En el caso de la integral de Simpson se puede probar que el error es proporcional a a h4 . Como ejemplo, consideremos la funcin error o 2 erf(x) = x 0 e-y dy . 2 (12.10) Para x = 1, erf(1) 0.842701. La regla trapezoidal con N = 5 da 0.83837, que es correcto en los dos primeros decimales. La regla de Simpson, con los mismos 5 puntos, da 0.84274, con cuatro decimales correctos . Por supuesto, el integrando en este ejemplo es muy suave y bien comportado lo cual asegura que los mtodos funcionaran bien. e 12.5. Integracin de Romberg o Una pregunta usual es cuntas subdivisiones del intervalo realizar. Un modo de decidir es a repetir el clculo con un intervalo ms peque~o. Si la respuesta no cambia apreciablemente, a a n la aceptamos como correcta (sin embargo, esto no evita que podamos ser enga~ados por funn ciones patolgicas o escenarios inusuales). Con la regla trapezoidal, si el nmero de paneles es o u una potencia de dos, podemos dividir el tama~o del intervalo por dos sin tener que recalcular n todos los puntos. Definamos la secuencia de tama~os de intervalo, n 1 1 h1 = (b - a) , h2 = (b - a) , . . . , hn = n-1 (b - a) . 2 2 Para n = 1 slo hay un panel, luego o 1 1 IT (h1 ) = (b - a)[f (a) + f (b)] = h1 [f (a) + f (b)] . 2 2 Para n = 2 se a~ade un punto interior, luego n 1 IT (h2 ) = h2 [f (a) + f (b)] + h2 f (a + h2 ) 2 1 = IT (h1 ) + h2 f (a + h2 ) . 2 (12.11) 12.5. INTEGRACION DE ROMBERG Hay una frmula recursiva para calcular IT (hn ) usando IT (hn-1 ): o 1 IT (hn ) = IT (hn-1 ) + hn 2 2n-2 313 f [a + (2i - 1)hn ] . i=1 (12.12) El segundo trmino del lado derecho da la contribucin de los puntos interiores que se han e o agregado cuando el tama~o del intervalo es reducido a la mitad. n Usando el mtodo recursivo descrito, podemos agregar paneles hasta que la respuesta e parezca converger. Sin embargo, podemos mejorar notablemente este proceso usando un mtodo llamado integracin de Romberg. Primero veamos la mecnica, y despus explicaremos e o a e por qu funciona. El mtodo calcula los elementos de una matriz triangular: e e R1,1 R2,1 R2,2 R=R 3,1 R3,2 R3,3 . . . .. . . . . . . . La primera columna es simplemente la regla trapezoidal recursiva: Ri,1 = IT (hi ) . (12.14) (12.13) Las sucesivas columnas a la derecha se calculan usando la frmula de extrapolacin de Rio o chardson: 1 [Ri+1,j - Ri,j ] . (12.15) Ri+1,j+1 = Ri+1,j + j 4 -1 La estimacin ms precisa para la integral es el elemento RN,N . o a El programa romberg.cc calcula la integral erf(1) usando el mtodo de Romberg. Con e N = 3, se obtiene la tabla 0.771743 0 0 0.825263 0.843103 0 0.838368 0.842736 0.842712 R3,3 da el resultado exacto con 4 decimales, usando los mismos 4 paneles que antes usamos con la regla trapezoidal (y que ahora reobtenemos en el elemento R3,1 ). Es util que el programa entregue toda la tabla y no slo el ultimo trmino, para tener o e una estimacin del error. Como en otros contextos, usar una tabla demasiado grande puede o no ser conveniente pues errores de redondeo pueden comenzar a degradar la respuesta. Para entender por qu el esquema de Romberg funciona, consideremos el error para la e regla trapezoidal, ET (hn ) = I - IT (hn ). Usando (12.9), ET (hn ) = - Como hn+1 = hn /2, ET (hn+1 ) = - 1 2 hn [f (b) - f (a)] + O(h4 ) . n 48 1 2 h [f (b) - f (a)] + O(h4 ) . n 12 n 314 CAP ITULO 12. INTEGRACION NUMERICA BASICA Consideremos ahora la segunda columna de la tabla de Romberg. El error de truncamiento para Rn+1,2 es: 1 I - Rn+1,2 = I - IT (hn+1 ) + [IT (hn+1 ) - IT (hn )] 3 1 = ET (hn+1 ) + [ET (hn+1 ) - ET (hn )] 3 1 1 1 1 =- + - h2 [f (b) - f (a)] + O(h4 ) n n 48 3 48 12 = O(h4 ) n Notemos cmo el trmino h2 se cancela, dejando un error de truncamiento de orden h4 . La o e n n siguiente columna (la tercera) de la tabla de Romberg cancela este trmino, y as sucesivae i mente. 12.6. Cuadratura de Gauss. Consideremos el problema de cuadratura sin considerar puntos fijos equidistantes, sino que pensamos en hacer una eleccin adecuada de puntos y pesos para cada punto, tal que o nuestra integral pueda aproximarse como: b f (x) dx w1 f (x1 ) + . . . + wN f (xn ) , a (12.16) aqu los xi son un conjunto de puntos elegidos de manera inteligente tal que disminuyan el i error y los wi son sus pesos respectivos, no necesariamente iguales unos con otros. f(x) (a) f(x) (b) Figura 12.4: (a) Ilustracin de la regla trapezoidal que une los dos puntos extremos por una o recta. (B) Estimacin mejorada al elegir inteligentemente los puntos. o El nombre que reciben esta clase de tcnicas es Cuadratura de Gauss, la ms comn de e a u ellas es la conocida como de Gauss-Legendre, y es util para un intervalo finito, el cual es mapeado mediante un cambio de variables al intervalo [-1, 1]. Existen otras cuadraturas como la de Gauss-Laguerre ptima para integrales de la forma 0 e-x f (x) dx. o 12.6. CUADRATURA DE GAUSS. xi wi xi wi 315 N=2 0.57735 02692 1.00000 00000 N=3 0.00000 00000 0.88888 88889 0.77459 66692 0.55555 55556 N=4 0.33998 10436 0.65214 51549 0.86113 63116 0.34785 48451 N=5 0.00000 00000 0.56888 88889 0.53846 93101 0.47862 86705 0.90617 98459 0.23692 68850 N=8 0.18343 46425 0.36268 37834 0.52553 24099 0.31370 66459 0.79666 64774 0.22238 10345 0.96028 98565 0.10122 85363 N=12 0.12523 34085 0.24914 70458 0.36783 14990 0.23349 25365 0.58731 79543 0.20316 74267 0.76990 26742 0.16007 83285 0.90411 72564 0.10693 93260 0.98156 06342 0.04717 53364 Cuadro 12.1: Puntos y pesos para integracin de Gauss-Legendre. o Para evaluar (12.1), debemos mapear el intervalo [a, b] en el intervalo [-1, 1] mediante el 1 cambio de variable x = 1 (b + a) + 2 (b - a)z, quedndonos a 2 b a b-a f (x) dx = 2 1 f (z) dz , -1 (12.17) esta ultima integral puede ser evaluada usando diferentes conjuntos de puntos y pesos, 1 f (z) dz w1 f (x1 ) + . . . + wN f (xn ) . -1 (12.18) En la tabla 12.1 presentamos los conjuntos con N = 2, 3, 4, 8 y 12 puntos. Los puntos xi corresponden a los ceros del Polinomio de Legendre PN de grado N y los pesos vienen dados por 2 wi = 1 = 1, 2, . . . , N 2 (1 - xi )[(d/dx)PN (xi )]2 Como ejemplo, consideremos la funcin error o 2 erf(x) = para x = 1, es decir, 1 x 0 e-y dy , 2 (12.19) erf(1) = 0 2 2 e-y dy . 1 2 (12.20) + z 2 1 Haciendo el cambio de variable sugerido y = 2 (b + a) + 1 (b - a)z = 2 integral queda 1 y dy = dz/2, la erf(1) 0.842701 = -1 1 2 e-(1+z) /4 dz = 1 g(z) dz . -1 (12.21) 316 CAP ITULO 12. INTEGRACION NUMERICA BASICA Evaluemos con el conjunto de dos puntos 1 erf(1) = -1 g(z) dz g(-0.57735 02692) + g(+0.57735 02692) = 0.84244189252125179 , (12.22) tres decimales correctos. Ahora con el conjunto de tres puntos, 1 erf(1) = -1 g(z) dz 0.55555 55556 g(-0.77459 66692) + 0.88888 88889 g(0.00000 00000) + 0.55555 55556 g(+0.77459 66692) = 0.84269001852936587 , (12.23) tres decimales correctos. Finalmente con el conjunto de cuatro puntos 1 erf(1) = -1 g(z) dz 0.34785 48451 g(-0.86113 63116) + 0.65214 51549 g(-0.33998 10436) + 0.65214 51549 10436 g(+0.33998 10436) + 0.34785 48451 g(+0.86113 63116) = 0.84270117131761124 , (12.24) los seis decimales correctos. 12.7. Bibliograf ia Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall. Mtodos Numricos Aplicados en Ingeniera de Jean-Marie Ledanois, Aura Lpez de e e i o Ramos, Jos Antonio Pimentel M. y Filipo F. Pironti Lubrano, editorial Mc Graw e Hill. Mtodos Numricos para Ingenieros Steven C. Chapra y Raymond P. Canale, editorial e e Mc Graw Hill. 12.8. LISTADOS DEL PROGRAMA. 317 12.8. 12.8.1. Listados del programa. trapecio.cc #include "NumMeth.h" double integrando(double); int main(){ double a=0, b=1,x; int N; double h; double I, suma=0; cout << "Regla trapezoidal para erf(1)" << endl; cout << "Numero de puntos: " ; cin >> N; h = (b-a)/(N-1); for (int i=2;i<N;i++){ x = a+(i-1)*h; suma+=integrando(x); } I = h*((integrando(a)+integrando(b))/2.0 + suma); cout << "Valor aproximado: erf(1) ~= " << I << endl; cout << "Valor exacto: erf(1) = 0.842701" << endl; } double integrando(double x){ return (2.0/sqrt(M_PI))*exp(-x*x); } 12.8.2. romberg.cc #include "NumMeth.h" #include <iomanip.h> double integrando(double); int main(){ double a=0, b=1,x; int N,np; double h; double I, suma=0; cout << "Integracion de Romberg para erf(1)" << endl; 318 CAP ITULO 12. INTEGRACION NUMERICA BASICA cout << "Dimension de tabla: " ; cin >> N; double ** R = new double * [N]; for (int i=0;i<N;i++){ R[i] = new double[N]; } for (int i=0;i<N;i++){ for (int j=0;j<N;j++){ R[i][j] = 0 ; } } // // // // // // for (int i=0;i<N;i++){ for (int j=0;j<N;j++){ cout << R[i][j] << " "; } cout << endl; } h = (b-a); // Ancho del intervalo np = 1; // Numero de paneles for (int i=0;i<N;i++,h/=2,np*=2){ if (i==0){ R[0][0] = h*(integrando(a)+integrando(b))/2.0; } else { suma = 0; for (int j=1;j<=np-1;j+=2){ x = a+j*h; suma += integrando(x); } R[i][0] = R[i-1][0]/2.0 + h*suma; } } int m = 1; for (int j=1;j<N;j++){ m *= 4; for (int i=j;i<N;i++){ R[i][j] = R[i][j-1] + (R[i][j-1]-R[i-1][j-1])/(m-1); } } 12.8. LISTADOS DEL PROGRAMA. cout << "Tabla R" << endl << endl; for (int i=0;i<N;i++){ for (int j=0;j<N;j++){ cout << /*setprecision(6) << */ setw(8) << } cout << endl; } 319 R[i][j] << " "; cout << endl; cout << "Valor aproximado: erf(1) ~= " << R[N-1][N-1] << endl; cout << "Valor exacto: erf(1) = 0.842701" << endl; for (int i=0;i<N;i++){ delete R[i]; } delete R; } double integrando(double x){ return (2.0/sqrt(M_PI))*exp(-x*x); } 320 CAP ITULO 12. INTEGRACION NUMERICA BASICA Parte III Apndices. e 321 Apndice A e Transferencia a diskettes. La filosof de diferentes unidades (A:, B:,. . . ) difiere de la estructura unica del sistema ia de archivos que existe en unix. Son varias las alternativas que existen para la transferencia de informacin a diskette. o Una posibilidad es disponer de una mquina win9x con ftp instalado y acceso a red. a Empleando dicha aplicacin se pueden intercambiar archivos entre un sistema y el otro. o Existe un conjunto de comandos llamados mtools disponible en multitud plataformas, que permiten el acceso a diskettes en formato win9x de una forma muy eficiente. mdir a: Muestra el contenido de un diskette en a:. mcopy file a: Copia el archivo file del sistema de archivos unix en un diskette en a:. mcopy a:file file Copia el archivo a:file del diskette en el sistema de archivos unix con el nombre file. mdel a:file Borra el archivo a:file del diskette. Con a: nos referimos a la primera diskettera /dev/fd0 y luego al archivo que se encuentra en el diskette. Su nombre se compone de a:filename. Si se desea emplear el caracter comod para un conjunto de archivos del diskette, estos deben rodearse de in dobles comillas para evitar la actuacin del shell (p.e. mcopy ``a:*.dat''). La opcin o o -t realiza la conversin necesaria entre unix y win9x, que se debe realizar slo en o o archivos de texto. Una alternativa final es montar el dispositivo /dev/fd0 en algn directorio, t u ipicamente /floppy, considerando el tipo especial de sistema de archivos que posee vfat y luego copiar y borrar usando comandos unix. Esta forma suele estar restringida slo a root, o el comando: mount -t vfat /dev/fd0 /floppy no puede ser dado por un usuario. Sin embargo, el sistema aceptar el comando a mount /floppy de parte del usuario. Una vez terminado el trabajo con el floppy ste e debe ser desmontado, antes de sacarlo, mediante el comando: umount /floppy. 323 324 APENDICE A. TRANSFERENCIA A DISKETTES. Apndice B e Las shells csh y tcsh. Son dos de los Shells interactivos ms empleados. Una de las principales ventajas de tcsh a es que permite la edicin de la l o inea de comandos, y el acceso a la historia de rdenes usando o las teclas de cursores.1 B.1. Comandos propios. Los comandos propios o intr insecos, Built-In Commands, son aqullos que proporciona el e propio shell 2 . alias name def Asigna el nombre name al comando def. history Muestra las ultimas rdenes introducidas en el shell. Algunos comandos relacionados con el o Command history son: !! Repite la ultima orden. !n Repite la orden n-sima. e !string Repite la orden ms reciente que empiece por la cadena string. a !?string Repite la orden ms reciente que contenga la cadena string. a str1 str2 o !!:s/str1/str2/ (substitute) Repite la ultima orden reemplanzando la primera ocurrencia de la cadena str1 por la cadena str2. bash tambin lo permite. e A diferencia de los comandos que provienen de un ejecutable situado en alguno de los directorios de la variable PATH. 2 1 325 326 !!:gs/str1/str2/ APENDICE B. LAS SHELLS CSH Y TCSH. (global substitute) Repite la ultima orden reemplazando todas las ocurrencias de la cadena str1 por la cadena str2. !$ Es el ultimo argumento de la orden anterior que se haya tecleado. repeat count command Repite count veces el comando command. rehash Rehace la tabla de comandos (hash table). set variable = VALUE Asigna el valor de una variable del shell. set Muestra el valor de todas las variables. setenv VARIABLE VALUE Permite asignar el valor de una variable de entorno. source file Ejecuta las rdenes del fichero file en el shell actual. o unset variable Borra la asignacin del valor de una variable del shell. o unsetenv VARIABLE VALUE Borra la asignacin del valor de una variable de entorno. o umask value Asigna la mscara para los permisos por omisin. a o unalias name Elimina un alias asignado. B.2. Variables propias del shell. Existe un conjunto de variables denominadas shell variables, que permiten modificar el funcionamiento del shell. filec (FILE Completion) Es una variable toggle que permite que el shell complete automticamente el nombre de un a 3 archivo o un directorio . Para ello, si el usuario introduce slo unos cuantos caracteres de o un archivo y pulsa el TAB, el shell completa dicho nombre. Si slo existe una posibilidad, el o 3 bash permite no slo completar ficheros/directorios sino tambin comandos. o e B.2. VARIABLES PROPIAS DEL SHELL. 327 completado es total y el shell deja un espacio tras el nombre. En caso contrario hace sonar un pitido. Pulsando Ctrl-D el shell muestra las formas existentes para completar. prompt Es una variable de cadena que contiene el texto que aparece al principio de la l inea de comandos. savehist Permite definir el nmero de rdenes que se desea almacenar al abandonar el shell. Esto u o permite recordar las rdenes que se ejecutaron en la sesin anterior. o o 328 APENDICE B. LAS SHELLS CSH Y TCSH. Apndice C e Editores tipo emacs. Los editores tipo emacs se parecen mucho y en su mayor sus comandos son los mismos. ia Para ejemplificar este tipo de editores nos centraremos en XEmacs, pero los comandos y descripciones se aplican casi por igual a todos ellos. Los editores tipo emacs constan de tres zonas: La zona de edicin: donde aparece el texto que est siendo editado y que ocupa la o a mayor parte de la pantalla. La zona de informacin: es una barra que esta situada en la penltima l o u inea de la pantalla. La zona de introduccin de datos: es la ultima l o inea de la pantalla. Emacs es un editor que permite la edicin visual de un archivo (en contraste con el modo o de edicin de vi). El texto se agrega o modifica en la zona de edicin, usando las teclas o o disponibles en el teclado. Adems, existen una serie de comandos disponibles para asistir en esta tarea. a La mayor de los comandos de emacs se realizan empleando la tecla de CONTROL o la ia 1 tecla META . Emplearemos la nomenclatura: C-key para indicar que la tecla key debe de ser pulsada junto con CONTROL y M-key para indicar que la tecla META debe de ser pulsada junto a key. En este ultimo caso NO es necesario pulsar simultneamente las teclas ESC y a key, pudiendo pulsarse secuencialmente ESC y luego key, sin embargo, si se usa ALT como META deben ser pulsadas simultneamente. Observemos que en un teclado normal hay unos a 50 caracteres (letras y nmeros). Usando SHIFT se agregan otros 50. As usando CONTROL u i, y META, hay unos 50 4 = 200 comandos disponibles. Adems, existen comandos especiales a llamados prefijos, que modifican el comando siguiente. Por ejemplo, C-x es un prefijo, y si C-s es un comando (de bsqueda en este caso), C-x C-s es otro (grabar archivo). As a travs u i, e de un prefijo, se duplican el nmero de comandos disponibles slo con el teclado, hasta llegar u o a unos 200 2 = 400 comandos en total. Aparte de estos comandos accesibles por teclas, algunos de los cuales comentaremos a continuacin, existen comandos que es posible ejecutar por nombre, haciendo as el nmero o i u de comandos disponibles virtualmente infinito. 1 Dado que la mayor de los teclados actuales no poseen la tecla META se emplea ya sea ESC o ALT. ia 329 330 APENDICE C. EDITORES TIPO EMACS. Revisemos los comandos ms usuales, ordenados por tpico. a o Abortar y deshacer En cualquier momento, es posible abortar la operacin en curso, o deshacer un comando o indeseado: C-g C-x u abortar deshacer Archivos C-x C-x C-x C-x C-x C-f i C-s C-w C-c cargar archivo insertar archivo grabar archivo grabar con nombre salir Ventanas Emacs permite dividir la pantalla en varias ventanas. En cada ventana se puede editar texto e ingresar comandos independientemente. Esto es util en dos situaciones: a) si necesi tamos editar un solo archivo, pero necesitamos ver su contenido en dos posiciones distintas (por ejemplo, el comienzo y el final de archivos muy grandes); y b) si necesitamos editar o ver varios archivos simultneamente. Naturalmente, aunque son independientes, slo es posible a o editar un archivo a la vez. A la ventana en la cual se encuentra el cursor en un momento dado le llamamos la "ventana actual". C-x C-x C-x C-x C-x 2 3 1 0 o dividir ventana actual en 2 partes, con l inea horizontal dividir ventana actual en 2 partes, con l inea vertical slo 1 ventana (la ventana actual, eliminando las otras) o elimina slo la ventana actual o cambia el cursor a la siguiente ventana El cambio del cursor a una ventana cualquiera se puede hacer tambin rpidamente a e a travs del mouse. e Comandos de movimiento Algunos de estos comandos tienen dos teclas asociadas, como se indica a continuacin. o 331 C-b o C-p o C-a o Home M-< o C-Home M-f o M- C-v o Page Up M-g (nmero) u izquierda un carcter a arriba una l inea principio de la l inea principio del documento avanza una palabra avanza una pgina a salta a la l inea (nmero) u C-f o C-n o C-e o End M-> o C-End M-b o M- M-v o Page Down C-l derecha un carcter a abajo una l inea fin de la l inea fin del documento retrocede una palabra retrocede una pgina a refresca la pantalla Comandos de insercin y borrado o Al ser un editor en modo visual, las modificaciones se pueden hacer en el texto sin necesidad de entrar en ningn modo especial. u C-d o Delete Backspace C-k borra un carcter despus del cursor a e borra un carcter antes del cursor a borra desde la posicin del cursor hasta el fin de l o inea (no incluye el cambio de l inea) M-d borra desde el cursor hacia adelante, hasta que termina una palabra M-Backspace borra desde el cursor hacia atrs, hasta que comienza una palabra a C-o Inserta una l inea en la posicin del cursor o May sculas y min sculas u u M-u M-l M-c Cambia a mayscula desde la posicin del cursor hasta el fin de la palabra u o Cambia a minscula desde la posicin del cursor hasta el fin de la palabra u o Cambia a mayscula el carcter en la posicin del cursor y u a o a minscula hasta el fin de la palabra u Por ejemplo, veamos el efecto de cada uno de estos comandos sobre la palabra EmAcS, si el cursor est sobre la letra E (el efecto es distinto si est sobre cualquier otra letra!): a a M-u : EmAcS - EMACS M-l : EmAcS - emacs M-c : EmAcS - Emacs Transposicin o Los siguientes comandos toman como referencia la posicin actual del cursor. Por ejemplo, o C-t intercambia el carcter justo antes del cursor con el carcter justo despus. a a e C-t M-t C-x C-t Transpone dos caracteres Transpone dos palabras Transpone dos l ineas 332 B squeda y reemplazo u APENDICE C. EDITORES TIPO EMACS. C-s C-r M- % M-& Bsqueda u Bsqueda u Bsqueda u Bsqueda u hacia el fin del texto hacia el inicio del texto y sustitucin (pide confirmacin cada vez) o o y sustitucin (sin confirmacin) o o Definicin de regiones y reemplazo o Uno de los conceptos importantes en emacs es el de regin. Para ello, necesitamos dos o conceptos auxiliares: el punto y la marca. El punto es simplemente el cursor. Espec ificamente, es el punto donde comienza el cursor. As si el cursor se encuentra sobre la letra c en emacs, i, el punto est entre la a y la c. La marca, por su parte, es una se~al que se coloca en algn a n u punto del archivo con los comandos apropiados. La regin es el espacio comprendido entre el o punto y la marca. Para colocar una marca basta ubicar el cursor en el lugar deseado, y teclear C-Space o C-@. Esto coloca la marca donde est el punto (en el ejemplo del prrafo anterior, quedar a a ia entre las letras a y c. Una vez colocada la marca, podemos mover el cursor a cualquier otro lugar del archivo (hacia atrs o hacia adelante respecto a la marca). Esto define una cierta a ubicacin para el punto, y, por tanto, queda definida la regin automticamente. o o a La regin es una porcin del archivo que se puede manipular como un todo. Una regin se o o o puede borrar, copiar, pegar en otro punto del archivo o incluso en otro archivo; una regin se o puede imprimir, grabar como un archivo distinto; etc. As muchas operaciones importantes i, se pueden efectuar sobre un bloque del archivo. Por ejemplo, si queremos duplicar una regin, basta con definir la regin deseada (ponieno o do la marca y el punto donde corresponda) y teclear M-w. Esto copia la regin a un buffer o temporal (llamado kill buffer). Luego movemos el cursor al lugar donde queremos insertar el texto duplicado, y hacemos C-y. Este comando toma el contenido del kill buffer y lo inserta en el archivo. El resultado final es que hemos duplicado una cierta porcin del texto. o Si la intencin era mover dicha porcin, el procedimiento es el mismo, pero con el comando o o C-w en vez de M-w. C-w tambin copia la regin a un kill buffer, pero borra el texto de la e o pantalla. Resumiendo: C-Space o C-@ M-w C-w C-y Comienzo de regin o Copia regin o Corta regin o Pega regin o El concepto de kill buffer es mucho ms poderoso que lo explicado recin. En realidad, a e muchos comandos, no slo M-w y C-w, copian texto en un kill buffer. En general, cualquier o comando que borre ms de un carcter a la vez, lo hace. Por ejemplo, C-k borra una l a a inea. Lo que hace no es slo borrarla, sino adems copiarla en un kill buffer. Lo mismo ocurre o a con los comandos que borran palabras completas (M-d, M-Backspace), y muchos otros. Lo 333 interesante es que C-y funciona tambin en todos esos casos: C-y lo unico que hace es tomar e el ultimo texto colocado en un kill buffer (resultado de la ultima operacin que borr ms de o o a un carcter a la vez), y lo coloca en el archivo. Por lo tanto, no slo podemos copiar o mover a o "regiones", sino tambin palabras o l e ineas. Ms an, el kill buffer no es borrado con el C-y, a u as que ese mismo texto puede ser duplicado muchas veces. Continuar disponible con C-y i a mientras no se ponga un nuevo texto en el kill buffer. Adems, emacs dispone no de uno sino de muchos kill buffers. Esto permite recuperar a texto borrado hace mucho rato. En efecto, cada vez que se borra ms de un carcter de una a a vez, se una un nuevo kill buffer. Por ejemplo, consideremos el texto: La primera linea del texto, la segunda linea, y finalmente la tercera. Si en este prrafo borramos la primera l a inea (con C-k), despus borramos la primera e palabra de la segunda (con M-d, por ejemplo), y luego la segunda palabra de la ultima, entonces habr tres kill buffers ocupados: a buffer 1 : La primera linea del texto, buffer 2 : la buffer 3 : finalmente Al colocar el cursor despus del punto final, C-y toma el contenido del ultimo kill buffer e y lo coloca en el texto: segunda linea, y la tercera. finalmente Si se teclea ahora M-y, el ultimo texto recuperado, finalmente, es reemplazado por el penltimo texto borrado, y que est en el kill buffer anterior: u a segunda linea, y la tercera. la Adems, la posicin de los kill buffers se rota: a o buffer 1 : finalmente buffer 2 : La primera linea del texto, buffer 3 : la Sucesivas aplicaciones de M-y despus de un C-y rotan sobre todos los kill buffers (que e pueden ser muchos). El editor, as conserva un conjunto de las ultimas zonas borradas durante i, la edicin, pudiendo recuperarse una antigua a pesar de haber seleccionado una nueva zona, o o borrado una nueva palabra o l inea. Toda la informacin en los kill buffers se pierde al salir o de emacs (C-c). Resumimos entonces los comandos para manejo de los kill buffers: 334 APENDICE C. EDITORES TIPO EMACS. C-y Copia el contenido del ultimo kill buffer ocupado M-y Rota los kill buffers ocupados Definicin de macros o La clave de la configurabilidad de emacs est en la posibilidad de definir nuevos comandos a que modifiquen su comportamiento o agreguen nuevas funciones de acuerdo a nuestras necesidades. Un modo de hacerlo es a travs del archivo de configuracin $HOME/.emacs, para lo e o cual se sugiere leer la documentacin disponible en la distribucin instalada. Sin embargo, si o o slo necesitamos un nuevo comando en la sesin de trabajo actual, un modo ms simple es o o a definir una macro, un conjunto de rdenes que son ejecutados como un solo comando. Los o comandos relevantes son: C-x ( C-x ) C-x e Comienza la definicin de una macro o Termina la definicin de una macro o Ejecuta una macro definida Todas las sucesiones de teclas y comandos dados entre C-x ( y C-x ) son recordados por emacs, y despus pueden ser ejecutados de una vez con C-x e. e Como ejemplo, consideremos el siguiente texto, con los cinco primeros lugares del rnking a ATP (sistema de entrada) al 26 de marzo de 2002: 1 2 3 4 5 hewitt, lleyton (Aus) kuerten, gustavo (Bra) ferrero, juan (Esp) kafelnikov, yevgeny (Rus) haas, tommy (Ger) Supongamos que queremos: (a) poner los nombres y apellidos con mayscula (como deu ber ser); (b) poner las siglas de pa slo en maysculas. ia ises o u Para definir una macro, colocamos el cursor al comienzo de la primera l inea, en el 1, y damos C-x (. Ahora realizamos todos los comandos necesarios para hacer las tres tareas solicitadas para el primer jugador solamente: M-f (avanza una palabra, hasta el espacio antes de hewitt; M-c M-c (cambia a Hewitt, Lleyton); M-u (cambia a AUS); Home (vuelve el cursor al comienzo de la l inea); (coloca el cursor al comienzo de la l inea siguiente, en el 2). Los dos ultimos pasos son importantes, porque dejan el cursor en la posicin correcta para o ejecutar el comando nuevamente. Ahora terminamos la definicin con C-x ). Listo. Si ahora o ejecutamos la macro, con C-x e, veremos que la segunda l inea queda modificada igual que la primera, y as podemos continuar hasta el final: i 1 2 3 4 5 Hewitt, Lleyton (AUS) Kuerten, Gustavo (BRA) Ferrero, Juan (ESP) Kafelnikov, Yevgeny (RUS) Haas, Tommy (GER) 335 Comandos por nombre Aparte de los ya comentados existen muchas otras rdenes que no tienen necesariamente o una tecla asociada (bindkey) asociada. Para su ejecucin debe de teclearse previamente: o M-x y a continuacin en la zona inferior de la pantalla se introduce el comando deseado. Emo pleando el TAB se puede completar dicho comando (igual que en bash). De hecho, esto sirve para cualquier comando, incluso si tiene tecla asociada. Por ejemplo, ya sabemos M-g n va a la l inea n del documento. Pero esto no es sino el comando goto-line, y se puede tambin ejecutar tecleando: M-x goto-line n. e Repeticin o Todos los comandos de emacs, tanto los que tienen una tecla asociada como los que se ejecutan con nombre, se pueden ejecutar ms de una vez, anteponindoles un argumento a e numrico con e M-(number) Por ejemplo, si deseamos escribir 20 letras e, basta teclear M-20 e. Esto es particularmente util con las macros definidos por el usuario. En el ejemplo anterior, con el rnking ATP, a despus de definir la macro quedamos en la l e inea 2, y en vez de ejecutar C-x e 4 veces, podemos teclear M-4 C-x e, con el mismo resultado, pero en mucho menos tiempo. Para terminar la discusin de este editor, diremos que es conveniente conocer las secuencias o de control bsico de emacs: a C-a, C-e, C-k, C-y, C-w, C-t, C-d, etc., porque funcionan para editar la l inea de comandos en el shell, como tambin en muchos e programas de texto y en ventanas de dilogo de las aplicaciones X Windows. A su vez, los a editores jed, xjed, jove tambin usan por defecto estas combinaciones. e 336 APENDICE C. EDITORES TIPO EMACS. Apndice D e Una breve introduccin a o Octave/Matlab D.1. Introduccin o Octave es un poderoso software para anlisis numrico y visualizacin. Muchos de sus a e o comandos son compatibles con Matlab. En estos apuntes revisaremos algunas caracter isticas de estos programas. En realidad, el autor de este cap itulo ha sido usuario durante algunos a~os n de Matlab, de modo que estos apuntes se han basado en ese conocimiento, considerando los comandos que le son ms familiares de Matlab. En la mayor de las ocasiones he verificado a ia que los comandos descritos son tambin compatibles con Octave, pero ocasionalmente se e puede haber omitido algo. . . . Matlab es una abreviacin de Matrix Laboratory. Los elementos bsicos con los que se o a trabaja con matrices. Todos los otros tipos de variables (vectores, texto, polinomios, etc.), son tratados como matrices. Esto permite escribir rutinas optimizadas para el trabajo con matrices, y extender su uso a todos los otros tipos de variables fcilmente. a D.2. Interfase con el programa Con Octave/Matlab se puede interactuar de dos modos: un modo interactivo, o a travs e de scripts. Al llamar a Octave/Matlab (escribiendo octave en el prompt, por ejemplo), se nos presenta un prompt. Si escribimos a=1, el programa responder a=1. Alternativamente, a podemos escribir a=3; (con punto y coma al final), y el programa no responder (elimina a el eco), pero almacena el nuevo valor de a. Si a continuacin escribimos a, el programa o responder a=3. Hasta este punto, hemos usado el modo interactivo. a Alternativamente, podemos introducir las instrucciones anteriores en un archivo, llamado, por ejemplo, prueba.m. En el prompt, al escribir prueba, y si nuestro archivo est en el path a de bsqueda del programa, las l u ineas de prueba.m sern ejecutadas una a una. Por ejemplo, a si el archivo consta de las siguientes cuatro l ineas: a=3; a 337 338 a=5 a APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB el programa responder con a a=3 a=5 a=5 prueba.m corresponde a un script. Todas las instrucciones de Octave/Matlab pueden ejecutarse tanto en modo interactivo como desde un script. En Linux se puede ejecutar un archivo de comandos Octave de modo stand-alone incluyendo en la primera l inea: #!/usr/bin/octave -q. D.3. D.3.1. Tipos de variables Escalares A pesar de que stos son slo un tipo especial de matrices (ver subseccin siguiente), e o o conviene mencionar algunas caracter isticas espec ificas. Un nmero sin punto decimal es tratado como un entero exacto. Un nmero con punto u u decimal es tratado como un nmero en doble precisin. Esto puede no ser evidente u o en el output. Por default, 8.4 es escrito en pantalla como 8.4000. Tras la instruccin o format long, sin embargo, es escrito como 8.40000000000000. Para volver al formato original, basta la instruccin format. o Octave/Matlab acepta nmeros reales y complejos. La unidad imaginaria es i: 8i y u 8*i definen el mismo nmero complejo. Como i es una varible habitualmente usada u en iteraciones, tambin est disponible j como un sinnimo. Octave/Matlab distinguen e a o entre maysculas y minsculas. u u Octave/Matlab representa de manera especial los infinitos y cantidades que no son nmeros. inf es infinito, y NaN es un no-nmero (Not-a-Number). Por ejemplo, escribir u u a=1/0 no arroja un error, sino un mensaje de advertencia, y asigna a a el valor inf. Anlogamente, a=0/0 asigna a a el valor NaN. a D.3.2. Matrices Este tipo de variable corresponde a escalares, vectores fila o columna, y matrices convencionales. Construccin o Las instrucciones: a = [1 2 ; 3 4] D.3. TIPOS DE VARIABLES o a = [1, 2; 3, 4] 339 1 2 . Las comas (opcionales) separan elementos de columnas distintas, 3 4 y los punto y coma separan elementos de filas distintas. El vector fila (1 2) es definen la matriz b = [1 2] y el vector columna c = [1;2] Un nmero se define simplemente como d = [3] d = 3. u o Nota importante: Muchas funciones de Octave/Matlab en las pginas siguientes acepa tan indistintamente escalares, vectores filas, vectores columnas, o matrices, y su output es un escalar, vector o matriz, respectivamente. Por ejemplo, log(a) es un vector fila si a es un vector fila (donde cada elemento es el logaritmo natural del elemento correspondiente en a), y un vector columna si a es un vector columna. En el resto de este manual no se advertira este hecho, y se pondrn ejemplos con un solo tipo de variable, en el entendido que el lector a est conciente de esta nota. a Acceso y modificacin de elementos individuales o Accesamos los elementos de cada matriz usando los indices de filas y columnas, que parten de uno. Usando la matriz a antes definida, a(1,2) es 2. Para modificar un elemento, basta 1 2 escribir, por ejemplo, a(2,2) = 5. Esto convierte a la matriz en . En el caso especial 3 5 de vectores filas o columnas, basta un indice. (En los ejemplos anteriores, b(2) = c(2) = 2.) Una caracter istica muy importante del programa es que toda matriz es redimensionada automticamente cuando se intenta modificar un elemento que sobrepasa las dimensiones a actuales de la matriz, llenando con ceros los lugares necesarios. Por ejemplo, si b = [1 2], y en seguida intentamos la asignacin b(5) = 8, b es automticamente convertido al vector o a fila de 5 elementos [1 2 0 0 8]. Concatenacin de matrices o Si a = 1 2 ,b= 5 6 ,c= 3 4 7 , entonces 8 1 2 es d = [a c] 1 2 7 3 4 8 d = [a; b] d= 1 2 d = 3 4 5 6 340 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB d = [a [0; 0] c] d= 1 2 0 7 3 4 0 8 D.3.3. Strings Las cadenas de texto son casos particulares de vectores fila, y se construyen y modifican de modo idntico. e Construccin o Las instrucciones t t t t = = = = ['un buen texto'] ["un buen texto"] 'un buen texto' "un buen texto" definen el mismo string t. Acceso y modificacin de elementos individuales o r = t(4) r = 'b' t(9) = 's' texto = 'un buen sexto' Concatenacin o t = 'un buen texto'; t1 = [t ' es necesario'] t1 = 'un buen texto es necesario' D.3.4. Estructuras Las estructuras son extensiones de los tipos de variables anteriores. Una estructura consta de distintos campos, y cada campo puede ser una matriz (es decir, un escalar, un vector o una matriz), o una string. Construccin o Las l ineas persona.nombre = 'Eduardo' persona.edad = 30 persona.matriz_favorita = [2 8;10 15]; D.4. OPERADORES BASICOS 341 definen una estructura con tres campos, uno de los cuales es un string, otro un escalar, y otro una matriz: persona = { nombre = 'Eduardo'; edad = 30; matriz_favorita = [2 8; 10 15]; } Acceso y modificacin de elementos individuales o s = persona.nombre s = 'Eduardo' persona.nombre = 'Claudio' persona.matriz_favorita(2,1) = 8 persona = { nombre = 'Claudio'; edad = 30; matriz_favorita = [2 8; 8 15]; } D.4. D.4.1. Operadores bsicos a Operadores aritmticos e Los operadores +, -, * corresponden a la suma, resta y multiplicacin convencional de o matrices. Ambas matrices deben tener la misma dimensin, a menos que una sea un escalar. o Un escalar puede ser sumado, restado o multiplicado de una matriz de cualquier dimensin. o .* y ./ permiten multiplicar y dividir elemento por elemento. Por ejemplo, si a= entonces c = a.*b c= 5 12 21 32 1 2 3 4 b= 5 6 7 8 c = a./b c= 0.2 0.3333 0.42857 0.5 342 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Si b es un escalar, a.*b y a./b equivalen a a*b y a/b. a^b es a elevado a b, si b es un escalar. a.^b eleva cada elemento de a a b. a' es la matriz a (traspuesta y conjugada) a.' es la matriz traspuesta de a. D.4.2. Operadores relacionales Los siguientes operadores estn disponibles: a < <= > >= == ~= El resultado de estas operaciones es 1 (verdadero) 0 (falso). Si uno de los operandos o es una matriz y el otro un escalar, se compara el escalar con cada elemento de la matriz. Si ambos operandos son matrices, el test se realiza elemento por elemento; en este caso, las matrices deben ser de igual dimensin. Por ejemplo, o a b c d = = = = [1 2 3]; [4 2 1]; (a<3); (a>=b); c = (1, 1, 0) d = (0, 1, 1) D.4.3. Operadores lgicos o Los siguientes s imbolos corresponden a los operadores AND, OR y NOT: & | ~ El resultado de estas operaciones es 1 (verdadero) 0 (falso). o D.4.4. El operador : Es uno de los operadores fundamentales. Permite crear vectores y extraer submatrices. : crea vectores de acuerdo a las siguientes reglas: j:k j:i:k es lo mismo que [j,j+1,...,k], si j<=k. es lo mismo que [j,j+i,j+2*i,...,k], si i>0 y j<k, o si i<0 y j>k. : extrae submatrices de acuerdo a las siguientes reglas: A(:,j) A(i,:) A(:,:) A(:,j:k) A(:) es la j-sima columna de A. e es la i-sima fila de A. e es A. es A(:,j), A(:,j+1), . . . , A(:,k). son todos los elementos de A, agrupados en una unica columna. D.5. COMANDOS MATRICIALES BASICOS 343 D.4.5. Operadores de aparicin preferente en scripts o Los siguientes operadores es ms probable que aparezcan durante la escritura de un script a que en modo interactivo. % : Comentario. El resto de la l inea es ignorado. ... : Continuacin de l o inea. Si una l inea es muy larga y no cabe en la pantalla, o por alguna otra razn se desea dividir una l o inea, se puede usar el operador ... . Por ejemplo, m = [1 2 3 ... 4 5 6]; es equivalente a m = [1 2 3 4 5 6]; D.5. Comandos matriciales bsicos a Antes de revisar una a una diversas familias de comandos disponibles, y puesto que las matrices son el elemento fundamental en Octave/Matlab, en esta seccin reuniremos algunas o de las funciones ms frecuentes sobre matrices, y cmo se realizan en Octave/Matlab. a o Op. aritmtica e Conjugar Trasponer Trasponer y conjugar Invertir Autovalores, autovectores Determinante Extraer elementos Traza Dimensiones Exponencial +, -, *, .*, ./ conj(a) a.' a' inv(a) [v,d]=eig(a) det(a) : trace(a) size(a) exp(a) expm(a) (ver subseccin D.4.1) o (ver subseccin D.6.5) o (ver subseccin D.4.4) o (elemento por elemento) (exponencial matricial) D.6. Comandos En esta seccin revisaremos diversos comandos de uso frecuente en Octave/Matlab. Esta o lista no pretende ser exhaustiva (se puede consultar la documentacin para mayores detalles), o y est determinada por mi propio uso del programa y lo que yo considero ms frecuente a a debido a esa experiencia. Insistimos en que ni la lista de comandos es exhaustiva, ni la lista de ejemplos o usos de cada comando lo es. Esto pretende ser slo una descripcin de los o o aspectos que me parecen ms importantes o de uso ms recurrente. a a D.6.1. clear Comandos generales Borra variables y funciones de la memoria 344 clear clear a disp APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Borra todas las variables en memoria Borra la variable a Presenta matrices o texto disp(a) presenta en pantalla los contenidos de una matriz, sin imprimir el nombre de la matriz. a puede ser una string. disp(' c1 disp([.3 .4]); c2'); c1 c2 0.30000 0.40000 load, save Carga/Guarda variables desde el disco Guarda las variables a y b en el archivo fname Lee el archivo fname, cargando las definiciones de variables en l definidas. e save fname a b load fname size,length Dimensiones de una matriz/largo de un vector Si a es una matrix de n m: d = size(a) [m,n] = size(a) d = [m,n] Aloja en m el nmero de filas, y en n el de columnas u Si b es un vector de n elementos, length(b) es n. who quit Lista de variables en memoria Termina Octave/Matlab D.6.2. Como lenguaje de programacin o Control de flujo for n=3; for i=1:n a(i)=i^2; end a=[1 4 9] Para Octave el vector resultante es columna en vez de fila. Observar el uso del operador : para generar el vector [1 2 3]. Cualquier vector se puede utilizar en su lugar: for i=[2 8 9 -3], for i=10:-2:1 (equivalente a [10 8 6 4 2]), etc. son vlidas. El ciclo for anterior se podr haber escrito en una sola l a ia inea as i: for i=1:n, a(i)=i^2; end D.6. COMANDOS if, elseif, else Ejemplos: a) if a~=b, disp(a); end b) if a==[3 8 9 10] b = a(1:3); end c) if a>3 clear a; elseif a<0 save a; else disp('Valor de a no considerado'); end 345 Naturalmente, elseif y else son opcionales. En vez de las expresiones condicionales indicadas en el ejemplo pueden aparecer cualquier funcin que d valores 1 (verdadero) 0 o e o (falso). while while s comandos end Mientras s es 1, se ejecutan los comandos entre while y end. s puede ser cualquier expresin que d por resultado 1 (verdadero) 0 (falso). o e o break Interrumpe ejecucin de ciclos for o while. En loops anidados, break sale del ms interno o a solamente. Funciones lgicas o Adems de expresiones construidas con los operadores relacionales ==, <=, etc., y los a operadores lgicos &, | y ~, los comandos de control de flujo anteriores admiten cualquier o funcin cuyo resultado sea 1 (verdadero) 0 (falso). Particularmente utiles son funciones o o como las siguientes: all(a) any(a) isempty(a) 1 si todos los elementos de a son no nulos, y 0 si alguno es cero 1 si alguno de los elementos de a es no nulo 1 si a es matriz vac (a=) ia 346 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Otras funciones entregan matrices de la misma dimensin que el argumento, con unos o o ceros en los lugares en que la condicin es verdadera o falsa, respectivamente: o finite(a) isinf(a) isnan(a) 1 donde a es finito (no inf ni NaN) 1 donde a es infinito 1 donde a es un NaN Por ejemplo, luego de ejecutar las l ineas x y a b c = = = = = [-2 -1 0 1 2]; 1./x; finite(y); isinf(y); isnan(y); se tiene a = [1 1 0 1 1] b = [0 0 1 0 0] c = [0 0 0 0 0] Otra funcin lgica muy importante es find: o o find(a) Encuentra los indices de los elementos no nulos de a. Por ejemplo, si ejecutamos las l ineas x=[11 0 33 0 55]; z1=find(x); z2=find(x>0 & x<40); obtendremos z1 = [1 3 5] z2 = [1 3] find tambin puede dar dos resultados de salida simultneamente (ms sobre esta posie a a bilidad en la seccin D.6.2), en cuyo caso el resultado son los pares de o indices ( indices de fila y columna) para cada elemento no nulo de una matriz y=[1 2 3 4 5;6 7 8 9 10]; [z3,z4]=find(y>8); da como resultado z3 = [2;2]; z4 = [4;5]; z3 contiene los indice de fila y z4 los de columna para los elementos no nulos de la matriz 2 4 y>8. Esto permite construir, por ejemplo, la matriz z5=[z3 z4] = , en la cual cada 2 5 fila es la posicin de y tal que la condicin y>8 es verdadera (en este caso, es verdadera para o o los elementos y(2,4) e y(2,5)). D.6. COMANDOS Funciones definidas por el usuario 347 Octave/Matlab puede ser fcilmente extendido por el usuario definiendo nuevas funciones a que le acomoden a sus propsitos. Esto se hace a travs del comando function. o e Podemos definir (en modo interactivo o dentro de un script), una funcin en la forma o function nombre (argumentos) comandos endfunction argumentos es una lista de argumentos separados por comas, y comandos es la sucesin o de comandos que sern ejecutados al llamar a nombre. La lista de argumentos es opcional, a en cuyo caso los parntesis redondos se pueden omitir. e A mediano y largo plazo, puede ser mucho ms conveniente definir las funciones en ara chivos especiales, listos para ser llamados en el futuro desde modo interactivo o desde cualquier script. Esto se hace escribiendo la definicin de una funcin en un script con extensin o o o .m. Cuando Octave/Matlab debe ejecutar un comando o funcin que no conoce, por ejemo plo, suma(x,y),busca en los archivos accesibles en su path de bsqueda un archivo llamado u suma.m, lo carga y ejecuta la definicin contenida en ese archivo. o Por ejemplo, si escribimos en el script suma.m las l ineas function s=suma(x,y) s = x+y; el resultado de suma(2,3) ser 5. a Las funciones as definidas pueden entregar ms de un argumento si es necesario (ya hemos i a visto algunos ejemplos con find y size). Por ejemplo, definimos una funcin que efecte un o u anlisis estad a istico bsico en stat.m: a function [mean,stdev] = stat(x) n = length(x); mean = sum(x)/n; stdev = sqrt(sum((x-mean).^2/n)); Al llamarla en la forma [m,s] = stat(x), si x es un vector fila o columna, en m quedar el a promedio de los elementos de x, y en s la desviacin estndard. o a Todas las variables dentro de un script que define una funcin son locales, a menos que o se indique lo contrario con global. Por ejemplo, si un script x.m llama a una funcin f, y o dentro de f.m se usa una variable a que queremos sea global, ella se debe declarar en la forma global a tanto en f.m como en el script que la llam, x.m, y en todo otro script que o pretenda usar esa variable global. D.6.3. Matrices y variables elementales Matrices constantes importantes Las siguientes son matrices que se emplean habitualmente en distintos contextos, y que es util tener muy presente: 348 eye(n) ones(m,n) rand(m,n) randn(m,n) zeros(m,n) APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Matriz identidad de n n Matriz de m n, con todos los elementos igual a 1. Matriz de m n de nmeros al azar, distribuidos uniformeu mente. Igual que rand, pero con distribucin normal (Gaussiana). o Igual que ones, pero con todos los elementos 0. Matrices utiles para construir ejes o mallas para graficar Las siguientes son matrices se emplean habitualmente en la construcci'on de grficos: a v = linspace(min,max,n) v = logspace(min,max,n) [X,Y] = meshgrid(x,y) Vector cuyo primer elemento es min, su ultimo elemento es max, y tiene n elementos equiespaciados. Anlogo a linspace, pero los n elementos estn espaa a ciados logar itmicamente. Construye una malla del plano x-y. Las filas de X son copias del vector x, y las columnas de Y son copias del vector y. Por ejemplo: x = [1 2 3]; y = [4 5]; [X,Y] = meshgrid(x,y); da X= 1 2 3 1 2 3 , Y = 4 4 4 5 5 5 . Notemos que al tomar sucesivamente los distintos pares ordenados (X(1,1),Y(1,1)), (X(1,2),Y(1,2)), (X(1,3),Y(1,3)), etc., se obtienen todos los pares ordenados posibles tales que el primer elemento est en x y el segundo est en y. Esta caracter a a istica hace particularmente util el comando meshgrid en el contexto de grficos de funciones de dos variables (ver secciones a D.6.7, D.6.7). Constantes especiales Octave/Matlab proporciona algunos nmeros especiales, algunos de los cuales ya menciou namos en la seccin D.3.1. o i, j Unidad imaginaria ( -1 ) inf Infinito NaN Not-A-Number pi El nmero (= 3.1415926535897 . . .) u Funciones elementales Desde luego, Octave/Matlab proporciona todas las funciones matemticas bsicas. Por a a ejemplo: D.6. COMANDOS a) Funciones sobre nmeros reales/complejos u abs angle conj real imag sign sqrt Valor absoluto de nmeros reales, o mdulo de nmeros imaginarios u o u Angulo de fase de un nmero imaginario u Complejo conjugado Parte real Parte imaginaria Signo Ra cuadrada iz 349 b) Exponencial y funciones asociadas cos, sin, etc. cosh, sinh, etc. exp log c) Redondeo ceil fix floor round Redondear Redondear Redondear Redondear hacia hacia hacia hacia + cero - el entero ms cercano a Funciones trigonomtricas e Funciones hiperblicas o Exponencial Logaritmo Funciones especiales Adems, Octave/Matlab proporciona diversas funciones matemticas especiales. Algunos a a ejemplos: bessel besselh beta ellipke erf gamma Funcin o Funcin o Funcin o Funcin o Funcin o Funcin o de Bessel de Hankel beta el iptica error gamma As por ejemplo, bessel(alpha,X) evala la funcin de Bessel de orden alpha, J (x), i, u o para cada elemento de la matriz X. D.6.4. Polinomios p = cn xn + + c1 x + c0 Octave/Matlab representa los polinomios como vectores fila. El polinomio es representado en Octave/Matlab en la forma p = [c_n, ..., c1, c0] 350 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Podemos efectuar una serie de operaciones con los polinomios as representados. i poly(x) polyval(p,x) roots(p) Polinomio cuyas ra son los elementos de x. ices Evala el polinomio p en x (en los elementos de x si ste es u e un vector) Ra del polinomio p ices D.6.5. det rank trace inv eig poly Algebra lineal (matrices cuadradas) Determinante Nmero de filas o columnas linealmente independientes u Traza Matriz inversa Autovalores y autovectores Polinomio caracter istico Unos pocos ejemplos, entre los comandos de uso ms habitual: a Notar que poly es la misma funcin de la seccin D.6.4 que construye un polinomio de o o ra ices dadas. En el fondo, construir el polinomio caracter istico de una matriz es lo mismo, y por tanto tiene sentido asignarles la misma funcin. Y no hay confusin, pues una opera o o sobre vectores y la otra sobre matrices cuadradas. El uso de todos estos comandos son autoexplicativos, salvo eig, que se puede emplear de dos modos: d = eig(a) [V,D] = eig(a) La primera forma deja en d un vector con los autovalores de a. La segunda, deja en D una matriz diagonal con los autovalores, y en V una matiz cuyas columnas son los autovalores, de modo que A*V = V*D. Por ejemplo, si a =[1 2; 3 4], entonces d= y D= 5.37228 . . . 0 0 -0.37228 . . . , V = 0.41597 . . . -0.82456 . . . 0.90938 . . . 0.56577 . . . . 5.37228 -0.37228 La primera columna de V es el autovector de a asociado al primer autovalor, 5.37228 . . .. D.6.6. Anlisis de datos y transformada de Fourier a En Octave/Matlab estn disponibles diversas herramientas para el anlisis de series de a a datos (estad istica, correlaciones, convolucin, etc.). Algunas de las operaciones bsicas son: o a a) Mximos y m a inimos Si a es un vector, max(a) es el mayor elemento de a. Si es una matriz, max(a) es un vector fila, que contiene el mximo elemento para cada columna. a D.6. COMANDOS a = [1 6 7; 2 8 3; 0 4 1] b = max(a) 351 b = (2 8 7) Se sigue que el mayor elemento de la matriz se obtiene con max(max(a)). min opera de modo anlogo, entregando los m a inimos. b) Estad istica bsica a Las siguientes funciones, como min y max, operan sobre vectores del modo usual, y sobre matrices entregando vectores fila, con cada elemento representando a cada columna de la matriz. mean median std prod sum Valor promedio Mediana Desviacin standard o Producto de los elementos Suma de los elementos c) Orden sort(a) ordena los elementos de a en orden ascendente si a es un vector. Si es una matriz, ordena cada columna. b = sort([1 3 9; 8 2 1; 4 -3 0]); 1 -3 0 b = 4 2 1 8 3 9 d) Transformada de Fourier Por ultimo, es posible efectuar transformadas de Fourier directas e inversas, en una o dos dimensiones. Por ejemplo, fft y ifft dan la transformada de Fourier y la transformada inversa de x, usando un algoritmo de fast Fourier transform (FFT). Espec ificamente, si X=fft(x) y x=ifft(X), y los vectores son de largo N: N X(k) = j=1 x(j)N N (j-1)(k-1) , 1 x(j) = N donde N = e-2i/N . X(k)N k=1 -(j-1)(k-1) , D.6.7. Grficos a Una de las caracter isticas ms importantes de Matlab son sus amplias posibilidades grfia a cas. Algunas de esas caracter isticas se encuentran tambin en Octave. En esta seccin revie o saremos el caso de grficos en dos dimensiones, en la siguiente el caso de tres dimensiones, y a luego examinaremos algunas posibilidades de manipulacin de grficos. o a 352 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Grficos bidimensionales a Para graficar en dos dimensiones se usa el comando plot. plot(x,y) grafica la ordenada y versus la abscisa x. plot(y) asume abscisa [1,2,...n], donde n es la longitud de y. Ejemplo: Si x=[2 8 9], y=[6 3 2], entonces plot(x,y) Figura D.1: Grfico simple. a Por default, Octave utiliza gnuplot para los grficos. Por default, los puntos se conectan a con una l inea roja en este caso. El aspecto de la l inea o de los puntos puede ser modificado. Por ejemplo, plot(x,y,'ob') hace que los puntos sean indicados con c irculos ('o') azules ('b', blue). Otros modificadores posibles son: . @ + * o x l inea (default) puntos otro estilo de puntos signo ms a asteriscos c irculos cruces r g b m c w red green blue magenta cyan white Dos o ms grficos se pueden incluir en el mismo output agregando ms argumentos a a a a plot. Por ejemplo: plot(x1,y1,'x',x2,y2,'og',x3,y3,'.c'). Los mapas de contorno son un tipo especial de grfico. Dada una funcin z = f (x, y), a o nos interesa graficar los puntos (x, y) tales que f = c, con c alguna constante. Por ejemplo, consideremos 2 2 z = xe-x -y , x [-2, 2], y [-2, 3] . Para obtener el grfico de contorno de z, mostrando los niveles z = -.3, z = -.1, z = 0, a z = .1 y z = .3, podemos usar las instrucciones: x = -2:.2:2; y = -2:.2:3; [X,Y] = meshgrid(x,y); D.6. COMANDOS Z = X.*exp(-X.^2-Y.^2); contour(Z.',[-.3 -.1 0 .1 .3],x,y); # Octave por default (gnuplot) contour(x, y, Z.',[-.3 -.1 0 .1 .3]); # Octave con plplot y Matlab 353 Figura D.2: Curvas de contorno. Las dos primeras l ineas definen los puntos sobre los ejes x e y en los cuales la funcin o ser evaluada. En este caso, escojimos una grilla en que puntos contiguos estn separados por a a .2. Para un mapa de contorno, necesitamos evaluar la funcin en todos los pares ordenados o (x, y) posibles al escoger x en x e y en y. Para eso usamos meshgrid (introducida sin mayores o explicaciones en la seccin D.6.3). Luego evaluamos la funcin [Z es una matriz, donde cada o elemento es el valor de la funcin en un par ordenado (x, y)], y finalmente construimos el o mapa de contorno para los niveles deseados. Grficos tridimensionales a Tambin es posible realizar grficos tridimensionales. Por ejemplo, la misma doble gause a siana de la seccin anterior se puede graficar en tres dimensiones, para mostrarla como una o superficie z(x, y). Basta reemplazar la ultima instruccin, que llama a contour, por la si o guiente: mesh(X,Y,Z) Observar que, mientras contour acepta argumentos dos de los cuales son vectores, y el tercero una matriz, en mesh los tres argumentos son matrices de la misma dimensin (usamos o X, Y, en vez de x, y). Nota importante: Otro modo de hacer grficos bi y tridimensionales es con gplot a y gsplot (instrucciones asociadas realmente no a Octave sino a gnuplot, y por tanto no equivalentes a instrucciones en Matlab). Se recomienda consultar la documentacin de Octave o para los detalles. 354 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Figura D.3: Curvas de contorno. Manipulacin de grficos o a Los siguientes comandos estn disponibles para modificar grficos construidos con Octaa a ve/Matlab: a) Ejes axis([x1 y1 x2 y2]) b) T itulos title(s) xlabel(s) ylabel(s) zlabel(s) c) Grillas grid Incluye o borra una grilla de referencia en un grfico bidimena sional. grid ``on'' coloca la grilla y grid ``off'' la saca. grid equivale a grid ``on''. T itulo (s es un string) T itulo del eje x, y, z. Cambia el eje x al rango (x1, x2), y el eje y al rango (y1, y2). Al usar gnuplot, el grfico mostrado en pantalla no es actualizado automticamente. a a Para actualizarlo y ver las modificaciones efectuadas, hay que dar la instruccin replot. o Los siguientes comandos permiten manipular las ventanas grficas: a D.6. COMANDOS hold Permite "congelar" la figura actual, de modo que sucesivos comandos grficos se superponen sobre dicha figura (nora malmente la figura anterior es reemplazada por la nueva). hold on activa este "congelamiento", y hold off lo desactiva. hold cambia alternativamente entre el estado on y off. Cierra la ventana actual. 355 closeplot Finalmente, si se desea guardar un grfico en un archivo, se puede proceder del siguiente a modo si Octave est generando los grficos con gnuplot y se trabaja en un terminal con a a XWindows. Si se desea guardar un grfico de la funcin y = x3 , por ejemplo: a o x = linspace(1,10,30); y = x.^3; plot(x,y); gset term postscript color gset output ``xcubo.ps'' replot gset term x11 Las tres primeras l ineas son los comandos de Octave/Matlab convencionales para graficar. Luego se resetea el terminal a un terminal postscript en colores (gset term postscript si no deseamos los colores), para que el output sucesivo vaya en formato postscript y no a la pantalla. La siguiente l inea indica que la salida es al archivo xcubo.ps. Finalmente, se redibuja el grfico (con lo cual el archivo xcubo.ps es realmente generado), y se vuelve al a terminal XWindows para continuar trabajando con salida a la pantalla. Debemos hacer notar que no necesariamente el grfico exportado a Postscript se ver igual a a al resultado que gnuplot muestra en pantalla. Durante la preparacin de este manual, nos o dimos cuenta de ello al intentar cambiar los estilos de l inea de plot. Queda entonces advertido el lector. D.6.8. lower upper Strings Convierte a minsculas u Convierte a maysculas u Para manipular una cadena de texto, disponemos de los siguientes comandos: As lower('Texto') da 'texto', y upper('Texto') da 'TEXTO'. i, Para comparar dos matrices entre s usamos strcmp: i, strcmp(a,b) 1 si a y b son idnticas, 0 en caso contrario e Podemos convertir nmeros enteros o reales en strings, y strings en nmeros, con los u u comandos: int2str num2str str2num Convierte entero en string Convierte nmero en string u Convierte string en nmero u 356 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Por ejemplo, podemos usar esto para construir un t itulo para un grfico: a s = ['Intensidad transmitida vs. frecuencia, n = ', num2str(1.5)]; title(s); Esto pondr un t a itulo en el grfico con el texto: a Intensidad transmitida vs. frecuencia, n = 1.5. D.6.9. Manejo de archivos Ocasionalmente nos interesar grabar el resultado de nuestros clculos en archivos, o a a utilizar datos de archivos para nuevos clculos. El primer paso es abrir un archivo: a archivo = fopen('archivo.dat','w'); Esto abre el archivo archivo.dat para escritura ('w'), y le asigna a este archivo un nmero u que queda alojado en la variable archivo para futura referencia. Los modos de apertura posibles son: r w a r+ w+ a+ Abre para lectura Abre para escritura, descartando contenidos anteriores si los hay Abre o crea archivo para escritura, agregando datos al final del archivo si ya existe Abre para lectura y escritura Crea archivo para lectura y escritura Abre o crea archivo para lectura y escritura, agregando datos al final del archivo si ya existe En un archivo se puede escribir en modo binario: fread fwrite o en modo texto fgetl fgets fprintf fscanf Lee una l inea del archivo, descarta cambio de l inea Lee una l inea del archivo, preserva cambio de l inea Escribe datos siguiendo un formato Lee datos siguiendo un formato Lee datos binarios Escribe datos binarios Referimos al lector a la ayuda que proporciona Octave/Matlab para interiorizarse del uso de estos comandos. Slo expondremos el uso de fprintf, pues el formato es algo que o habitualmente se necesita tanto para escribir en archivos como en pantalla, y fprintf se puede usar en ambos casos. La instruccin o fprintf(archivo,'formato',A,B,...) D.6. COMANDOS 357 imprime en el archivo asociado con el identificador archivo (asociado al mismo al usar fopen, ver ms arriba), las variables A, B, etc., usando el formato 'formato'. archivo=1 corresponde a a la pantalla; si archivo se omite, el default es 1, es decir, fprintf imprime en pantalla si archivo=1 o si se omite el primer argumento. 'formato' es una string, que puede contener caracters normales, caracteres de escape o especificadores de conversin. Los caracteres de escape son: o \n \t \b \r \f \\ \' New line Horizontal tab Backspace Carriage return Form feed Backslash Single quote Por ejemplo, la l inea fprintf('Una tabulacion\t y un \'\'original\'\' cambio de linea\n aqui\n') da como resultado Una tabulacion aqui y un ''original'' cambio de linea Es importante notar que por default, el cambio de l inea al final de un fprintf no existe, de modo que, si queremos evitar salidas a pantalla o a archivo poco estticas, siempre hay e que terminar con un \n. Los especificadores de conversin permiten dar formato adecuado a las variables numricas o e A, B, etc. que se desean imprimir. Constan del caracter %, seguido de indicadores de ancho (opcionales), y caracteres de conversin. Por ejemplo, si deseamos imprimir el nmero con o u 5 decimales, la instruccin es: o fprintf('Numero pi = %.5f\n',pi) El resultado: Numero pi = 3.14159 Los caracteres de conversin pueden ser o %e %f %g Notacin exponencial (Ej.: 2.4e-5) o Notacin con punto decimal fijo (Ej.: 0.000024) o %e o %f, dependiendo de cul sea ms corto (los ceros no a a significativos no se imprimen) Entre % y e, f, o g segn corresponda, se pueden agregar uno o ms de los siguientes u a caracteres, en este orden: Un signo menos (-), para especificar alineamiento a la izquierda (a la derecha es el default). 358 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Un nmero entero para especificar un ancho m u inimo del campo. Un punto para separar el nmero anterior del siguiente nmero. u u Un nmero indicando la precisin (nmero de d u o u igitos a la derecha del punto decimal). En el siguiente ejemplo veremos distintos casos posibles. El output fue generado con las siguientes instrucciones, contenidas en un script: a = .04395; fprintf('123456789012345\n'); fprintf('a = %.3f.\n',a); fprintf('a = %10.2f.\n',a); fprintf('a = %-10.2f.\n',a); fprintf('a = %4f.\n',a); fprintf('a = %5.3e.\n',a); fprintf('a = %f.\n',a); fprintf('a = %e.\n',a); fprintf('a = %g.\n',a); El resultado: 12345678901234567890 a = 0.044. a = 0.04. a = 0.04 . a = 0.043950. a = 4.395e-02. a = 0.043950. a = 4.395000e-02. a = 0.04395. En la primera l inea, se imprimen tres decimales. En la segunda, dos, pero el ancho m inimo es 10 caracteres, de modo que se al inea a la derecha el output y se completa con blancos. En la tercera l inea es lo mismo, pero alineado a la izquierda. En la cuarta l inea se ha especificado un ancho m inimo de 4 caracteres; como el tama~o del nmero es mayor, esto no tiene efecto n u y se imprime el nmero completo. En la quinta l u inea se usa notacin exponencial, con tres o decimal (nuevamente, el ancho m inimo especificado, 5, es menor que el ancho del output, luego no tiene efecto). Las ultimas tres l ineas comparan el output de %f, %e y %g, sin otras especificaciones. Si se desean imprimir ms de un nmero, basta agregar las conversiones adecuadas y los a u argumentos en fprintf. As la l i, inea fprintf('Dos numeros arbitrarios: %g y %g.\n',pi,exp(4)); da por resultado Dos numeros arbitrarios: 3.14159 y 54.5982. D.6. COMANDOS 359 Si los argumentos numricos de fprintf son matrices, el formato es aplicado a cada e columna hasta terminar la matriz. Por ejemplo, el script x = 1:5; y1 = exp(x); y2 = log(x); a = [x; y1; y2]; fprintf = ('%g %8g %8.3f\n',a); da el output 1 2 3 4 5 2.71828 7.38906 20.0855 54.5982 148.413 0.000 0.693 1.099 1.386 1.609 360 APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Apndice E e Asignacin dinmica. o a La reserva de memoria para la matriz podemos hacerla en forma dinmica ocupando el a operador new que pedir al sistema la memoria necesaria, si est disponible el sistema se a a la asignar. Como con cualquier puntero, una vez desocupado el arreglo debemos liberar la a memoria con el comando delete. #include <iostream> using namespace std; int main() { cout<<"Ingrese la dimension deseada :" ; int dim ; cin >> dim ; double * matriz = new double[dim] ; // Reserva la memoria for(int i=0; i < dim; i++) { cout << "Ingrese elemento "<< i <<" : "; cin >> matriz[i] ; } for (int i=0;i<dim;i++){ cout << matriz[i] << ", "; } cout << endl; delete matriz; return 0; } Este ejemplo permite apreciar una gran ventaja del uso de punteros, al permitirnos liberarnos de definir la dimensin de una matriz como una constante. Aqu dim es simplemente un int. o i, La asignacin dinmica permite definir matrices cuya dimensin se determina recin durante o a o e la ejecucin. o Observemos finalmente que la liberacin de memoria, en el caso de arreglos, se hace con o el operador delete , no delete como en los punteros usuales. 361 // Libera la memoria reservada 362 APENDICE E. ASIGNACION DINAMICA. E.1. Arreglos dinmicos bidimensionales. a Tambin es posible definir arreglos bidimensionales dinmicamente. En el siguiente ejeme a plo, se define una matriz de 200 filas y 400 columnas, inicializndose sus elementos a cero, y a finalmente se borra: int main() { int width; int height; width = 200; height = 400; double ** matriz = new double * [width]; for (int i=0;i<width;i++){ matriz[i] = new double[height]; } for (int i=0;i<width;i++){ for (int j=0;j<height;j++){ matriz[i][j] = 0; } } for (int i=0;i<width;i++){ delete matriz[i]; } delete matriz; return 0; } Primero se crea, con new, un puntero (matriz) de dimensin 200, que representar las o a filas. Cada uno de sus elementos (matriz[i]), a su vez, ser un nuevo puntero, de dimensin a o 400, representando cada columna. Por tanto, matriz debe ser un puntero a puntero (de dobles, en este caso), y as es definido inicialmente (double ** ...). Esto puede parecer i extra~o a primera vista, pero recordemos que los punteros pueden ser punteros a cualquier n objeto, en particular a otro puntero. Luego se crean los punteros de cada columna (primer ciclo for). A continuacin se llenan los elementos con ceros (segundo ciclo for). Finalmente, o se libera la memoria, en orden inverso a como fue asignada: primero se libera la memoria de cada columna de la matriz (delete matriz[i], tercer ciclo for), y por ultimo se libera la memoria del puntero a estos punteros (delete matriz). Apndice F e make & Makefile. Frecuentemente los programas estn compuestos por diferentes subprogramas que se haa yan contenidos en diferentes archivos. La orden de compilacin necesaria puede ser muy o engorrosa, y a menudo no es necesario volver a compilar todos los archivos, sino slo aqueo llos que hayan sido modificados. unix dispone de una orden denominada make que evita los problemas antes mencionados y permite el mantenimiento de una biblioteca personal de programas. Este comando analiza qu archivos fuentes han sido modificados despus de la e e ultima compilacin y evita recompilaciones innecesarias. o En su uso ms simple slo es necesario suministrar una lista de dependencias y/o instruca o ciones a la orden make en un archivo denominado Makefile. Una dependencia es la relacin o entre dos archivos de forma que un archivo se considera actualizado siempre que el otro tenga una fecha de modificacin inferior a ste. Por ejemplo, si el archivo file.cc incluye el o e archivo file.h, no se puede considerar actualizado el archivo file.o si el archivo file.cc o el archivo file.h ha sido modificado despus de la ultima compilacin. Se dice que el e o archivo file.o depende de file.cc y el archivo file.cc depende del archivo file.h. El Makefile se puede crear con un editor de texto y tiene el siguiente aspecto para establecer una dependencia: # Esto es un ejemplo de Makefile. # Se pueden poner comentarios tras un caracter hash (#). FILE1: DEP1 DEP2 comandos para generar FILE1 ETIQUETA1: FILE2 FILE2: DEP3 DEP4 comandos para generar FILE2 ETIQUETA2: comandos Se comienza con un destino, seguido de dos puntos (:) y los prerrequisitos o dependencias necesarios. Tambin puede ponerse una etiqueta y como dependencia un destino, o bien una e etiqueta y uno o ms comandos. Si existen muchos prerrequisitos, se puede finalizar la l a inea con un backslash (\) y continuar en la siguiente l inea. En la(s) l inea(s) siguiente(s) se escriben uno o ms comandos. Cada l a inea se considera como un comando independiente. Si se desea utilizar mltiples l u ineas para un comando, 363 364 APENDICE F. MAKE & MAKEFILE. se deber poner un backslash (\) al final de cada l ia inea del comando. El comando make conectar las l a ineas como si hubieran sido escritas en una unica l inea. En esta situacin, se o deben separar los comandos con un punto y coma (;) para prevenir errores en la ejecucin de o el shell. Los comandos deben ser indentados con un tabulador, no con 8 espacios Make lee el Makefile y determina para cada archivo destino (empezando por el primero) si los comandos deben ser ejecutados. Cada destino, junto con los prerrequisitos o dependencias, es denominado una regla. Si make se ejecuta sin argumentos, slo se ejecutar el primer destino. Veamos un ejemplo: o a file.o: file.cc file.h g++ -c file.cc En este caso se comprueban las fechas de las ultima modificaciones de los archivos file.cc y file.h; si esta fecha es ms reciente que las del archivo file.o se procede a la compilacin. a o El comando make se puede suministrar con un argumento, que indica la etiqueta situada a la izquierda de los dos puntos. As en el ejemplo anterior podr invocarse make file.o.. i ia Gracias a las variables, un Makefile se puede simplificar significativamente. Las variables se definen de la siguiente manera: VARIABLE1=valor1 VARIABLE2=valor2 Una variable puede ser utilizada en el resto del Makefile refirindonos a ella con la expresin e o $(VARIABLE). Por defecto, make sabe las rdenes y dependencias (reglas impl o icitas) para compilar un archivo *.cc y producir un archivo *.o, entonces basta especificar solamente las dependencias que make no puede deducir a partir de los nombres de los archivos, por ejemplo: OUTPUTFILE = prog OBJS = prog.o misc.o aux.o INCLUDESMISC = misc.h aux.h INCLUDESFILE = foo.h $(INCLUDESMISC) LIBS = -lmylib -lg++ -lm prog.o: $(INCLUDESFILE) misc.o: $(INCLUDESMISC) aux.o: aux.h $(OUTPUTFILE): $(OBJS) gcc $(OBJS) -o $(OUTPUTFILE) $(LIBS) Las reglas patrones son reglas en las cuales se especifican mltiples destinos y construye u el nombre de las dependencias para cada blanco basada en el nombre del blanco. La sintaxis de una regla patrn: o destinos ... : destino patron:dependencias patrones comandos La lista de destinos especifica aquellos sobre los que se aplicar la regla. El destino patrn y a o las dependencias patrones dicen cmo calcular las dependencias para cada destino. Veamos o un ejemplo: 365 objects = foo.o \ bar.o all: $(objects) $(objects): %.o: %.cc $(CXX) -c $(CFLAGS) $< -o $@ Cada uno de los destinos (foo.o bar.o) es comparado con el destino patrn %.o para extraer o parte de su nombre. La parte que se extrae es conocida como el tronco o stem, foo y bar en este caso. A partir del tronco y la regla patrn de las dependencias %.cc make construye los o nombres completos de ellas (foo.cc bar.cc). Adems, en el comando del ejemplo anterior a aparecen un tipo de variables especiales conocidas como automticas. La variable $< mana tiene el nombre de la dependencia actual y la variable $@ mantiene el nombre del destino actual. Finalmente un ejemplo completo: # # Makefile para el programa eapp #_________________________________________________________ CXX = g++ CXXFLAGS = -Wall -O3 -mcpu=i686 -march=i686 #CXXFLAGS = -Wall -g LIBS = -lm BIN = eapp OBJECTS = eapp.o md.o atoms.o vectores.o metalesEA.o Monte_Carlo.o\ string_fns.o nlista.o rij2.o velver2.o cbc2.o nforce.o \ temperature.o controles.o inparamfile.o \ azar.o velver3.o funciones.o observables.o $(BIN): $(OBJECTS) $(CXX) $(OBJECTS) -o $(BIN) $(LIBS) $(OBJECTS): %.o:%.cc $(CXX) -c $(CXXFLAGS) $< -o $@ clean: rm -fr $(OBJECTS) $(BIN) #End 366 APENDICE F. MAKE & MAKEFILE. Apndice G e Herramientas bsicas en el uso de a L.A.M.P. L.A.M.P. es la sigla popular para referirse al uso conjunto: Linux+Apache+Mysql+PHP (tambin sta ultima se reemplaza por Python o Perl) . e e G.1. Objetivo. Se espera que tras leer este apndice el lector interesado sea capaz de: e Elaborar sus propias paginas web utilizando PHP, a partir de las cuales se pueda intercambiar informacin de manera segura mediante el sistema gestor de base de datos o MySql. G.2. Prerequisitos Conocimiento bsico sobre qu es un navegador, es decir, tener cierto tiempo utilizndoa e a lo. Tener instalados y operando conjuntamente los siguientes programas: Apache 1.3 o superior. MySql 4 o superior. PHP 4 o superior. G.3. Breve referencia sobre paginas web. Un navegador es un software que mediante la conexin a Internet interpreta scripts preo sentes en el servidor web, desplegando el resultado en pantalla. Dichos scripts normalmente se encuentran escritos en lenguaje html. La gran ventaja que ofrecen las pginas web son los llamados hipervnculos o links: objetos a i que permiten saltar entre diferentes pginas web de manera fcil. Gracias a los links existen a a 367 368 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. los "rboles de pginas": diferentes scripts interconectados mediante links correspondientes a a a un mismo dominio1 . Una pgina como la anteriormente descrita es capaz de desplegar a informacin en un navegador o recibirla a travs de formularios. Este tipo de pginas reciben o e a el nombre de pginas estticas, es decir, si se quiere cambiar la informacin desplegada, se a a o est obligado a modificar el script en html. a En contraste, existen pginas que cambian su informacin dependiendo de cundo o cmo a o a o son ejecutadas, recibiendo el nombre de pginas dinmicas. Para lograr el dinamismo, el a a servidor, tras leer una serie de archivos, genera un nuevo cdigo en html a tiempo de ejecucin. o o Ejemplos de dichas pginas son aquellas visitadas a diario por cualquier persona: buscadores, a bancos en l inea, correos electrnicos revisados desde un navegador, etc. Para generar este o tipo de pginas existen muchos lenguajes de programacin, sin embargo, el ms utilizado y a o a sobre la que se introducir aqu es el lenguaje PHP. a i G.3.1. Ejemplos Pgina Esttica en html. a a Archivo hola.html <html> <title> :::::El Clasico Hola mundo::: </title> <body> Hola mundo! </body> </html> El ejemplo anterior corresponde a lo ms simple en una pgina web en html ; notar que el a a script est estructurado mediante el uso de etiquetas del tipo: <algo> .... </algo>. a Pgina Dinmica en PHP a a Archivo hola.php <html> <?php $h="Hola mundo!"; ?> <title> :::::El Clasico <?php echo $h; ?>::: </title> <body> <?php echo $h; ?> </body> </html> Si se procede a ejecutar ambos scripts probablemente no se aprecie ninguna diferencia; sin embargo, el proceso que se ha llevado a cabo por el servidor establece fuertes diferencias entre ambos cdigos. Notar que el cdigo en PHP se encuentra inserto por completo en el o o cdigo html. Por lo anterior, es necesario tener, al menos, un conocimiento bsico de html o a para comenzar a programar en PHP. 1 Nombre del sitio Internet. G.4. ADMINISTRADOR DE BASES DE DATOS. 369 G.4. Administrador de Bases de datos. Una base de datos es una manera ordenada de guardar cualquier tipo de informacin o para, de este modo, facilitar su bsqueda posterior. El encargado de buscar la informacin u o de manera efectiva es el administrador de la base de datos; en nuestro caso, el administrador corresponder al software MySql. La informacin de la base de datos se almacena en matrices a o llamadas tablas, conformadas por columnas definidas. Las diferentes filas de una tabla se van constituyendo conforme se agregan nuevos registros; la informacin contenida en los registros o corresponde a un conjunto de strings o nmeros. u G.5. Servidor Web. Un servidor Web es un software que opera en la mquina remota. El servidor posee la a informacin contenida en la pgina y su funcin es proporcionar al internauta el contenido de o a o sta. Para efectos de este apndice, esto se reduce a interpretar el cdigo en PHP y generar e e o en tiempo de ejecucin el nuevo script en html. o Creando scripts. En las secciones posteriores se listarn los comandos que permiten generar scripts, el a modo de chequearlos y, de esta forma, aprender mediante ensayo y error es: crear la carpeta ~/public_html. Escribir un script en el directorio antes citado utilizando algn editor2 . u abrir el navegador e ir a la URL http://nombredelhost/~nombredelusuario/pathdelscript. Luego de seguir estos pasos, el navegador desplegar en la pantalla la ejecucin del script. a o Es importante se~alar que el navegador no acusa errores de manera tan implacable como n compiladores u otros intrpretes (p.ej. Python), por lo cual se recomienda ser especialmente e riguroso. G.6. Pginas Bsicas en html. a a Prcticamente todo el cdigo en html corresponde a aspectos estticos de la pgina, sobre a o e a lo cual no se profundizar. Entre los objetivos que se buscan alcanzar en este apndice, presena e tan especial relevancia los formularios, pues permiten introducir informacin proporcionada o por un internauta a la base de datos. 2 Existen varios editores especializados en lenguajes web sobre los cuales conviene averiguar un poco. 370 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. G.6.1. Estructura de una pgina en html. a Si bien el navegador es capaz de interpretar correctamente cdigo en html escrito sin o seguir las reglas, es importante al menos saber algunas. Todo el dise~o de la pgina se encuentra entre etiquetas del tipo <algo> .... </algo>. n a Las ms relevantes y que le dan estructura son: a <html>: Esta etiqueta delimita en qu parte del script comienza y termina el cdigo en e o html. <title>: Lo que se escriba dentro de esta etiqueta conformar el t a itulo de la pgina, a es decir, el nombre que aparecer en el t a itulo de la ventana del navegador. <head>: Contiene etiquetas y contenidos del encabezado. Principalmente datos que no aparecen en la pgina, pero que son relevantes. a <body>: Contiene la informacin que ser desplegada en la pantalla, ya sea texto imgeo a a nes, sonido, etc. Cabe destacar que ninguna de las etiquetas mencionadas es obligatoria; puede precindirse de ellas si tan slo se quiere escribir texto sin ninguna estructura. o G.6.2. Algo de estilo. Las etiquetas utilizadas para dar estilo al texto dentro del cuerpo de la pgina (i.e. a etiqueta <body>) son: Propiedades del texto. <p>: Delimita un prrafo que finalizar al cerrarse la etiqueta. Esta etiqueta admite a a opciones especiales de alineacin tales como: <p align="center">, la cual centra el o prrafo. Las variantes obvias de las otras alineaciones son dejadas al lector. a <h1>:Delimita un t itulo de porte variable en dependencia del nmero que se ponga u acompa~ando a la letra h, dicho nmero debe estar entre 1 y 6. n u <br>: Introduce un salto de l inea. A diferencia de las etiquetas anteriores, sta no tiene e una etiqueta de cerrado. <hr>:Introduce una l inea horizontal. Al igual que en la etiqueta anterior, sta es dese apareada. <b>: Todo lo escrito dentro de esta etiqueta quedar en negritas. a <em>: Convierte en itlica todo el texto dentro de esta etiqueta. a <u>: Subraya el texto dentro de la etiqueta. <sub>: Convierte en sub indice los caracteres dentro de esta etiqueta. G.6. PAGINAS BASICAS EN HTML. <sup>: Convierte en super indice los caracteres delimitados por la etiqueta. 371 <font>: Etiqueta que permite definir atributos sobre el texto, tales como el porte o el color. Por ejemplo, si se requiere texto en rojo: <font color="red">. Propiedades globales de la Pgina. a Con las etiquetas anteriormente explicadas es posible crear una pgina con informacin a o de manera relativamente ordenada, mas no esttica. Un primer paso en esta ultima direccin e o es lo que se tratar a continuacin. a o Todos los atributos globales corresponden a opciones de la etiqueta <body>. Lo que se har es definir los colores de: el texto, los links, links ya usados y el fondo. En html los colores a se especifican mediante un cdigo (para conocer el cdigo correspondiente a cada color puede o o consultarse la tabla de colores (G.2) al final de este apndice3 ).Lo anterior puede apreciarse e en el siguiente ejemplo: <body bgcolor="#000000" text="#ffffff" link="#ffff33" alink="#ffffcc"> El campo bgcolor corresponde al color de fondo; text al color del texto; link y alink, a los colores de los links por visitar y visitados respectivamente. Alternativamente, es posible poner una foto de fondo de pgina, simplemente hay que a suplir bgcolor por: <body background="fondo.jpg"> Se recomienda poner fotos peque~as que sean visualmente agradables como mosaicos, de n lo contrario, puede variar el cmo se vean dependiendo del navegador, adems de hacer ms o a a pesada la pgina. El siguiente ejemplo utiliza las herramientas desarrolladas. a Ejemplo Archivo ejemplo2.html <html> <title> :::Herramientas de estilo::: </title> <body bgcolor="#336699" text="#000033" link="#660000" alink="#33ff00"> <h1 align="center" > <font color="red"> Sobre lo que se hablar en esta pgina esttica a a a </font> </h1> <p align="right"> <em> ...Aqu por ejemplo una cita para comenzar</em> i </p> <br> <p algin="center"> Escribiendo la parte medular de la pgina.....<br> a Es posible escribir una formula sin caracteres especiales como la siguiente: <p align="center">(a<sub>11</sub>+a<sub>22</sub>+....)<sup>2</sup>=(traza)<sup>2</sup></p 3 La cual por razones obvias debe ser vista a color. 372 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. <p align="left"> Finalmente, se espera un manejo <b> bsico </b> de <em> html </em> si se ha logrado comprender a <u> este ejemplo por completo </u></p> </body> </html> Otros recursos. Como se se~al en la introduccin, la caracter n o o istica ms relevante de una pgina web es a a su capacidad de interconexin con otras mediante links. Asimismo, existen otros recursos o ampliamente usados que mejoran el aspecto y orden de una pgina en html. a Insertando una imagen e Para insertar una imagen existe una etiqueta desapareada4 , en sta debe darse el path relativo del archivo grfico de la siguiente forma: a <img src="path"> Tambin se pueden especificar atributos adicionales, tales como: la alineacin, el espacio e o vertical y horizontal utilizado por la foto: <img src="path" align="left" hspace="20" vspace="30"> En la orden anterior, la imagen (dentro del espacio que puede utilizar) se encuentra alineada a la izquierda y tiene un marco de "20" horizontal por "30" vertical. Links. El enlace, es decir, el espacio de la pgina donde el cursor del mouse cambia y permite a acceder a la pgina siguiente, puede corresponder tanto a texto como a una imagen: a Enlace en el texto: Para esto existe la etiqueta: <a href="path_a_la_pgina_en_cuestion">texto clickeable del link</a> a a Los path pueden ser relativos5 si se trata de material presente en la misma mquina; de tratarse de un enlace externo a la pgina, debe especificarse la URL completa. a Enlace sobre una imagen: Opera exactamente de la misma manera que un enlace de texto y solo cambia el argumento dentro de la etiqueta. <a href="path_a_la_pgina_en_cuestion"><img src="path"></a> a 4 5 No tiene otra etiqueta de cierre Respecto al cdigo que se est ejecutando o a G.6. PAGINAS BASICAS EN HTML. Tablas. 373 Una tabla permite administrar el espacio en una pgina de manera eficiente y es especiala mente util cuando se quiere una pgina ordenada y sin muchas caracter a isticas grficas. La a tabla es delimitada por la etiqueta <table>, dentro de sta, las filas quedan delimitadas por e la etiqueta <tr>. A su vez, el elemento de cada columna queda atrapado en la etiqueta <td>. Dentro de los elementos de la tabla es posible utilizar prcticamente cualquier etiqueta. A a continuacin, un esquema sobre cmo se programa una tabla: o o <table> <tr> <td> "a11"</td> <td>"a12"</td> <td>"a13"</td> <td>"a14"</td> </tr> <tr> <td> "a21"</td> <td> "a22"</td> <td> "a23"</td> <td> "a24"</td> </tr> <tr> <td> "a31"</td> <td> "a32"</td> <td> "a33"</td> <td> "a34"</td> </tr> <tr> <td> "a41"</td> <td> "a42"</td> <td> "a43"</td> <td> "a44"</td> </table> </tr> Figura G.1: Esquema de una tabla en html, utilizando los elementos de una matriz. G.6.3. Formularios. Toda la preparacin previa que se ha llevado a cabo tiene como fin el proveer de interfaz o grfica a la pgina dinmica. El instrumento que permitir recibir informacin desde el visia a a a o tante son los formularios, el qu se hace con dicha informacin escapa de las posibilidades de e o html. Para procesar la informacin debe recurrirse a otros lenguajes. o Manejo de la informacin utilizando el formulario. o Todo formulario se encuentra definido dentro de la etiqueta <form>, la cual contiene algunos atributos que especifican qu hacer con la informacin. Sin entrar en complicaciones, e o slo se se~alar que para poder recuperar la informacin contenida en un formulario deben o n a o definirse los siguientes atributos: <form method="post" action="path_del_archivo_que_recupera_las_variables.php"> El atributo method="post" determina de qu forma es almacenada la informacin; el e o atributo action="archivo.php", indica el nombre del archivo al cual es exportada dicha informacin. o Dise~ o de formularios. n Existen una serie de formularios que deben escogerse segn lo requiera la clase de pgina u a que se ste programando. A continuacin se listan las etiquetas para implementar los de e o 374 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. mayor uso, recurdese que se est dentro de un formulario y por lo tanto dentro de una e a etiqueta <form>. Cajas de texto: Para crear una dentro del formulario basta escribir: <input type="text" name="Nombre_de_la_informacin"> o Si bien son vlidas otras etiquetas adicionales, cabe destacar que el atributo type tama bin admite otras alternativas de rellenado tales como password, el cual oculta el texto e introducido. Usualmente, la informacin recaudada en los formularios es procesada de o manera algor itmica, por lo que conviene dar menos libertad sobre qu informacin es e o ingresada por el usuario. Para ello se le hace optar, como se muestra en los 3 siguientes dise~os de formularios. n Listado de opciones: La sintaxis es la siguiente: <select name="escoga"> <option value="op1">nombrealt1</option> <option value="op2">nombrealt2</option> <option value="op3">nombrealt3</option> <option value="op4">nombrealt4</option> </select> Recordar que el listado de opciones debe estar dentro de la etiqueta de formulario, de lo contrario, la informacin obtenida de ste no ir a ningn lado. El atributo value o e a u corresponde al nombre que se ha asignado a esa alternativa al procesar la informacin, o es decir, si por ejemplo la nombrealt1 es escogida, se registrar op1 como valor de la a variable escoja cuando se procese el formulario. Botones de radio: La gran ventaja de ste sistema es que se obliga al internauta a e optar, la sintaxis es: <input type="radio" name="escoja" value="op1">nombrealt1 <br> <input type="radio" name="escoja" value="op2">nombrealt2 Sobra decir que un formulario puede tambin ser mixto, es decir, contener listados de e opciones cajas de textos y/o botones de radio. Envi de la informacin. o o Una vez que se ha finalizado la definicin del formulario, debe agregarse un botn que o o env la informacin, el cual corresponde a otro input type. Adicionalmente, si el formulario ie o es muy largo es posible agregar un botn que ponga el formulario en blanco. Las sintaxis son o las siguientes: Botn de envi de la informacin: <input type="submit" value="boton_de_envio"> o o o Botn de reseteo: <input type="reset" value="resetear"> o G.6. PAGINAS BASICAS EN HTML. Ejemplos 375 Con las nuevas herramientas es posible construir pginas como las expuestas en los sia guientes ejemplos: usando el primer ejemplo de esta seccin como un archivo de nombre o ejemplo2.html, se puede construir un peque~o rbol de pginas con los siguientes 2 scripts. n a a El primer script requiere una foto llamada inicio.jpg en el directorio local. Archivo ejemplo3.html <html> <title> :::Utilizando los nuevos recursos::: </title> <body bgcolor="#666666" text="#660000" link="#66FF00" alink="#660066"> <hr> <table align="center"><tr><td><a href="ejemplo2.html"> ejemplo<br> anterior </a></td><td> <a href="ejemplo4.html"> <img src="inicio.jpg" align="center" hspace="30" vspace="20"></a> </td> <td> <a href="http://www.uchile.cl">enlace externo</a> </td> </tr></table> <hr> </body> </html> Archivo ejemplo4.html <html> <title>.::Ejemplo del uso de formularios tipo caja de texto::.</title> <body bgcolor="#000000" text="#FFFFFF" link="#66FF00" alink="#00FF99"> <br> <h2 align="center"> Complete con sus datos y gane!<h2> <form " method="post" action="procesa.php"> <table align="center"> <tr><td> Nombre:</td><td><input type="text" name="Nombre"></td></tr> <tr> <td>e-mail:</td><td> <input type="text" name="email"></td></tr> <tr><td>Telefono:</td><td> <input type="number" name="fono"></td></tr> <tr><td>Direccin:</td><td> <input type="text" name="direc"></td></tr> o <tr><td></td><td><input type="submit" value="enviar"></td></tr> </form> </table> </body> </html> Ejemplo de formularios, tipo listado de alternativas: Archivo ejemplo4b.html <html><title>::Listado de opciones:::</title> <body bgcolor="#000000" text="#FFFFFF" link="#66FF99" alink="#660033"> <h1 algin="left"><u>Particulas subatomicas</u></h1> 376 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. <form method="post" action="psa.php"> <table><tr><td>Particula subatomica:</td> <td><select name="psa"><option value="proton">protn</option> o <option value="neutron">neutrn</option><option value="electron">electrn</option> o o </td></tr><tr><td></td><td><input type="submit" value="ver"></td></table></form></body></ht A partir de estas herramientas bsicas en la programacin de pginas html, es posible a o a comenzar a introducir elementos que cambien dentro de la pgina a tiempo de ejecucin. Esto a o es, la programacin en PHP. Sin embargo, primero debe explorarse brevemente el lenguaje o que permite comunicarse con la base de datos. G.7. G.7.1. MySql. Iniciando sesin. o MySql es un administrador de base de datos que tiene una estructura de usuarios similar a la de UNIX: existe un superusuario llamado root y los usuarios ordinarios, cada uno con su propia cuenta. Se supondr en los siguientes ejemplos la posesin de una cuenta cuyo nombre a o de usuario es lamp y de palabra clave bd. Para comenzar a interactuar con el administrador de bases de datos, hay que iniciar una sesin en ste desde la consola del siguiente modo: o e usa@host:$mysql -u lamp -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 to server version: 4.0.24_Debian-10sarge2-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> La orden que se da desde la consola es: usa@host:$mysql -u lamp -p, que quiere decir: "comienza una sesin de MySql con el nombre de usuario lamp (-u lamp) y pide el password o (-p)". La ultima l inea corresponde al prompt de MySql. G.7.2. Creando una base de datos. A partir de aqu puede interactuarse con MySql ; para hacerlo debe conocerse el lenguaje i de interaccin llamado Sql, del cual tan slo se ense~arn las ordenes bsicas. Cabe destacar o o n a a que todo lo que se escriba en la consola de MySql debe finalizar con ";". El primer paso es crear una base de datos, de nombre base, para ello debe introducirse la orden: mysql> create database base; Una vez creada la base de datos se puede comenzar a trabajar. Un usuario de MySql puede tener varias bases de datos dentro de su cuenta, es por ello que cada vez que ste se e conecte a MySql ( i.e. se loguee) debe escoger la base de datos que utilizar; desde la consola a esto se hace escribiendo: mysql> connect base; G.7. MYSQL. 377 G.7.3. Creando tablas. La base de datos ser completamente intil si no se han creado tablas. Probablemente a u esto constituye el paso ms complicado en el abordaje de un problema a solucionar con una a base de datos, pues es en la estructura de las tablas que quedar plasmado el esquema bajo a el cual operar lo que se programe. Por ello se recomienda fuertemente pensar este punto a antes que cualquier otro. Para crear una tabla debe especificarse (Al menos): el nombre de la tabla, el nombre de cada campo y el tipo de cada campo. Supngase el caso simple de o una tabla con telfonos llamada "agenda", esta tabla debe contener al menos dos campos: e nombres, que contenga texto, y telfono, que contenga nmeros. Para crear tal tabla debe e u introducirse: mysql> create table agenda(nombre text, telefono int); O en general: mysql> create table nombretabla(campo1 tipo, campo2 tipo,.......,campo_i tipo); Podr juzgarse el ejemplo demasiado simple, pues no queda claro de cuntos tipos pueden ia a ser los campos en una tabla; como la intencin no es extenderse, se recomienda instalar el o script en PHP llamado phpmyadmin 6 , el cual permite una administracin de la base de o datos desde el navegador de una forma bastante ms intuitiva y didctica que simplemente a a interactuando con la consola. No se debe abusar del uso de esta interfase, pues es fundamental conocer la sintaxis para interactuar con la base de datos ya que justamente son stas rdenes e o las que se incluyen en los scripts. G.7.4. Interactuando con la Tabla. Teniendo la capacidad para crear bases de datos y, dentro de stas, crear tablas, lo que e resta es aprender a: insertar, buscar y remover registros de una tabla. Para ilustrar estas acciones se continuar con el ejemplo de la agenda telefnica. a o Escribiendo nuevos registros en la tabla: sentencia7 INSERT. Supngase que se quiere ingresar un nuevo usuario llamado "Pedro" de nmero telefnio u o co "5437896". Para ello debe escribirse en la consola: mysql> insert into agenda(nombre,telefono) values ("Pedro",5437896); o en general: mysql> insert into nombre_tabla(campo1,campo2,.....,campoj,..) values (valcampo1, valcampo2,....,valcampoj,...); 6 7 Disponible para la distribucin Debian GNU/Linux. o Tanto MySql como html no son sensibles a las maysculas al escribir scripts. u 378 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. Notar que los string deben ir entre comillas dobles o simples, no as los nmeros. Si se i u escribe dos veces el mismo registro, la base de datos guardar dos registros diferentes a con exactamente la misma informacin y los diferenciar por su fecha de ingreso. o a Removiendo registros: sentencia DELETE. Supngase que se quiere borrar exclusivamente a Pedro; para ello debe escribirse: o mysql> delete from agenda where nombre='Pedro'; Notar la aparicin de la condicin WHERE, la cual especifica a quin borrar; de truncar o o e la sentencia antes de esta condicin, MySql borrar todos los registros de la tabla. o a Como es de esperarse, se podria haber identificado a quin se quer eliminar mediante e ia cualquier otro campo. El administrador se podr preguntar cmo borrar la cantidad ia o de usuarios que quiera de manera efectiva haciendo algo similar a lo que permite bash, esto es posible y fcilmente deducible de la sentencia select. a Buscando registros en la base de datos: sentencia SELECT. La sintaxis de la sentencia SELECT es la siguiente: mysql> select nomcampo from nomtabla where condiciones; Un par de ejemplos para ilustrar lo anterior: Seleccionar todos los elementos: mysql> select * from agenda; Listar todos los elementos de la agenda. a Seleccionar todos los nombres de la agenda: mysql> select nombre from agenda; Listar todos los nombres de la agenda ( a idem con los telfonos). e Seleccionar el par (telfono, nombre) del usuario "Andrea": e mysql> select telefono,nombre from agenda where nombre='Andrea'; Operadores lgicos: tambin es posible ser ms espec o e a ifico mediante operadores lgicos como OR o AND, los cuales funcionan como se esperar Esto sirve para, o ia. por ejemplo, corroborar la existencia de un registro. Supngase que se conoce el o telfono "5534126" y se tiene la sospecha de que pertenece a "Andrea". Para ello e puede digitarse: mysql> select * from agenda where nombre='Andrea' and telefono= 5534126; Si no retorna ningn registro quiere decir que Andrea no tiene ese nmero. Alteru u nativamente, para obtener ms informacin se puede escribir: a o mysql> select * from agenda where nombre='Andrea' or telefono= 5534126; Listar todos los registros que cumplan alguna o ambas condiciones. a Mostrar registros que contengan informacin diferente: o G.7. MYSQL. mysql> select ncampos DISTINCT FROM ntabla where condiciones 379 Orden: La mayor de las veces es necesario saber parcialmente de qu forma vendrn ia e a los datos listados, para ello es necesario introducir un orden y una tolerancia, de esta forma es posible controlar exactamente qu hacer aparecer en el resultado de e la bsqueda. Supngase que se quieren mostrar todos los elementos de la agenda u o ordenados alfabticamente por nombre, para esto hay que escribir: e mysql> select * from agenda order by nombre; Queda claro que hace la condicin ORDER BY. Supngase que se desea invertir el o o orden y poner los ultimos 3 registros, para ello debe escribirse: mysql> select * from agenda order by nombre desc limit 3; La condicin DESC exige un orden descendente, mientras que LIMIT, acompa~ado o n de un entero, da la cantidad mxima de registros que pueden aparecer como resula tado de la bsqueda. Resulta especialmente importante hacer rdenes con nmeu o u ros, pues permiten utilizar comparadores aritmticos. Supngase que se tiene una e o tabla llamada usuarios que contiene los campos edad y nombre de personas. Para encontrar los mayores de edad deber escribirse: ia mysql> select * from usuarios where edad >= 18; Actualizacin de datos, sentencia: UPDATE. o Esta sentencia permite la actualizacin de los datos, es decir, toma un registro viejo o y le modifica algn campo. Supngase que en el ejemplo de la agenda telefnica se u o o quiere cambiar el telfono a un usuario llamado "Juan", quien tiene un nuevo telfono e e "8571646". Para hacerlo debe introducirse la orden: mysql> update agenda set telefono=8571646 where nombre='Juan'; Es evidente la funcin de SET en la sintaxis; de no especificarse WHERE y truncarse la o frase, se cambiar el telfono de todos los registros por el nuevo nmero. ia e u Funciones sobre los campos. Existen, adems, funciones que pueden aplicarse sobre los campos, las cuales pueden a investigarse utilizando phpmyadmin. Se ver un ejemplo simple: en presencia de una tabla a con informacin importante como contrase~as, ser necesario algn sistema de seguridad o n ia u sobre ellas. Para esto existe la funcin PASSWORD, la cual encripta el argumento. La tabla o se llama registrados y contiene 2 campos: Nombre tipo texto y clave tipo VARCHAR. Se sabe como crear una tabla e insertar registros. La siguiente sintaxis muestra la diferencia hecha por la funcin PASSWORD: o 380 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. mysql> create table registrados (nombre text, clave VARCHAR(20)); mysql> insert into registrados (nombre, clave) values ('andres','te45'); mysql> select * from registrados; +--------+-------+ | nombre | clave | +--------+-------+ | andres | te45 | +--------+-------+ 1 row in set (0.00 sec) Se procede a encriptar la clave. mysql> update registrados set clave=PASSWORD('te45') where nombre='andres'; mysql> select * from registrados; +--------+------------------+ | nombre | clave | +--------+------------------+ | andres | 37d3b95821add054 | +--------+------------------+ Se ha expuesto lo ms bsico para poder interactuar con la base de datos. El conocimiento a a de esta sintaxis volver ms rpidos, seguros y eficientes lo programado; sin embargo, el a a a alcance del apndice utilizar tan slo las herramientas aqu expuestas. e a o i G.8. Programacin en PHP. o Los 2 lenguajes antes vistos no tienen relacin entre s y, de hecho, no podrn funcionar o i a en conjunto de no ser por el lenguaje PHP. Este lenguaje es interpretado por un mdulo del o servidor web, por ello, el cdigo en PHP nunca abandona el servidor, es decir, el internauta o no puede ver la fuente en PHP visitando la pgina. a Para el estudiante de este apndice se espera un aprendizaje muy rpido de PHP por su e a similitud con bash y C++. En lo sucesivo, todo el trabajo de PHP ser comunicarse con la a base de datos y manipular los recursos de html de manera dinmica. a G.8.1. Lenguaje PHP. Como ya fue se~alado en la introduccin, el lenguaje en PHP se encuentra inserto dentro n o del html. Esto significa que el script est escrito principalmente en html con trozos en PHP. a Todo el cdigo en PHP queda delimitado por las etiquetas <?php... aqui todo el codigo en php .... ?>. o Al igual que en bash, las variables van antecedidas por un s imbolo $, por otra parte, al igual que en C++ cada l inea de cdigo debe ir finalizada por un ";". o Si se regresa con esta nueva visin sobre el primer ejemplo de pgina dinmica expuesto o a a en este apndice, se tendr: e a G.8. PROGRAMACION EN PHP. Pgina Dinmica en PHP a a Archivo hola.php <html> <?php $h="Hola mundo!";?> <title> :::::El Clasico <?php echo $h; ?>::: </title> <body> <?php echo $h; ?> </body> </html> 381 Lo que ocurre al escribir esta pgina en el navegador es lo siguiente: el servidor web a procesa el script interpretando el cdigo delimitado en PHP, generando a tiempo de ejecucin o o el siguiente nuevo script en html, el que es interpretado por el navegador. <html> <title> :::::El clasico Hola Mundo!:::</title> <body> Hola Mundo! </body> </html> Debe quedar completamente claro que el cdigo en PHP jams abandona el servidor web, o a por lo tanto, el cdigo en PHP se encuentra inserto dentro del html y no viceversa. Dentro o de un script en html es posible, las veces que sea necesario y donde sea necesario, escribir cdigo en PHP. o G.8.2. Variables. Las variables en PHP pueden ser string, nmeros o arreglos. Para desplegar en pantalla u una variable se utiliza la instruccin echo. El ejemplo anterior constituye un caso simple de o esto. G.8.3. Recuperando variables desde un formulario. En el formulario del ejemplo 4, ste enviaba v post las variables al archivo procesa.php. e ia Ahora se proceder a crear dicho archivo operando sobre las variables. a Ejemplo Archivo procesa.php <html><title> recuperando las variables </title> <body bgcolor="#000000" text="#FFFFFF" link="#66FF00" alink="#00FF99"> <h2 align="center"> La informacin tirada a pantalla<h2> o <p align="center"> Tu nombre es <b><?php echo $_POST['Nombre'];?></b> ,vives en <b> <?php echo $_POST['direc']; ?> </b>. Tu e-mail es <b> <?php echo $_POST['correo']; ?> </b> , adems tu telfono es <?php echo $_POST['fono'];?></p></body> </html> a e 382 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. Este archivo simplemente toma las variables y las despliega en pantalla. Se debe notar que la informacin contenida en un formulario queda contenida en el grupo de variables o $_POST['nombredelavariable']. Con este conocimiento es posible rehacer todo ejercicio propuesto en el cap itulo de C++ donde se pidan variables y opere con ellas en PHP. Cabe destacar todo lo que es posible mezclar html y PHP. G.8.4. Control de flujo. Las sintaxis de los controles de flujo ms usuales en PHP son exactamente iguales a los ya a conocidos de C++. A continuacin se dan ejemplos de los bucles while y if respectivamente. o Cabe destacar que el uso de "." pega los string. ejemplo while <?php $i=1; $j="Ejemplo de un bucle haciendo iteraciones, iteracion no :";?> <html><body bgcolor="#336699" text="000033" link="660000" alink="#33ff00"> <h2 align='center'> LOOP <em> while </em>. </h2> <p align="right"> <?php while($i<10)//comentario en php {echo $j . $i; $i++; ?> <br> <?php } ?> </p></body></html> ejemplo if El condicional if logra que el script haga diferentes cosas segn el valor de alguna variable. u A fin de economizar cdigo, a continuacin se ejemplificar el uso del control de flujo if o o a procesando la informacin introducida en el formulario del ejemplo4b.html. La idea es tener o la informacin contenida en variables diferentes y que sta sea desplegada en la pantalla o e segn se elija. La sintaxis del if es exactamente igual que en C++. Archivo psa.php u <?php $opcion=$_POST['psa']; //proton $pmasa="1,672 * 10^27 kg"; $pcarga="1,60217653(14)*10^(-19)C"; $ps="-"; //neutron $nmasa="1,672 * 10^27 kg"; $ncarga="0"; $ns="no tiene carga"; //electron $emasa="9,10 * 10^(-31) kg"; $ecarga="1,60217653(14)*10^(-19)C"; $es="-"; //general G.8. PROGRAMACION EN PHP. $masa; $carga; $signo; 383 if ($opcion=="proton") {$masa=$pmasa; $carga=$pcarga; $signo=$ps;} else if ($opcion=="electron") {$masa=$emasa; $carga=$ecarga; $signo=$es;} else {$masa=$nmasa; $carga=$ncarga; $signo=$ns;} ?> <html><title> informacion</title> <body bgcolor="#000000" text="#FFFFFF" link="#66FF99" alink="#660033"> <table><tr><td>La particula: </td><td> <?php echo $opcion; ?> </td></tr> <tr><td>tiene una masa de :</td><td> <?php echo $masa; ?> </td></tr> <tr><td>tiene una carga de signo :</td><td> <?php echo $signo; ?> </td></tr> <tr><td>tiene una cantidad de carga :</td><td> <?php echo $carga; ?> </td></tr> </table></html> G.8.5. Funcin require. o Al igual que en todos los dems lenguajes estudiados en este curso, PHP posee funciones a intr insecas a l o que pueden crearse. En este apndice tan slo se har uso de funciones que e e o a vienen ya incluidas en el lenguaje, pues son las primeras que deben conocerse. La funcin o require pide como argumento algn archivo cuando se ejecuta el cdigo. La funcin se encarga u o o de incluir el archivo y evaluarlo dentro del cdigo. Si el archivo en cuestin resulta ser ms o o a cdigo, ste ser ejecutado. Usualmente, esto es utilizado para pedir formularios; el uso de o e a esta funcin se ejemplifica ampliamente en el ejemplo final. o G.8.6. Sesin. o PHP tiene la capacidad de definir variables globales sobre un conjunto de pginas a a eleccin; para ello debe realizarse una sesion. Estas son usualmente utilizadas cuando se posee o una estructura de usuarios. Para poder crear una sesin debe contarse con: un rbol de pginas o a a ya armado, una pgina donde se inicie la sesin, y una pgina donde se termine la sesin. Para a o a o ilustrar el uso de las sesiones se considerarn 4 pginas: el formulario del ejemplo4.html; el a a ejemplo anterior procesa.php(con un par de modificaciones) como pgina de inicio de sesin; a o una nueva pgina ejemplo5.php, que gracias a la sesin es capaz de recuperar las variables; a o y una pgina de cierre de sesin salir.php, la cual vuelve al ejemplo4.html. Es importante a o 384 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. adquirir el hbito de generar rboles de pginas lo ms intuitivos posible, pues stas suelen a a a a e ser usadas por personas con poco o nulo conocimiento de su construccin y gran parte de su o xito radicar en su simpleza. Sin ms prembulos, los ejemplos son los siguientes: e a a a Ejemplos. Nuevo archivo procesa.php <?php session_start();//inicio de la sesin o header("Cache-control: private"); //esta lnea se escribe para no borrar los formularios como lo hace i.e. i ?> <html><title> recuperando las variables </title> <body bgcolor="#000000" text="#FFFFFF" link="#66FF00" alink="#00FF99"> <h2 align="center"> La informacin tirada a pantalla<h2> o <p align="center"> Tu nombre es <b><?php echo $_POST['Nombre'];?> </b>, vives en <b> <?php echo $_POST['direc']; ?> </b>. Tu e-mail es <b> <?php echo $_POST['correo']; ?> </b>, adems tu telfono es <?php echo $_POST['fono'];?> </p> a e <h1 align="center"> <a href="ejemplo5.php"> <font color="red"> Aqui para seguir </font></a></h1> </body> </html> <?php $_SESSION['nombre']= $_POST['Nombre']; $_SESSION['mail']= $_POST['correo']; //Definiendo las variables globales de session.?> Archivo ejemplo5.php <?php session_start(); ?> <html> <body bgcolor="#000000" text="#FFFFFF" link="66FF00" alink="00FF99"> <table align="center"><tr><td> <b> Las variables aun se recuperan y son: </b></td></tr> <tr><td> <b> El nombre era: <em> <?php echo $_SESSION['nombre']; ?> </em> </b></td> </tr> <tr><td> <b> El correo era: <em> <?php echo $_SESSION['mail']; ?> </em> </b></td></tr> <h1 align="center"><a href="salir.php"><font color="red">finalizar sesin.</font></a></h1> o </table> </body> </html> archivo salir.php <?php G.8. PROGRAMACION EN PHP. session_start(); session_unset(); header("Location:ejemplo4.html"); echo"<html></html>"; exit; ?> 385 Un par de comentarios sobre los ejemplos: la funcin session_start() debe ser lo primero o que aparezca en el script, es decir, lo primero registrado por el servidor. Para definir una variable de sesin basta asignarla como $_SESSION['nombre'] la cual existe como variable o global para todas las pginas que integren la sesin a partir desde donde fue definida la a o variable. Para salir se utiliza la funcin session_uset(), la cual destruye todas las variables o de la sesin. En el ejemplo salir.php se ha utilizado un mtodo que permite redireccionar o e la pgina de manera automtica sobre el cual no se profundizar. Usualmente, por razones a a a de seguridad, se requiere un rbol de pginas que sea cerrado, para ello simplemente basta a a definir una variable de sesin en la pgina de entrada y luego, en cada nueva pgina que o a a integre la sesin, anteponer un condicional if que chequee que esa variable exista, es decir, o chequea que se haya pasado por la primera de las pginas. Por ejemplo, si se define la variable a de sesin $_SESSION['estado']="conectado"; en la primera pgina, una forma de definir o a el condicional es: if ( $_SESSION['estado']!= 'conectado' ) {die( "Ud no esta logueado!.Click aqui para <a href='ejemplo4.html'>volver</a>");} Esto quiere decir que si la variable de sesin 'estado' es diferente de conectado, niegue la o entrada a la pgina y despliegue este mensaje. De lo contrario, se continuar procesando el a a cdigo. o G.8.7. PHP interactuando con MySql. Si se ha seguido el apndice hasta aqu con xito, el camino est casi completo. Para lograr e i e a el objetivo final tan slo deben introducirse un par de funciones de PHP que permitirn la o a conexin a MySql. Para esto se esquematizarn los pasos que todo script que se conecta a la o a base de datos debe seguir: 1. Conectarse a MySql. 2. Escoger la base. 3. Determinar si se escribe o se lee desde la base de datos. 4. Escribir la peticin como variable en un string. o 5. Enviarla (si hab que escribir en la base de datos, con esto es suficiente). ia 6. Si se est leyendo desde la base de datos, convertir el resultado en un arreglo y operar a sobre la parte de l que se necesite. e 386 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. Siguiendo la numeracin respectiva, utilizando el nombre de usuario y contrase~a de MySql o n antes citado, las funciones son: 1. $conexion=mysql_connect('localhost','lamp', 'bd')or die('No es posible conectar'.mysql_error()); Se conecta al servidor de MySql local bajo el usuario "lamp". Podr parecer en principio ia un poco inseguro que aparezca la clave del usuario expl icitamente en el script; sin embargo, recurdese que esta parte del script est escrita en lenguaje PHP y por lo e a tanto jams abandona la mquina donde se encuentra el script. a a 2. mysql_select_db('nombredelabase')or die ('Base no encontrada'); Notar que, a diferencia del item anterior, aqu la seleccin de base no se almacena como i o variable. 3. Para leer o escribir en la base de datos, basta crear una variable de string con la sintaxis de lo requerido en lenguaje sql. Por ejemplo, supngase que se quiere escribir en o la agenda un nombre guardado en la variable $nombre y un telfono almacenado en la e variable $telefono; la sintaxis es: $p="insert into agenda(nombre, telefono) values ('$nombre','$telefono')"; 4. Por otra parte, si quiere escogerse un registro particular, por ejemplo el nmero teu lefnico del usuario $usuario , la sintaxis es: o $u="select nombre,telefono from agenda where nombre='$usuario'"; 5. Independiente de si se quiera leer o escribir, si la peticin est en una variable $p, esta o a se ejecuta en MySql mediante la orden: $pedido=mysql_query($p) or die ('no se pudo'); 6. Supngase que se pidi un registro, lo que se obtendr de vuelta en la variable $pedido o o a no es un nmero ni un arreglo. Para poder operar con la informacin, primero debe u o convertirse en un arreglo. Dos maneras diferentes de hacerlo son: $fila=mysql_fetch_row($pedido); $arreglo=mysql_fetch_array($pedido); En ambos casos, el arreglo se recorre de la misma manera que en C++. Por ejemplo, en el primer caso, si quiere obtenerse el primer elemento, ste corresponder a la vae a riable $fila[0].En contraste, el segundo caso, permite seleccionar los elementos del arreglo por su nombre dentro de la tabla de MySql. Por ejemplo, si tenemos una tabla con los campos nombre, direccin, entonces los elementos del arreglo corresponden o a $arreglo['nombre'] y $arreglo['direccin'] respectivamente. En la prctica es o a mucho ms utilizada esta representacin que la de row, pues es ms fcil identificar a o a a los elementos. Finalmente, cabe se~alar que en ambos casos, los arreglos respectivos, n contienen un slo registro, pese a que el query, contenga ms de uno. Para obtener o a todos los registros arrojados por el query, basta recorrerlo con un while, de la siguiente forma. G.9. EJEMPLO FINAL. 387 //suponiendo conectado a la base, y con la sentencia sql escrita en un string. $pedido=mysql_query($sentencia_mysql); //supongse que el query de arriba devuelve ms de un registro, a a // para obtener cada uno basta hacer while($miarreglo=mysql_fetch_array($pedido){echo $miarreglo['campo'];} ?> Lo anterior desplegar en pantalla el contenido de los sucesivos registros en el campo a campo. Lo anterior, tambin funciona para mysql_fetch_row. e Con esta seccin se da por finalizado el apndice; sin embargo, se ha escrito un o e ejemplo final para ver puestas en prctica las herramientas aqu expuestas. Se invita al a i lector a tomarlo como una prueba final de si logr un aprendizaje real. o G.9. Ejemplo Final. Se espera haber recorrido con xito todos los tpicos de una manera superficial. A fin de e o aclarar cualquier concepto que para el lector haya quedado poco claro, se llevar a cabo un a ejemplo simple, el cual debe cumplir el siguiente objetivo: un sistema en l inea donde estudiantes que cursen un ramo puedan averiguar sus notas y promedio de manera personalizada mediante una clave. Se hubiera esperado un ejemplo ms cient a ifico, sin embargo, todas las herramientas de este apndice apuntan a tareas administrativas ms que a otra cosa. e a G.9.1. Paso I: Estructura de las tablas. Para todo el ejemplo se tiene el mismo nombre y clave de usuario en MySql que en los ejemplos anteriores. El sistema debe contener una base de datos llamada "ramo" y dentro de sta, por lo menos, dos tablas: una con los nombres y contrase~as de los diferentes alumnos, e n es decir, dos campos y otra con el nombre de cada estudiante y las notas de las respectivas evaluaciones. Para poner una cota superior se crearn 8 campos de evaluacin. Adicionala o mente, se crear una tabla que contenga tanto el nombre como la clave del administrador de a este sistema. La creacin de la base de datos y las respectivas tablas en la consola de MySql o son por lo tanto: mysql>create database ramo; mysql>connect ramo; mysql>create table alumnos(Nombre text,clave varchar(20)); mysql>create table notas(Nombre text ,nota1 float, nota2 float, nota3 float, nota4 float, nota5 float, nota6 float, nota7 float, nota8 float); mysql> create table administrador(Nombre text, clave varchar(20)); mysql> insert into administrador(Nombre,clave) values ("administrador", password("admin") Esta es toda la sintaxis que es necesario hacer desde la consola de MySql. Ahora toca "pensar el rbol de pginas" y la comunicacin que tendrn stas con la base de datos. a a o a e 388 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. G.9.2. Paso II: rbol de pginas. a a El rbol de pginas debe surgir de manera natural a partir de los objetivos que debe a a cumplir lo que se est programando. Este se reducir a formularios que permitan introducir a a informacin, la cual ser procesada por otro script en PHP. Si bien existen 2 clases de o a usuarios (el administrador y los usuarios corrientes), todos deben pasar por una pgina que a les permita "entrar" en el sistema, es decir, 'loguearse'. El archivo expuesto a continuacin o es simplemente un formulario que env la informacin a logueo.php para ser procesada. ia o Archivo log.html <html><title> Bienvenido </title><body bgcolor="#66FFFF" text="#660000"> <h1 align="left"> Proceda a identificarse </h1><br><br><br><hr> <form method="post" action="logueo.php"> <table align="left"> <tr><td><b>Nombre de Usuario:</b></td><td> <input type="text" name="nombre"></td></tr> <tr><td><b>Contrase~a:</b></td><td><input type="password" name="clave"></td></tr> n <tr><td><b>tipo de usuario:</b></td> <td><select name="usrcls"><option value="1">usuario</option> <option value="2">administrador</option></td></tr> <tr><td><input type="submit" value="iniciar sesion"></td></tr> </table></form><br><br><br><br><br><hr></body></html> El formulario recin expuesto pide 3 datos: el nombre, la contrase~a y el tipo de usuario e n que est intentando 'loguearse'. El script que procesa esta informacin debe crear una sesin, a o o pues recurdese que esto debe ser lo primero que aparezca en el script. Luego debe chequear e que la clave ingresada corresponda a un usuario existente, sin embargo, tambin debe realizar e diferentes acciones si se trata de un usuario comn o del administrador, por lo anterior, este u script funcionar en base al condicional if. No debe sorprender la cantidad de cdigo, pues, a o la idea es una sola, cambiando los nombres de las variables: Archivo logueo.php <?php session_start(); $nombre=$_POST['nombre']; $clave=$_POST['clave']; $tipo=$_POST['usrcls']; $conexion=mysql_connect('localhost','lamp', 'bd')or die('No es posible conectar'.mysql_error()); mysql_select_db('ramo')or die ('error al conectar a la base'); if($tipo==1) {$p="select Nombre,clave from alumnos where Nombre='$nombre' and clave=PASSWORD('$clave')"; $q=mysql_query($p) or die('no se pudo hacer el pedido'); $b=mysql_fetch_row($q); if($b==false) {echo "usted no es reconocido por el sistema"; ?> <a href="log.html"><font color="red"> Volver</font></a> <?php} G.9. EJEMPLO FINAL. else {$_SESSION['estado']="conectado"; require('notas.php');}} else if($tipo==2) {$p="select Nombre,clave from administrador where Nombre='$nombre' and clave=PASSWORD('$clave')"; $q=mysql_query($p) or die('no se pudo hacer el pedido'); $b=mysql_fetch_row($q); if($b==false) {echo "usted no es reconocido por el sistema"; ?> <a href="log.html"><font color="red"> Volver</font></a><?php} else{$_SESSION['estado']="conectado"; require('acciones.php');}} else{require("log.html");}?> 389 La funcin del script es la siguiente: primero recupera las variables introducidas en el o formulario y se conecta a la base de datos ramo; despus, en funcin del valor de la variable e o 'usrcls', decide dnde buscar la informacin del nombre de usuario y claves respectivas. Fio o nalmente, la ultima l inea contempla la posibilidad de que se haya intentado acceder a esta pgina sin haber pasado por el formulario, requirindol. A partir de este script, el rbol de a e o a pginas se bifurca en 2 : la "rama del usuario" y la "rama del administrador". Los noma bres de las pginas ya fueron nombrados en el ultimo script. Se lista a continuacin el script a o acciones.php, el cual permite al administrador ingresar informacin de manera intuitiva. o Archivo acciones.php <?php session_start();if ( $_SESSION['estado'] != 'conectado' ) {die( "Ud no esta logueado!.Click aqui para <a href='log.html'>volver</a>");}?> <html><title> Administrando las notas</title> <body bgcolor="#000000" text="#66FF00" link="#CC0033" alink="#66FF66"> <font color="red"><u><a href="salir.php"><h4 align="right"> Cerrar sesin.</h4> o <h1 align="center"><font color="blue"> acciones.</h1> <table><tr><td><?php require('nuser.php');?></td><td><?php require('nnota.php');?> </td></tr></table></body></html> Las primeras l ineas chequean que el usuario se haya "logueado" y especifica el estilo de la pgina. Luego, se utiliza la funcin require para solicitar los 2 formularios que corresponden a a o las acciones que pueden ser realizadas por el administrador: crear nuevos usuarios y agregar notas a cada usuario. Ambos formularios son del tipo caja de texto y la informacin de stos o e es enviada a un archivo del mismo nombre con una "p" final (de procesar). Los archivos que procesan la informacin solo escriben directamente en la base de datos la informacin o o obtenida de los formularios. Finalmente, cabe destacar el link "cerrar sesin", el cual conduce o a un script que cual destruye todas las variables de sesin y devuelve a la pgina de "logueo" o a log.html, lo que se presenta a continuacin: o Archivo salir.php <?php session_start();if ( $_SESSION['estado'] != 'conectado' ) {die( "Ud no esta logueado!.Click aqui para <a href='log.html'>volver</a>");} session_unset();header("Location:log.html");echo"<html></html>";exit;?> 390 APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. A continuacin se presentan los scripts que permiten poner notas, crear nuevos usuarios o y sus respectivos archivos de proceso: Archivo nnota.php. <?php session_start();if ( $_SESSION['estado'] != 'conectado' ) {die( "Ud no esta logueado!.Click aqui para <a href='log.html'>volver</a>");}?> <html><body bgcolor="#000000" text="#66FF00" link="#CC0033" alink="#66FF66"> <br><br><form method="post" action="nnotap.php"><table align="center"> <tr><td><h2>Nueva nota</h2></td></tr> <tr><td>Nombre:</td><td><input type="text" name="nombre"></td></tr> <tr><td>Nota No :</td><td><input type="text" name="nnota"></td></tr> <tr><td>La Nota es:</td><td><input type="text" name="nota"></td></tr> <tr><td></td><td><input type="submit" value="ingresar nota"></table></form></body></html> El archivo que procesa las variables: nnotap.php <?php session_start();if ( $_SESSION['estado'] != 'conectado' ) {die( "Ud no esta logueado!.Click aqui para <a href='log.html'>volver</a>");} $alumno=$_POST['nombre']; $nnota=$_POST['nnota'];$nota=$_POST['nota']; if($nnota>8){echo "el sistema aguanta mximo 8 evaluaciones"; require("acciones.php");} a else{$conexion=mysql_connect('localhost','lamp','bd') or die ('No conecta'.mysql_error()); mysql_select_db('ramo'); $escribe="update notas set nota$nnota='$nota' where nombre='$alumno'"; $haz=mysql_query($escribe); echo "<b>".$alumno. " saco un ".$nota." en la evaluacion no ".$nnota."</b>"; require("acciones.php");}?> Debiera quedar completamente claro lo que ejecuta este script: recupera las variables y revisa que no se haya sobrepasado la cota mxima de las 8 notas por alumno. De ser as procede a i, a escribir la nueva informacin en la base de datos. Cabe notar que la informacin no esta o o escrita con la sentencia INSERT, sino UPDATE, por lo cual las notas pueden ser cambiadas. La segunda accin habilitada por el administrador es la de agregar nuevos usuarios, lo cual se o hace de una manera totalmente anloga a los scripts anteriores: a Archivo nuser.php <?php session_start();if ( $_SESSION['estado'] != 'conectado' ) {die( "Ud no esta logueado!.Click aqui para <a href='log.html'>volver</a>");}?> <html><body bgcolor="#000000" text="#66FF00" link="#CC0033" alink="#66FF66"><br><br> <form method="post" action="nuserp.php"><table align="left"> <tr><td align="center"> <h2>Nuevo registro</h2><br></td></tr> <tr><td>Nombre:</td><td><input type="text" name="nombre"></td></tr> <tr><td>Contrase~a:</td><td><input type="password" name="clave"></td></tr> n <tr><td></td><td><input type="submit" value="ingresar usuario"></td></tr> </table></form></body></html> El archivo que procesa las variables. Archivo nuserp.php G.9. EJEMPLO FINAL. 391 <?php session_start();if ( $_SESSION['estado'] != 'conectado' ) {die( "Ud no esta logueado!.Click aqui para <a href='log.html'>volver</a>");} $conexion=mysql_connect('localhost','lamp','bd') or die ('No conecta'.mysql_error()); mysql_select_db('ramo'); $alumno=$_POST['nombre']; $clave=$_POST['clave']; $nusuario="insert into alumnos(Nombre,clave) values ('$alumno',PASSWORD('$clave'))"; $nusuariob="insert into notas (nombre) values ('$alumno')"; $escribe=mysql_query($nusuario)or die('no se pudo escribir'); $escribeb=mysql_query($nusuariob) or die('no se pudo escribir'); echo "<b> alumno ".$alumno. " ingresado con exito</b>"; require("acciones.php");?> Con esto se da por finalizado el proceso de introducir informacin al sistema. Ahora solo o resta generar un script que muestre la informacin correspondiente a cada usuario. o Archivo notas.php <?php session_start(); $nombre=$_POST['nombre']; $clave=$_POST['clave']; $conexion=mysql_connect('localhost','lamp', 'bd')or die('No es posible conectar'.mysql_er mysql_select_db('ramo')or die ('error al contactar base'); $pedir="select nota1, nota2, nota3, nota4, nota5, nota6, nota7, nota8 from notas where no $pedido=mysql_query($pedir); $notas=mysql_fetch_row($pedido); ?> <html> <title> Notas: </title> <body bgcolor="#333300" text="#3300FF" link="33FF33" alink="#669900"> <h2 align="right"> <a href="salir.php" ><font color="red" <u> Cerrar sesion.</u> </a> </h <h3 align="left"> <font color="green"> Alumno <?php echo $nombre;?></h3> <table align="left"><tr><td><b> Sus notas son</b></td></tr> <tr><td>Eval.No :</td><td>Nota</td><tr> <?php $i=1; $g=0; $cont=0; while($i<=8) { $k=$i-1; echo "<tr><td>". $i . "</td><td>" .$notas[$k]. "</td></tr>"; $i++; if($notas[$k]>=1){$cont++;} $g=$g+$notas[$k]; } if($g==0){echo "usted no tiene notas";} else{$t=$g/$cont;}?> <br><br> <tr><td>Su promedio final es:</td><td><b><?php echo $t; ?> </b> </td></tr> </table> 392 </body></html> APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P. Sobre el ultimo ejemplo cabe destacar: se piden todas las notas del alumno en cuestin; la o base de datos devuelve para esto la informacin que es convertida en fila (mysql_fetch_row()); o luego la fila comienza a ser recorrida utilizando un control de flujo while, el cual va generando a tiempo de ejecucin una tabla en html ; las variables auxiliares $i, $g y $cont son utilizadas o para calcular el promedio del nmero de notas que existan. u G.10. Conclusiones. El ejemplo ha sido chequeado siguiendo los pasos dados en este apndice y funciona de e manera bsica (pudiendo ser mejorado),pues su fin no es ser operativo, sino explicativo. a Podr parecer que se trata de una gran cantidad de cdigo, sin embargo, la mayor parte ia o del tiempo se est repitiendo lo mismo con variaciones obvias. Esperando haber logrado a una comprensin aceptable por parte del lector, A partir de las herramientas entregadas, es o posible realizar proyectos bastante ms ambiciosos tales como: a Sistema de votaciones en l inea. Comunicacin mediante mensajes entre usuarios (un rudimentario chat). o Sistema de encuestas en l inea. En general, cualquier problema de administracin que involucre diferentes usuarios a o distancia se torna en algo solucionable mediante las herramientas aqu desarrolladas. Por i ultimo, se deja como ejercicio al lector un par de puntos que restan por mejorar del ejemplo final. G.10.1. Mejoras al Ejemplo final. Falt lograr: o No se repitan usuarios. Solo existan notas entre 1 y 7. Comunique al administrador cuando ste intente ingresar notas a un usuario inexistente. e Sobra decir para el lector con algo de experiencia en programacin que todas estos proo blemas sern fcilmente solucionables utilizando el condicional if, de manera de cubrir todas a a las posibilidades. Esto no se ha hecho, pues volv el ejemplo demasiado redundante y por lo ia tanto se ha priorizado su funcionalidad. G.11. TABLA DE COLORES EN HTML. 393 G.11. Tabla de Colores en html. Figura G.2: Los 256 colores posibles de desplegar en una pgina en html, con su respectivo a cdigo. o ...
View Full Document

This note was uploaded on 09/11/2009 for the course FÍSICA PROGRAMACI taught by Professor Joserogan during the Spring '09 term at Universidad de Chile.

Page1 / 411

mfm0f -

This preview shows document pages 1 - 6. Sign up to view the full document.

View Full Document Right Arrow Icon
Ask a homework question - tutors are online