You are on page 1of 442

Departamento de F sica, Facultad de Ciencias, Universidad de Chile. n Las Palmeras 3425, Nuoa.

. Casilla 653, Correo 1, Santiago fono: 562 978 7276 fax: 562 271 2973 e-mail: secretaria@sica.ciencias.uchile.cl

Apuntes de un curso de

PROGRAMACION Y METODOS NUMERICOS


Octava edicin, revisin 081104-03 o o

Jos Rogan C. e V ctor Muoz G. n

ii

Agradecimientos:
Xavier Andrade. Denisse Pastn. e De la promocin del 2004 a: Daniel Asenjo y Max Ram o rez. De la promocin del 2005 a: Alejandro Varas y Mar Daniela Cornejo. o a De la promocin del 2006 a: Nicols Verschueren y Paulina Chacn, o a o Sergio Valdivia y Elizabeth Villanueva. De la promocin del 2007 a: Sebastin Godoy y Carola Cerda, o a Rodrigo Pedrasa y Felipe Fuentes.

iv

Indice
I Computacin o
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1
3 3 4 4 5 5 6 6 7 9 9 10 11 11 12 12 13 16 24 24 24 25 26 27 28 28 28 30 30 30 32 32 34 34

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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 36 37 38 40 40 40 41 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 nea. . . . . 3.2.3. Imprimiendo un texto de varias l neas. 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.5.5. Argumentos claves. . . . . . . . . . . . . . 3.5.6. Documentacin de una funcin, docstrings. o o 3.5.7. La palabra clave return. . . . . . . . . . . 3.5.8. Funciones que tienen un valor de retorno. . 3.5.9. Recursin. . . . . . . . . . . . . . . . . . . o 3.6. Iteraciones con while. . . . . . . . . . . . . . . . 3.7. Los strings. . . . . . . . . . . . . . . . . . . . . . 3.7.1. Indice negativos. . . . . . . . . . . . . . . 3.7.2. Cun largo es un string? . . . . . . . . . a 3.7.3. Recorriendo un string. . . . . . . . . . . . 3.7.4. Comparando strings. . . . . . . . . . . . . 3.8. El ciclo for. . . . . . . . . . . . . . . . . . . . . . 3.8.1. El comando break. . . . . . . . . . . . . . 3.8.2. El comando else. . . . . . . . . . . . . . . 3.9. Listas. . . . . . . . . . . . . . . . . . . . . . . . . 3.9.1. Rebanando listas. . . . . . . . . . . . . . . 3.9.2. Mutabilidad. . . . . . . . . . . . . . . . . 3.9.3. Modicando listas. . . . . . . . . . . . . . 3.9.4. Agregando a una lista. . . . . . . . . . . . 3.9.5. Borrando items de una lista. . . . . . . . . 3.9.6. Operaciones con listas. . . . . . . . . . . . 3.9.7. Qu contiene una lista? . . . . . . . . . . e 3.9.8. Un ciclo for y las listas. . . . . . . . . . . 3.9.9. Otros trucos con listas. . . . . . . . . . . . 3.9.10. Generando listas de nmeros. . . . . . . . u 3.10. Tuplas. . . . . . . . . . . . . . . . . . . . . . . . . 3.11. Parmetros desde la l a nea de comando. . . . . . . 3.12. Ejemplos de funciones: ra cuadrada y factorial. . z 3.12.1. Ra cuadrada. . . . . . . . . . . . . . . . z 3.12.2. Factorial. . . . . . . . . . . . . . . . . . . 3.13. Trabajando con archivos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

vii

57 57 58 58 59 60 60 60 60 61 61 62 62 62 63 64 64 65 65 66 66 67 67 67 68 68 69 69 69 69 70 70 70 71 71 71 72 72 72 72 73 74 74 75 76

viii

INDICE 3.13.1. Funciones del mdulo os. . . . . . . . . . . . o 3.13.2. Funciones del mdulo os.path. . . . . . . . o 3.13.3. Ejemplo de un cdigo. . . . . . . . . . . . . o 3.13.4. Abriendo un archivo. . . . . . . . . . . . . . 3.13.5. Leyendo un archivo. . . . . . . . . . . . . . 3.13.6. Escribiendo a un archivo. . . . . . . . . . . . 3.13.7. Cerrando un archivo. . . . . . . . . . . . . . 3.13.8. Archivos temporales. . . . . . . . . . . . . . 3.13.9. Ejemplo de lectura escritura. . . . . . . . . . 3.14. Excepciones. . . . . . . . . . . . . . . . . . . . . . . 3.15. Diccionarios. . . . . . . . . . . . . . . . . . . . . . . 3.15.1. Editando un diccionario. . . . . . . . . . . . 3.15.2. Un ejemplo de cdigo, un men. . . . . . . . o u 3.15.3. Tuplas y diccionarios como argumentos. . . 3.16. Modules y Shelve. . . . . . . . . . . . . . . . . . . . 3.16.1. Partiendo el cdigo. . . . . . . . . . . . . . . o 3.16.2. Creando un mdulo. . . . . . . . . . . . . . o 3.16.3. Agregando un nuevo directorio al path. . . . 3.16.4. Haciendo los mdulos fciles de usar. . . . . o a 3.16.5. Usando un mdulo. . . . . . . . . . . . . . . o 3.16.6. Trucos con mdulos. . . . . . . . . . . . . . o 3.16.7. Preservando la estructura de la informacin. o 3.16.8. Cmo almacenar? . . . . . . . . . . . . . . o 3.16.9. Ejemplo de shelve. . . . . . . . . . . . . . . 3.16.10.Otras funciones de shelve. . . . . . . . . . . 3.17. Clases y mtodos. . . . . . . . . . . . . . . . . . . . e 3.17.1. Clase de muestra LibretaNotas. . . . . . . . 3.17.2. Valores por defecto. . . . . . . . . . . . . . . 3.18. Sobrecarga de Operadores. . . . . . . . . . . . . . . 3.18.1. Funcin driver. . . . . . . . . . . . . . . . . o 3.18.2. Atributos de las clases. . . . . . . . . . . . . 3.18.3. Ejemplo de clase vectores. . . . . . . . . . . 3.19. Algunos mdulos interesantes. . . . . . . . . . . . . o 3.19.1. El mdulo Numeric. . . . . . . . . . . . . . o 3.20. El mdulo Tkinter . . . . . . . . . . . . . . . . . . o 3.20.1. Elementos importantes en una ventana. . . . 3.20.2. Ubicacin de un elemento en la ventana. . . o 3.20.3. Atributos del master. . . . . . . . . . . . . . 3.20.4. Un ejemplo ms elaborado. . . . . . . . . . . a 3.20.5. El mdulo Visual. . . . . . . . . . . . . . . o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 77 78 78 78 78 79 79 79 80 80 81 82 82 82 82 82 83 83 83 84 84 84 85 85 85 86 87 87 88 88 89 89 89 90 90 93 93 94 95

4. Una breve introduccin a C++. o 97 4.1. Estructura bsica de un programa en C++. . . . . . . . . . . . . . . . . . . . 97 a 4.1.1. El programa ms simple. . . . . . . . . . . . . . . . . . . . . . . . . . . 97 a 4.1.2. Denicin de funciones. . . . . . . . . . . . . . . . . . . . . . . . . . . 98 o

INDICE 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 Control de ujo. . . . . . . . . . . . . . . . . . . . . . . 4.2.1. if, if... else, if... else if. . . . . . . . . 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. . . . . . . . . . . . . . . . . . . . . . . . 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. z 4.3.6. Alcance, visibilidad, tiempo de vida. . . . . . . 4.3.7. Recursin. . . . . . . . . . . . . . . . . . . . . . o 4.3.8. Funciones internas. . . . . . . . . . . . . . . . . Punteros. . . . . . . . . . . . . . . . . . . . . . . . . . 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). . . . . Manejo de archivos. . . . . . . . . . . . . . . . . . . . . 4.6.1. Archivos de salida. . . . . . . . . . . . . . . . . 4.6.2. Archivos de entrada. . . . . . . . . . . . . . . . 4.6.3. Archivos de entrada y salida. . . . . . . . . . . main como funcin. . . . . . . . . . . . . . . . . . . . . o 4.7.1. Tipo de retorno de la funcin main. . . . . . . . o Clases. . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8.1. Denicin. . . . . . . . . . . . . . . . . . . . . . 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. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

ix

4.2.

4.3.

4.4. 4.5.

4.6.

4.7. 4.8.

100 100 102 103 103 103 104 106 106 108 108 109 111 112 112 112 112 113 114 118 119 121 124 124 125 127 127 128 129 130 131 134 134 137 138 139 140 141 142 143 143 143 144 145 146

INDICE 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. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 147 147 148 148 149 150 153 153

5. Grca. a 5.1. Visualizacin de archivos grcos. . . o a 5.2. Modicando imgenes . . . . . . . . a 5.3. Conversin entre formatos grcos. . o a 5.4. Captura de pantalla. . . . . . . . . . 5.5. Creando imgenes. . . . . . . . . . . a 5.6. Gracando funciones y datos. . . . . 5.7. Gracando desde nuestros programas.

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

155 . 155 . 156 . 156 . 157 . 157 . 158 . 159 161 161 161 162 162 162 163 163 164 165 165 165 166 167 168 168 169 170 171 172 172 172 173 173 174 174

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 tulo. . . . . . . . . . . . . . . . . . . . . 6.3.11. Secciones. . . . . . . . . . . . . . . . . . . 6.3.12. Listas. . . . . . . . . . . . . . . . . . . . . 6.3.13. Tipos de letras. . . . . . . . . . . . . . . . 6.3.14. Acentos y s mbolos. . . . . . . . . . . . . . 6.3.15. Escritura de textos en castellano. . . . . . 6.4. Frmulas matemticas. . . . . . . . . . . . . . . . o a 6.4.1. Sub y supra ndices. . . . . . . . . . . . . . 6.4.2. Fracciones. . . . . . . . . . . . . . . . . . . 6.4.3. Ra ces. . . . . . . . . . . . . . . . . . . . . 6.4.4. Puntos suspensivos. . . . . . . . . . . . . . 6.4.5. Letras griegas. . . . . . . . . . . . . . . . . 6.4.6. Letras caligrcas. . . . . . . . . . . . . . a

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .

INDICE 6.4.7. S mbolos 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. . . 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. Modicando el estilo de la pgina. . . . . . . a 6.9.1. Estilos de pgina. . . . . . . . . . . . a 6.9.2. Corte de pginas y l a neas. . . . . . . 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. Modicando L TEX. . . . . . . . . . . . . . . 6.13.1. Denicin 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

174 176 177 179 180 180 180 181 181 182 183 183 184 187 187 187 188 188 189 192 193 193 195 197 198 198 203 210 210 213

II

Mtodos Numricos. e e
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

215
217 . 217 . 229 . 229 . 231 233 . 233 . 233 . 235 . 236

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

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

xii

INDICE 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 . . . . . . . . . . . . . . . . . . . . . . . . 8.3.2. pendulo.py . . . . . . . . . . . . . . . . . . . . . . . 8.4. Listado de los programas en c++. . . . . . . . . . . . . . . . 8.4.1. balle.cc . . . . . . . . . . . . . . . . . . . . . . . . 8.4.2. pendulo.cc . . . . . . . . . . . . . . . . . . . . . . . . . . . . tiempo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 237 238 240 240 242 243 246 250 250 252 254 254 255 259 259 259 261 265 265 267 268 269 270 270 271 274 274 279 284 285 286 291 291 291 292 293 295 295 296 298 298 300

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. (Slo c++) o 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.py . . . . . . . . . . . . . . . . . . 9.4.2. orbita.cc . . . . . . . . . . . . . . . . . . 9.4.3. vector4d.h . . . . . . . . . . . . . . . . . 9.4.4. vector4d.cc . . . . . . . . . . . . . . . . 9.4.5. orbita2.cc . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

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

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

INDICE 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. Manejo de matrices en Python. . . . . . 10.4.2. Programa newtn en Python. . . . . . . . 10.4.3. Denicin de la clase Matrix. . . . . . . o 10.4.4. Implementacin de la clase Matrix. . . . o 10.4.5. Funcin de eliminacin Gaussiana ge. . . o o 10.4.6. Funcin para inversin de matrices inv. o o 10.4.7. Programa newtn en Octave. . . . . . . . 10.4.8. Programa newtn en c++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

xiii

301 302 302 303 304 305 307 307 307 308 309 313 314 315 316 319 319 319 320 321 324 325

11.Anlisis de datos. a 11.1. Ajuste de curvas. . . . . . . . . . . . . . . . . . . . 11.1.1. El calentamiento global. . . . . . . . . . . . 11.1.2. Teor general. . . . . . . . . . . . . . . . . a 11.1.3. Regresin lineal. . . . . . . . . . . . . . . . . o 11.1.4. Ajuste general lineal de m nimos cuadrados. 11.1.5. Bondades del ajuste. . . . . . . . . . . . . . 12.Integracin numrica bsica o e a 12.1. Deniciones . . . . . . . . . . . . . . 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 . . . . . . . . . . . . . . a 12.8. Listados del programa. . . . . . . . . 12.8.1. Programa trapecio.py . . . 12.8.2. Programa romberg.py . . . . 12.8.3. Programa trapecio.cc . . . 12.8.4. Programa romberg.cc . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

327 . 327 . 328 . 329 . 330 . 332 . 334 . 336 . 337 . 337 . 338 . 339 . 340

III

Apndices. e

343
345

A. Transferencia a diskettes.

B. Las shells csh y tcsh. 347 B.1. Comandos propios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 B.2. Variables propias del shell. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348

xiv

INDICE 351 359 359 359 360 360 360 362 362 363 363 364 364 364 365 365 365 365 366 369 371 372 372 373 377 378

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 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 Fourier . a D.6.7. Grcos . . . . . . . . . . . . . . . . . . . . . a D.6.8. Strings . . . . . . . . . . . . . . . . . . . . . . D.6.9. Manejo de archivos . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

E. Asignacin dinmica. o a 383 E.1. Arreglos dinmicos bidimensionales. . . . . . . . . . . . . . . . . . . . . . . . . 384 a F. make y Makele. F.1. Un ejemplo sencillo en C++ . . . . . . . . F.2. Creando un Makele . . . . . . . . . . . . A F.3. Un ejemplo con varias dependencias: L TEX F.4. Variables del usuario y patrones . . . . . . F.5. C++: Programando con ms de un archivo a F.6. Un ejemplo completo . . . . . . . . . . . . 385 . 385 . 386 . 388 . 389 . 391 . 393 397 397 397 397 398 399 399

. . . . . . . . . . . . . . . . fuente . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

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. . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

INDICE 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 ujo. . . . . . . . . . . . . . . . . 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 nal. . . . . . . . . . . . G.11.Tabla de Colores en html. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

xv

399 400 400 403 406 406 406 407 407 410 410 411 411 412 413 413 415 417 417 418 422 423 424

xvi

INDICE

Indice de guras
6.1. Un sujeto caminando. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 7.1. Salida grca del programa interp. . . . . . . . . . . . . . . . . . . . . . . . . 224 a 7.2. Salida grca del programa interp. . . . . . . . . . . . . . . . . . . . . . . . . 227 a 7.3. Error absoluto (h), ecuacin (7.9), versus h para f (x) = x2 y x = 1. . . . . . 232 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 pequeo. e a n Mtodo de Verlet para m = 10 . . . . . . . . . . . e Mtodo de Verlet para m = 170 . . . . . . . . . . . e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 239 240 248 248 249 249 260 263 264 264 265 270 273 273

Orbita el ptica alrededor del Sol. . . . . . . . . . . . . . . . . . . . . . . . . . . Trayectoria y energ usando el mtodo de Euler. . . . . . . . . . . . . . . . . a e Trayectoria y energ usando el mtodo de Euler-Cromer. . . . . . . . . . . . . a e Trayectoria y energ usando el mtodo de Euler-Cromer. . . . . . . . . . . . . a e Trayectoria y energ con el paso de tiempo ms pequeo en Euler-Cromer. . . a a n Trayectoria y energ usando el mtodo de Runge-Kutta. . . . . . . . . . . . . a e Trayectoria y energ usando el mtodo de Runge-Kutta adaptativo. . . . . . . a 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. . . . . . . . 301 10.2. Representacin grca del mtodo de Newton. . . . . . . . . . . . . . . . . . . 303 o a e 11.1. Dixido de carbono medido en Hawai. . . . . . . . . . . . . . . . . . . . . . . . 320 o 11.2. Ajuste de datos a una curva. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 12.1. Subintervalos. . . . . . . . . . . . . . . . . . . . . 12.2. Sucesin de l o neas rectas como curva aproximante. 12.3. Aproximaciones, (a) lineal, (b) cuadrtica. . . . . a 12.4. Regla trapezoidal versus cuadratura de Gauss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 328 330 334

D.1. Grco simple. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 a D.2. Curvas de contorno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 D.3. Curvas de contorno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
xvii

xviii

INDICE DE FIGURAS G.1. Esquema de una tabla en html, utilizando los elementos de una matriz. . . . . 403 G.2. Los 256 colores posibles de desplegar en una pgina en html, con su respectivo a cdigo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424 o

Parte I Computacin o

Cap tulo 1 Elementos del sistema operativo unix.


versin revisada 7.1, 31 de Julio del 2007 o

1.1.

Introduccin. o

En este cap tulo 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 a 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 ca, tiene una larga historia y muchas de sus ideas y mtodos se encuentran presentes en otros sistemas operativos. e Algunas de las caracter sticas 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 diseadas para trabajar desde la l n nea de comandos. Adems, a la mayor de las aplicaciones permiten que la salida de una pueda ser la entrada de la a otra. Permite compartir dispositivos (como disco duro) entre una red de mquinas. a 3

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

Por su naturaleza de multiusuario, nunca se deber apagar impulsivamente una mquina a a 1 unix , ya que una mquina apagada sin razn puede matar trabajos de d perder los a o as, 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 de trabajo sun Solaris3 : disponible para la familia sparc de Sun as como para la familia x86. 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 n de una sesin en unix o o as como la modicacin de la contrasea (que a menudo no es la deseada por el usuario, y 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 grco: Consta de pantalla grca, 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.

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 nalizar 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 contrasea (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.

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 unican 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 modicacin de la contrasea en una mquina supone la modicacin 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 a 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 a 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 ca. 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 modicar 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 clasicaciones: stable (estable): Es la ultima versin ocial 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 De 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 ocial http://www.debian.org. o o a
Antiguamente se conoc como YP (Yellow Pages), pero debido a un problema de marca registrada de a 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.

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

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

El rbol que observamos muestra el t a pico rbol de directorios en Linux. Pueden haber a pequeas 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 conguracin de todo los diferentes softwares 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. Se usan para acceder los dispositivos f sicos 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 sucesia a 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 a (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 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 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.

1.5.

Ordenes bsicas. a

Para ejecutar un comando, basta con teclear su nombre (tambin debes tener permiso para e hacerlo). Las opciones o modicadores empiezan normalmente con el caracter - (p. ej. ls -l). Para especicar 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, gura, 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, z). 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 mbolos (el caracter / no se permite).

Los caracteres comod (wildcard ) pueden ser empleados para acceder a un conjunto n de archivos con caracter sticas 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. 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 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 aade el nombre de n un directorio el listado es del directorio suministrado. Existen varias opciones que modican su funcionamiento entre las que destacan: -l (Long listing) proporciona un listado extenso, que consta de los permisos13 de cada archivo, el usuario, el tamao del archivo, . . . , etc. Adicionalmente la opcin -h imprime n o los tamaos 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 modicacin. o -S ordena los archivos por tamao. n -r invierte el sentido de un ordenamiento. -p agrega un caracter al nal de cada nombre de archivo, indicando el tipo de archivo (por ejemplo, los directorios son identicados con un / al nal).
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 o.

1.5.3.

Visitando archivos.

Este conjunto de rdenes permite visualizar el contenido de un archivo sin modicar 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 tamaos 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 tamaos 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 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, signica poder examinar el contenido del mismo; en el caso de un directorio signica poder entrar en dicho directorio. escritura (w-Write): en el caso de un archivo signica poder modicar 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 signica 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 especicar 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 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 modicar los permisos de un archivo. Con opcin -R es recursiva. o chmod permisos les Existen dos modos de especicar 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 dueo 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 especicar 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: + : aadir permiso. n

1.5. ORDENES BASICAS. - : eliminar permiso. = : asignar permiso, el resto de permisos de la misma categor se anulan. a permission: es una combinacin de los caracteres: o r : read. w : write. x : execute. s : en ejecucin ja 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 nseca del Shell que permite asignar los permisos que se desea tengan los archivos y directorios por omisin. El argumento que acompaa 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 les 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 les La opcin -r hace que la orden se efecte recursivamente. o u id Muestra la identicacin del usuario18 , as como el conjunto de grupos a los que el usuario o pertenece. user@hostname:~$ id uid=1000(user) gid=1000(group) groups=1000(group),25(floppy),29(audio) user@hostname:~$
Un error muy frecuente es la creacin de un archivo de rdenes (script le) y olvidar permitir la ejecucin o o o del mismo. 18 A pesar de que el usuario se identica por una cadena denominada username, tambin existe un nmero e u denominado uid que es un identicativo 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 ltros (Unix Filters), porque normalmente se trabaja empleando redireccin o 19 20 recibiendo datos por su stdin y retornndolos modicados 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 ltro, pero nos ser muy util ms adelante. Despliega sobre la a a pantalla un mensaje, sin argumento despliega una l nea en blanco. La opcin -n elimina el o cambio de l nea al nal del mensaje. user@hostname:~$ echo Hola Mundo Hola Mundo user@hostname:~$ echo ; echo chao; echo chao user@hostname:~$ Varias instrucciones pueden ser separadas por ; cat Es el ltro ms bsico, copia la entrada a la salida. a a user@hostname:~$ cat 1 190 2 280 3 370 user@hostname:~$ mylist.txt

Tambin lo podemos usar para crear un archivo e user@hostname:~$ cat Este es mi archivo con muchas lineas ^d user@hostname:~$
19 20

> myfile.txt

Entrada estndar. a Salida estndar. a

1.5. ORDENES BASICAS. El caracter nal ^d corresponde a n de archivo y termina el ingreso. seq Genera una secuencia de nmeros naturales consecutivos. u user@hostname:~$ 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. user@hostname:~$ cut -b 3-4 mylist.txt 19 28 37 user@hostname:~$ paste Mezcla l neas de distintos archivos. Escribe l neas en el stdout pegando secuencialmente las l neas 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 user@hostname:~$ paste mylist.txt yourlist.txt 1 190 1 190 2 280 2 281 3 370 3 370 user@hostname:~$ sed Es un editor de ujo. Veamos algunos ejemplos user@hostname:~$ sed = mylist.txt 1 1 190 2 2 280 3 3 370 user@hostname:~$ Numera las l neas. user@hostname:~$ sed -n -e 3p mylist.txt 3 370 user@hostname:~$

18

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

Slo muestra la l o nea 3. El modicador -n suprime la impresin de todas las l o neas excepto aquellas especicadas por p. El modicador -e corre un script, secuencia de comandos. Separando por coma damos un rango en el nmero de l u neas. user@hostname:~$ sed -e 2q mylist.txt 1 190 2 280 user@hostname:~$ Muestra hasta la l nea 2 y luego se sale de sed. user@hostname:~$ sed -e s/0/a/g mylist.txt 1 19a 2 28a 3 37a user@hostname:~$ Reemplaza todos los 0 del archivo por la letra a. Este es uno de los usos ms comunes. a user@hostname:~$ sed -e /2 2/s/0/a/g mylist.txt 1 190 2 28a 3 370 user@hostname:~$ Busca las l neas con la secuencia 2 2 y en ellas reemplaza todos los 0 por la letra a. user@hostname:~$ sed -e s/1/XX/2 mylist.txt 1 XX90 2 280 3 370 user@hostname:~$ Reemplaza la segunda aparicin de un 1 en una l o nea por los caracteres XX. A continuacin mostramos otras posibilidades del comando sed o Para remover una l nea especica (X) de un archivo (file.txt) user@hostname:~$ sed -e Xd file.txt Para remover un intervalo de l neas de un archivo user@hostname:~$ sed -e X,Yd file.txt Para mostrar slo las l o neas X e Y de un archivo

1.5. ORDENES BASICAS. user@hostname:~$ sed -n -e Xp;Yp file.txt Para mostrar un archivo salvo las l neas que contengan key user@hostname:~$ sed -e /key/d file.txt Para mostrar de un archivo slo las l o neas que contengan key user@hostname:~$ sed -n -e /key/p file.txt Para mostrar un archivo salvo las l neas que comienzan con # user@hostname:~$ sed -e /^#/d file.txt Expresiones regulares: ^ Matches al comienzo de la l nea $ Matches al nal de la l nea, 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 user@hostname:~$ diff mylist.txt yourlist.txt 2c2 < 2 280 --> 2 281 user@hostname:~$ Hay una diferencia entre los archivos en la segunda la. sort Permite ordenar alfabticamente e user@hostname:~$ sort tercero.txt 11 b 222 a 33 c user@hostname:~$ user@hostname:~$ sort -r tercero.txt 33 c 222 a 11 b user@hostname:~$

19

20

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

user@hostname:~$ sort -n tercero.txt 11 b 33 c 222 a user@hostname:~$ user@hostname:~$ sort -k 2 tercero.txt 222 a 11 b 33 c user@hostname:~$ La opcin -n considera los valores numricos y la opcin -r invierte el orden. La opcin -k o e o o permite especicar 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 nea en que se encuentra la cadena. user@hostname:~$ grep 1 *list.txt mylist.txt:1 190 yourlist.txt:1 190 yourlist.txt:2 281 user@hostname:~$ 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 neas 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 neas donde no aparece la cadena pedida. head Muestra las primeras diez l neas de un archivo. head -30 file Muestra las 30 primeras l neas de le. user@hostname:~$ head -1 1 190 user@hostname:~$ mylist.txt

tail Muestra las diez ultimas l neas de un archivo. tail -30 file Muestra las 30 ultimas l neas de le. tail +30 file Muestra desde la l nea 30 en adelante de le. user@hostname:~$ tail -1 3 370 user@hostname:~$ 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 neas 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 user@hostname:~$ awk {print } 1 190 2 280 3 370 user@hostname:~$ Funciona como el comando cat user@hostname:~$ awk {print $2, $1 } 190 1 280 2 370 3 user@hostname:~$ Imprime esas dos columnas en orden inverso. user@hostname:~$ awk {print a, 8*$1, $2-1 } a 8 189 a 16 279 a 24 369 user@hostname:~$ mylist.txt mylist.txt mylist.txt

22

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

Permite operar sobre las columnas. user@hostname:~$ awk { if (NR>1 && NR < 3) print} mylist.txt 2 280 user@hostname:~$ Slo imprime la l o nea 2. user@hostname:~$ awk {print $NF} archivo.txt Imprime en pantalla la ultima columna de cada la del archivo archivo.txt. user@hostname:~$ awk {print NF} archivo.txt Imprime en pantalla el nmero respectivo a la ultima columna de cada la, que equivalenteu mente es la cantidad de columnas por la en el archivo archivo.txt. 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 aadir al nal n u (Update) aadir aquellos archivos que no se hallen en el tarle o que hayan sido n modicados 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 especicar el archivo para el tarle.
gnu es un acrnimo recursivo, signica: gnus 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.

23

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 tamao en bloques de cada archivo n aadido 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 tarle simul.tar. tar xvf simul.tar Extrae todos los archivos contenidos en el tarle simul.tar.

24

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

wc (Word Count) Contabiliza el nmero de l u neas, palabras y caracteres de un archivo. user@hostname:~$ wc 3 6 user@hostname:~$ mylist.txt 18 mylist.txt

El archivo tiene 3 l neas, 6 palabras, considerando cada nmero como una palabra i.e. 1 es la u primera palabra y 190 la segunda, y nalmente 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 Verica 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 user@hostname, 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 ao presenta el calendario del o n ao completo. n date Muestra el d y la hora actual. a

1.5.11.

Diferencias entre sistemas.

Cuando se transeren 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. do
22

1.6. SHELLS.

25

El cambio de l nea 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 unix visto desde windows parece una unica l nea. El caso inverso es la aparicin del o caracter ^M al nal de cada l nea. Adems, el n 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 neas 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 conguracin es o .cshrc (en el directorio $HOME). ksh : Korn-SHell, shell diseada 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 nea de comando. El archivo de conguracin 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 conguracin o es .bash_profile cuando se entra a la cuenta por primera vez, y despus el archivo de e conguracin es .bashrc siempre en el directorio $HOME. La l o nea 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 conguracin se encuentran las deniciones de las variables de entorno o (enviroment variables) como camino de bsqueda PATH, los aliases y otras conguraciones u personales. Veamos unos caracteres con especial signicado para el Shell:
23

Por omisin se asigna bash. o

26

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. 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. user@hostname:~$ echo pwd /home/user user@hostname:~$ 25 preserva el signicado literal de cada uno de los caracteres de la cadena que delimita. user@hostname:~$ echo Estoy en pwd Estoy en pwd user@hostname:~$ 26 preserva el signicado literal de todos los caracteres de la cadena que delimita, salvo $, , \. user@hostname:~$ echo "Estoy en pwd" Estoy en /home/user user@hostname:~$ ; permite la ejecucin de ms de una orden en una sola l o a nea de comando. user@hostname:~$ mkdir textos; cd textos; cp ../*.txt . ; cd .. user@hostname:~$

1.6.1.

Variables de entorno.

Las variables de entorno permiten la conguracin, por defecto, de muchos programas o cuando ellos buscan datos o preferencias. Se encuentran denidas en los archivos de conguracin anteriormente mencionados. Para referenciar a las variables se debe poner el s o mbolo $ delante, por ejemplo, para mostrar el camino al directorio por defecto del usuario user: user@hostname:~$ echo $HOME /home/user user@hostname:~$ 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

1.6. SHELLS. EDITOR - El editor por defecto del usuario.

27

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 a 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 ujo 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 mbolos mencionados existen otros que permiten acciones tales como: >> Aadir el stdout al nal 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.

28

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

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 especicado 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 especicados 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 denidos e y tambin denir nuevos. Es corriente denir el alias rm =rm -i, de esta forma la orden e siempre pide conrmacin para borrar un archivo. Si alguna vez quieres usar rm sin alias, slo o o hace falta poner delante el s mbolo \, denominado backslash . Por ejemplo \rm elimina los alias aplicados a rm. Otro ejemplo, bastante frecuente podr ser (debido a la complejidad de la a 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 nea de comandos, y el acceso a la historia de rdenes (readline). En uso normal (historia y editor o de l nea de comandos) bash es compatible con otras shells como tcsh y ksh, ver apndice. e En bash el modo de completado (le 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

1.6. SHELLS.

29

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 chero file en el shell actual. o umask value

30

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

Asigna la mscara para los permisos por omisin. a o Los comandos umask , source , history , unalias y hash shell tcsh.

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 nea declara la shell espec ca que se quiere usar. En la segunda l nea 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 nea 5 hace uso de la variable interna dentro de un comando. La ultima l nea, 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 nea fuerza a que se ejecute esa shell. Esto slo es una m o nima 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 , pueden disearse 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 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 a 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. a a
29

1.8. PROCESOS.

31

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 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 a termine. Un ejemplo de este caso ser la impresin de un archivo. a 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 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 denitiva 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 seal31 a un proceso unix. En particular, para a n enviar la seal de trmino a un programa, damos el comando kill -KILL, pero no n e hace falta al ser la seal por defecto. n
30 31

Por omisin un comando se ejecuta siempre en el foreground. o Para ver las seales disponibles entra la orden kill -l (l por list). n

32

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

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.

1.9.

Editores.

Un editor es un programa que permite crear y/o modicar 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 congurable 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 nea, comando C-H t dentro del editor. El archivo de conguracin persoo nalizada es: $HOME/.emacs. jove - Basado en Emacs, (Jonathans Own Version of Emacs). Posee tutorial en una utilidad asociada: teachjove. El archivo de conguracin personalizada es: $HOME/.joverc. o jed - Editor congurable escrito en S-Lang. Permite la emulacin de editores como o emacs y Wordstar. Posee una ayuda en l nea C-H C-H. El archivo de conguracin o personalizada es: $HOME/.jedrc. gedit - Un pequeo 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 conguracin 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 cil 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

1.9. EDITORES. ~ ~ ~ /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

33

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 nea que sigue a la l nea 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 neas enteras, entonces se debe presionar dos veces la tecla d sobre la l nea 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 modicar 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 echas hacia la izquierda, derecha, abajo o arriba. Con la tecla 0 nos movemos al comienzo de la l nea y con la tecla $ nos movemos al nal de la misma.

34

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

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 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 signicativas 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 a 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

1.10. EL SISTEMA X WINDOWS.

35

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 mite (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, tamao,. . . ) del resto de clientes. Existen varios, destacando: n icewm : Ice Window Manager, uno de los window managers gnome compatible. sawsh : Window managers gnome compatible, altamente congurable y muy integrado al gnome desktop. Metacity : Window managers gnome 2 compatible. El look and feel (o GUI) de X Windows es extremadamente congurable, 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 congurar 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 denir do los programas que aparecen al inicio de tu sesin. o .fvwmrc archivo de conguracin del fvwm. Ver las pginas del manual de fvwm. o a .olwmrc archivo de conguracin del olwm. Ver las pginas del manual de olwm. o a .Xdefaults Conguracin general de las aplicaciones de X Windows. Aqu puedes o denir 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): user@hostname1:~$ ssh -XC userB@hostname2 userB@hostname2s password: userB@hostname2:~$ gnome-terminal & Las opciones XC en el comando ssh corresponden a que exporte el DISPLAY y que comprima, respectivamente. La forma antigua

36

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

userA@hostname1:~$ xhost +hostname2 hostname2 being added to access control list user@hostname1:~$ ssh userB@hostname2 userB@hostname2s password: userB@hostname2:~$ export DISPLAY=hostname1:0 userB@hostname2:~$ gnome-terminal & Si todo est previamente congurado, es posible que no haga falta dar el password. a Cuando quieres salir, normalmente puedes encontrar un cono 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 a 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 conguracin 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

1.12. INTERNET.

37

hostname: es el nombre que tiene asociada la mquina (p.e. macul). A este nombre se a le suelen aadir una serie de sujos 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 identicacin entre un hostname y el IP-number correspondiente. La consulta o se realiza inicialmente en el archivo /etc/hosts, donde normalmente se guardan las identicaciones 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 identicacin 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 denir 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 especicar el puerto en conexin en la mquina a o a remota. ssh nombre@unix2, muy similar a telnet pero se puede especicar el usuario, si no se especica se usa el nombre de la cuenta local. Adems, el passwd pasa encriptado a a travs de la red. ssh nombre@unix2 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 usuario2@unix2: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 especica 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 usuario3@unix2:file2 .. Antes a: 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 usuario1@unix2, 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, (le 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

38

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX. bin: Establece el modo de comunicacin binario. Es decir, transere 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 conrmacin para transferencia mltiple de archivos. o u get rfile [lfile]: transere 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] : transere 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 grcas 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 especicar 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 o 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): user@domain

1.12. INTERNET. user : es la identicacin del usuario (i.e. login) en la mquina remota. o a

39

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 co de mquina en forma oculta para el que env a a. 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 tulo para el mensaje. Cc (Carbon Copy) : Permite el env de copias del mensaje que est siendo editado a o a terceras personas. Reply : Cuando se env un mensaje en respuesta a otro se suele aadir el comienzo a 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 modicaciones o sin ellas) a una tercera persona. Notando que Forward env tambin los archivos adjuntos, mientras a 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 a mismo. In-Box : Es el archivo donde se almacena el correo que todav no ha sido le por el a do 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 indenido y a no recibir nunca correo.
34

40 Aplicacin mail. o

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

Es posiblemente la aplicacin ms simple. Para la lectura de mail teclear simplemente: o a mail y a continuacin aparece un o ndice con los diferentes mensajes recibidos. Cada mensaje tiene una l nea de identicacin 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 nea 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 algunas que no permiten la entrada a usuarios que no se identican 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 activaa 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 modicador: 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 em plear el comando /usr/sbin/lpc status. La lista de impresoras y su conguracin 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

1.14. COMPRESION.

41

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 grca 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 a 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 tamao, 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 compress file : comprime el archivo, creando el archivo file.Z. Destruye el archivo original. 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). 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

42

CAP ITULO 1. ELEMENTOS DEL SISTEMA OPERATIVO UNIX.

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 tamao 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 Compresor Tamao n Sin comprimir 230 Mb compress 91 Mb gzip 51 Mb bzip2 40 Mb 7z 33 Mb Cuadro 1.1: Tabla de compresin del archivo linux-2.6.18.tar que contiene el kernel 2.6.18 o de Linux. 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

Cap tulo 2 Introduccin a programacin. o o


versin 1.0, 30 de Agosto del 2007 o

En este cap tulo 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 nea de cdigo, o tan o largo como varios millones de l neas 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 a 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: a o 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 reemplazar los 1 y 0 por una secuencia de abreviaturas de 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 y sentencias con palabras y expresiones algebraicas. Estos lenguajes fueron desarrollados en las dcadas del 50 y 60. Son lenguajes que estn ms cerca del e a a programador que de la mquina, por lo tanto, necesitan una etapa de traducin para que los a o entienda la mquina. Este proceso se puede hacer de dos maneras: traduciendo el programa a fuente todo de una vez, lo que llamaremos lenguaje compilando; o traduciendo el programa fuente l nea por l nea, lo que llamaremos lenguaje interpretando. 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 nal 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 nea por l nea, a medida que va ejecutando el programa original. Un programa interpretado suele ser ms pequeo 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 diseados para realizar tareas espec n cas. 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, Eiel, 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: Espaol, 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 reriendo 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 a 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 mica 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 mica: CH4 +2O2 2H2 O+CO2 ; o, nalmente, 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 mbolos) 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 a 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 signica, en particular, que el programa debe tener documentacin, ya que un programa sin documentacin es muy dif de usar. Pero o o cil 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 soan sticadas ventanas grcas. 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 signica. 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 nalice. a a Cada vez que se le pide algo al usuario deber estar claras las siguientes preguntas: an 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 pequeos? 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 a que sea claras son los siguientes: Parta con un t tulo 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 quele al usuario que el programa termin. o Una versin mejorada del programa anterior podr ser la siguiente: o a 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 tulo 3 Una breve introduccin a Python. o


versin 2.2, 18 de Enero del 2008 o

En este cap tulo 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 nimas 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 nimo.

3.1.

Python.

El Lenguaje Python fue inventado alrededor de 1990 por el cient co 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 ocial 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: username@host:~$ 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 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 identicarlo 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 jrogan@manque:~/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 tamao jo, 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 otante: Los nmeros, que pertenecen al conjunto R, es decir, u u con decimales (un nmero nito de ellos). u Enteros largos: Nmeros enteros mayores que 2 1012 . Los distinguimos por una L u al nal del nmero, por ejemplo: 23434235234L. u Varios de los otros tipos sern explicados ms adelante en el cap a a tulo Tipo bool int long int oat complex str tuple list dict le Descripcin o booleano entero entero largos nmero con punto otante 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 le(stu.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 sujo 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 signicado 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 nea nueva.

3.2.2.

Imprimiendo en la misma l nea.

Agregando una coma (,) al nal de una instruccin print har que el prximo comando o a o print aparezca en la misma l nea. Ejemplo print num1,"+", num2, "=", print respuesta

3.2.3.

Imprimiendo un texto de varias l neas.

Si queremos imprimir un texto que tenga varias l neas 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 signiquen 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 231=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 citamente 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 nal de la l nea, 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 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 neas 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 el programa no contina ejecutndose. e u a 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 nea termina con : requerido por la sintaxis del if. En las l neas siguientes statements, viene las instrucciones a seguir si la condicin es cierta. Estas instrucciones o deben ir con sangr (indent). a 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 la e o a condicin evaluada en el if sea falsa. Use esta construccin cuando tenga dos conjuntos o o diferentes 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 dene 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 neas 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 mbolo . 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 a no tener argumentos, pero an as deben ir los parntesis, son obligatorios. Los nmeros 8,9 u 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 otante. 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 otante 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) Justica a la derecha el string en un campo de un ancho dado por width. ljust(string, width) Justica 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 ao year. n prmoth(year, month) Imprime un calendario para el mes month del ao year. n

61

3.5.

Funciones hechas en casa.

Una funcin dene 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 denir 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 deni. A continuacin veamos e o o o la denicin 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 nal de la l nea que dene una funcin. El bloque de o commandos asociados a la funcin deben tener sangr para identicarlos como parte de la o a 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 denicin 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 denidas las funcines ellas o o se ejecutarn cuando sean llamadas. Cuando enviamos valores a nuestras funciones se crean a las variables nombradas en la denicin. Por ejemplo: o def mi_function(nombre1, nombre2): print nombre1+nombre2 Los nombres de las variables de una funcin slo sern vlidos dentro de la misma funcin, o o a a o esto es lo que se conoce como variables locales). Todas las funciones usan por defecto variables locales.

62

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

3.5.2.

Variables globales.

Si desea asignar una variable denida 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 denidas 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 denicin de variables. Usando la sentencia global queda claro que la variable se dene 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-denidos. Puedes especicar los valores a por defecto despus del nombre del parmetro en la denicin de la funcin con el operador e a o o de asignacin (=) seguido por el argumento a denir. o

3.5. FUNCIONES HECHAS EN CASA. #!/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.5.5.

Argumentos claves.

Si se tiene funciones con muchos parmetros y se quiere especicar 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.5.6.

Documentacin de una funcin, docstrings. o o

Python tiene una caracter stica 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.5.7.

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.5. FUNCIONES HECHAS EN CASA.

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. a o

3.5.8.

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.5.9.

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) En este caso la funcin nunca para, este tipo de recursin es llamada recursin innita. o o o Para prevenir este situacin creamos un caso base. El caso base es la condicin que causar que o o a la funcin pare de llamarse a si misma. Un ejemplo o def count(x): if x<100: x=x+1 print x count(x) else: return time.sleep(1) En un ejemplo, ms adelante, veremos un programa que calcula el factorial de un nmero a u en forma recursiva.

66

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

3.6.

Iteraciones con while.

La palabra reservada while puede ser usada para crear una iteracin. La instruccin o o while necesita una condicin que es cierta y luego deja de serlo, por ejemplo un contador o que se incrementa y supera un valor l mite. Ejemplo while x < 10: print x x = x+1 Para hacer una seccin de cdigo reusable, en vez de usar valores constantes 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.7.

Los strings.

Los strings son hechos de pequeas 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]

3.7. LOS STRINGS. Para tomar desde el comienzo a un punto dado en el string. parte = palabra[:4] Para tomar desde un punto dado al nal del string. parte = palabra[3:]

67

3.7.1.

Indice negativos.

Veamos que pasa cuando usamos ndices 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.7.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.7.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

68

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

3.7.4.

Comparando strings.

Los strings pueden ser usados en comparaciones. Ejemplo if palabra < "cebu": print palabra De acuerdo a Python, todas las letras minsculas. son mayores que las letras maysculas u u a>Z. As . 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.8.

El ciclo for.

Una manera ms compacta de escribir el ciclo while donde se recorrio un strings es a usando un ciclo for, veamos cmo queda el cdigo o o palabra = "computador" for letra in palabra: print letra Notemos que hemos creado la variable letra cuando iniciamos 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" aeou 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 nea de este programa que nos permite ingresar e imprimir strings con caracteres acentuados y caracteres especiales.

3.9. LISTAS.

69

3.8.1.

El comando break.

El comando break es capaz de salirse de un ciclo for o while. Un ejemplo que recorre los nmeros calculando su cuadrado mientras sea menor que 50: u for n in range(1,10): c=d*d if c > 50: print n, "al cuadrado es ",c," > 50" print "PARO" break else: print n,"su cuadrado es ",c

3.8.2.

El comando else.

Un ciclo puede tener una seccin else, esta es ejecutada cuando el ciclo termina por o haber agotado la lista, en un ciclo for o cuando la comparacin llega a ser falsa en un ciclo o while, pero no cuando el ciclo es ternimado con break. A continuacin, un programa que o muestra este hecho y sirve para 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"

3.9.

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 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.9.1.

Rebanando listas.

Una lista puede ser accesada al igual que un string usando el operador [ ]. Ejemplo

70

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

>>> 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 ndices. Ejemplo >>> lista_palabras = ["perro", ["fluffy", "mancha", "toto"], "gato"] >>> print lista_palabras[1][2] toto

3.9.2.

Mutabilidad.

A diferencia de los strings las listas son mutables, lo que signica 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]

Esta NO es un instruccion VALIDA call last): 1, in ? not support item assignment

3.9.3.

Modicando listas.

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 [Matias, Andres, Jaime, Juan] >>> lista[1:2]=["perro","gato"] >>> print lista [Matias, perro, gato, Jaime, Juan]

3.9.4.

Agregando a una lista.

Para agregar items al nal de una lista use list.append(item). Ejemplo

3.9. LISTAS. >>> lista=["Pedro", "Andres", "Jaime", "Juan"] >>> lista.append("Matias") >>> print lista [Pedro, Andres, Jaime, Juan, Matias]

71

3.9.5.

Borrando items de una lista.

Use el comando del para remover items basado en el ndice 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 ndice 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.9.6.

Operaciones con listas.

Las listas se pueden sumar resultando una sola lista que incluya ambas listas iniciales. Adems, podemos multiplicar una lista por un entero n obteniendo una nueva lista con n a rplicas de la lista inicial. Veamos ejemplos de ambas operaciones en forma interactiva e >>> 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.9.7.

Qu contiene una lista? e

Con la palabra reservada in podemos preguntar si un item est en la lista, veamos un a ejemplo lista = ["rojo", "naranjo", "verde", "azul"] if "rojo" in lista: haga_algo()

72

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

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.9.8.

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 = ["oto@mail.com", "ana@mail.com"] for item in email: envie_mail(item)

3.9.9.

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.9.10.

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 nal y el paso, para generar una lista de enteros que comienu za en el nmero de partida, termina con un nmero menor que el nal saltandose el paso u u sealado, 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.10.

Tuplas.

Una tupla es una lista inmutable. Una tupla no puede modicarse de ningn modo despus u e de su creacin. o

3.11. PARAMETROS DESDE LA L INEA DE COMANDO. >>> t = ("a", "b", 8) >>> t[0] a

73

Una tupla se dene 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 denido, como los de la lista. Las tuplas tienen primer ndice 0, como las listas, de modo que el primer elemento de una tupla t, no vac es siempre t[0]. Los a ndices negativos cuentan desde el nal 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 aadirse 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 elemento existe en la tupla. Las tuplas son ms rpidas que las listas. Si est deniendo 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.11.

Parmetros desde la l a nea de comando.

Python puede recibir parmetros directamente de la l a nea 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 nea de comando jrogan@huelen:~$ ./main.py h -l --mas xvzf La salida ser a ./main.py h -l --mas xvzf ./main.py

74

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON. Otro ejemplo, un programa que suma dos nmeros desde la l u nea 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 nea de comando jrogan@huelen:~$ ./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.12.
3.12.1.

Ejemplos de funciones: ra cuadrada y factorial. z


Ra cuadrada. z

Con lo visto hasta ahora, ya podemos escribir un programa que calcule la ra cuadrada de z una funcin. Para escribir una funcin, debemos tener claro qu se espera de ella: cuntos son o o e a los argumentos que recibir, si tendr valor de retorno, y, por cierto, un nombre adecuado. a a Para la ra cuadrada, es claro que el argumento es un nmero. Pero ese nmero podr ser un z u u a entero o un real, evidentemente esperamos que el valor de retorno de la funcin sea tambin o e un nmero. Llamando a la funcin raiz, tenemos la declaracin: u o o def raiz(x): Debido a la naturaleza de la funcin ra cuadrada, raiz() no tendr sentido, y por tanto o z a no corresponde declararla con un valor default. Ahora debemos pensar en cmo calcular la ra cuadrada. Usando una variante del mtodo o z 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 aproximaz 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 pequeo: o u n 2 | xN a | < 1. El valor de determinar la precisin de nuestro clculo. Un ejemplo de a o a cdigo lo encontramos a continuacin: o o

3.12. EJEMPLOS DE FUNCIONES: RA CUADRADA Y FACTORIAL. IZ #!/usr/bin/python # # Programa que calcula la raiz cuadrada import math def raiz(a): x =a/2.0 # para comenzar dx, epsilon = 1e3, 1e-8; while (math.fabs(dx)>epsilon): x = (x + a/x)/2; dx = x*x - a; print "x = ", x, ", precision = ", dx return x # main r=input("Ingrese un numero: ") print raiz(r)

75

Primero est la funcin raiz, y luego el main. En el main se pide al usuario que ingrese a o un nmero, el cual se aloja en la variable r, y se muestra en pantalla el valor de su ra u z cuadrada. 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 nal del ciclo, x contendr el a z. a valor (aproximado) de la ra cuadrada. dx contiene la diferencia entre el cuadrado de x y el z valor de a, epsilon es el nmero (pequeo) 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 sucientemente pequeo. El valor absoluto del real dx se obtiene con la n funcin matemtica fabs, disponible en el mdulo math incluido al comienzo del programa. o a o 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 a la aproximacin actual y la precisin alcanzada (dada por dx). Eventualmente, cuando la o o aproximacin es sucientemente buena, se sale del ciclo y la funcin devuelve al main el valor o o de x actual, que es la ultima aproximacin calculada. o

3.12.2.

Factorial.

Otro ejemplo util es el clculo del factorial, denido para nmeros naturales: a u n! = n (n 1) 2 1 , 0! 1 .

Una estrategia es utilizar un ciclo for, determinado por una variable entera i, que va

76

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

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 #!/usr/bin/python # # Programa que calcula el factorial def factorial(i): f = 1 for j in range(2,i+1): f = f*j return f # main n=input("Ingrese un numero: ") print "El factorial de ", n, " es: ", factorial(n) 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. a Esta funcion responde correctamente en el caso n = 0, pero retorna el valor 1 para todos los enteros negativos. Otra estrategia para calcular el factorial es hacer uso de su propiedad recursiva n! = n (n 1)! 1! = 0! 1 Un programa que calcula el factorial en forma recursiva #!/usr/bin/env python def fact(n): if n<2: return 1 else: return n*fact(n-1) #main i=input("Ingrese un natural :") print "El factorial de",i," es ",fact(i)

3.13.

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 nsecas de Python.

3.13. TRABAJANDO CON ARCHIVOS.

77

3.13.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. makedirs(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 o. 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.13.2.

Funciones del mdulo os.path. o

Funciones que verican. 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.

78

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

3.13.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.13.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 nal 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.13.5.

Leyendo un archivo.

entrada.read() Lee el archivo completo como un string. entrada.readline() Lee una l nea en un string. entrada.readlines() Lee el archivo completo, cada l nea llega a ser un item tipo string en una lista.

3.13.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 nea a menos que un elemento contenga una caracter de newline

3.13. TRABAJANDO CON ARCHIVOS.

79

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 resultados.txt print >> salida # Imprime una linea en blanco en el archivo resultados.txt salida.close()

3.13.7.

Cerrando un archivo.

file.close() Cierra un archivo previamente abierto.

3.13.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.13.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)

80 newfile.close()

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

# 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)

3.14.

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.15.

Diccionarios.

Las listas son colecciones de items (strings, nmeros o incluso otras listas). Cada item en u la lista tiene un ndice 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 ndice de posicin. Si uno remueve o un item desde la lista, el ndice 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 ndice uno crea los ndices. lista = ["primero", "segundo", "tercero"] diccionario = {0:"primero", 1:"segundo", 2:"tercero"}

3.15. DICCIONARIOS.

81

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 espaol pero no del espaol al japons. e n n e

3.15.1.

Editando un diccionario.

Para cambiar un valor de un par, simplemente reas gnelo 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 sustituciones (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

82

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

3.15.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.15.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.16.

Modules y Shelve.

Algunos problemas que se presentan a medida que los cdigos crecen son: con cientos o de l neas es muy fcil perderse; trabaja en equipo se hace dif con cdigos muy grandes. a cil o Entonces, ser bueno poder separar el cdigo en pequeos archivos independientes. Por otra a o n parte, se nos presenta otra dicultad, 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 a como diccionarios y as luego poder leerlos e incorporarlos a nuestro cdigo en forma fcil. o a

3.16.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.16.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

3.16. MODULES Y SHELVE.

83

la denicin 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.16.3.

Agregando un nuevo directorio al path.

Cuando Python busca mdulos slo lo hace en ciertos directorios. La mayor de los o o a 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.16.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 nal triple comilla. El texto en triple comilla deber explicar lo que a la funcin, clase o mdulo hace. Estas l o o neas de documentacin las podr ver, en el modo o e interactivo, si da el comando help(module.mi_funcion).

3.16.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)

84 una segunda forma

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

# 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.16.6.

Trucos con mdulos. o

Un mdulo puede ser corrido como programa independiente si inclu o mos las siguientes l neas en el nal if __name__ == __main__: funcion_a_correr() Sustituya funcion_a_correr() por el nombre de la funcin principal en el mdulo. o o

3.16.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.16.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.

3.17. CLASES Y METODOS.

85

3.16.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.16.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.17.

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 nea 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 deniciones de las funciones, a. 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):

86 print v1+v2 fred = MiClase() fred.hola() fred.math(2,4)

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

Creamos una instancia de una clase al asignarla a una variable, fred = MiClase(). Para aplicar una funcin o mtodo a una nueva instancia debemos especicar 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.17.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 prejo 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()

3.18. SOBRECARGA DE OPERADORES.

87

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 o propio promedio.

3.17.2.

Valores por defecto.

Una funcin puede tener valores por defecto, estos valores son usados slo cuando la o o funcin es llamada sin especicar 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.18.

Sobrecarga de Operadores.

Las clases pueden redenir comandos regulares de Python. Cambiar como los comandos regulares trabajan en una clase se llama sobrecarga de operadores. Para denir la sobrecarga, debemos usar nombres especiales cuando denimos los mtodos. Las deniciones 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

88

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

Notemos que tenemos un mtodo nuevo, el destructor que es la funcin que se invoca e o cuando un objeto 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.18.1.

Funcin driver. o

Una funcin driver es puesta al nal 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.18.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 dea niciones de las funciones de la clase. La data ser accesada dentro de las denicin 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.

3.19. ALGUNOS MODULOS INTERESANTES.

89

3.18.3.

Ejemplo de clase vectores.

Escribamos 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.19.

Algunos mdulos interesantes. o

Hay muchos mdulos que le pueden ser utiles, aqu le sugerimos unos pocos particularo mente importantes.

3.19.1.

El mdulo Numeric. o

Extensin numrica de Python que agrega poderosos arreglos multidimensionales. o e

90

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

>>> 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)

3.20.

El mdulo Tkinter o

Este paquete es el encargado de ayudarnos a desarrollar la interfaz grca con el usuario a de nuestro programa. Para comenzar a utilizarlo veamos el siguiente ejemplo: Ejemplo from Tkinter import * vent=Tk() etiqueta=Label(vent, text="Hola Mundo!!") etiqueta.grid(row=1, column=1) vent.mainloop() En la primera linea importamos el mdulo Tkinter, en la segunda creamos la ventana, la o que es proporcionada por el window manager, en la tercera linea generamos una etiqueta, y que en particular para este ejemplo ocupamos la opcin de texto text, en la cuarta linea o ubicamos la etiqueta en la la 1 y la columna 1 de la ventana (como no hay mas elementos en el ejemplo, la ventana se distribuye como una matriz de 1 1) y en la ultima linea se dice al computador que ejecute la orden (e.d. la ventana no aparecer antes de leer esta linea), a por lo que toda accin escrita despus de esta linea no aparecer en la ventana. o e a Al ejecutar el programa

3.20.1.

Elementos importantes en una ventana.

La forma de congurar un elemento en la ventana es de la forma:

3.20. EL MODULO TKINTER Funcion(master, opcion1=valor1, opcion2=valor2, ...)

91

Donde cada elemento esta determinado por una Funcion, la variable master es la que determina a la ventana particular (como en el ejemplo anterior lo era vent), y todas las opciones siguientes tienen un valor por defecto que podemos cambiar solo enuncindolas y a dandole el nuevo valor. Algunos de los elementos que podemos agregar son: 1. Etiquetas Se enuncian llamando a la funcin Label(...), cuyas opciones son: o text : El texto que llevar escrito la etiqueta. (p.e. text=Hola!) a image : Si quiero agregar una imagen. (p.e. image=imagen1 ) fg : El color del texto, si es que la etiqueta esta conformada por texto (p.e. fg=red) bg : El color del fondo de la etiqueta (p.e. bg=black) width : Nos dice el largo de la etiqueta en la ventana (p.e. width=100) 2. Botones Se enuncian llamando a la funcin Button(...), tiene las mismas opciones que la o etiqueta y adems se le agragan las siguientes: a command : Aqui ponemos el nombre de la funcin que se ejecuta cuando se clickea el o boton. relief : Es el relieve que tendra el boton, esta variable puede tomar los valores FLAT, RAISED, SUNKEN, GROOVE y RIDGE, el valor por defecto es RAISED, esttie camente se ven:

cursor : Es el nombre del cursor que aparece cuando pasamos el mouse sobre el boton, algunos de los valores que puede tomar esta opcin son: arrow, mouse, pencil, o question arrow, circle, dot, star, fleur, hand1, heart, xterm, etc. bitmap : Los bitmaps son imgenes prehechas que vienen incorporadas en Tkinter, a algunos de los valores que puede tomar sta variable son: error, hourglass, e info, questhead, question, warning, etc, estticamente se ven: e

3. Input Es equivalente a la opcin raw input, y se enuncia llamando a la funcin Entry(...), o o tiene disponibles las opciones witdh, bg, fg, cursor, entre otros. Se ve de la forma:
1

Donde la variable imagen est determinada por la funcin imagen=PhotoImage(file=archivo.gif) a o

92

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

4. Boton de Checkeo Se llama con la funcin Checkbutton(...) y tiene las mismas opciones que Button(), o se ve as :

5. Men u Para crear un men debemos generar una variable similar al master que determinaba u la ventana, pero esta vez para determinar al men, la forma de hacer esto es con la u funcin Menu(...), cuyo argumento debe ser la variable que representa a la ventana. o Luego, con esta variable puedo crear un men, veamos el siguiente ejemplo: u

vent=Tk() . . . men=Menu(vent) archivo=Menu(men, tearoff=0) men.add_cascade(label="Archivo", men=archivo) archivo.add_command(label="Abrir", command=A) archivo.add_command(label="Nuevo", command=B) archivo.add_command(label="Salir", command=C) editar=Menu(men, tearoff=0) men.add_cascade(label="Editar", men=editar) editar.add_command(label="Copiar", command=D) editar.add_command(label="Cortar", command=E) vent.config(menu=men) . . . vent.mainloop() El cdigo anterior generar un men llamado Archivo, que contiene las opciones Abrir o a u (cuya funcion es A()), Nuevo (cuya funcin es B()) y Salir (con funcin C()), y otro o o men llamado Editar, de similares caracter u sticas.

3.20. EL MODULO TKINTER

93

3.20.2.

Ubicacin de un elemento en la ventana. o

Para ubicar en la ventana los distintos elementos existe la funcin grid(... ) cuyos o argumentos son desde que la (row) hasta que la (rowspan) y desde que columna (column) hasta que columna (columnspan) se encuentra el lugar que determinar para el elemento e particular, es importante saber que las las se enumeran de arriba hacia abajo y las columnas de izquierda a derecha. Para ejecutar grid() correctamente debemos escribirla seguida de un punto despues de la variable que tiene asignada el elemento, por ejemplo: vent=Tk() . . . A=Label(vent, text="hola") B=Button(vent, text="aceptar", command=F) A.grid(row=1, rowspan=2, column=1, columnspan=3) B.grid(row=3, column=1) . . . vent.mainloop() El cdigo anterior pondr el texto hola desde la primera la hasta la segunda y desde o a la primera columna hasta la tercera, y debajo, en la la 3 y la columna 1 pondr un botn a o que dice aceptar y ejecuta la funcin F. o

3.20.3.

Atributos del master.

El master como ya lo hemos visto, es la variable que est determinada por la funcin a o Tk(), y la forma de darle distintos atributos es: master.atributo(valor) o master.atributo(opcion1=valor1,...)

Algunos de los atributos que le puedes asignar a una ventana son. T tulo : La forma de ponerle el t tulo a la ventana es dando la orden: master.title("texto en el titulo de mi ventana") Geometr : Se reere a las dimensiones de la ventana (la unidad que se ocupa es 0,023 a cm), se debe dar la orden: master.geometry("nxm"), donde n=ancho y m=alto. Conguracin : Aqu ponemos algunas de las caracter o sticas generales de la ventana, como por ejemplo, el color de fondo, el cursor que aparece cuando el mouse pasa sobre ella, etc. Se debe dar la orden: master.configure(cursor="nombre cursor", background= "color")

94

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

3.20.4.

Un ejemplo ms elaborado. a

Veamos un ejemplo usando los elementos explicados.

#IMPORTO EL PAQUETE from Tkinter import * #DEFINO UNA FUNCION def salir(): vent.destroy() #DEFINO EL MASTER vent=Tk() #ATRIBUTOS DEL MASTER vent.title("Ejemplo") vent.geometry("350x120") vent.configure(cursor="spider") #GUARDO UNA IMAGEN EN LA VARIABLE dibujo1 dibujo1 = PhotoImage(file="tux.gif") #DEFINO LOS ELEMENTOS DE LA VENTANA Dibujo1 = Label(vent, image=dibujo1, bg="white") Nombre = Label(vent, text="Nombre", fg="white", bg="red") nombre = Entry(vent, width=20, bg="white") Apellido = Label(vent, text="Apellido", fg="white", bg="red") apellido = Entry(vent, width=20, bg="white") boton = Button(vent,width=30, text="Salir", cursor="hand1", \ fg="white", bg="black", command=salir) #UBICO LOS ELEMENTO EN LA VENTANA Dibujo1 .grid(row=1, rowspan=3, column=1) Nombre .grid(row=1, column=2) nombre .grid(row=1, column=3) Apellido.grid(row=2, column=2) apellido.grid(row=2, column=3) boton .grid(row=3, column=2, columnspan=3) #EJECUTO EL CODIGO vent.mainloop()

Al ejecutar el programa el resultado es:

3.20. EL MODULO TKINTER

95

3.20.5.

El mdulo Visual. o

Un mdulo que permite crear y manipular objetos 3D en un espacio 3D. o

96

CAP ITULO 3. UNA BREVE INTRODUCCION A PYTHON.

Cap tulo 4 Una breve introduccin a C++. o


versin 7.60, 13 de Noviembre del 2007 o

En este cap tulo se intentar dar los elementos bsicos del lenguaje de programacin a a o C++. No se pretende ms que satisfacer las m a nimas 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 nimo.

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 neas 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 nea 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 picamente /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 amos incluir un path completo cuando se ocupan las comillas. En nuestro ejemplo se incluye el archivo iostream, en el cual se hacen las deniciones adecuadas para el manejo de la entrada y salida en C++. Este archivo es necesario para enviar luego un mensaje a pantalla. 97

98

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 os 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 neas termina con el carcter ;. El identicador predenido 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 nea 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 predenido en el archivo iostream que corresponde a un cambio de l nea, el cual ser agregado al nal del mensaje. La l a nea nal 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 jrogan@pucon:~/tmp$ xemacs primero.cc jrogan@pucon:~/tmp$ g++ -Wall -o primero primero.cc jrogan@pucon:~/tmp$ ./primero Hola. jrogan@pucon:~/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 nea como PATH="${PATH}:." y ejecutar en la l nea de comando source ~/.bashrc para que los cambios tengan efecto.)

4.1.2.

Denicin 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 plica su modicacin y la localizacin de errores. Nos encontraremos frecuentemente con o o este concepto. Aprovecharemos de introducir las funciones modicando 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; }

99

La funcin debe estar denida 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 os 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 citamente el cdigo o que corresponde a la funcin. Hab o amos dicho que una funcin debe estar denida 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.

100

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 mbolo _ (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 stica 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 nea: 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++.

101

o declarar ms de una variable del mismo tipo simultneamente, e inicializar algunas en la a a misma l nea: int r1, r2, r3 = 10; A veces se requiere que una variable no var una vez que se le asigna un valor. Por ejemplo, e podr amos necesitar denir el valor de = 3.14159..., y naturalmente no nos gustar que, a 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 modicador 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 103 . 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 1038 |x| 3.40282347 1038 , (Precisin de 7 d o gitos decimales.) double Reales x tal que 2.2250738585072014 10308 |x| 1.7976931348623157 10308 , (Precisin de 15 d o gitos decimales.) long double Reales x tal que 3.36210314311209350626 104932 |x| 1.18973149535723176502 104932 , (Precisin de 18 d o gitos 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

102

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 mbolos 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 nea: 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 dene 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++.

103

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 mbolos 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 cito, 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 nimo), 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 a 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

104

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 prejos o sujos sobre una variable y su accin diere en ambos casos. o Como prejo 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 sujo 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 amos 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 cita.

105

Si i es un int, por ejemplo, entonces float(i) la convierte en float. As el programa , 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 cita. En este caso, el compilador realiza las conversiones de modo automtico, preriendo 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 , cdigo anterior habr funcionado en su forma original. Evidentemente esto es muy o a cmodo, porque no necesitamos hacer una conversin expl o o cita 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 nalmente la operacin se o o puede llevar a cabo. Entender este proceso nos permitir aprovechar las posibilidades a de la conversin impl o cita 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 citas 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 a 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

106

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 a e a que ser conveniente adoptar como standard cuando queremos utilizar enteros dena tro de expresiones reales, para evitar errores que pueden llegar a ser muy dif ciles de detectar.

4.2.
4.2.1.

Control de ujo.
if, if... else, if... else if.

Las construcciones siguientes permiten controlar el ujo 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 neas 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 neas entre los parntesis de llave que le siguen, saltndose la o las l e a neas 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 neas 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.

107

c) En el ultimo caso se evaluar la expresin que acompaa al if y si ella es cierta se a o n ejecutar la o las l a neas entre los parntesis de llave que le siguen, saltndose todo el e a resto de las l neas 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 acompaa al primer else if y si ella es cierta ejecutar la u o n a o las l neas entre los parntesis de llave que le siguen, saltndose todo el resto de las e a l neas 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 neas 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 , amos 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 cil 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; }

108 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 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 . 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; }

109

La instruccin break permite que la ejecucin del programa salte a la l o o nea siguiente despus e de la serie de instrucciones asociadas a switch. De esta manera slo se ejecutarn las l o a neas correspondientes al case elegido y no el resto. Por ejemplo, si i==1 ver amos en pantalla slo la l o nea Caso 1. En el otro caso, si no existieran los break, y tambin i==1, entonces e ver amos en pantalla las l neas 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 denido 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 nalmente 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 verica 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 verica 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 nea siguiente al parntesis que e indica el n 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 interere con otras posibles variables i que existan en nuestro cdigo. o

110

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

for es una instruccin particularmente exible. 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: a 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 pico en que se aprovecha la opcionalidad de los argumentos del for es para tener un loop innito, que puede servir para dejar el programa en pausa indenida. 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

111

aun cuando la condicin de continuacin permite que indice llegue hasta 9. o o Finalmente, las variables involucradas en el for pueden ser modicadas dentro del ciclo. Por ejemplo, modiquemos 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, a al cabo del primer ciclo, k = 2 + 5 = 7 > 5. En general no es una buena prctica modicar 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 acompaa 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 nea siguiente al parntesis que indica el n del bloque asociado al while. e Hay que notar que la instruccin while podr no ejecutarse ni una sola vez si la condicin o a o no se cumple inicialmente. Un ejemplo simple: int i=1; while (i < 3) { cout << i++ << " "; }

112

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 innito 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 nea que contiene la instruccin salto:). Sin o embargo, se considera una mala tcnica de programacin usar goto, y siempre se puede die o sear un programa evitndolo. Es altamente no recomendable, pero si su utilizacin simplica 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 denicin de u o o o estas funciones debe ir precedida de la palabra void, como en el ejemplo citado.

4.3. FUNCIONES.

113

4.3.2.

return.

Si deseamos denir una funcin que calcule una ra cuadrada, evidentemente esperamos o z que la funcin nos entregue un resultado: el valor de la ra cuadrada. En este caso hay que o z 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 citamente o a travs de un cast impl e cito. Las siguientes funciones devuelven un double al programa:

114 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 a o prdida de precisin: e o int f4(){ double l=3.0; return l; } Naturalmente, podemos modicar la funcin anterior haciendo una conversin expl o o cita 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 z a o parmetro (el nmero al cual se le va a calcular la ra cuadrada). Consideremos por ejemplo a u z 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

115

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 intereren. Lo 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 verica cuidadosamente que cada funcin sea llamada con el nmero de o u parmetros adecuados, y que cada parmetro corresponda al tipo especicado. 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 cito (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 verica que el valor de retorno a a de la funcin sea usado como corresponde. Por ejemplo, en las dos l o neas: double m = funcion2(2,1e-3); int k = funcion4(0.4); la primera compilar exitosamente (pero hay un cast impl a cito), 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 114, 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

116

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 modicar el valor de tales variables. a La misma funcin de la pgina 114 puede ser modicada para que el paso de parmetros o a sea por referencia, modicando la declaracin: o #include <iostream> using namespace std; 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 modicar 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. a. 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 las por 10 millones de columnas. Seguramente estaremos llevando al

4.3. FUNCIONES.

117

l mite los recursos de nuestra mquina, y ser una torpeza pasarle la matriz por valor: a a ello involucrar primero, duplicar la memoria utilizada, con el consiguiente riesgo de a, que nuestro programa se interrumpa; y segundo, har el programa ms lento, porque a a la funcin necesitar llenar su versin local de la matriz elemento por elemento. Es o a o decir, nada de eciente. En esta situacin, el paso por referencia es lo adecuado. o 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 pico es el intercambio de dos variables entre s digamos a1=1 y a2=3. Luego de ejecutar la funcin queremos , o que a1=3 y a1=1. El siguiente cdigo muestra la denicin 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 refea a rencia, para ahorrar memoria y tiempo de ejecucin, pero sin correr el riesgo de que nuestra o matriz gigantesca sea modicada 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 modicador a const, el compilador avisar si se intenta modicar el argumento en medio del cdigo de la a o funcin. o

118

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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 int funcion(int); de la subseccin 4.3.3, y modiqumosla de modo que si no le entregao e mos parmetros, asuma que el nmero entregado fue 5: a u #include <iostream> using namespace std; 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 especicados son reemplazados por a a sus valores predeterminados.

4.3. FUNCIONES.

119

4.3.5.

Ejemplos de funciones: ra cuadrada y factorial. z

Ra cuadrada. z Con lo visto hasta ahora, ya podemos escribir un programa que calcule la ra cuadrada z de una funcin. Para escribir una funcin, debemos tener claro qu se espera de ella: cuntos o o e a 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 z nmero. Pero ese nmero podr ser un entero o un real, y eso al compilador no le da lo u u a mismo. En este punto nos aprovechamos del cast impl cito: en realidad, basta denir la ra z 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 deniramos para int y la llamamos con argumento double, el compilador se quejar de que e a 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 z a no corresponde declararla con un valor default. Ahora debemos pensar en cmo calcular la ra cuadrada. Usando una variante del mtodo o z 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 aproximaz 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 pequeo: o u n | x2 a | < 1. El valor de determinar la precisin de nuestro clculo. Un ejemplo de a o 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 ;

120 }

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

double raiz(double a){ double x =a/2.0 ; // para comenzar double dx = 1e3, epsilon = 1e-8; 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 nal 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) z o permite que la salida a pantalla muestre el resultado con 20 cifras signicativas. 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 nal del ciclo, x contendr el a z. a valor (aproximado) de la ra cuadrada. dx contiene la diferencia entre el cuadrado de x y el z valor de a, epsilon es el nmero (pequeo) 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 sucientemente pequeo. 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 a la aproximacin actual y la precisin alcanzada (dada por dx). Eventualmente, cuando la o o aproximacin es sucientemente 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, denido 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;

4.3. FUNCIONES. int factorial(int); int main(){ int n=5 ; cout << "El factorial de " << n << " es: " << factorial(n) << endl; return 0 ; } int factorial(int i) { int f =1; for (int j=1;j<=i;j++){ f = f*j; } return f; }

121

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. a 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 signiquen 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 nal del cuerpo de la o funcin donde es declarada. o Si la variable es declarada dentro de una funcin es local . Si es denida 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 nuestros ejemplos (subseccin 4.3.3), la variable i en main an est al alcance dentro o u a 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 denir: (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 modicador static.

122

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

El efecto del modicador static se aprecia en el siguiente ejemplo: #include <iostream> int f(); using namespace std; int main(){ cout << f() << endl; cout << f() << endl; return 0; } int f(){ int x=0; x++; return x; } 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 modiquemos 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; }

4.3. FUNCIONES.

123

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 Veamos un ejemplo de una variable esttica en el clculo del factorial: a a #include <iostream> using namespace std; 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 ; } 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. 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!. 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 sujo, y es equivalente a las dos instrucciones: a factorial2(n); n--; Si fuera un prejo [factorial2(n--)], primero disminuir n en 1, y llamar luego a factorial2 a a 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

124

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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 denimos, digamos, una o 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; a a C++ permite soslayar este hecho). La recursin permite denir de modo muy compacto una o funcin que calcule el factorial de un nmero entero n. o u #include <iostream> using namespace std; 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 denido 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 nal 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 a a eciente, 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 amos en una recursin o innita que har intil nuestro programa. En el caso del factorial, pudimos vericar que dicha a u condicin existe, por tanto el programa es nito. 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

4.4. PUNTEROS.

125

el archivo de header <cmath> y luego al compilar agregar al nal 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: 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 z 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)

Para elevar a potencias enteras, es ms conveniente usar la forma expl a cita en vez de la funcin pow, i.e. calcular x^3 como x*x*x es ms eciente 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 cita 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 pequeo ejemplo nos permite ver la diferencia entre un puntero y la variable a la cual n ese puntero apunta: #include <iostream> using namespace std; 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; }

126

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

En este programa denimos 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 nea 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 maniesto en la forma de la declaracin: int * p. En la o misma l nea 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). 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 nea 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 #include <iostream> using namespace std; 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 nea crea un nuevo puntero a int llamado p. new verica que haya suciente memoria para alojar un nuevo int, y si es as reserva ese espacio de memoria. En p queda la 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

4.5. MATRICES O ARREGLOS.

127

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.
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 : 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] ; }

128

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

4.5.2.

Matrices como parmetros de funciones. a

Si deseamos, por ejemplo, disear 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: #include <iostream> using namespace std; 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; } } 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 modicar main a: o #include <iostream> using namespace std; 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 modicar una l o nea 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 a que cambiar la l nea 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 a este programa con un comando de preprocesador para hacer la denicin de la dimensin: o o

4.5. MATRICES O ARREGLOS. #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; }

129

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++) { 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 denir la dimensin de una matriz como una constante. Aqu dim es simplemente un int. o , La asignacin dinmica permite denir matrices cuya dimensin se determina recin durante o a o e la ejecucin. o Observemos nalmente que la liberacin de memoria, en el caso de arreglos, se hace con o el operador delete [], no delete como en los punteros usuales. // Libera la memoria reservada

130

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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 denir 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 las o por columnas. Hay que tener cuidado del orden en el cual uno realiza las operaciones. En el siguiente cdigo, denimos una matriz de 10 las 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; #define dimx 3 #define dimy 10 void imprime(int,int,double[][dimx]); int main() { double a[dimy][dimx]; for (int i=0;i<dimy;i++) { for (int j=0;j<dimx;j++) { a[i][j]=0; } } a[0][0]=1; a[3][2]=2; a[9][2]=3; imprime(dimx,dimy,a); return 0; } void imprime(int dx, int dy, double a[][dimx]) { for (int i=0;i<dy;i++) {

4.5. MATRICES O ARREGLOS. for (int j=0;j<dx;j++) { cout << a[i][j] << ", "; } cout << endl; } }

131

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 a 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.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 denidas con dimensin constante (a menos que sean denidas 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 ,

132

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

el valor Hola, debe denirse 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 a 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 tulo. De hecho, la declaracin de palabra o podr haberse escrito: a char palabra[5] = "Hola"; Esto ya es bastante ms cmodo, aunque persiste la inconsistencia de denir 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; } Observar que la l nea 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 denir 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):

4.5. MATRICES O ARREGLOS. #include <iostream> #include <string> using namespace std; int main(){ string palabra; cin >> palabra; return 0; }

133

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 denida (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 Ingreso con espacios. Dijimos que es muy fcil ingresar una cadena desde el teclado, pues no es necesario a denir 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 nea 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 a a a 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

134

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

llamada get, y leer desde el teclado hasta que el usuario d el primer cambio de l e nea. 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 n de l nea 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 conguracin, hacer anlisis estad a o a stico sobre un gran nmero de datos generados por otro programa, entregar las coordenadas de u los puntos de una trayectoria para gracarlos 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: #include <iostream> #include <fstream> using namespace std; int main(){ ofstream nombre_logico("nombre_fisico.dat"); int i = 3, j; cout << i << endl; nombre_logico << i << endl; cout << "Ingrese un numero entero: ";

4.6. MANEJO DE ARCHIVOS. cin >> j; cout << j << endl; nombre_logico << j << endl; nombre_logico.close(); return 0; }

135

La primera l nea de main dene un objeto de tipo ofstream (output le stream). Esto corresponde a un archivo de salida. Dentro de main este archivo ser identicado por a una variable llamada nombre_logico, y corresponder a un archivo en el disco duro llamaa do nombre_fisico.dat. Naturalmente, el identicador 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 sico. 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 sintaxis expl citamente string mi_nombre_archivo=archivo.txt; ofstream nombre_logico_1( mi_nombre_archivo.c_str()); Las l neas cuarta y octava de main env an a nombre_logico (es decir, escribe en nombre_fisico.dat), las variables i y j. Observar la analog que existe entre estas operaa 4 ciones y las que env la misma informacin a pantalla. Si ejecutamos el programa y en an o el teclado ingresamos el nmero 8, al nalizar la ejecucin el archivo nombre_fisico.dat u o tendr los dos nmeros escritos: a u 3 8 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 o debiera tener cuidado de cerrarlos expl citamente. Por ejemplo, un mismo programa podr a desear utilizar un mismo archivo ms de una vez, o varios programas podr querer acceder a an al mismo archivo, y si no se ha insertado un close en el punto adecuado esto podr provocar a 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
Esta analog no es casual y se entiende con el concepto de clases (Sec. 4.8). fstream e iostream denen a 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

136

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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 nea 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 predenidos 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 amos usar el mismo nombre lgico para identicar dos archivos f o sicos distintos, usados en distintos momentos del programa: 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();

4.6. MANEJO DE ARCHIVOS.

137

Observar la necesidad del primer close, que permitir liberar la asociacin de a a un nombre a o f sico 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 le 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; } 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 nea, de modo que el archivo podr haber sido tambin: a 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:

138

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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 amos 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 exible, 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 especicar 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; 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;
Nuevamente, este hecho se debe al concepto de clases que subyace a las deniciones 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

4.7. MAIN COMO FUNCION. cout << j << endl; nombre_logico.close(); return 0; }

139

Las dos primeras l neas 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 pa ra hacer evidente la simetr entre el uso del archivo como salida primero y como entrada a 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: user@host:~/$ programa Si el mismo usuario desea ejecutar alguno de los comandos del sistema operativo, debe hacer lo mismo: user@host:~/$ 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 modicacin, basta dar otro argumento, en forma de opcin: ls -tr l*. Se ve entonces que o o los argumentos de un archivo ejecutable permiten modicar el comportamiento del programa de modos espec cos. 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, , o pero hasta el momento no hemos aprovechado esa caracter stica. Simplemente sabemos que el programa empieza a ejecutarse en la l nea donde est la funcin main. Adems, siempre a o a hemos escrito esa l nea como main(). Sin embargo, main, como cualquier funcin, es capaz de o aceptar argumentos. Espec camente, 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:

140 #include <iostream> using namespace std;

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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: user@host:~/$ argumentos argumentos user@host:~/$ 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 nea de comandos, escribiendo el cdigo correspondiente. o

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 amos hacer ese valor de retorno igual a 0 o 1, respectivamente. As la siguiente estructura es correcta: , int main(){ // Codigo

return 0; }

4.8. CLASES. En este caso, el programa entrega siempre el valor 0 al sistema operativo. Los cdigos del tipo: o main(){ // Codigo

141

} 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.

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 predenida que corresponda a nmeros u complejos, vectores de dimensin n o matrices, por ejemplo. Y sin embargo, nos agradar o a disponer de nmeros complejos que pudiramos denir como u e z = (3,5); w = (6,8); y que tuvieran sentido las expresiones

142 a b c d e f = = = = = = z + w; z * w; z / w; z + 3; modulo(z); sqrt(z);

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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 a ejemplo, el signo + es un operador que espera a ambos lados suyos un nmero. Sumar cualquier u cosa con cualquier cosa no signica nada necesariamente, as que slo est permitido operar o a con nmeros. Pero los humanos sabemos que los complejos son nmeros. Cmo dec u u o rselo 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 a La respuesta es: a travs del concepto de clases. Lo que debemos hacer es denir una clase e de nmeros complejos. Llammosla Complejo. Una vez denida 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 denir 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

4.8.1.

Denicin. 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 denido por el usuario. La estructura m nima de la denicin de la clase Persona es: o class Persona { }; Todas las caracter sticas de la clase se denen entre los parntesis cursivos. e

4.8. CLASES.

143

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 denen; 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 picamente 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 modicar a y conocer esas cantidades. Eso slo puede hacerse a travs de funciones pblicas. o e u class Complejo { private: double real, imaginaria; public: void setreal(double); void setimag(double); double getreal(); double getimag(); }; En este ejemplo, los miembros privados son slo variables, y los miembros pblicos son slo o u o funciones. Este es el caso t pico, pero puede haber variables y funciones de ambos tipos.

4.8.4.

Operador de seleccin (.). o

Hemos denido una clase de nmeros complejos y funciones que nos permiten conocer u y modicar las partes real e imaginaria. Cmo se usan estos elementos? Consideremos el o siguiente programa de ejemplo:

144 using namespace std;

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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; } Vemos en la primera l nea de main cmo la clase Complejo se usa del mismo modo que o usar amos int o double. Ahora Complejo es un tipo de variable tan vlido como los tipos a predenidos por C++. Una vez denida 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) {

4.8. CLASES. imaginaria = x; } double Complejo::getreal() { return real; } double Complejo::getimag() { return imaginaria; }

145

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 suciente para alojarla. Cuando se trata de variables de tipos predenidos en C++ esto no es problema, pero cuando son tipos denidos 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 { 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) {} Denir 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);

146

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

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 denir 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 especica el constructor de una clase C++ crea uno default, pero en general ser insuciente 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 denir una variable, hay que deshacerse de ese espacio cuando la variable deja de ser necesaria. En otras palabras, la clase necesita 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) { }

4.9. SOBRECARGA.

147

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 predenidas 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 nea Complejo z[2]; es incorrecta, pero s es aceptable la l nea Complejo z[2] = {Complejo(3.5,-0.8), Complejo(-2,4)};

4.9.

Sobrecarga.

Para que la denicin 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 an concepto de clase, nos gustar sumar nmeros complejos, y que esa suma utilizara el mismo a u signo + de la suma usual. O extraerles la ra cuadrada, y que la operacin sea tan fcil z o a como escribir sqrt(z). Lo que estamos pidiendo es que el operador + o la funcin sqrt() o sean polimrcos, 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 z u calcular la ra de un nmero complejo. a z u La tcnica de programacin mediante la cual podemos denir funciones polimrcas 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 z 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 denirla o u as : Complejo sqrt(Complejo z) { return Complejo (z.getreal()/2, z.getimag()/2); }

148

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

Observemos que denimos 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 z 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 denicin anterior podemos obtener la ra cuadrada de un nmero complejo o z 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 denir a + b, con a y b complejos. Pero qu pasa si a o b son enteros? O reales? e Pareciera que tendr amos que denir no slo o 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 denir 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 denir 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 nea del tipo: Complejo c = Complejo(3,2.8) + 5; el computador convertir impl a citamente 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 denir. a

4.10. HERENCIA.

149

4.10.

Herencia.

Herencia es el mecanismo mediante el cual es posible denir clases a partir de otras, preservando parte de las propiedades de la primera y agregando o modicando otras. Por ejemplo, si denimos la clase Persona, toda Persona tendr una variable miembro a que sea su nombre. Si denimos una clase Hombre, tambin ser Persona, y por tanto deber e a a 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 denir 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(); } class Hombre : public Persona { private: string esposa; public: Hombre(string a) : Persona(a) { }; string getwife(); void setwife(string); }; Primero denimos una clase Persona que tiene nombre. Luego denimos una clase Hombre a partir de Persona (con la l nea class Hombre : public Persona). Esto permite de modo automtico que Hombre tenga tambin una variable nombre. Y nalmente, dentro de la clase a e Hombre, se denen todas aquellas caracter sticas adicionales que una Persona no tiene pero un Hombre s esposa, y funciones miembros para modicar y obtener el nombre de ella. : 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;

150

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

Observemos que panadero tambin tiene una funcin getname(), a pesar de que la clase e o Hombre no la dene expl citamente. 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 deniciones: #ifndef _complejos_ #define _complejos_ #include <iostream> #include <cmath> class Complejo { private: double real, imaginaria; 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

4.11. EJEMPLO: LA CLASE DE LOS COMPLEJOS. 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; } 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()

151

152 {

CAP ITULO 4. UNA BREVE INTRODUCCION A C++.

return atan2(real,imaginaria); }

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) { 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()); }

4.12. COMPILACION Y DEBUGGING.

153

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.
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 dene 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 tamao del ejecutable y el tiempo de ejecucin, con n se aumenta el n o grado de optimizacin. o

154

CAP ITULO 4. UNA BREVE INTRODUCCION A C++. -Wall notica 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.

Cap tulo 5 Grca. a


versin 4.12, 24 de Octubre del 2003 o

En este cap tulo quisiramos mostrar algunas de las posibilidades grcas presentes en Lie a nux. Nuestra intensin es cubrir temas como la visualizacin, conversin, captura y creacin o o o o de archivos grcos. Slo mencionaremos las aplicaciones principales en cada caso centrndoa o a nos en sus posibilidades ms que en su utilizacin espec a o ca, ya que la mayor posee una a interfase sencilla de manejar y una amplia documentacin. o

5.1.

Visualizacin de archivos grcos. o a

Si disponemos de un archivo grco conteniendo algn tipo de imagen lo primero que es a u importante determinar es en qu tipo de formato grco est codicada. Existe un nmero e a a u realmente grande de diferentes tipos de codicaciones de imgenes, cada una de ellas se a considera un formato grco. Por razones de reconocimiento inmediato del tipo de formato a grco se suelen incluir en el nombre del archivo, que contiene la imagen, un tr de letras a o nales, conocidas como la extensin, que representan el formato. Por ejemplo: bmp, ti, jpg, o ps, eps, g, 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, identicados 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 a desea imprimir el documento debe transformar a ps v dvips y luego se imprime como a cualquier otro Postscript. Para la gran mayor de formatos grcos ms conocidos y usualmente usados para ala a a macenar fotos existen otra serie se programas especializados en visualizacin que son capaces o 155

156

CAP ITULO 5. GRAFICA.

de entender la mayor de los formatos ms usados. Entre estos programas podemos mencioa a nar: Eye of Gnome (eog), Electric Eyes (eeyes), kview o display. Podemos mencionar que aplicaciones como display entienden sobre ochenta formatos grcos distintos entre los que a se encuentran la mayor de los formatos conocidos ms otros como ps, eps, pdf, fig, html, a 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.

Modicando imgenes a

Si queremos modicaciones como rotaciones, ampliaciones, cortes, cambios de paleta de colores, ltros 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 ocial 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 grcos. o a

El problema de transformar de un formato a otro es una situacin usual en el trabajo con o archivos grcos. 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 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 grcos. Tambin display o a e permite este hecho. Sin embargo, en ambos casos la conversin es v mens, lo cual lo o a 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 nea de comando. Este programa junto con display, import y varios otros forman la suite grca 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 cula. 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.

157

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 grca. a

5.5.

Creando imgenes. a

Para imgenes art a sticas sin duda la alternativa es gimp, todo le que se dijo respecto a sus posibilidades para modicar 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 sica en tareas, pruebas y apuntes son realizados con software de este tipo, principalmente xfig, luego exportados A a PostScript e inclu dos 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 modicado. 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 gura en bitmap a forma vectorial. Una aparente limitacin de este tipo de software es que se podr pensar que no podemos o a incluir curvas anal ticas, 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 graca funciones anal ticas, tales como gnuplot,

158

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 stica 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 grcos 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.

Gracando funciones y datos.

Existen varias aplicaciones que permiten gracar datos de un archivo, entre las ms popua lares estn: gnuplot, xmgrace y SciGraphica. La primera est basada en la l a a nea de comando y permite grcos en 2 y 3 dimensiones, pudiendo adems, gracar funciones directamente a a sin pasar por un archivo de datos. Las otras dos son aplicaciones basadas en mens que u permiten un resultado nal de mucha calidad y con mltiples variantes. La debilidad en el u caso de xmgrace es que slo hace grcos bidimensionales. o a El programa gnuplot se invoca de la l nea 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.

159

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 ca que permite el despliegue de grcos 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.

Gracando desde nuestros programas.

Finalmente para poder gracar desde nuestro propio programa necesitamos alguna biblioteca grca, 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 neas: #!/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];

160 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 graca 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 tulo 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 diseo de documentos de gran calin dad, conteniendo textos y frmulas matemticas. Aos despus, L TEX fue desarrollado por o a n e A Leslie Lamport, facilitando la preparacin de documentos en TEX, gracias a la denicin 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 modicaciones, 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 denitiva de L TEX, L TEX3. u a 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 a A desuso, diremos expl citamente 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 161

162

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . b) log. Aqu se encuentran todos los mensajes producto de la compilacin, para 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 neas: \documentclass[12pt]{article} \begin{document} \end{document} Haremos algunas precisiones respecto a la primera l nea ms tarde. Lo importante es que a una l nea 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 signicado espec co para L TEX. Algunos de ellos se pueden obtener anteponindoe les un backslash:

\#

\$

\%

&

\&

\{

\}

Los caracteres + = | < >

6.3. INPUT BASICO.

163

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 n de l nea 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} 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 sticas que quizs no apreciamos cuando a leemos textos bien diseados, pero las cuales es bueno conocer para aprovecharlas. n

a) Observemos la siguiente palabra: no. Esta palabra fue generada escribiendo simplemente fino, pero observemos que las letras f e i no estn separadas, sino que unidas a art sticamente. Esto es una ligadura, y es considerada una prctica estticamente prea e A X sabe esto e inserta este peque o efecto tipogrco 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 labas al nal de la l nea) 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 pequeo 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 a as como es cierto que generalmente cuando un punto viene despus de una mayscula e u no hay n de frase:

Saint-Exupry e

164

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 n de e e frase, y que el punto despus de la ultima S s termina frase. Esto se consigue as e : 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 pequeo espacio adicional despus de hoy, n e para compensar el espacio entre palabras perdido por la inclinacin de la itlica. Este o a pequeo 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.

165

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 mbolo 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 n de la l a nea correspondiente ser ignorado (incluyendo el n de l a nea).
Un pequeo comentario. n Un peque{\~n}o co% mentario. Texto ignorado

6.3.8.

Estilo del documento.

Las caracter sticas generales del documento estn denidas 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 a? entre l neas? 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 culos cortos (sin cap tulos) o ms largos (con cap a tulos), libros y cartas, respectivamente.

166

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

La eleccin del estilo global se hace en la primera l o nea del archivo:2 \documentclass{article} Esta l nea ser aceptada por el compilador, pero nos entregar un documento con un a a tamao de letra pequeo, tcnicamente llamado de 10 puntos 10pt (1pt = 1/72 pulgadas). n n e o Existen tres tamaos de letra disponibles: 10, 11 y 12 pt. Si queremos un tamao de letra n n ms grande, como el que tenemos en este documento, se lo debemos indicar en la primera a l nea del archivo: \documentclass[12pt]{article} Todas las decisiones de estilo contenidas dentro del archivo cls son modicables, existiendo tres modos de hacerlo: a) Modicando el archivo cls directamente. Esto es poco recomendable, porque dicha modicacin (por ejemplo, un cambio de los mrgenes) se har extensible a todos los o a a 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 cas de estilo vlidas slo a o para el archivo que nos interesa. c) Creando un nuevo archivo cls. Esto es muy recomendable cuando las modicaciones 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 a

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 o, reclamar incluso eso (\footnote{} no genera problemas, pero \documentclass{} s es a 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 nea 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.

167

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 tamao de letra de 10pt. Un argumento en parntesis n e cuadrados es una opcin que modica 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 tulo.

Un t tulo 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 tulo: \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 culos cortos, L TEX coloca el t tulo en la parte superior de la primera pgina a del texto. Para art culos largos, en una pgina separada. a

168

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

6.3.11.

Secciones.

Los t tulos 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

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, tem 1. 2. Nivel 1, tem 2. a) Nivel 2, tem 1. 1) Nivel 3, tem 1. 3. Nivel 1, tem 3.

1. 2. 1. 1.

3.

b) Listas no numeradas (ambiente itemize):


Nivel 1, tem 1. Nivel 1, tem 2. Nivel 2, tem 1. Nivel 3, tem 1. Nivel 1, tem 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.

169

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 modicarlos agregando un parmetro opcional: a
a) Nivel 1, tem 1. b) Nivel 1, tem 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 tulos de cap tulos, secciones, subsecciones, etc. \textrm, \textbf, etc., slo permiten cambiar porciones denidas 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 innito. . . 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 modicadas de \rm, \bf, etc.: \rmfamily \sffamily \ttfamily \mdseries

170 \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 tamaos 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 ndices; \footnotesize para notas a pie de pgina. a

6.3.14.

Acentos y s mbolos.

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 mbolos 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

171

Cuadro 6.1: Acentos. c a \dag \ddag \S \P \copyright \textcircled a \textvisiblespace \pounds a A \oe \OE \ae \AE \aa \AA \o \O l L SS \l \L \ss \SS ? !

Cuadro 6.2: S mbolos 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 mbolos 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 labas de acuerdo a reglas distintas, y esto es relevante cuando se debe cortar el A texto en l neas. 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 congurado 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 labas 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 conictiva 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 nal de la l u o nea, 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 tulos o ndices, por ejemplo, son escritos Indice, en vez de Chapter e Index, y cuando se usa el comando \date, la fecha aparece Cap tulo e en castellano.

172

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 o a palabra acentuada tuvo problemas y no lo hizo muy bien, pues qued demasiado espacio o A entre palabras en esa l nea. 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 nal de l e o nea 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 ndices.


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 ndices 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.

173

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 ces.
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 mbolos 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.

174

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 mbolos para , , , etc. maysculas, pues corresponden a letras romanas u (A, B, E, etc.).

6.4.6.

Letras caligrcas. a

Letras caligrcas 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 mbolos matemticos. a

A L TEX proporciona una gran variedad de s mbolos matemticos (Tablas 6.4, 6.5, 6.6, 6.7). a La negacin de cualquier s o mbolo 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 nalizar 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 a e sica:

6.4. FORMULAS MATEMATICAS.

175

\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 mbolos 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 mbolos 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

176

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX . \aleph \hbar \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 mbolos varios. \sum \prod \coprod \int \oint \bigcap \bigcup \biguplus \bigvee \bigwedge \bigsqcup \bigodot \bigotimes \bigoplus

Cuadro 6.8: S mbolos de tamao variable. n [Notemos, s en la Tabla 6.5, que existe el s , mbolo = (\neq).] Algunos s mbolos tienen tamao variable, segn aparezcan en el texto o en frmulas n u o separadas del texto. Se muestran en la Tabla 6.8. Estos s mbolos pueden tener ndices que se escriben como sub o supra ndices. Nuevamente, la ubicacin de estos o ndices 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 ndices:

l xn = 0 m

$$\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

177

Cuadro 6.9: Funciones tipo logaritmo


l n xn = 0 m $\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 nea se separan con & y l neas consecutivas se separan con \\. As el ejemplo anterior se obtiene con: , \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 mbolo 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 tamao correcto para encerrar la expresin corresponn o diente hay que anteponerles \left y \right. Podemos obtener as expresiones matriciales:
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

178

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 picos:
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

179

Cuadro 6.11: Acentos matemticos a Frmulas de ms de una l o a nea. 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 nea 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 neas 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 suciente 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 nea \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 . \imath y \jmath generan las versiones sin punto de estas letras:
+ \vec \imath + \hat \jmath

180

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

6.4.11.
Vcr tico

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 nos. Hay cuatro comandos que agregan pequeos espacios dentro de modo matemtico: n a \, \! espacio pequeo n espacio pequeo (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 pequeo 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 gitos y acentos, pero no de los otros s mbolos 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 dierent dierent $different$ $\mathnormal{different}$ $\mathit{different}$ \textit{different}

181

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 neas verticales y horizontales para ayudar a la lectura, lo hacemos insertando | en los puntos apropiados del argumento de tabular, y \hline al nal de cada l nea 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 tulos 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 citamente el nmero u correspondiente, pues la insercin de una nueva ecuacin, cap o o tulo, etc., su eliminacin o cambio de o orden del texto podr alterar la numeracin, obligndonos a modicar estos nmeros dispersos en a 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 gitos o signos de puntuacin. Letras maysculas y minsculas son o u u

182

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. , a Podemos usar \label dentro de equation, eqnarray y enumerate. Tambin podemos referenciar pginas con \pageref: e a Ver pgina 182 para ms dea a talles. [Texto en pg. 182] a El signicado 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 a entonces o no ten informacin util.) a 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 modicacin 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 nal. 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 neas consecutivas se separan con \\: Una l nea centrada, otra y otra ms. a Ahora el texto contina u alineado a la izquierda y nalmente dos l neas 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

183

6.8.

Algunas herramientas importantes

A Hasta ahora hemos mencionado escencialmente comandos disponibles en L TEX standard. Sin A X, se vuelven insucientes cuando embargo, stos, junto con el resto de los comandos bsicos de L TE e a se trata de ciertas aplicaciones demasiado espec cas, 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 , sticas 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 nea:

\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 signica, entre otras e cosas, que se incorporan los patrones de silabacin correctos para dicho idioma, para cortar adecuao damente las palabras al nal de cada l nea. 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 conguracin 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 nea \usepackage[spanish]{babel}

184

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 nea correspondiente en el prembulo: a \usepackage{amsmath} aliviar mucho la tarea. He aqu algunas de las caracter a sticas 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 neas, de modo que la primera l nea 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 neas (como multline), pero permite alinear las l neas 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

185

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 ndices textuales ms fcilmente que con \mbox (ver seccin 6.4.11): a a o Vcr tico $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

186

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 coecientes 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 echas en la tabla 6.6 vienen en ciertos tamaos predenidos. amsmath proporciona en chas extensibles \xleftarrow y \xrightarrow, para ajustar sub o super ndices 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 ni1

A \xleftarrow{n+\mu-1} B \xrightarrow[T]{n\pm i-1} C \xrightarrow[U]{} D

Uso del paquete amssymb


Este paquete contiene s mbolos 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 s mbolo interesante es: (\therefore) para por lo tanto.

187

6.8.3.

fontenc

A Ocasionalmente, L TEX tiene problemas al separar una palabra en s labas. T picamente, 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 labas 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 codicacin 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 codicacin 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 dene 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 tem. B Segundo tem. Si queremos etiquetas de la forma 1.-, \begin{enumerate}[1.-]: 1.- Primer tem. 2.- Segundo tem. 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 tem. Caso B: Segundo tem.

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}

188

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

De este modo, est disponible el comando \color, que permite especicar un color, ya sea por a nombre (en el caso de algunos colores predenidos), 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 especicar 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 especicar 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 innidad 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.

Modicando 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 tulo de seccin, etc.) en la parte suo perior de la pgina. (Default para estilo a book.) Sin nmeros de pgina. u a

189

\pagestyle{headings}

\pagestyle{empty}

6.9.2.

Corte de pginas y l a neas.

TEX tiene modos internos de decidir cundo cortar una pgina o una l a a nea. Al preparar la versin o nal de nuestro documento, podemos desear coartar sus decisiones. En todo caso, no hay que hacer esto antes de preparar la versin verdaderamente nal, porque agregar, modicar o quitar texto o puede alterar los puntos de corte de l neas 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 neas.
o nea en un punto deseado En la pgina 171 ya vimos un ejemplo de induccin de un corte de l a del texto, al dividir una palabra en s labas. Cuando el problema no tiene relacin con s o labas disponemos de dos comandos: \newline \linebreak Corta la l nea y pasa a la siguiente en el punto indicado. Lo mismo, pero justicando la l nea 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 nea no justicado a los mrgenes a en curso. Un corte de l nea justicado 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

190

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

Corte de pginas. a
Como para cortar l neas, 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 tamao 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 metro mil metro 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 mao 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 a. Ancho del texto. Altura del texto. Margen izquierdo menos 1 pulgada. Margen superior menos 1 pulgada. Distancia entre la base de dos l neas de texto consecutivas. Distancia entre prrafos. a

191

Todas estas variables son modicables con los comandos \setlength, que le da a una variable un valor dado, y \addtolength, que le suma a una variable la longitud especicada. 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 denidos 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 pico 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 neas aumentan el tamao 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 queo 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.

192

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 a a comenzara algunos cent metros ms abajo que en el resto. Lo mismo puede ocurrir si el a espacio horizontal de un \hspace queda al comienzo de una l nea. Los comandos \vspace*{<longitud>} y \hspace*{<longitud>} permiten que el espacio en blanco de la <longitud> especicada 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 nea por ejemplo, para insertar una gura.

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 guras, 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 neas, c rculos, valos y echas, as como para posicionar texto. Infortunadamente, el proceso de o 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 neas de pendiente arbitraria), y por tanto no es una solucin o o ptima. Para obtener guras de buena calidad es imprescindible recurrir a lenguajes grcos externos, y a A X da la posibilidad de incluir esos formatos grcos en un documento. De este modo, tanto el L TE a texto como las guras 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 grco 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 co. 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 a PostScript sirve ms que para imprimir, siendo un lenguaje de programacin grco 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 grcos permiten exportar sus resultados en formato PostScript. Por lo tanto, a podemos generar nuestras guras 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 guras provenientes de clculos cient a cos, etc.), lo cual crear un archivo con a 5 Luego introducimos la gura 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 gura, informacin o o A que es utilizada por L TEX para insertar sta adecuadamente en el texto. e

6.10. FIGURAS.

193

6.10.1.

graphicx.sty

Si nuestra gura 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 gura o rotarla usando a comandos disponibles en graphicx. Una gura aqu : 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 gura (3cm). El ancho fue determinado de modo o que las proporciones de la gura no fueran alteradas. Si no se especica ni la altura ni el ancho, la gura es insertada con su tamao natural. n Observemos tambin que pusimos la gura en un ambiente center. Esto no es necesario, pero e normalmente uno desea que las guras estn centradas en el texto. e

6.10.2.

Ambiente figure.

Insertar una gura es una cosa. Integrarla dentro del texto es otra. Para ello est el ambiente a figure, que permite: (a) posicionar la gura automticamente en un lugar predeterminado o espea cicado por el usuario; (b) numerar las guras; y (c) agregar un breve texto explicativo junto a la gura. Coloquemos la misma gura 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}

194

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 otante, 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 gura es al principio o al nal o o de la pgina. Adems, lo ideal es que cada pgina tenga un cierto nmero mximo de guras, a a a u a que ninguna gura aparezca en el texto antes de que sea mencionada por primera vez, y que, por supuesto, las guras aparezcan en el orden en que son mencionadas. Estas y otras condiciones determinan la posicin que un objeto otante tenga al nal 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 oats) extremo superior de la pgina a extremo inferior de la pgina a aqu en el punto donde est el comando , a en una pgina separada al nal del texto a

El argumento adicional ! suprime, para ese objeto otante espec co, cualquier restriccin que o exista sobre el nmero mximo de objetos otantes en una pgina y el porcentaje de texto m u a a nimo 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 gura se debe colocar como primera prioridad aqu mismo; si ello no es posible, al comienzo de pgina (sta o la siguiente, dependiendo de los detalles de la compilacin), y as sucea e o sivamente. Adems, figure numera automticamente la gura, colocando el texto Figura N :, y \caption a a permite colocar una leyenda, centrada en el texto, a la gura. Puesto que la numeracin es automtio a ca, las guras 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 gura debi ser centrada expl o citamente con center. figure no hace nada ms que tratar la gura como un objeto otante, proporcionar numeracin y leyenda. El a o resto es responsabilidad del autor.

6.11. CARTAS.

195

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 rma, 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

196

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

Las Palmeras 3425 n Nuoa, Santiago 9 de Julio de 1998 Dr. Juan Prez e Las Palmeras 3425 n Nuoa, Santiago Estimado Juan An no tenemos novedades. u Parece incre ble, 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.

197

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 rma 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 rma, salvo la segunda. a o En todos estos comandos, l neas 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

198

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 , a archivo <archivo>.pdf en vez del <archivo>.dvi generado por el compilador usual. Si nuestro documento tiene guras, slo es posible incluirlas en el documento si estn tambin o a e en formato pdf. Por tanto, si tenemos un documento con guras en PostScript, debemos introducir dos modicaciones 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 guras PostScript a pdf (con epstopdf, por ejemplo). Si tenemos una gura 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 guras o PostScript permite, sin modicaciones, incluir guras en pdf.

6.13.

A Modicando LTEX.

Esta seccin se puede considerar avanzada. Normalmente uno se puede sentir satisfecho con o A el desempeo de L TEX, y no es necesaria mayor intervencin. A veces, dependiendo de la aplicacin n o o y del autor, nos gustar modicar el comportamiento default. Una alternativa es denir nuevos a 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 modicaciones. o a

6.13.1.

Denicin 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, , 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 denicin de un comando puede contener otros comandos a o (en este caso, \). Finalmente, notamos que ha sido necesario agregar un espacio expl cito con \ , al escribir Cristbal Loyola: recordemos que un comando comienza con un backslash y termina o

A 6.13. MODIFICANDO L TEX.

199

con el primer carcter que no es letra. Por tanto, \nombre Loyola ignora el espacio al nal de a \nombre, y el output ser CristbalLoyola. a o Tambin es posible denir 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 denicin 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 denir 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

200

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

Nuevos comandos con argumentos


Podemos tambin denir 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 denicin 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 denir 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 modicar e , 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 \ . $$

Redenicin de comandos o
Ocasionalmente no nos interesa denir un nuevo comando, sino redenir 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 nea 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 neas 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 denicin del comando queda ms compacta: a o a

A 6.13. MODIFICANDO L TEX.

201

\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 tulo 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 neas en blanco, los cambios de l nea pueden causar problemas dentro de la denicin de un nuevo comando. El ejemplo anterior, con el comando \seccion, es un buen ejemplo: o notemos que cuando se deni, pusimos un cambio de l o nea despus de \vspace{.5cm}. Ese cambio e de l nea es interpretado (como todos los cambios de l nea) 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 nea, incluyendo el cambio de l nea. Ilustremos lo anterior con los siguientes tres comandos, que subrayan (comando \underline) una palabra, y dieren slo en el uso de % para borrar cambios de l o nea: 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

202

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 denen con \newenvironment:

\newenvironment{<ambiente>}{<comienzo ambiente>}{<final ambiente>} dene un ambiente <ambiente>, tal que \begin{ambiente} ejecuta los comandos <comienzo ambiente>, y \end{ambiente} ejecuta los comandos <final ambiente>. Denamos un ambiente que, al comenzar, cambia el font a itlica, pone una l a nea 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. a Nunca esper una recepcin tan calurosa. e o XXX Los nuevos ambientes tambin pueden ser denidos 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, modiquemos el ambiente na anterior, de modo que en vez de colocar una l nea 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.

203
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 sucientemente 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 modicaciones: mrgenes ms pequeos, inclusin a a a n o automtica de los paquetes amsmath, babel y graphicx, entre otros, y denicin de ciertos ambientes a o espec cos. 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, a a a que sirve para esos tres propsitos, deniendo comandos que le permiten especicar 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 cos 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) Identicacin: 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.)

204

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 (Obligatoria: si no hay ninguna declaracin, el paquete o clase no hace nada, naturalmente.) o La identicacin est consituida por las siguientes dos l o a neas, que deben ir al comienzo del archivo: \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{<paquete>}[<fecha> <otra informacion>]
A A La primera l nea indica a L TEX que ste es un archivo para L TEX 2 . La segunda l e nea especica 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 neas:

\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{addmath}[1998/09/30 Macros matematicos adicionales (VM)] Si lo que estamos deniendo 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 identicacin 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 denir mientras escrib amos estos apuntes. Veamos los contenidos de una versin o simplicada 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.

205

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 dene bastantes comandos, pero nos gustar denir va, a 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 deniciones necesarias para compilar el documento exitosamente. Sin embargo, un usuario normal, aun cuando desee denir una nueva clase, estar interesado en modicar slo parte del comportamiento. Con \LoadClass, dicho usuario a o puede cargar la clase sobre la cual se desea basar, y luego introducir las modicaciones 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 a e an ciertas modicaciones. 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 modicar o aadir 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

206

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 ).

Manejo de opciones
En el ultimo ejemplo anterior, la clase mfm2 carga la clase book con la opcin 12pt. Esto signica 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 a pudiramos especicar el tamao 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 modicar en mfm2.cls la l nea \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 suciente en muchas ocasiones, pero en general uno podr llamar a a nuestra nueva clase, mfm2, con opciones que no tienen nada que ver con book. Por ejemplo, podr amos llamarla con opciones spanish,12pt. En tal caso, deber pasarle spanish a babel, y a 12pt a book. Ms an, podr a u amos necesitar denir una nueva opcin, que no existe en ninguna de o las clases o paquetes cargados por book, para modicar el comportamiento de mfm2.cls de cierta manera espec ca 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, guras, 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 especicada. o As nuestro archivo mfm2.cls debe ser modicado: , \NeedsTeXFormat{LaTeX2e} \ProvidesClass{mfm2}[2002/03/25 Estilo para apuntes MFM II (VM)] ... \DeclareOption{keys}{...}

A 6.13. MODIFICANDO L TEX.

207

... \ProcessOptions\relax ... Observamos que despus de declarar la o las opciones (en este caso keys), hay que procesarlas, e con \ProcessOptions.7

Las l neas 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 nea vlida, dea bemos procesar keys dentro de mfm2.cls, y pasarle a book.cls las opciones restantes. El siguiente es el cdigo denitivo: 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 nea del cdigo). La siguieno te l nea (\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 nalmente se carga la clase book. Las l neas siguientes cargan todos los paquetes necesarios, y nalmente se encuentran todos los nuevos comandos y deniciones 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 denimos: 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 ticos de un documento, como en este ejemplo.
7

208

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 nal sin , o o ella, para no confesar al lector nuestra mala memoria o nuestra comodidad.

A 6.13. MODIFICANDO L TEX.

209

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

210

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

6.14.
6.14.1.

Errores y advertencias.
Errores.

Un mensaje de error t pico 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 nea 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 nea nos informa quin encontr el error. e o La tercera l nea comienza con un signo de exclamacin. Este es el indicador del error. Nos o dice de qu error se trata. e Las dos l neas siguientes describen el error en trminos de comandos de bajo nivel. e La l nea 6 nos dice dnde ocurri el error: la l o o nea 140 en este caso. Adems nos informa a del texto conictivo: \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 a indicacin es precisa. De hecho, es fcil darse cuenta, con la tercera l o a nea (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 picamente 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 pica 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 nal 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 ,

6.14. ERRORES Y ADVERTENCIAS.

211

muchos errores ms. Podemos continuar con <Enter> sucesivos hasta llegar al nal de a la compilacin. o (d) q <Enter> La accin descrita en el punto anterior puede llegar a ser tediosa o innita. q hace o ingresar a TEX en batchmode, modo en el cual la compilacin prosigue ignorando todos o los errores hasta el nal del archivo, sin enviar mensajes a pantalla y por ende sin que debamos darle innitos <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 nea:

... un error inesperado\fotnote{En cualquier punto.} puede decidir... generar el mensaje de error: a ! Undefined control sequence. l.249 ...un error inesperado\fotnote {En cualquier punto.} ? En la l nea 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 nea en la cual detect el error, sino el punto de ella donde ello o ocurri. (En realidad, hizo lo mismo cortar la l o nea para hacer resaltar el problema en el o caso expuesto en la pg. 210, 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 nea en blanco en ambiente matemtico. a

212

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

Algunos mensajes de error.


A A continuacin, una pequea 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 denido. ! 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,

! Somethings 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.

213

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 denido por un \label. TEX tambin env advertencias. Se reconocen porque no comienzan con TeX warning. e a Algunos ejemplos. Overfull \hbox ... TEX no encontr un buen lugar para cortar una l o nea, 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 nea 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 deniA da, o no compilar por segunda vez cuando L TEX lo sugiere, generar un resultado incorrecto a en el dvi. Una referencia no denida, por su parte, hace aparecer un signo ?? en el texto nal. 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 nea 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 a los defectos en el resultado nal son imperceptibles a simple vista, o por lo menos no son sucientes para molestarnos realmente. A veces s por supuesto, y hay que estar atentos. , Siempre conviene revisar el texto y prestar atencin a estos detalles, aunque ello slo tiene o o sentido al preparar la versin denitiva del documento. o

214

CAP ITULO 6. EL SISTEMA DE PREPARACION DE DOCUMENTOS TEX .

Parte II Mtodos Numricos. e e

215

Cap tulo 7 Preliminares.


versin nal 4.3, 22 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 tulo est basado en el primer cap a tulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall
1

217

218

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 &) ; std::istream & operator >> (std::istream &, Vector &) ; #endif

219

La pequea 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() ; } std::istream & operator >> (std::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 neas son

220

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 neas son comentarios que nos recuerdan lo que el programa hace. La l nea siguiente incluye las deniciones de nuestra recin creada clase. Luego inclu e mos una l nea 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 neas 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 o pica 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.

221

Primero consideremos la versin en Octave del programa que llamaremos orthog.m. Las o primeras l neas 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 neas son comentarios; si tipeamos help orthog desde la l nea de comandos, Octave desplegar estas l a neas. El comando clear all en la tercera l nea borra la memoria. Las prximas l o neas 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 neas. Los comentarios que comienzan con %* son aquellos que corresponden al bosquejo del programa que hicimos. En las l neas 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 ndice i, recorre las componentes de los vectores. Una manera hbil a de hacer lo mismo podr ser usar a %* 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 la a y el columna b (donde hemos usado el operador Herm tico conjugado ). Las ultimas l neas 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

222

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 n a Encuentra y para los valores deseados de x , usando la funcin intrpf. o Finalmente, podemos gracar 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 neas 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()

223

224 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 grco: a

Figura 7.1: Salida grca del programa interp. a

7.1. PROGRAMAS Y FUNCIONES. Programa de interpolacin en C++. o Las primeras l neas 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() {

225

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(..) arma 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 neas 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.

226 Estas l neas tambin podr reemplazarse por e an

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 a 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 van 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 grca estndar, as que necesitamos a a una aplicacin grca adicional para gracar la salida. Tambin podemos usar un pequeo 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

227

Figura 7.2: Salida grca del programa interp. a

La ultima l nea del programa delete [] xi ; // Libera la memoria pedida con "new" delete [] yi ; // Libera la memoria pedida con "new" return 0; } Esta l nea 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 neas 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 Especica 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 modicar el valor que ten la variable en el programa principal. o a El resto de la funcin o

228

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 neas 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 neas 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 inter a polado. Los valores interpolados y = p(x ) son calculados por la funcin intrpf desde x = xm o n 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 gracados usando las funciones grcas 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.

229

Los puntos de la interpolacin (x , y ) son gracados con l o nea segmentada y los datos originales con c rculos, ver gura (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 a que aqu cada funcin tiene que ir en un archivo separado. El nombre del archivo debe 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 denido 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 otante usando slo una pequea cantidad u o n de memoria. T picamente, 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 otante es representado por su mantisa y su exponente (por ejemplo, para 6.6251027 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 signicativas. El intervalo mximo es el l a mite sobre la magnitud de los nmeros de punto otante u impuesta por el nmero de bit usados para el exponente. Para precisin simple un valor u o

230

CAP ITULO 7. PRELIMINARES.

t pico es 2127 1038 ; para precisin doble es t o picamente 21024 10308 . Exceder el intervalo de la precisin simple no es dif o cil. Consideremos, por ejemplo, la evaluacin del o radio de Bohr en unidades SI, a0 = 40 2 5.3 1011 [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 1068 [kg C2 ]). La mejor solucin para lidiar con este tipo de dicultades 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 denicin 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 en 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 .

231

(7.6)

Esta aproximacin puede ser usada cuando n es grande (n > 30), de otra manera es preferible o la denicin 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 mite 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 mite, la divisin por cero tiene varias posibles salidas. El computador puede asignar el valor, o Inf, el cual es un nmero de punto otante especial reservado para representar el innito. Ya u que el numerador es tambin cero el computador podr evaluar el cociente siendo indenido e a (Not-a-Number), NaN, otro valor reservado. O el clculo podr parar y arrojar un mensaje a a 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 pequeo, 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 otante: el nmero de d u gitos en la mantisa. Para precisin simple, el nmero de d o u gitos signicantes es t picamente 6 o 7 d gitos decimales; para doble precisin es sobre 16 d o gitos. As en doble precisin, la operacin 3 + 1020 retorna una respuesta 3 por el redondeo; , o o usando h = 10300 en la ecuacin (7.8) casi con seguridad regresar 0 cuando evaluemos el o a numerador. La gura 7.3 ilustra la magnitud del error de redondeo en un clculo t a pico de derivada. Denimos el error absoluto (h) = f (x) f (x + h) f (x) h . (7.9)

Notemos que (h) decrece cuando h se hace ms pequeo, lo cual es esperado, dado que a n la ecuacin (7.8) es exacta cuando h 0. Por debajo de h = 1010 , el error comienza a o incrementarse debido a efectos de redondeo. En valores menores de h el error es tan grande

232

CAP ITULO 7. PRELIMINARES.

10

10

(h)

10

10

10

10

10

10

20

10

16

10

12

10

10

10

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 tulo a la pregunta de cmo o mejorar el clculo de la derivada numricamente. a e Para testear la tolerancia del redondeo, denimos como el ms pequeo 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 1016 . En C++, el archivo de encabezamiento <cfloat> dene DBL_EPSILON (2.2204460492503131e-16) como para doble precisin. o Debido a los errores de redondeo la mayor de los clculos cient a a cos 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 dicultades de redondeo. Por ejemplo, el o o clculo de la inversa de una matriz trabaja bien en simple precisin para matrices pequeas 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 tulo 8 Ecuaciones diferenciales ordinarias: Mtodos bsicos. e a


versin nal 4.1, 22 de Noviembre del 20071 . o

En este cap tulo resolveremos uno de los primeros problemas abordados por un estudiante de f sica: 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 deniremos o e primero la diferenciacin numrica. De hecho antes de aprender f o e sica uno aprende clculo a as que no debemos sorprendernos si este es nuestro punto de partida. En la segunda mitad del cap tulo nos ocuparemos de otro viejo conocido, el pndulo simple, pero sin la aproximacin a e o a ngulos pequeos. 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 ujo alrededor del proyectil. Comnmente, esta fuerza es aproximada por u 1 Fa (v) = Cd A | v | v , 2
1

(8.2)

Este cap tulo est basado en el segundo cap a tulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall

233

234

CAP ITULO 8. EDO: METODOS BASICOS.

donde Cd es el coeciente de arrastre, es la densidad del aire, y A es el rea de la seccin a o transversal del proyectil. El coeciente de arrastre es un parmetro adimensional que depende a de la geometr del proyectil: entre ms aerodinmico el objeto, el coeciente es menor. a a a Para una esfera suave de radio R movindose lentamente a travs del uido, el coeciente e e de arrastre es dado por la Ley de Stokes, Cd = 12 24 = , Rv Re (8.3)

donde es la viscosidad del uido ( 1.5 105 [m2 /s] para el aire) y Re = 2Rv/ es el adimensional nmero de Reynolds. Para un objeto del tamao 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 coeciente 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 tico, el ujo en la estela llega a ser turbulento y el coeciente 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 tico de Reynolds es aproximadamente 3 105 . Para una pelota de baseball, el coeciente de arrastre es usualmente ms pequeo que el de a n una esfera suave, porque las costuras rompen el ujo laminar precipitando el inicio de la turbulencia. Nosotros podemos tomar Cd = 0.35 como un valor promedio para el intervalo de velocidades t picas de una pelota de baseball. Notemos que la fuerza de arrastre, ecuacin (8.2), var como el cuadrado de la magnitud o a 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.

235

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 denicin 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 tulo pasado esta ecuacin debe ser tratada con cuidado. La gura 7.3 ilustra que el uso de un valor o extremadamente pequeo para causa un gran error en el clculo de (f (t + ) f (t))/ . n a Espec camente, 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 pequeo, nosotros necesitamos estimar la diferencia entre f (t) y (f (t + ) f (t))/ para un n nito. Para encontrar esta diferencia usaremos una expansin de Taylor. Como f o sicos usualmente vemos las series de Taylor expresadas como f (t) l m 2 f (t) + . . . (8.8) 2 donde el s mbolo (. . . ) signica 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 nito 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 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 especicado por su orden en , en este caso el error de truncamiento es lineal en . En la gura 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 < 1010 y es el error de truncamiento cuando h > 1010 . f (t) =

236

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 a a Primero, introducimos la notacin o fn = f (tn ) , tn = n , n = 0, 1, 2, . . . (8.17)

tal que f0 = 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 a : 1. Especique las condiciones iniciales, r0 y v0 . 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 sucientes 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 gura 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.

237

an

vn

vn

vn vn+1 an

rn

rn+1 y

Figura 8.1: Trayectoria de una part cula 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 injusticada) modicacin 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 sicos 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).

238

CAP ITULO 8. EDO: METODOS BASICOS.

sido el error local, el error cometido en un unico paso de tiempo. En un problema t pico 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( n1 ) . (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 101 [m], cuando = 101 [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 101 [s] no introducir amos ningn error signicativo 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, ojera, etc.). Sin embargo, a menudo podemos usar la intuicin f o sica. 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 sucientemente 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.

239

Fijar la posicin inicial r0 y la velocidad inicial v0 de la pelota de baseball. o Fijar los parmetros f a sicos ( 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 gracar. 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 Gracar 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)

Altura [m]

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 nea 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

240

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 gura 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 gura 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 coeciente 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 sicos 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.

241

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 pequeo, sen , la ecuacin (8.26) se simplica 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 odo para ngulos pequeos, 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 pequeos, la ecuacin de movimiento es ms dif de o a n o a cil resolver. Sin embargo, sabemos de la experiencia que el movimiento es todav peridico. En a o efecto, es posible obtener una expresin para el per o odo sin resolver expl citamente (t). La energ total es a 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 , a 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 odo el pndulo se balancea de = m a = m y regresa a = m . As en medio e , per odo el pndulo se balancea desde = m a = m . Por ultimo, por el mismo argumento, e

242

CAP ITULO 8. EDO: METODOS BASICOS.

en un cuarto de per odo el pndulo se balancea desde = m a = 0, as integrando ambos e 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 a 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 ptica completa de primera especie,4


/2

K(x)
0

dz , 1 x2 sen2 z

(8.36)

podr amos escribir el per odo 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 pequeos de m , n podr amos 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 pequeo (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 denicin equivalente para la derivada es o f (t) = l m
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 nito. 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.

243

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 a o a o a tengan errores de truncamiento an ms pequeos, 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 citamente 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

244

CAP ITULO 8. EDO: METODOS BASICOS.

De nuevo usamos la notacin fn f (t = n ), en la cual las ecuaciones (8.47) y (8.46) son o escritas como, vn+1 vn1 + 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 = vn1 + 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 pares (r0 , r2 , r4 , . . . ), mientras que la velocidad est calculada en o a los valores impares (v1 , v3 , v5 , . . . ). 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 = vn1/2 + a(rn ) , rn+1 = rn + vn+1/2 , (8.52) (8.53)

con vn1/2 v(t = (n 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 tulo 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 rn1 + O( 2 ) = vn , 2 rn+1 + rn1 2rn + O( 2 ) = an , 2 donde an a(rn ). Reordenando trminos, e vn = rn+1 rn1 + O( 2 ) , 2 (8.58) (8.59) (8.56) (8.57)

rn+1 = 2rn rn1 + 2 an + O( 4 ) .

8.2. PENDULO SIMPLE.

245

Estas ecuaciones, conocidas como el mtodo de Verlet 5 , podr parecer extraas a prie an 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 amos ahora calcular r3 , luego usando la ecua 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 r0 = r(t = 0) y v0 = v(t = 0), pero no v1 = v(t = ) [necesitado por el salto de la rana en la ecuacin (8.50)] o r1 = 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, v1 = v0 a0 . a a Algunas precauciones deber ser tomadas en este primer paso para preservar la precisin an o del mtodo; usando e 2 r1 = r0 v0 + a(r0 ) , (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 tiene propiedades favorables a e (e.g. conservacin de la energ El mtodo de Verlet tiene muchas ventajas. Primero, la o a). e ecuacin de posicin tiene un error de truncamiento menor que otros mtodos. Segundo, si la o o e fuerza es solamente una funcin de la posicin y si nos preocupamos slo de la trayectoria de o o o la part cula y no de su velocidad (como en muchos problemas de mecnica celeste), podemos a saltarnos completamente el clculo de velocidad. El mtodo es popular para el clculo de las a e a trayectorias en sistemas con muchas part culas, e.g., el estudio de uidos a nivel microscpico. o El algoritmo de Verlet, recien visto, no incorpora la velocidad en forma expl cita. Una variante, conocida como velocity Verlet, lo hace expl citamente 1 (8.61) rn+1 = rn + vn + 2 a(rn ) 2 vn+1 = vn + [a(rn ) + a(rn+1 )] . (8.62) 2 Sin embargo, en ambas versiones del algoritmo slo se consideran aceleraciones que deo penden de las posiciones. Para enfretar un problema con aceleraciones que dependen tanto de las posiciones como de las velocidades hay que usar la variante desarrollada por Martys y Mountain de velocity Verlet 6 : 1 rn+1 = rn + vn + 2 a(rn , vn ) (8.63) 2 rn+1 rn un+1/2 = (8.64) vn+1 = vn + a(rn , vn ) + a(rn+1 , un+1/2 ) , (8.65) 2
L. Verlet, Computer experiments on classical uid I. Thermodynamical properties of Lennard-Jones molecules, Phys. Rev. 159, 98-103 (1967). 6 N.S. Martys & R.D. Mountain, Velocity Verlet algorithm for dissipative-particle-dynamics-based models of suspensions, Phys. Rev. E 59, 3733 (1999).
5

246

CAP ITULO 8. EDO: METODOS BASICOS.

Seleccionar el mtodo a usar: Euler o Verlet. e Fijar la posicin inicial 0 y la velocidad 0 = 0 del pndulo. o e Fijar los parmetros f a sicos 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 gracar. 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 transcurrido para estimar el per odo. Estima el per odo de oscilacin, incluyendo barra de error. o Gracar 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

8.2.4.

Programa de pndulo simple. e


d = () dt d = , dt

Las ecuaciones de movimiento para un pndulo simple son e (8.66)

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.67) (8.68)

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 n1 + 2 n . (8.69) 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 odo para pequeas 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 odo de pequeas 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

8.2. PENDULO SIMPLE.

247

per odo por registrar cuando el ngulo cambia de signo; esto es vericar 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 per odo, Tk = 2 (nk+1 nk ), donde nk es el paso de tiempo en el cual el k-simo cambio de e signo ocurre. El per odo estimado de cada inversin de signo es registrado, y el valor medio o calculado como M = 1 T Tk , (8.70) 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 odo es estimada como = s/ M , donde 1 M 1
M 2

s=

Tk T
k=1

(8.71)

es la desviacin estndar de la muestra T . Note que cuando el nmero de medidas se increo a u 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 pequeos, a n m , ya que conocemos el per odo T 2. Tomando = 0.1 tendremos sobre 60 puntos por oscilacin; tomando 300 pasos deber o amos tener como cinco oscilaciones. Para m = 10 , el mtodo de Euler calcula un per e odo 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 odo es entorno a en cada medida. Cinco oscilaciones son 9 medidas de T , as que nuestro error estimado para el per odo deber ser ( /2)/ 9 0.02. Notemos que la a estimacin est en buen acuerdo con los resultados obtenidos usando la desviacin estndar. o a o a Hasta aqu todo parece razonable. Infortunadamente si miramos el grco 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 a a mximo, esto signica que la energ total se incrementa en el tiempo. El error global de a a truncamiento en el mtodo de Euler se acumula en este caso. Para pasos de tiempos pequeos e n = 0.05 e incrementos en el nmero de pasos (600) podemos mejorar los resultados, ver gura 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 gracados 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 pequeo, ecuacin o o a n o (8.38), da T = 7.252. Usando el mtodo de Verlet, el programa da un per e odo estimado de T = 7.414 0.014, lo cual indica que (8.38) es una buena aproximacin (alrededor de un o 2 % de error), an para ngulos grandes. Para el ngulo muy grande de m = 170 , vemos u a a la trayectoria en la gura 8.6. Notemos como la curva tiende a aplanarse en los puntos de retorno. En este caso el per odo estimado es T = 15.3333 0.0667, mientras que (8.38) da

248
40

CAP ITULO 8. EDO: METODOS BASICOS.

30

20

Angulo [grados]

10

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.
20

15

10

Angulo [grados]

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.

T = 9.740, indicando que esta aproximacin para (8.37) deja de ser vlida para este ngulo o a a tan grande.

8.2. PENDULO SIMPLE.


15

249

10

Angulo [grados]

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.

200

150

100

Angulo [grados]

50

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.

250

CAP ITULO 8. EDO: METODOS BASICOS.

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 *

def main(): Cd=0.35 rho=1.293 # [kg/m^3] radio=0.037 # [m] A=math.pi*radio*radio m=0.145 # [kg] g=9.8 # [m/s^2] a=-Cd*rho*A/(2.0*m) 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):") 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:

8.3. LISTADO DE LOS PROGRAMAS EN PYTHON. tiempo = tiempo+tau aux_c=math.cos(math.pi*theta0/180.0) aux_s=math.sin(math.pi*theta0/180.0) l_xT.append(x0+v0*aux_c*tiempo) l_yT.append(y0+v0*aux_s*tiempo-g*tiempo*tiempo/2.0) l_xn.append(xn) l_yn.append(yn)

251

print >> salidaT,x0+v0*aux_c*tiempo, print >> salidaT,y0+v0*aux_s*tiempo-g*tiempo*tiempo/2.0 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 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()

252

CAP ITULO 8. EDO: METODOS BASICOS.

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 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

8.3. LISTADO DE LOS PROGRAMAS EN PYTHON. 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}) grid(True) show() # if __name__==__main__: main()

253

254

CAP ITULO 8. EDO: METODOS BASICOS.

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) ; 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;

8.4. LISTADO DE LOS PROGRAMAS EN C++. 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; }

255

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 ; 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] ;

256

CAP ITULO 8. EDO: METODOS BASICOS.

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 ; } 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 ;

8.4. LISTADO DE LOS PROGRAMAS EN C++. salida.close() ; delete [] periodo; return 0; }

257

258

CAP ITULO 8. EDO: METODOS BASICOS.

Cap tulo 9 Ecuaciones Diferenciales Ordinarias II: Mtodos Avanzados. e


versin nal 4.0, 22 Noviembre 20071 o

En el cap tulo anterior aprendimos cmo resolver ecuaciones diferenciales ordinarias usano do algunos mtodos simples. En este cap e tulo haremos algo de mecnica celeste bsica comena a zando con el problema de Kepler. Al calcular la rbita de un satlite pequeo alrededor de o e n un cuerpo masivo (e.g un cometa orbitando el Sol), descubriremos que mtodos mucho ms e a sosticados 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 pequeo satlite, tal como un cometa, orbita n e el Sol. Usamos un sistema de coordenadas Copernicano y jamos 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 [ao] a n AU (el per odo de una rbita circular de radio 1 [AU]). En estas unidades, el producto o GM = 4 2 [AU3 /ao2 ]. Tomaremos la masa del cometa, m, como la unidad; en unidades n MKS la masa t pica de un cometa es 10153 [kg]. Ahora tenemos suciente 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 tulo est basado en el tercer cap a tulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall.
1

259

260

CAP ITULO 9. EDO II: METODOS AVANZADOS.

a algunos textos de mecnica estndar, tales como Symon2 o Landau y Lifshitz3 . La energ a a a 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, a 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 fuga 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 a [AU/ao] (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 ptica, los semiejes mayores y menores, a y b, son desiguales (gura 9.1). La v= (9.4)

y q 2b r Q 2a
Figura 9.1: Orbita el ptica alrededor del Sol. excentricidad, e, est denida como a e=
2 3

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 [aos] 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

261

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 ptica, si reemplazamos el radio con el semieje mayor; por lo tanto la energ total es a 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 nima en el afelio, la razn entre las velocidades o est dada por Q/q. Finalmente, usando la conservacin de momento angular, podr a o amos derivar la tercera ley de Kepler, 4 2 3 a , (9.10) T2 = GM donde T es el per odo 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 ptico (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 tulo anterior, calcula la trayectoria del cometa como rn+1 = rn + vn , vn+1 = vn + a(rn ) , (9.11) (9.12)

262

CAP ITULO 9. EDO II: METODOS AVANZADOS.

Fijar la posicin y velocidad inicial del cometa. o Fijar los parmetros f a sicos (m, G, etc.). Iterar sobre el nmero deseado de pasos usando el mtodo numrico especicado. u e e Grabar posicin y la energ para gracar. o a 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.

Gracar la trayectoria del cometa. Gracar la energ del cometa versus el tiempo. a

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/ao]. Unos 50 puntos por revolucin o n o orbital nos dar una suave curva, tal que = 0.02 [aos] (o cercano a una semana) es a 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 gura 9.2. Inmediatamente vemos que la rbita no es circular, pero una espiral hacia fuera. La razn es clara desde el grco de energ en vez de o a a; ser constante, la energ total aumenta continuamente. Este tipo de inestabilidad se observa, a 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 gura 9.3. La rbita es casi circular, y la energ total se conserva. o a Las energ potencial y cintica no son constantes, pero este problema podr ser mejorado as e a usando un paso de tiempo pequeo. 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 pticas, como se muestra en la gura 9.4. Note que si la

9.1. ORBITAS DE COMETAS.


90 o
30 Energa Cintica Energa Potencial Energa Total

263

Energa [M AU*AU/ao*ao]

20

10

180o

0o

10

20

30

40 3 2 1

Distancia [AU]

270o

0.5

1.5

2.5

3.5

Tiempo [aos]

Figura 9.2: Grco de la trayectoria y la energ desde el programa orbita usando el mtodo a a e de Euler. La distancia radial inicial es 1 [AU] y la velocidad tangencial inicial es 2 [AU/ao]. n El paso en el tiempo es = 0.02 [aos]; 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 a

energ llega a ser positiva; el satlite alcanza la velocidad de escape. Si bajamos el paso de a e tiempo desde = 0.02 [aos] a = 0.005 [aos] obtenemos mejores resultados, como los n n mostrados en la gura 9.5. Estos resultados no son del todo perfectos; la rbita puede ser o una elipse cerrada, pero todav tiene una notable deriva espria. a u En este punto usted se podr estar preguntando, Por qu estamos estudiando este a e problema?, si la solucin anal o tica 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 amos, siempre, chequear los algoritmos de problemas conocidos. Suponga que introducimos una pequea fuerza de n arrastre sobre el cometa. Podr amos pecar de inocentes creyendo que la precisin de la gura o 9.5 fue un fenmeno f o sico 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 pticas. 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 desa a tructivo que una guerra nuclear. Muchos cometas tienen rbitas extremadamente el o pticas y per odos de cientos de aos. Esta amenaza desde el espacio exterior motiva nuestro estudio n de mtodos ms avanzados para resolver ecuaciones diferenciales ordinarias. e a

264
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: Grco de la trayectoria y la energ desde el programa orbita usando el mtodo a a e de Euler-Cromer. Los parmetros son los mismos que en la gura 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 a 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]

Figura 9.4: Grco de la trayectoria y la energ desde el programa orbita usando el mtodo a a e de Euler-Cromer. La distancia radial inicial es 1 [AU] y la velocidad tangencial inicial es [AU/ao]. El paso en el tiempo es = 0.02 [aos]; y 200 pasos son calculados. Debido al n n error numrico el cometa alcanza la velocidad de escape, la posicin nal es 35 [AU] y la e o energ total es positiva. a

9.2. METODOS DE RUNGE-KUTTA.


90 o Energa [M AU*AU/aos*aos] 300 200 100 0 Energa Cintica Energa Potencial Energa Total

265

180o

0o

100 200 300

270o

0.5 Distancia [AU]

0.5

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: Grco de la trayectoria y la energ desde el programa orbita usando el mtodo a a e de Euler-Cromer. Los parmetros son los mismos que en la gura 9.4 excepto que el paso de a tiempo es ms pequeo = 0.005 [aos]. 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 camente a nuestro problema del cometa. De esta manera ser fcil usar el mtodo Runge-Kutta para otros sistemas f a a e sicos. 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 citamente del tiempo sino que slo depende de x(t). o

266

CAP ITULO 9. EDO II: METODOS AVANZADOS.

Nuestro punto de partida es el mtodo simple de Euler; en forma vectorial podr ser e a 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) = et . 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.

267

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: 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

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 coecientes no especicados: , , 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 coecientes 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 coecientes 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 cita 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.

268

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 cos, 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 tmo de paso adaptativo. . . Bulirsch-Stoer o los mtodos predictor-corrector pueden ser e mucho ms ecientes para problemas donde se require una alta precisin. Estos a o mtodos son los nos caballos de carrera mientras que Runge-Kutta es el el 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 pequeo 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 gura 9.6, la cual es mucho mejor que las obtenidas usando el mtodo de e Euler-Cromer (gura 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.

269

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. (Slo c++) o

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 denicin de f (como lo haremos en la ultima seccin). Para el problema de o o Kepler, la funcin gravrk (tabla 9.4) dene 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 nea de rk4 es void rk4(double * x, int nX, double t, double tau, void (*derivsRK) (double *, double, double, double *) , double param)

270
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

100

200

0.5

Distancia [AU]

270

0.5

300

0.2

0.4

0.6

0.8

1.0

Tiempo [aos]

Figura 9.6: Grco de la trayectoria y la energ desde el programa orbita usando el mtodo a a e de Runge-Kutta. La distancia radial inicial es 1 [AU] y la velocidad tangencial inicial es [AU/ao]. El paso en el tiempo es = 0.005 [aos]; y 200 pasos son calculados. Comparemos n n con la gura 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 pequeos), hace un mejor trabajo dentro de una rbita altamemente el n o ptica. An para una u distancia inicial al afelio de 1 [AU] y una velocidad inicial en el afelio de /2 [AU/ao] usando n 1 un paso tiempo tan pequeo como = 0.0005 [aos] ( 4 2 [hrs]), la energ total var sobre n n a a el 7 % por rbita. Si pensamos la f o sica, llegamos a que realizar una integracin con un paso o pequeo 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 pequeo en la trayectoria cuando rodea al Sol a n causa una gran desviacin en la energ potencial. o a La idea ahora es disear un programa que use un paso de tiempo pequeo 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

271

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 n a y error manual, podr ser peor que hacindolo por la fuerza bruta calculando con un paso a e de tiempo pequeo toda la trayectoria. Idealmente, deseamos estar completamente liberados n de tener que especicar un paso de tiempo. Deseamos tener una trayectoria calculada de la misma posicin inicial hasta algn tiempo nal con la seguridad de que la solucin es correcta o u o a una precisin especicada o Los programas adaptativos continuamente monitorean la solucin y modican el paso de o tiempo para asegurar que se mantenga la precisin especicada 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 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 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 especicado 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 amos 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.

272

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 mite. Tomar dos pequeos 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 mite 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 insucientemente pequeo, a a n y tendr amos que continuar reduciendo el paso de tiempo; pero al menos sabr amos que no ocurrir de un modo incontrolado. a Este procedimiento no es a prueba de balas, los errores de redondeo llegan a ser signicativos en pasos de tiempos muy pequeos. Por esta razn la iteracin adaptativa podr n o o a fallar para encontrar un paso de tiempo que de la precisin deseada. Debemos mantener esta o limitacin en mente cuando especiquemos 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 especicado. 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 a o la rka. Usando el mtodo de Runge-Kutta adaptativo, el programa orbita da los resultados en e la gura 9.7 para una rbita altamente el o ptica. 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 (gura 9.6) en el cual los pasos en el perihelio son ampliamente

9.3. METODOS ADAPTATIVOS


90 o
1500

273

Energa [M AU*AU/aos*aos]

Energa Cintica Energa Potencial Energa Total

1000

500

180

0o

500

1000

270
1 0.5 0

o 0.5 1

1500

0.05

0.1

0.15

0.2

0.25

Distancia [AU]

Tiempos [aos]

Figura 9.7: Grco de la trayectoria y la energ desde el programa orbita usando el mtodo a a e de Runge-Kutta adaptativo. La distancia radial inicial es 1 [AU] y la velocidad tangencial inicial es /2 [AU/ao]. El paso inicial en el tiempo es = 0.1 [aos]; y 40 pasos son n n calculados.

0.1

0.01 Tau [aos]

0.001

0.0001 0.01

0.1 Distancia [Au]

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 gura e e 9.7.

espaciados. Una grca de los pasos de tiempo versus la distancia radial (gura 9.8) muestra a que var casi tres rdenes de magnitud. a o Interesantemente esta grca 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

274

CAP ITULO 9. EDO II: METODOS AVANZADOS.

9.4.
9.4.1.

Listados del programa.


orbita.py

#!/usr/bin/env python # -*- coding: iso-8859-1 -*import sys import math from matplotlib import rc from pylab import * import numpy rc(text, usetex=True) GM=4.0e0*math.pi*math.pi masaCometa = 1.0e0 adaptErr = 1.0e-3 def gravrk(x,t): global GM vX=x[2] vY=x[3] mod_r= math.sqrt(x[0]*x[0]+x[1]*x[1]) aX= -GM*x[0]/(mod_r*mod_r*mod_r) aY= -GM*x[1]/(mod_r*mod_r*mod_r) ## Retorna la derivada return numpy.array( [vX,vY,aX,aY] )

def rk4( x, tiempo, tau): ## Evaluemos F1=f(x,t) F1 = gravrk(x,tiempo) half_tau = tau/2.0e0 t_half = tiempo+half_tau t_full = tiempo+tau ## Evaluamos F2=f(x+tau*F1/2, t+tau/2) xtemp = x + half_tau*F1 F2 = gravrk(xtemp, t_half) ## Evaluamos F3=f(x+tau*F2/2, t+tau/2)

9.4. LISTADOS DEL PROGRAMA. xtemp = x + half_tau*F2 F3 = gravrk(xtemp, t_half) ## Evaluamos F4=f(x+tau*F3, t+tau) xtemp = x + tau*F3 F4 = gravrk(xtemp, t_full) ## Retornamos x(t+tau) return x + tau*(F1+F4+2.0*(F2+F3))/6.0

275

def rka( x ): global adaptErr tiempo = x[4] tSave = tiempo tau=x[5] ## factores de seguridad safe1 = 0.9 safe2 = 4.0 maxTray=100 for iTray in range(0,maxTray): ## Tomemos dos pequennos pasos en el tiempo half_tau = 0.5*tau xSmall = numpy.array( [x[0],x[1],x[2],x[3]] ) xSmall=rk4( xSmall, tSave, half_tau) tiempo = tSave + half_tau xSmall=rk4( xSmall, tiempo, half_tau) ## Tomemos un solo tiempo grande xBig = numpy.array( [x[0],x[1],x[2],x[3]] ) xBig=rk4( xBig, tSave, tau) ## Calculemos el error de truncamiento estimado erroRatio = 0.0e0 eps = 1.0e-16 for i in range(0,4): scale = adaptErr * (math.fabs(xSmall[i]) + fabs(xBig[i]))/2.0e0 xDiff = xSmall[i] - xBig[i] ratio = fabs(xDiff)/(scale+eps) if erroRatio <= ratio : erroRatio=ratio

276

CAP ITULO 9. EDO II: METODOS AVANZADOS. ## Estimamos el nuevo valor de tau (incluyendo factores de seguridad) tau_old= tau tau = safe1*tau_old*math.pow(erroRatio, -0.20) if tau <= tau_old/safe2 : tau=tau_old/safe2 if tau >= safe2*tau_old : tau=safe2*tau_old

## Si el error es aceptable regrese los valores computados if erroRatio < 1 : return numpy.array( [xSmall[0],xSmall[1],xSmall[2],xSmall[3], tiempo, tau] ) else: print "Error: Runge-Kutta adaptativo fallo" sys.exit()

def main(): salidaO = open("Orbita.txt","w") salidaE = open("Energia.txt","w") salidaT = open("Tau.txt","w") r0 = input("Ingrese la distancia radial inicial [AU]: ") vT = input("Ingrese la velocidad tangencial inicial [AU/annos]: ") x0=r0 y0=0.0e0 vx0=0.0e0 vy0=vT ## ## Suponemos angulo inicial nulo ## metodo = 0 while metodo < 1 or metodo > 4: print "Ingrese el metodo a usar :" print "\t Metodo de Euler \t\t\t[1]" print "\t Metodo de Euler-Cromer \t\t[2]" print "\t Metodo de Runge-Kutta 4 orden \t\t[3]" print "\t Metodo de Runge-Kutta adaptativo \t[4]" metodo=input("elija : ") tau= input("Ingrese paso en el tiempo: ") numPasos = input("Ingrese el numero de pasos: ")

9.4. LISTADOS DEL PROGRAMA. xN= x0 yN= y0 vxN=vx0 vyN=vy0 tiempo = 0.0e0 l_r=[] l_theta=[] l_tiempo=[] l_Ek=[] l_Ep=[] l_ET=[] l_distancia=[] l_tau=[] for pasos in range(0,numPasos): r = math.sqrt(xN*xN+yN*yN) v2 =vxN*vxN+vyN*vyN theta= math.atan2(yN, xN) l_r.append(r) l_theta.append(theta) print >> salidaO, theta, r Ek = masaCometa*v2/2.0e0 Ep = -GM*masaCometa/r ET= Ep+Ek l_tiempo.append(tiempo) l_Ek.append(Ek) l_Ep.append(Ep) l_ET.append(ET) print >> salidaE, tiempo, Ek, Ep, ET modr3=math.pow(xN*xN+yN*yN, 3.0/2.0) axN= -GM*xN/modr3 ayN= -GM*yN/modr3

277

if metodo==1:

## Euler

vxNp1=vxN+tau*axN vyNp1=vyN+tau*ayN xNp1= xN+tau* vxN yNp1= yN+tau* vyN tiempo += tau elif metodo==2: ## Euler-Cromer

278

CAP ITULO 9. EDO II: METODOS AVANZADOS.

vxNp1=vxN+tau*axN vyNp1=vyN+tau*ayN xNp1= xN+tau* vxNp1 yNp1= yN+tau* vyNp1 tiempo += tau elif metodo==3: ## Runge-Kutta 4to Orden x= numpy.array( [xN,yN,vxN,vyN] ) x_new = rk4( x, tiempo, tau) xNp1=x_new[0] yNp1=x_new[1] vxNp1=x_new[2] vyNp1=x_new[3] tiempo += tau elif metodo==4: ## Runge-Kutta 4to Orden Adaptativo

x= numpy.array( [xN,yN,vxN,vyN, tiempo, tau] ) x_new = rka( x ) distancia = math.sqrt( x_new[0]*x_new[0]+x_new[1]*x_new[1]) tiempo=x_new[4] tau=x_new[5] l_distancia.append(distancia) l_tau.append(tau) print >> salidaT, distancia, tau xNp1=x_new[0] yNp1=x_new[1] vxNp1=x_new[2] vyNp1=x_new[3] xN=xNp1 yN=yNp1 vxN=vxNp1 vyN=vyNp1 salidaO.close() salidaE.close() salidaT.close() figure(1) ax = axes([0.1, 0.1, 0.8, 0.8], polar=True, axisbg=#d5de9c) polar(l_theta, l_r, color=#ee8d18, lw=2) title(r\textbf{\Huge \Orbita})

9.4. LISTADOS DEL PROGRAMA.

279

figure(2) linea_Ek = plot(l_tiempo, l_Ek) setp(linea_Ek, color=b, linewidth=1.0) linea_Ep = plot(l_tiempo, l_Ep) setp(linea_Ep, color=g, linewidth=1.0) linea_ET = plot(l_tiempo, l_ET) setp(linea_ET, color=r, linewidth=1.0) legend((rEnerg\ia Cin\etica, rEnerg\ia Potencial, rEnerg\ia Total), upper right, shadow=True) xlabel(r\textbf{\Large Tiempo (a\~nos)}) ylabel(r\textbf{\Large Energ\ia (M*AU$^2$/a\~no$^2$)}) title(r\textbf{\Huge Energ\ia}) grid(True) if metodo == 4: figure(3) loglog(l_distancia,l_tau,"b+") xlabel(r\textbf{\Large Distancia (AU)}) ylabel(r\textbf{\Large $\tau$ (a\~no)}) title(r\textbf{\Huge Variaci\on del paso de tiempo}) grid(True) show() # if __name__==__main__: main()

9.4.2.

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] ;

280

CAP ITULO 9. EDO II: METODOS AVANZADOS.

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 ; } 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\~nos pasos en el tiempo double half_tau = 0.5*tau ; for (int i =0; i < nX; i++) xSmall[i]=x[i] ;

9.4. LISTADOS DEL PROGRAMA. 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 ; exit(-1) ; }

281

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] = vX;

282 deriv[1] = vY; deriv[2] = aX; deriv[3] = aY; }

CAP ITULO 9. EDO II: METODOS AVANZADOS.

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/annos]: " ; 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 metodo a usar :" << endl ; cout << "\t Metodo de Euler \t\t\t[1]" << endl; cout << "\t Metodo de Euler-Cromer \t\t[2]" << endl; 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] ;

9.4. LISTADOS DEL PROGRAMA. double double double double double double xN= x0; yN= y0; vxN=vx0; vyN=vy0; vxNp1, vyNp1, xNp1, yNp1; tiempo = 0.0e0 ;

283

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 ; } 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);

284 xNp1=x[0] ; yNp1=x[1]; vxNp1=x[2]; vyNp1=x[3]; tiempo += tau ;

CAP ITULO 9. EDO II: METODOS AVANZADOS.

} 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() ; delete [] x; return 0; } Otra versin del programa, esta vez con clases o

9.4.3.

vector4d.h

#ifndef _vector_4d_h #define _vector_4d_h // // Clase basica de vectores 4d para Runge-Kutta // #include <iostream> class Vector{

9.4. LISTADOS DEL PROGRAMA.

285

private: double c_t; double c_x; double c_y; double c_z; public: Vector():c_t(0),c_x(0),c_y(0),c_z(0) {} ; Vector(double t,double x, double y, double z):c_t(t),c_x(x),c_y(y),c_z(z) {} ; void set(double,double, double, double); double componente(int); ~Vector() {} ; double t() const {return c_t;}; double x() const {return c_x;}; double y() const {return c_y;}; double z() const {return c_z;}; }; Vector Vector Vector Vector double #endif operator operator operator operator operator + * / * (const Vector &, const Vector &) ; (const Vector &, const Vector &) ; (double, const Vector &) ; (const Vector &, double) ; (const Vector &, const Vector &) ;

9.4.4.

vector4d.cc

#include "vector4d.h"

void Vector::set(double t, double x, double y, double z) { c_t=t; c_x=x; c_y=y; c_z=z; } double Vector::componente(int i) { double d=0; if (i==0) { d=c_t; } else if(i==1) { d=c_x; } else if(i==2) { d=c_y; } else if(i==3) {

286

CAP ITULO 9. EDO II: METODOS AVANZADOS.

d=c_z; } else { std::cout << "Error en componente"<< std::endl; exit(-1); } return d; } Vector operator + (const Vector & v1, const Vector &v2) { return Vector(v1.t()+v2.t(),v1.x()+v2.x(),v1.y()+v2.y(),v1.z()+v2.z()) ; } Vector operator - (const Vector & v1, const Vector &v2) { return Vector(v1.t()-v2.t(),v1.x()-v2.x(),v1.y()-v2.y(),v1.z()-v2.z()) ; } Vector operator * (double r, const Vector &v) { return Vector(r*v.t(),r*v.x(),r*v.y(),r*v.z()) ; } Vector operator / (const Vector & v, double r) { return Vector(v.t()/r,v.x()/r,v.y()/r,v.z()/r) ; } double operator * (const Vector & v1, const Vector &v2) { return v1.t()*v2.t()+v1.x()*v2.x()+v1.y()*v2.y()+ v1.z()*v2.z() ; }

9.4.5.

orbita2.cc

#include "NumMeth.h" #include "vector4d.h" const double GM=4.0e0*M_PI*M_PI ; const double masaCometa = 1.0e0 ; const double adaptErr = 1.0e-3; Vector rk4(Vector, double, double); Vector rka ( Vector, double & , double &); Vector gravrk( Vector, double );

int main() { ofstream salidaO ("Orbita.txt") ; ofstream salidaE ("Energia.txt") ;

9.4. LISTADOS DEL PROGRAMA. 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\~nos]: " ; 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\etodo num\erico a usar :" << endl ; cout << "\t M\etodo de Euler \t\t\t[1]" << endl; cout << "\t M\etodo de Euler-Cromer \t\t[2]" << endl; cout << "\t M\etodo de Runge-Kutta 4 orden \t\t[3]" << endl; cout << "\t M\etodo 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 n\umero de pasos: " ; cin >> numPasos ; Vector x; double double double double double double xN= x0; yN= y0; vxN=vx0; vyN=vy0; vxNp1, vyNp1, xNp1, yNp1; tiempo = 0.0e0 ;

287

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 ;

288

CAP ITULO 9. EDO II: METODOS AVANZADOS.

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 ; } 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.set(xN,yN,vxN,vyN); Vector x_new=rk4( x, tiempo, tau); xNp1=x_new.t() ; yNp1=x_new.x(); vxNp1=x_new.y(); vyNp1=x_new.z(); tiempo += tau ; } break ; case 4: { x.set(xN,yN,vxN,vyN); // Runge-Kutta 4to orden adaptativo Vector x_new=rka( x, tiempo, tau); double distancia = sqrt( x_new.t()*x_new.t()+x_new.x()*x_new.x()) ; salidaT<< distancia << " " <<tau << endl ; xNp1=x_new.t() ; yNp1=x_new.x(); vxNp1=x_new.y(); vyNp1=x_new.z();

9.4. LISTADOS DEL PROGRAMA. } } xN=xNp1 ; yN=yNp1 ; vxN=vxNp1 ; vyN=vyNp1 ; } salidaO.close() ; salidaE.close() ; salidaT.close() ; return 0; } Vector rk4(Vector x, double t, double tau) { // Evaluemos F1=f(x,t) Vector F1 = gravrk(x, t) ; 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) Vector xtemp=x+half_tau*F1; Vector F2 = gravrk(xtemp, t_half) ; // Evaluamos F3=f(x+tau*F2/2, t+tau/2) xtemp=x+half_tau*F2 ; Vector F3 = gravrk(xtemp, t_half) ; // Evaluamos F4=f(x+tau*F3, t+tau) xtemp=x+tau*F3 ; Vector F4 = gravrk(xtemp, t_full) ; // Retornamos x(t+tau) Vector x_new = x + tau*(F1+F4+2.0e0*(F2+F3))/6.0e0 ; return x_new; } Vector rka ( Vector x, double & t, double & tau) { double tSave = t ; double safe1 = 0.9, safe2 = 4.0 ; //factores de seguridad

289

290

CAP ITULO 9. EDO II: METODOS AVANZADOS.

int maxTray=100 ; for (int iTray=0; iTray<maxTray; iTray++) { // Tomemos dos peque\~nos pasos en el tiempo double half_tau = 0.5*tau ; Vector xSmall = x ; xSmall=rk4( xSmall, tSave, half_tau) ; t= tSave + half_tau ; xSmall=rk4( xSmall, t, half_tau) ; // Tomemos un solo tiempo grande Vector xBig = x; xBig=rk4( xBig, tSave, tau) ; // Calculemos el error de truncamiento estimado double erroRatio = 0.0e0 ; double eps = 1.0e-16 ; for (int i = 0 ; i < 4; i++) { double scale = adaptErr * (fabs(xSmall.componente(i)) + fabs(xBig.componente(i)))/2.0e0 ; double xDiff = xSmall.componente(i) - xBig.componente(i) ; double ratio = fabs(xDiff)/(scale+eps) ; if (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) ; if (tau <= tau_old/safe2) tau=tau_old/safe2 ; if(tau >= safe2*tau_old) tau=safe2*tau_old ; // Si el error es aceptable regrese los valores computados if ( erroRatio < 1 ) { return xSmall; } } cout << "Error: Runge-Kutta adaptativo fallo" << endl ; exit(-1) ; } Vector gravrk( Vector v, double t) { double mod_r= sqrt(v.t()*v.t()+v.x()*v.x()) ; double aX= -GM*v.t()/(mod_r*mod_r*mod_r) ; double aY= -GM*v.x()/(mod_r*mod_r*mod_r) ; // Retorna la derivada return Vector(v.y(),v.z(),aX,aY); }

Cap tulo 10 Resolviendo sistemas de ecuaciones.


versin nal 3.1, 22 Noviembre 20071 o

En este cap tulo 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 tulo 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 autnomos donde f (x, t) = f (x), esto es, f no depende expl o citamente 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 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 tulo est basado en el cuarto cap a tulo 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).

291

292

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 a a estados estacionario. En este cap tulo 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 nal del cap tulo.

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.

293

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 . 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 a 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 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 coecientes son a 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 mite 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 a 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 pequeo, 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

294

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 a o a 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 mite 0. Los algoritmos que reordenan las ecuaciones cuando ellas sitan elementos pequeos 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 a pequeos elementos sobre la diagonal principal. El precio de pivotear es slo un par de l n o neas extras en el programa, pero es esencial usar pivoteo para todas, no slo para las matrices ms o a pequeas. 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.

295

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 cientes 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 coecientes 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 lmente ms complicado cuando se usa el pivoteo. Si el nmero a u de pivoteos es impar, el determinante es el producto negativo de los coecientes de los elementos de la diagonal. Ahora deber ser obvio que la regla de Cramer es computacionalmente a una manera ineciente 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 z deber entender, en general, como trabaja y reconocer posibles problemas, especialmente los a 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 la, 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).

296

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 otante 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 la con un delete[]). Una asignacin a o esttica es simple pero r a gida, ya que las dimensiones son constantes jas. Cuando el arreglo esttico es pasado a una funcin, esta funcin deber declarar algn arreglo con el mismo a o o a u nmero de columnas de acuerdo al arreglo a ser indexado apropiadamente. Una asignacin u o dinmica es exible pero es dif de manejar, aunque los detalles pueden ser escondidos a cil 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 cil a C++ nos permite corregir estas deciencias creando nuestros propios tipos de variables. Estas variables denidas por el usuario son llamadas clases de objetos. De aqu en adelante usaremos la clase Matrix para declarar arreglos de una o dos dimensiones de nmeros de punto u otante. 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 jas. 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 jados 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.

297

Entradas: A, b. Salidas: x, det A. Fija el factor de escala, si = maxj (| Ai,j |) para cada la. Itera sobre las las k = 1, . . . , (N 1). Selecciona la la a pivotear a partir de maxj (| Aj,k |)/sk . Realiza pivoteos usando la lista de ndice de las. 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 vericacin de los contornos se realiza cada vez que o un objeto Matrix es indexado. Las l neas Matrix newA(3, 7) ; newA(4,5) = 0; // Una matriz no cuadrada de 3 por 7 // Fuera de los limites

produce el mensaje de error: Indice de fila fuera de los limites cuando el programa es corrido. Esto signica que al menos uno de los ndices 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 tamao (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 an picamente 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.

298

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 a o Ax = b , como x = A1 b , (10.21) donde A1 es la matriz inversa de A. No nos deber sorprender que el clculo de la matriz a 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 denida por la ecuacin a o A A1 = I , donde I es la matriz identidad 1 0 I = 0 . . . ... . . . . . . . .. . (10.22) (10.20)

0 1 0 . . .

0 0 1 . . .

(10.23)

Deniendo los vectores columna 1 0 e1 = 0 , . . .

0 1 e2 = 0 , . . .

... ,

. . . eN = 0 , 0 1

(10.24)

podr amos escribir la matriz identidad como una vector la 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 A1 . Si procedemos de esta manera o con los otros e calcularemos todas las columnas de A1 . 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.

299

Entradas: A. Salidas: A1 , det A. Matriz es inicializada a la matriz identidad. b Fija el factor de escala, si = maxj (| Ai,j |) para cada la. Itera sobre las las k = 1, . . . , (N 1). Selecciona la la a pivotear a partir de maxj (| Aj,k |)/sj . Realiza pivoteos usando la lista de ndice de las. 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 A1 como e (x1 )1 (x1 )2 = . . . (x2 )1 (x2 )2 . . . . . . (xN )1 . . . (xN )2 . .. . . . . . . (xN )N

A1 = 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 a nmero de problemas similares en el cual la matriz A es ja pero el vector b toma muchos u valores diferentes. Finalmente, aqu hay una frmula manual para tener presente: la inversa o de una matriz 2 2 es A1 = 1 a22 a12 a11 a22 a12 a21 a21 a11

(10.29)

Para matrices mayores las frmulas rpidamente llegan a ser muy desordenadas. o a

300

CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES.

10.2.2.

Matrices singulares y patolgicas. o

Antes que regresemos a la F sica, 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 a 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) 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 innito o de un mensaje 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 an a 1+ 2 1 2 , (10.33)

donde es un nmero muy pequeo. 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.

301

Formalmente, la condicin numrica est denida como la distancia normalizada entre o e a una matriz y la matriz singular ms cercana5 . Hay una variedad de maneras para denir 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 pequeo determinante puede algunas veces advertirnos que la matriz podr o n a 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 tulo, 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 gura 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 citamente 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).

302

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 as a cil 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.

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 desaante) 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 cil, 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 z 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 z; a esta estimacin x1 . Nuestro error podr ser escrito como x = x1 x o x = x1 x. o a 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 z, 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 a 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 grcamente (gua a ra 10.2). Note que en cada paso usamos la derivada de f (x) para dibujar la l nea tangente a
7

F.S. Acton, Numerical Methods that Work (New York: Harper&Row, 1970).

10.3. SISTEMAS DE ECUACIONES NO LINEALES.

303

f(x)

x2 x1 x3

x*

Figura 10.2: Representacin grca del mtodo de Newton. o a e

la funcin. Donde esta l o nea 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 z. o es bien comportada, pronto ser aproximadamente lineal en alguna vecindad cerca de la ra a z 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 z a falla. Para funciones bien comportadas, este mtodo es garantizado que converger si estamos e sucientemente cerca de la ra Por esta razn algunas veces est combinada con un algoritmo z. o a ms lento pero que asegura encontrar la ra tal como la biseccin. Segundo, si hay varias a z, o raices, la ra a la cual el mtodo converge depende de la estimacin inicial (que podr no z e o a ser la ra deseada). Hay procedimientos (e.g., deation) para encontrar mltiples raices z 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 cil e incgnita x = [x1 , x2 , . . . , xN ] es un vector la, y deseamos encontrar los ceros (raices) de o la funcin vector la 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 z, o Nuestro error podr ser esrito como x = x1 x o x = x1 x. Usando la expansin de a o Taylor de f (x1 ), f (x ) = f (x1 x) = f (x1 ) x D(x1 ) + O(x 2 ) , donde D es el Jacobiano, denido como Dij (x) = fj (x) . xi (10.44) (10.43)

304

CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES.

Ya que x es la ra f (x ) = 0, como antes podr z, amos 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 ) D1 (x1 ) . Nuestra nueva estimacin es o x2 = x1 x = x1 f (x1 ) D1 (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 a 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 e o o tiempo es intr nsecamente 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, o reduciendo el problema a un sistema de ecuaciones diferenciales ordinarias de 12 variables. El observ que este sistema ten un comportamiento aperidico y que era extremadamente o a o sensible a las condiciones iniciales. Estudiemos un modelo de Lorenz simplicado 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 uido 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 uido y de la geometr del contenedor; a a 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.

305

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 z Imprime la estimacin nal de la ra o z.

Cuadro 10.3: Descripcin del programa newtn, el cual encuentra una ra para un conjunto o z de ecuaciones. Para r = 28, = 10 y b = 8/3, las tres ra ces 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]. z 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]. z Comenzando por el punto [4, 4, 15], el mtodo converge a una ra slo despus de hacer e z o e una excursin incre o blemente distante del origen.

10.3.4.

Continuacin. o

La primera dicultad 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 z. f (x ; ) = 0 , (10.50)

donde es algn parmetro en el problema. Supongamos que conocemos una ra x0 para el u a z valor 0 pero necesitamos encontrar una ra para un valor diferente de a . Intuitivamente, z si a 0 , entonces x0 deber ser una buena estimacin inicial para encontrar xa usando a o

306

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 z conocida? La respuesta es s y la tcnica es conocida como continuacin. La idea es acercarse poco e o a poco a a deniendo 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 sucientemente grande, entonces 1 0 y el mtodo o e podr converger rpidamente. Luego usamos x1 como una estimacin inicial para resolver a a o f (x2 ; 2 ) = 0; la secuencia contina hasta alcanzar nuestro valor deseado en a . La tcnica u e de continuacin tiene un benecio adicional que podemos usar cuando estamos interesados o en conocer no slo una ra simple, sino conocer como x var con . o z a

10.4. LISTADOS DEL PROGRAMA.

307

10.4.
10.4.1.

Listados del programa.


Manejo de matrices en Python.

#!/usr/bin/env python # -*- coding: iso-8859-1 -*from numpy import * A= array( [[0,1,1], [1,1,0], [1,0,1]] ) b= array( [[5],[3],[4]] ) c= array( [5,3,4] ) print A print b print c print print print print linalg.solve(A,b) linalg.solve(A,c) linalg.det(A) linalg.inv(A) # # # # Resuelve Ax=b Resuelve Ax=c Determinante matriz Inversa de la matriz # Matriz # vector columna # vector fila

10.4.2.

Programa newtn en Python.

#!/usr/bin/env python from numpy import * def fnewt(x,a): f = array( [a[1]*(x[1]-x[0]), a[0]*x[0]-x[1]-x[0]*x[2], x[0]*x[1]-a[2]*x[2]]) D = array( [[-a[1], a[1], 0], [a[0]-x[2], -1, -x[0]], [x[1], x[0],-a[2]]]) return (f,D) def main(): x = input("Ingrese la estimacion inicial x_1, x_2, x_3 : ") x0=array(x) t = input("Ingrese los parametros r, sigma, b : ") a=array(t) nStep=10 for i in range(0,nStep): f, D = fnewt(x,a)

308

CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES. dx = linalg.solve(D,f) x=x-dx print "Despues de %d iteraciones la raiz es" % nStep print x

# end main if __name__==__main__: main()

10.4.3.

Denicin 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 );

10.4. LISTADOS DEL PROGRAMA.

309

void error ( int, string="Error") ; Matrix operator * (Matrix, Matrix) ; Matrix operator + (Matrix, Matrix) ; Matrix operator - (Matrix, Matrix) ; #endif

10.4.4.

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++) } // Constructor de copia matriz de N por M a un valor ingresado double v) { las dimensiones no es positiva" ) ;

// Habia memoria para reservar dataP[i]=v ;

310

CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES.

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 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 double max= dataP[nColP*indF]; for(int i=nColP*indF; i<nColP*(indF+1); i++ ) {

en maximoF") ;

10.4. LISTADOS DEL PROGRAMA. max = (max > fabs(dataP[i]) ) ? max : fabs(dataP[i]) ; } return max ; }

311

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") ; 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) {

312

CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES.

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() ; 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 ; } 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++){

10.4. LISTADOS DEL PROGRAMA. for (int indC=0; indC<nColA; indC++){ R(indF, indC) = A( indF, indC) - B(indF, indC); } } return R ; }

313

10.4.5.

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); }

314

CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES.

} 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 } ;

10.4.6.

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. LISTADOS DEL PROGRAMA.

315

10.4.7.

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; for iStep=1:nStep [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

316

CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES.

10.4.8.

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 b, Matrix & x) { int nFil = A.nRow() ; int nCol = A.nCol() ; Matrix si (nFil) ; for ( int indF= 0; indF < nFil ; indF++) si(indF)= A.maximoF(indF) ; double determinante=1.0e0 ; for (int indC= 0; indC< nCol-1; indC++) { double max = A(indC,indC)/si(indC) ; // pivoteo 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) {

10.4. LISTADOS DEL PROGRAMA. 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 ) ; ge(D, f, dx) ; xNp1=xN-dx ; xN=xNp1 ; cout << xN(0)<< " " << xN(1) << " " << xN(2) << endl ; } cout << xN <<endl ; return 0; }

317

318

CAP ITULO 10. RESOLVIENDO SISTEMAS DE ECUACIONES.

Cap tulo 11 Anlisis de datos. a


versin 3.0, 02 de Diciembre 20031 o

A menudo se destaca que los sistemas f sicos simulados sobre un computador son similares al trabajo experimental. La razn de esta analog es hecha ya que la simulacin computacioo a 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 tulo 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 a o aos, aunque no la cantidad de precipitaciones de un d en particular. n a 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 cos y legisladores todav estn debatiendo la amenaza del calentamiento a a global. Sin embargo, nadie se pregunta qu concentraciones de gases invernadero estn en e a aumento. Espec camente, los niveles de dixido de carbono han estado rmemente aumeno tados desde la revolucin industrial. La gura 11.1 muestra el aumento en la concentracin o o de dixido de carbono durante los aos 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 tulo estudiaremos algunas tcnicas bsicas para analizar y reducir tales conjuntos de datos. Por e a ejemplo, para los datos mostrados en la gura 11.1, cul es la razn estimada de crecimiento a o
Este cap tulo est basado en el quinto cap a tulo del libro: Numerical Methods for Physics, second edition de Alejandro L. Garcia, editorial Prentice Hall.
1

319

320

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 ao?. Esta es la primera pregunta que motiva nuestro estudio o n de ajustes de curvas.

11.1.2.

Teor general. a

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 grco del conjunto de datos (xi , yi ) a y la funcin Y (x; {aj }) mostrarn la curva pasando cerca de los puntos (ver gura 11.2). o a Podemos cuanticar 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 nimo; 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.

321

yi 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 obtener un ajuste de la curva, pero es la ms comn. El mtodo de los m a u e nimos 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 amos modicar nuestro criterio de ajuste tanto como para dar un peso menor a los puntos con ms error. En este esp a ritu denimos
N

({aj }) =
i=1

i i

=
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 sticas 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 signica que los resultados sean signicativos. Para establecer un signicado 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 signicativa de un curso estad o o stico 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 nea recta, Y (x; {a1 , a2 }) = a1 + a2 x .
2

(11.4)

W. Mendenhall, R.L. Scheaer, and D.D. Wackerly, Mathematical Statistics with Applications (Boston: Duxbury Press, 1981).

322

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 nimo 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

x
i=1 N

xi , 2 i

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 a amos 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

323

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

0 a2 = N

x2

1 x

(11.14)

xi ,
i=1

1 = N

x2 . i
i=1

(11.15)

Finalmente, si nuestro conjunto de datos no tiene un conjunto de barras de error asociadas, podr amos estimar 0 a partir de la diferencia muestral de los datos,
2 0 s2 =

1 N 2

[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. do 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 a 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 gracar datos en an escala semi logar tmica o escalas log-log.

324

CAP ITULO 11. ANALISIS DE DATOS.

11.1.4.

Ajuste general lineal de m nimos cuadrados.

El procedimiento de ajuste de m nimos 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 nimo de 2 , 2 = aj aj o
N N

i=1

1 2 i

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 nimos cuadrados. Las ecuaciones normales son ms fciles de trabajar en forma matricial. Primero, denaa a como mos la matriz de diseo 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 diseo no depende de yi , los valores de datos, pero depende de xi , esto n es, sobre el diseo del experimento (donde las mediciones son tomadas). Usando la matriz de n diseo, 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 denido como bi = yi /i y AT es la traspuesta de la matriz de diseo. 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.

325

donde C = (AT A)1 . Una aplicacin comn de esta formulacin general lineal de ajuste de m o u o nimos cuadrados es el ajuste de los datos polinomiales, Y (x; {aj }) = a1 + a2 x + a3 x2 + . . . + aM xM 1 . (11.30)

La matriz de diseo tiene elementos Aij = aj xj1 /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 a o no hemos tomado sucientes 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, a | yi Y (xi ) | i . (11.31)

Colocando esto dentro de nuestra denicin 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 a stico 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 pequeas. 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 coeciente de correlacin adimeno sional que es un nmero que var entre 0 y 1, correspondiendo a 1 un mejor ajuste. u a r2 = S(a1 y a2 xy) ( S y 2 ( y)2 y)2 . (11.33)

326

CAP ITULO 11. ANALISIS DE DATOS.

Cap tulo 12 Integracin numrica bsica o e a


versin nal 4.2, 22 de Noviembre del 2007 o

En este cap tulo veremos algunos mtodos bsicos para realizar cuadraturas (evaluar e a integrales numricamente). e

12.1.

Deniciones
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 Denamos 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 gura 12.1.

f(x)

x0=a x1

x2

xi

xN=b

Figura 12.1: Subintervalos.

327

328

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 neas rectas, y la funcin lineal formada por la sucesin de l o o neas 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 neas 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 ba 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.

329

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 coecientes 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 denicin 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 nita. Usando estas o e deniciones 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, deniendo 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

330

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 queos 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, gura 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, gura 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 ,

331

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 Ii (h) (f (xi ) + 4f (xi+1 ) + f (xi+2 )) . (12.6) 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 nita (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 nita, (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

signica que el ndice i de la suma se incrementa en dos en cada oportunidad. Si donde hacemos la suma tenemos Is (h) = f (b) 2h f (a) + 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

u(u h) du =
0

h3 h3 3 2

1 d2 f () h3 d2 f () = 2 dx2 12 dx2

332

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

ey dy .

(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 pequeo. Si la respuesta no cambia apreciablemente, a a n la aceptamos como correcta (sin embargo, esto no evita que podamos ser engaados 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 tamao del intervalo por dos sin tener que recalcular n todos los puntos. Denamos la secuencia de tamaos de intervalo, n 1 1 h1 = (b a) , h2 = (b a) , . . . , hn = n1 (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 aade 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 (hn1 ): o 1 IT (hn ) = IT (hn1 ) + hn 2
2n2

333

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 tamao 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

334

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 mente.

12.6.

Cuadratura de Gauss.

Consideremos el problema de cuadratura sin considerar puntos jos 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 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 nito, 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 ex f (x) dx. o

12.6. CUADRATURA DE GAUSS. xi wi xi wi

335

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

ba f (x) dx = 2

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

ey dy ,

(12.19)

erf(1) =
0

2 2 ey 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 =

g(z) dz .
1

(12.21)

336

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 a

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 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.

337

12.8.
12.8.1.

Listados del programa.


Programa trapecio.py

#!/usr/bin/env python # -*- coding: iso-8859-1 -*import sys import math from matplotlib import rc from matplotlib.patches import Polygon from pylab import * import numpy rc(text, usetex=True) def integrando(x): return (2.0/math.sqrt(math.pi))*math.exp(-x*x) def main(): a=0.0 b=1.0 print "Regla trapezoidal para erf(1)" N=input("Ingrese el numero de puntos : ") h=(b-a)/float(N-1) suma=0.0 for i in range(2,N): x=a+(i-1)*h suma+=integrando(x) I=h*((integrando(a)+integrando(b))/2.0 +suma) print "Valor aproximado: erf(1) : ",I print "Valor exacto : ertf(1)= 0.842701 " ax = subplot(111) l_t=[] l_fdt=[] Graficando for t in arange(a,b,0.01): l_t.append(t) l_fdt.append(integrando(t)) plot(l_t, l_fdt, color=b,linewidth=1)

338 # make the shaded region

CAP ITULO 12. INTEGRACION NUMERICA BASICA

verts = [(a,0)] + zip(l_t,l_fdt) + [(b,0)] poly = Polygon(verts, facecolor=0.8, edgecolor=k) ax.add_patch(poly) text(0.5 * (a + b), 0.5, r"${\rm erf}(1)=\frac{2}{\sqrt{\pi}} \int_0^1 \, e^{-t^2}\,dt$", horizontalalignment=center,fontsize=20) xlabel(r\textbf{\Large $t$}) ylabel(r\textbf{\Large erf($t$)}) title(r\textbf{\Huge Integrado con Trapecio}) grid(True)

show() # if __name__==__main__: main()

12.8.2.

Programa romberg.py

#!/usr/bin/python from math import * def integrando(x): return (2.0/sqrt(pi))*exp(-x*x) a = 0.0 b = 1.0 suma = 0.0 print "Integracion de Romberg para erf(1)" N=input("Dimension de tabla: ") R=[] for i in range(N): R.append( [0.0] * N ) h=b-a np=1

12.8. LISTADOS DEL PROGRAMA.

339

for i in range(N): if i==0: R[0][0]=h*(integrando(a)+integrando(b))/2.0 else: suma=0 j=1 for j in range(1,np,2): x=a+j*h suma+=integrando(x) R[i][0]=R[i-1][0]/2.0 + h*suma h/=2 np*=2 m=1.0 for j in range(1,N): m*=4.0 for i in range(j,N): R[i][j] = R[i][j-1] + (R[i][j-1]-R[i-1][j-1])/(m-1.0) print "Tabla R" print for i in range(N): for j in range(N): print R[i][j], print print print "Valor aproximado: erf(1) ~= ", R[N-1][N-1] print "Valor exacto: erf(1) = 0.842701"

12.8.3.

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;

340

CAP ITULO 12. INTEGRACION NUMERICA BASICA

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.4.

Programa 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 suma=0; cout << "Integracion de Romberg para erf(1)" << endl; 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 ; } } h = (b-a); // Ancho del intervalo

12.8. LISTADOS DEL PROGRAMA. 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); } } 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; }

341

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); }

342

CAP ITULO 12. INTEGRACION NUMERICA BASICA

Parte III Apndices. e

343

Apndice A e Transferencia a diskettes.


La losof de diferentes unidades (A:, B:,. . . ) diere de la estructura unica del sistema a 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 eciente. 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 n 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 nal es montar el dispositivo /dev/fd0 en algn directorio, t u picamente /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 oppy ste e debe ser desmontado, antes de sacarlo, mediante el comando: umount /floppy.

345

346

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 nea 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 nsecos, 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

347

348 !!: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 chero 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 modicar 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 cheros/directorios sino tambin comandos. o e

B.2. VARIABLES PROPIAS DEL SHELL.

349

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 nea de comandos. savehist Permite denir 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

350

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. a Para ejemplicar 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 nea de la pantalla. La zona de introduccin de datos: es la ultima l o nea 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 modica 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 a 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 , y META, hay unos 50 4 = 200 comandos disponibles. Adems, existen comandos especiales a llamados prejos, que modican el comando siguiente. Por ejemplo, C-x es un prejo, y si C-s es un comando (de bsqueda en este caso), C-x C-s es otro (grabar archivo). As a travs u , e de un prejo, 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 u de comandos disponibles virtualmente innito.
1

Dado que la mayor de los teclados actuales no poseen la tecla META se emplea ya sea ESC o ALT. a

351

352

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 nal 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 nea horizontal dividir ventana actual en 2 partes, con l nea 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

353

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 nea principio de la l nea principio del documento avanza una palabra avanza una pgina a salta a la l nea (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 nea n de la l nea n 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 modicaciones 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 n de l o nea (no incluye el cambio de l nea) 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 nea 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 n de la palabra u o Cambia a minscula desde la posicin del cursor hasta el n de la palabra u o Cambia a mayscula el carcter en la posicin del cursor y u a o a minscula hasta el n 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 neas

354 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 n del texto hacia el inicio del texto y sustitucin (pide conrmacin cada vez) o o y sustitucin (sin conrmacin) o o

Denicin 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 camente, es el punto donde comienza el cursor. As si el cursor se encuentra sobre la letra c en emacs, , el punto est entre la a y la c. La marca, por su parte, es una seal 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 a 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 dene una cierta a ubicacin para el punto, y, por tanto, queda denida 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 , se pueden efectuar sobre un bloque del archivo. Por ejemplo, si queremos duplicar una regin, basta con denir la regin deseada (ponieno o do la marca y el punto donde corresponda) y teclear M-w. Esto copia la regin a un buer o temporal (llamado kill buer). Luego movemos el cursor al lugar donde queremos insertar el texto duplicado, y hacemos C-y. Este comando toma el contenido del kill buer y lo inserta en el archivo. El resultado nal 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 buer, 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 buer 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 buer. 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 nea. Lo que hace no es slo borrarla, sino adems copiarla en un kill buer. Lo mismo ocurre o a con los comandos que borran palabras completas (M-d, M-Backspace), y muchos otros. Lo

355 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 buer (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 neas. Ms an, el kill buer no es borrado con el C-y, a u as que ese mismo texto puede ser duplicado muchas veces. Continuar disponible con C-y a mientras no se ponga un nuevo texto en el kill buer. Adems, emacs dispone no de uno sino de muchos kill buers. 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 buer. 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 nea (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 buers ocupados: a buer 1 : La primera linea del texto, buer 2 : la buer 3 : finalmente Al colocar el cursor despus del punto nal, C-y toma el contenido del ultimo kill buer 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 buer anterior: u a

segunda linea, y la tercera. la Adems, la posicin de los kill buers se rota: a o buer 1 : finalmente buer 2 : La primera linea del texto, buer 3 : la Sucesivas aplicaciones de M-y despus de un C-y rotan sobre todos los kill buers (que e pueden ser muchos). El editor, as conserva un conjunto de las ultimas zonas borradas durante , la edicin, pudiendo recuperarse una antigua a pesar de haber seleccionado una nueva zona, o o borrado una nueva palabra o l nea. Toda la informacin en los kill buers se pierde al salir o de emacs (C-c). Resumimos entonces los comandos para manejo de los kill buers:

356

APENDICE C. EDITORES TIPO EMACS.

C-y Copia el contenido del ultimo kill buer ocupado M-y Rota los kill buers ocupados Denicin de macros o La clave de la congurabilidad de emacs est en la posibilidad de denir nuevos comandos a que modiquen su comportamiento o agreguen nuevas funciones de acuerdo a nuestras necesidades. Un modo de hacerlo es a travs del archivo de conguracin $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 denir 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 denicin de una macro o Termina la denicin de una macro o Ejecuta una macro denida

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. a ses o u Para denir una macro, colocamos el cursor al comienzo de la primera l nea, 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 nea); (coloca el cursor al comienzo de la l nea 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 denicin con C-x ). Listo. Si ahora o ejecutamos la macro, con C-x e, veremos que la segunda l nea queda modicada igual que la primera, y as podemos continuar hasta el nal: 1 2 3 4 5 Hewitt, Lleyton (AUS) Kuerten, Gustavo (BRA) Ferrero, Juan (ESP) Kafelnikov, Yevgeny (RUS) Haas, Tommy (GER)

357 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 nea 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 denidos por el usuario. En el ejemplo anterior, con el rnking ATP, a despus de denir la macro quedamos en la l e nea 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 nea 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

358

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 sticas de estos programas. En realidad, el autor de este cap tulo ha sido usuario durante algunos aos 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 vericado a a 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 nal), 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 neas de prueba.m sern ejecutadas una a una. Por ejemplo, a si el archivo consta de las siguientes cuatro l neas: a=3; a 359

360 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 nea: #!/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 sticas espec cas. 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 denen 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 innitos y cantidades que no son nmeros. inf es innito, 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 la 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]

361

1 2 . Las comas (opcionales) separan elementos de columnas distintas, 3 4 y los punto y coma separan elementos de las distintas. El vector la (1 2) es denen la matriz b = [1 2] y el vector columna c = [1;2] Un nmero se dene simplemente como d = [3] d = 3. u o Nota importante: Muchas funciones de Octave/Matlab en las pginas siguientes acepa tan indistintamente escalares, vectores las, vectores columnas, o matrices, y su output es un escalar, vector o matriz, respectivamente. Por ejemplo, log(a) es un vector la si a es un vector la (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 modicacin de elementos individuales o Accesamos los elementos de cada matriz usando los ndices de las y columnas, que parten de uno. Usando la matriz a antes denida, a(1,2) es 2. Para modicar 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 las o columnas, basta un ndice. (En los ejemplos anteriores, b(2) = c(2) = 2.) Una caracter stica muy importante del programa es que toda matriz es redimensionada automticamente cuando se intenta modicar 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 la 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

362

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 la, y se construyen y modican de modo idntico. e Construccin o Las instrucciones t t t t = = = = [un buen texto] ["un buen texto"] un buen texto "un buen texto"

denen el mismo string t. Acceso y modicacin 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 neas persona.nombre = Eduardo persona.edad = 30 persona.matriz_favorita = [2 8;10 15];

D.4. OPERADORES BASICOS

363

denen 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 modicacin 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

364

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 mbolos 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 la 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

365

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 nea es ignorado. ... : Continuacin de l o nea. Si una l nea es muy larga y no cabe en la pantalla, o por alguna otra razn se desea dividir una l o nea, 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

366 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 deniciones de variables en l denidas. 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 las, 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 ujo 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 la. 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 a nea as : 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

367

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 ujo 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=[]) a

368

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 nito (no inf ni NaN) 1 donde a es innito 1 donde a es un NaN

Por ejemplo, luego de ejecutar las l neas 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 ndices de los elementos no nulos de a.

Por ejemplo, si ejecutamos las l neas 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 ndices ( ndices de la 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 ndice de la 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 la 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 denidas por el usuario

369

Octave/Matlab puede ser fcilmente extendido por el usuario deniendo nuevas funciones a que le acomoden a sus propsitos. Esto se hace a travs del comando function. o e Podemos denir (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 denir 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 denicin 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 denicin contenida en ese archivo. o Por ejemplo, si escribimos en el script suma.m las l neas function s=suma(x,y) s = x+y; el resultado de suma(2,3) ser 5. a Las funciones as denidas pueden entregar ms de un argumento si es necesario (ya hemos a visto algunos ejemplos con find y size). Por ejemplo, denimos una funcin que efecte un o u anlisis estad a stico 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 la 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 dene 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:

370 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 gracar Las siguientes son matrices se emplean habitualmente en la construccion de grcos: 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 tmicamente. Construye una malla del plano x-y. Las las 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 stica hace particularmente util el comando meshgrid en el contexto de grcos 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 Innito 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 z

371

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 ptica error gamma

As por ejemplo, bessel(alpha,X) evala la funcin de Bessel de orden alpha, J (x), , 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 la. El polinomio

es representado en Octave/Matlab en la forma p = [c_n, ..., c1, c0]

372

APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB

Podemos efectuar una serie de operaciones con los polinomios as representados. poly(x) polyval(p,x) roots(p) Polinomio cuyas ra son los elementos de x. ces Evala el polinomio p en x (en los elementos de x si ste es u e un vector) Ra del polinomio p ces

D.6.5.
det rank trace inv eig poly

Algebra lineal (matrices cuadradas)


Determinante Nmero de las o columnas linealmente independientes u Traza Matriz inversa Autovalores y autovectores Polinomio caracter stico

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 ces dadas. En el fondo, construir el polinomio caracter stico 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 stica, correlaciones, convolucin, etc.). Algunas de las operaciones bsicas son: o a a) Mximos y m a nimos Si a es un vector, max(a) es el mayor elemento de a. Si es una matriz, max(a) es un vector la, 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)

373

b = (2

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 nimos. b) Estad stica bsica a Las siguientes funciones, como min y max, operan sobre vectores del modo usual, y sobre matrices entregando vectores la, 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 camente, si X=fft(x) y x=ifft(X), y los vectores son de largo N:
N

X(k) =
j=1

x(j)N
N

(j1)(k1)

1 x(j) = N donde N = e2i/N .

X(k)N
k=1

(j1)(k1)

D.6.7.

Grcos a

Una de las caracter sticas ms importantes de Matlab son sus amplias posibilidades gra a cas. Algunas de esas caracter sticas se encuentran tambin en Octave. En esta seccin revie o saremos el caso de grcos en dos dimensiones, en la siguiente el caso de tres dimensiones, y a luego examinaremos algunas posibilidades de manipulacin de grcos. o a

374

APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB

Grcos bidimensionales a Para gracar en dos dimensiones se usa el comando plot. plot(x,y) graca 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: Grco simple. a

Por default, Octave utiliza gnuplot para los grcos. Por default, los puntos se conectan a con una l nea roja en este caso. El aspecto de la l nea o de los puntos puede ser modicado. Por ejemplo, plot(x,y,ob) hace que los puntos sean indicados con c rculos (o) azules (b, blue). Otros modicadores posibles son: . @ + * o x l nea (default) puntos otro estilo de puntos signo ms a asteriscos c rculos cruces r g b m c w red green blue magenta cyan white

Dos o ms grcos 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 grco. Dada una funcin z = f (x, y), a o nos interesa gracar los puntos (x, y) tales que f = c, con c alguna constante. Por ejemplo, consideremos 2 2 z = xex y , x [2, 2], y [2, 3] . Para obtener el grco 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

375

Figura D.2: Curvas de contorno.

Las dos primeras l neas denen 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 nalmente construimos el o mapa de contorno para los niveles deseados. Grcos tridimensionales a Tambin es posible realizar grcos tridimensionales. Por ejemplo, la misma doble gause a siana de la seccin anterior se puede gracar en tres dimensiones, para mostrarla como una o supercie 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 grcos 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.

376

APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB

Figura D.3: Curvas de contorno.

Manipulacin de grcos o a Los siguientes comandos estn disponibles para modicar grcos construidos con Octaa a ve/Matlab: a) Ejes axis([x1 y1 x2 y2]) b) T tulos title(s) xlabel(s) ylabel(s) zlabel(s) c) Grillas grid Incluye o borra una grilla de referencia en un grco bidimena sional. grid on coloca la grilla y grid off la saca. grid equivale a grid on. T tulo (s es un string) T tulo 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 grco mostrado en pantalla no es actualizado automticamente. a a Para actualizarlo y ver las modicaciones efectuadas, hay que dar la instruccin replot. o Los siguientes comandos permiten manipular las ventanas grcas: a

D.6. COMANDOS hold Permite congelar la gura actual, de modo que sucesivos comandos grcos se superponen sobre dicha gura (nora malmente la gura 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.

377

closeplot

Finalmente, si se desea guardar un grco en un archivo, se puede proceder del siguiente a modo si Octave est generando los grcos con gnuplot y se trabaja en un terminal con a a XWindows. Si se desea guardar un grco 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 neas son los comandos de Octave/Matlab convencionales para gracar. 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 nea indica que la salida es al archivo xcubo.ps. Finalmente, se redibuja el grco (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 grco 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 nea 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. , Para comparar dos matrices entre s usamos strcmp: , 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

378

APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB

Por ejemplo, podemos usar esto para construir un t tulo para un grco: a s = [Intensidad transmitida vs. frecuencia, n = , num2str(1.5)]; title(s); Esto pondr un t a tulo en el grco 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 nal 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 nal 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 nea del archivo, descarta cambio de l nea Lee una l nea del archivo, preserva cambio de l nea 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

379

imprime en el archivo asociado con el identicador 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 especicadores 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 nea 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 nea al nal 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 especicadores 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 jo (Ej.: 0.000024) o %e o %f, dependiendo de cul sea ms corto (los ceros no a a signicativos 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 especicar alineamiento a la izquierda (a la derecha es el default).

380

APENDICE D. UNA BREVE INTRODUCCION A OCTAVE/MATLAB Un nmero entero para especicar un ancho m u nimo 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 gitos 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 nea, se imprimen tres decimales. En la segunda, dos, pero el ancho m nimo es 10 caracteres, de modo que se al nea a la derecha el output y se completa con blancos. En la tercera l nea es lo mismo, pero alineado a la izquierda. En la cuarta l nea se ha especicado un ancho m nimo de 4 caracteres; como el tamao del nmero es mayor, esto no tiene efecto n u y se imprime el nmero completo. En la quinta l u nea se usa notacin exponencial, con tres o decimal (nuevamente, el ancho m nimo especicado, 5, es menor que el ancho del output, luego no tiene efecto). Las ultimas tres l neas comparan el output de %f, %e y %g, sin otras especicaciones. Si se desean imprimir ms de un nmero, basta agregar las conversiones adecuadas y los a u argumentos en fprintf. As la l , nea 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

381

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

382

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 denir la dimensin de una matriz como una constante. Aqu dim es simplemente un int. o , La asignacin dinmica permite denir matrices cuya dimensin se determina recin durante o a o e la ejecucin. o Observemos nalmente que la liberacin de memoria, en el caso de arreglos, se hace con o el operador delete [], no delete como en los punteros usuales. 383 // Libera la memoria reservada

384

APENDICE E. ASIGNACION DINAMICA.

E.1.

Arreglos dinmicos bidimensionales. a

Tambin es posible denir arreglos bidimensionales dinmicamente. En el siguiente ejeme a plo, se dene una matriz de 200 las y 400 columnas, inicializndose sus elementos a cero, y a nalmente 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 las. 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 denido inicialmente (double ** ...). Esto puede parecer extrao 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 y Makele.


make es un comando particularmente util cuando se trata de hacer tareas repetitivas y que involucran a un nmero posiblemente grande de archivos distintos para producir un resultado u nal. La idea es sencilla: dar el comando make signica, bsicamente, decirle al sistema: a haga todo lo que sea necesario hacer para crear una versin actualizada del resultado nal, o considerando que algunos de los archivos necesarios para producirlo pueden haber cambiado desde la ultima vez. A travs de algunos ejemplos simples veamos cmo es posible traducir e o este mandato en instrucciones que un computador pueda entender.

F.1.

Un ejemplo sencillo en C++

Consideremos un programa sencillo en C++, hola.cc que slo dice Hola: o #include <iostream> using namespace std; int main() { cout << "Hola" << endl; return 0; } El comando g++ -o hola hola.cc crear un ejecutable a partir de esta fuente. Por sua puesto, al dar nuevamente el comando g++ -o hola hola.cc el proceso de compilacin o comenzar nuevamente. Esto no es muy eciente, porque hola slo depende de hola.cc, y a o no necesita ser recreado a menos que hola.cc sea modicado. Usemos, en cambio, el comando make. Creemos el archivo hola.cc (si ya existe, modiqumoslo agregndole un espacio en blanco, por ejemplo), y luego ejecutemos el comando: e a user@hostname:~$ make hola La siguiente l nea es escrita en el terminal: g++ hola.cc -o hola 385

386 y un ejecutable hola es generado. Ahora ejecutemos nuevamente make: user@hostname:~$ make hola make: hola is up to date.

APENDICE F. MAKE Y MAKEFILE.

Esta vez make no tiene ningn efecto. Esa es toda la gracia de make: darse cuenta de u qu necesita ser recreado, porque sabe qu resultado depende de qu archivo fuente. e e e

F.2.

Creando un Makele

En el ejemplo anterior, make detect automticamente que hola depende de hola.cc. En o a realidad, lo que ocurre es que existen una serie de reglas predenidas. En este caso, make busc en el directorio actual un archivo del cual pudiera depender hola, encontr a hola.cc, o o y ejecut g++ con las opciones adecuadas. Pero si hubiera encontrado un hola.f, hubiera o entendido que deb ejecutar el compilador de Fortran. A veces estas reglas son insucientes y a uno debe decirle a make expl citamente cmo proceder con cada dependencia. O simplemente o no deseamos conar en el azar. Cualquiera que sea el caso, podemos extender o modicar las reglas de make usando un Makefile. La estrategia, nuevamente, es sencilla: cree en el directorio de trabajo un archivo Makefile, con las instrucciones necesarias (en este apndice hay algunos ejemplos). Cuando make sea e ejecutado, leer este archivo y proceder en consecuencia. a a El siguiente es un Makefile para el ejemplo sencillo de la Sec. F.1: hola: hola.cc g++ -o $@ $< La sintaxis es la siguiente: hola: es un target (blanco). Indica que la siguiente regla sirve para generar el archivo hola. Luego de los dos puntos, vienen las dependencias de hola. En este caso, slo es hola.cc. o En la segunda l nea, viene la regla para generar hola. Aqu se han usado dos variables predenidas de make (hay muchas ms): $@ es el target de la regla, y $< es la dependencia a de la regla. En este caso, entonces, una vez que make reemplaza dichas variables, la regla queda como g++ -o hola hola.cc, que es por supuesto lo que queremos. Un punto muy importante: En la regla, antes de los caracteres g++, no hay 8 espacios en blanco, sino un carcter de tabulacin, TAB. De hecho, si uno reemplazara ese TAB por a o 8 espacios, make se dar cuenta. La versin 3.81 de GNU make, por ejemplo, entrega el a o siguiente mensaje al intentar ejecutarlo: user@localhost:~$ make Makefile:2: *** missing separator (did you mean TAB instead of 8 spaces?).

Stop.

F.2. CREANDO UN MAKEFILE

387

Este Makefile hace exactamente lo mismo que en la Sec. F.1, pero ahora no necesitamos descansar en las dependencias default: make hola busca el target hola en el archivo Makefile en el directorio actual, y revisa sus dependencias. Si alguna de las dependencias es ms a reciente que el archivo hola, entonces ejecuta las l neas que constituyen la regla. (En el ejemplo analizado, la regla consta de una sola l nea, pero podr ser por supuesto ms de una a a l nea si para generar el target se debe ejecutar ms de un comando.) a Observemos que, puesto que make toma decisiones slo en base a las fechas de modicacin o o de los archivos, para probar que las reglas funcionan adecuadamente no es necesario editar hola.cc. Basta con touch hola.cc, con lo cual la fuente aparecer como ms reciente que a a el ejecutable. En un mismo Makefile puede haber ms de una regla. Por ejemplo: a hola: hola.cc g++ -o $@ $< chao.dvi: chao.tex latex $< En este caso, adems del ejecutable hola, podemos generar un archivo chao.dvi, compia A X el archivo chao.tex. Es claro, entonces, que un solo Makefile nos permite lando con L TE generar muchos archivos distintos, con una unica l nea de comando, del tipo make <target>. Si se omite el argumento, make ejecuta el primer target que encuentra en el Makefile. Por ello, puede ser util, dependiendo de la aplicacin, poner al principio un target que simplemente o genere todos los archivos necesarios: all: make hola make chao hola: hola.cc g++ -o $@ $< chao.dvi: chao.tex latex $< As el comando make, sin argumentos, compilar lo necesario para obtener los archivos nales , a actualizados. Notamos que all es un target especial, pues no tiene dependencias. Es decir, se ejecuta incondicionalmente. Otro uso habitual de un target sin dependencias es el siguiente: all: make hola make chao hola: hola.cc g++ -o $@ $<

388

APENDICE F. MAKE Y MAKEFILE.

chao.dvi: chao.tex latex $< clean: rm hola chao.dvi chao.log chao.aux Ahora, make clean borra todos los productos de compilacin y archivos auxiliares que o hayan podido generarse, quedando slo lo importante: las fuentes, y el propio Makefile. o

F.3.

A Un ejemplo con varias dependencias: LTEX

En el ejemplo anterior, el resultado nal, hola, depende de un solo archivo, hola.cc. Es posible, sin embargo, que el archivo a generar tenga ms de una dependencia, y que incluso a esas dependencias deban generarse a partir de otras dependencias. Ilustraremos esto con un A ejemplo en L TEX. Consideremos el siguiente archivo, texto.tex: \documentclass[12pt]{article} \usepackage{graphicx} \begin{document} Una figura: \includegraphics{figura.eps} \end{document}

El archivo compilado, texto.dvi, depende de texto.tex, por cierto, pero tambin de e figura.eps. Un Makefile adecuado para esta situacin es: o texto.dvi: texto.tex figura.eps latex texto clean: rm texto.dvi texto.log texto.aux Qu pasa ahora si figura.eps, a su vez, es generada a partir de otros archivos fuente? Por e ejemplo, digamos que creamos, con xfig, el archivo figura.fig. En principio, si editamos la gura, podemos no slo grabarla como un archivo fig, sino tambin como un archivo o e postscript, con lo cual la gura queda actualizada. Existe otro modo, un poco ms eciente: a en xfig grabamos slo la versin fig, y generamos el eps con la l o o nea de comandos: username@host:~$ fig2dev -L eps figura.fig figura.eps

F.4. VARIABLES DEL USUARIO Y PATRONES Ahora podemos incluir este comando como una regla adicional en el Makefile: texto.dvi: texto.tex figura.eps latex texto figura.eps: figura.fig fig2dev -L eps $< $@ clean: rm texto.dvi texto.log texto.aux figura.eps

389

Para cada dependencia declarada, make verica si existe alguna regla para construirla. En el caso de texto.tex no la hay, as que contina. Para figura.eps la hay: verica la fecha u de modicacin de figura.fig, y determina si es necesario actualizar figura.eps. Ahora o que todas las dependencias de texto.dvi estn actualizadas, revisa si es necesario actualizar a texto.dvi. Son claras entonces las ventajas de make: Un proyecto dado, por complicado que sea, se puede escribir en trminos de productos nales y dependencias, posiblemente mltiples, y e u posiblemente encadenadas. Naturalmente, proyectos ms complicados tendrn un Makefile a a ms complicado. Pero una vez construido ste, el producto nal se obtiene simplemente con a e el comando make.1 Observemos, adicionalmente, que en el ultimo Makefile agregamos al target clean la orden de borrar figura.eps. Ahora dicho archivo puede ser generado siempre a partir de figura.fig, por tanto no es necesario mantenerlo en disco.

F.4.

Variables del usuario y patrones

En nuestro ejemplo sencillo de Makefile de la seccin anterior, hemos usado dos variao bles internas del sistema, $< y $@. Hay ms, por supuesto, y sugerimos leer la documena tacin de make para ello. Pero adems, el usuario puede denir sus propias variables. Por o a A ejemplo, supongamos ahora que nuestro archivo L TEX necesita dos guras, figura.eps y otra_figura.eps, ambas provenientes de sendos archivos fig. Debemos modicar el Makefile en tres puntos: Agregar la dependencia otra_figura.eps a texto.dvi. Agregar una regla para construir otra_figura.eps a partir de otra_figura.fig. Agregar otra_figura.eps a la lista de archivos a borrar con make clean. Es claro que este proceso es cada vez ms engorroso mientras ms guras tenga un archia a vo. Aqu es donde es util denir variables de usuario, para evitar modicar tantas veces el
El software distribuido en forma de cdigo fuente habitualmente hace uso de esta herramienta. As o , independiente de la complejidad del software, el usuario simplemente debe dar un solo comando, make, para obtener el ejecutable nal.
1

390

APENDICE F. MAKE Y MAKEFILE.

Makefile, con la consiguiente ganancia de tiempo y reduccin de la probabilidad de comeo ter errores. Deniremos entonces una variable figuras, para agrupar a los archivos eps de guras. La sintaxis es parecida a la de bash, tanto para denir la variable como para usarla: figuras=figura.eps otra_figura.eps texto.dvi: texto.tex $(figuras) latex texto figura.eps: figura.fig fig2dev -L eps $< $@ otra_figura.eps: otra_figura.fig fig2dev -L eps $< $@ clean: rm texto.dvi texto.log texto.aux $(figuras) De este modo, agregar ms guras implica slo dos modicaciones: agregar un valor a la a o denicin de figuras, y agregar la regla correspondiente. o Pero an es posible una simplicacin adicional: si todas las guras eps van a venir de u o fig, ser posible que make entienda eso de una vez y para siempre, y no tener que darle a reglas redundantes? S es posible, y eso se logra gracias a los patrones, simbolizados con el , carcter especial %. Observemos el siguiente Makefile, equivalente al anterior: a figuras=figura.eps otra_figura.eps texto.dvi: texto.tex $(figuras) latex texto $(figuras):%.eps:%.fig fig2dev -L eps $< $@ clean: rm texto.dvi texto.log texto.aux $(figuras) Se ha puesto una dependencia en la forma $(figuras):%.eps:%.fig. Esto signica lo siguiente: de todos los nombres contenidos en la variable $(figuras), seleccione los eps. Cada eps, a su vez, depende de un archivo que se llama igual, pero con extensin fig. El o patrn % representa en este caso, al nombre sin extensin del archivo. o o As este Makefile permite, para todas las guras (variable figuras), crear los eps a , partir de los fig correspondientes, a travs de la misma regla (fig2dev). Ahora s agregar e , ms guras es trivial: basta con modicar slo una l a o nea del Makefile, la denicin de o figuras. El tiempo invertido y las posibilidades de error ahora son m nimos. Naturalmente, estrategias similares se pueden emplear si deseamos generar, en vez de un dvi, un pdf. En tal caso, las guras deben ser convertidas a pdf:

F.5. C++: PROGRAMANDO CON MAS DE UN ARCHIVO FUENTE figuras=figura.pdf otra_figura.pdf texto.pdf: texto.tex $(figuras) pdflatex texto $(figuras):%.pdf:%.fig fig2dev -L pdf $< $@ clean: rm texto.pdf texto.log texto.aux $(figuras)

391

F.5.
A LT

C++: Programando con ms de un archivo fuente a

Hasta el momento, hemos centrado la mayor parte de la discusin en un ejemplo de o a EX, pero el uso de make es por supuesto mucho ms general, y el mismo tipo de ideas se pueden usar para cualquier tipo de proyecto en que se deben realizar tareas automticas y a posiblemente en secuencia. En lo que sigue, continuaremos la discusin con un ejemplo en o C++. No introduciremos conceptos nuevos de make que los vistos en secciones anteriores, sino que veremos cmo se pueden utilizar en un proyecto de programacin ms complicado, o o a consistente en varios archivos fuentes. En principio, un programa en C++, o en cualquier lenguaje de programacin, puede o constar de un solo archivo que contenga todas las instrucciones necesarias. Para escribir "Hola mundo" en pantalla se requieren unas pocas l neas de cdigo, que pueden estar cono tenidas en un archivo hola.cc. En ese caso, se puede crear un ejecutable hola a partir de dicha fuente, en la forma user@hostname:~$ g++ hola.cc -o hola Sin embargo, cuando el programa es un poco ms complicado, puede ser necesario, y de a hecho es aconsejable, dividir el programa en varios archivos fuentes. As si nuestro programa , hola usa una funcin auxiliar, PrintHola(), para enviar el mensaje a pantalla, una posibilio dad es poner la declaracin de dicha funcin en un header , que podemos llamar, por ejemplo, o o print_hola.h, y su implementacin en el correspondiente archivo print_hola.cc. En ese o caso, adems de incluir en el archivo hola.cc una l a nea del tipo #include "print_hola.h", es neceario cambiar la l nea de compilacin a: o user@hostname:~$ g++ print_hola.cc hola.cc -o hola El ejemplo anterior puede parecer banal, pero es una situacin usual cuando se construye o un programa en C++ usando clases. En ese caso, si se dene una clase Complejo, para utilizar nmeros complejos, entonces las declaraciones de la clase y sus funciones asociadas estarn u a en un archivo llamado, por ejemplo, complejo.h, y la implementacin correspondiente en o complejo.cc. Ya que mencionamos este ejemplo, imaginemos un programa llamado "mi_gran_programa", que dice "Hola mundo" (usando la funcin PrintHola() anterior), y sabe manipular matrio ces de nmeros complejos. Los nmeros complejos estn denidos con la clase Complejo, en u u a

392

APENDICE F. MAKE Y MAKEFILE.

complejo.h y complejo.cc, y las matrices con la clase Matriz, en matriz.h y matriz.cc. La l nea de compilacin ser entonces, o a, user@hostname:~$ g++ print_hola.cc complejo.cc matriz.cc \ mi_gran_programa.cc -o mi_gran_programa Ya ni siquiera nos cabe en una l nea! Y no es un programa tan complicado. Ahora el problema: si realizo una pequea modicacin en complejo.cc, hay que dar toda esta n o l nea de compilacin de nuevo. No slo eso, sino que el compilador es obligado a leer y o o codicar los contenidos de print_hola.cc, print_hola.h, complejo.cc y complejo.h, y mi_gran_programa.cc, a pesar de que ninguno de ellos fue modicado. Esto, claramente, es un desperdicio de recursos, que va a ser ms evidente mientras ms archivos fuentes (*.cc) a a compongan en proyecto, o mientras ms grandes sean dichos archivos. a Podemos intuir, con lo que ya sabemos, que ste es el t e pico problema en que make nos ser de gran ayuda. Pero antes, debemos conocer un poco ms cmo es el proceso de creacin a a o o de un ejecutable en C++. En realidad, crear un ejecutable consta de dos procesos: compilacin y linkeo. El linkeo es o el proceso mediante el cual se une un cdigo fuente con cdigo proveniente de librer del o o as sistema o generadas por el propio usuario, para agregar funcionalidad inexistente en el cdigo o fuente. Complicado? No tanto. El sencillo programa hola.cc env un mensaje a pantalla, a pero en realidad no contiene el cdigo necesario para ello, salvo la llamada a la funcin cout, o o que no est denida en hola.cc. El cdigo necesario se encuentra en una librer del sistema. a o a Entonces, el comando g++ primero compila el cdigo fuente en hola.cc, convirtindolo a un o e lenguaje ms cercano a la mquina, y luego lo linkea, en este caso a las librer del sistema. a a as Slo entonces se tiene un ejecutable con toda la funcionalidad deseada. o Ahora podemos ver que, para no tener que pasar por todos los archivos fuentes cada vez que se hace una modicacin en uno de ellos, hay que separar compilacin y linkeo. o o Primero, generamos object les (archivos con extensin .o), a partir de cada archivo fuente, o compilando con la opcin -c: o user@hostname:~$ g++ -c print_hola.cc -o print_hola.o user@hostname:~$ g++ -c complejo.cc -o complejo.o user@hostname:~$ g++ -c matriz.cc -o matriz.o Finalmente linkeamos los tres object les, junto al cdigo que contiene a main(), para generar o el ejecutable nal: user@hostname:~$ g++ print_hola.o complejo.o matriz.o hola.cc -o hola Esto genera exactamente el mismo ejecutable que la larga l nea de comandos anterior. Pero ahora, si modicamos complejo.cc, basta con rehacer el correspondiente object le y linkear todo nuevamente: user@hostname:~$ g++ -c complejo.cc -o complejo.o user@hostname:~$ g++ print_hola.o complejo.o matriz.o hola.cc -o hola Como vemos, no es necesario que el compilador vuelva a leer los archivos matriz.cc y print_hola.cc. Esto reduce el tiempo de compilacin considerablemente si los archivos fueno te son numerosos o muy grandes.

F.6. UN EJEMPLO COMPLETO

393

Ahora podemos automatizar todo este proceso a travs del comando make. Basta con e construir un Makefile con las siguientes condiciones: El ejecutable nal (hola) depende de los object les involucrados, y se construye linkendolos entre s a . Cada object le depende de su respectiva fuente (archivos .cc y .h), y se construye compilando con g++ -c). make clean puede borrar todos los object les y el ejecutable nal, pues se pueden construir a partir de las fuentes. Usando lo aprendido en las subsecciones anteriores (dependencias, variables de usuario e internas, patrones), podemos construir el siguiente Makefile, que hace lo pedido: objects=print_hola.o complejo.o matriz.o hola: $(objects) g++ $(objects) hola.cc -o $@ $(objects):%.o:%.cc %.h g++ -c $< -o $@ clean: rm hola $(objects) Observmos cmo hemos usado los patrones para crear dependencias mltiples: cada e o u archivo o depende de dos archivos con el mismo nombre, pero con extensiones cc y h. Ya con este Makefile, de ahora en adelante, crear el ejecutable hola ser mucho ms a a sencillo: editar los archivos fuentes y dar el comando make.

F.6.

Un ejemplo completo

Terminamos nuestra discusin del comando make con un ejemplo completo, un Makefile o para compilar un programa de dinmica molecular llamado embat: a ############################################################ # Makefile for C++ program EMBAT # Embedded Atoms Molecular Dynamics # # You should do a "make" to compile ############################################################ #Compiler name CXX = g++ #Linker name

394 LCC = g++ #Compiler flags you want to use MYFLAGS = -Wall OPFLAGS = -O4 CPPFLAGS = $(MYFLAGS) $(OPFLAGS)

APENDICE F. MAKE Y MAKEFILE.

#Library flags you want to use MATHLIBS = -lm CLASSLIBS= -lg++ LIBFLAGS = $(MATHLIBS) $(CLASSLIBS) ############################################################ OBJFILES = embat.o lee2.o crea100.o errores.o\ archivos.o azar.o lista.o rij.o\ escribir2.o velver.o cbc.o force.o\ fMetMet.o fDf.o relaja.o funciones.o\ initvel.o leerfns.o spline.o embat : $(OBJFILES) $(LCC) -o embat $(OBJFILES) $(LIBFLAGS) $(OBJFILES): %.o:%.cc $(CXX) -c $(CPPFLAGS) $< -o $@ ############################################################ clean: rm embat $(OBJFILES) ############################################################ Podemos reconocer varias de las tcnicas discutidas en las secciones anteriores. El ejee cutable embat se construye a partir de ciertos OBJFILES, que se construyen compilando los archivos cc respectivos. Se compila usando g++, desplegando todos los warnings (opcin o Wall), con nivel de optimizacin 4 (opcin O4), y usando las librer matemticas de C++ o o as a (opcin m). Observamos tambin algunos aspectos adicionales: o e Se pueden poner l neas de comentarios con #. Todos los compiladores y opciones de compilacin y linkeo se han puesto dentro de o variables (p. ej. CXX, LCC, MYFLAGS, MATHLIBS, etc. Esto permite mayor exibilidad a futuro. Por ejemplo, podr amos desear compilar con una versin ms reciente, o ms o a a antigua, del compilador, o cambiar el nivel de optimizacin (variable OPFLAGS). Con o el Makefile anterior, es posible hacerlo slo cambiando una l o nea: la denicin de la o variable correspondiente.

F.6. UN EJEMPLO COMPLETO

395

El carcter \ indica continuacin de l a o nea. En este caso, en vez de denir OBJFILES en una sola l nea de muchos caracteres (lo que probablemente no ser cmodo de ver en a o un editor de texto o en un terminal), se separa en l neas conectadas por \.

396

APENDICE F. MAKE Y 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 que permiten saltar entre diferentes pginas web de manera fcil. Gracias a los links existen a a 397

398

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 modicar 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 nea, 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

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.

399

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 denidas. Las diferentes las 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 sealar 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.

400

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 diseo 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 tulo de la pgina, a es decir, el nombre que aparecer en el t a tulo 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 nalizar 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 tulo de porte variable en dependencia del nmero que se ponga u acompaando a la letra h, dicho nmero debe estar entre 1 y 6. n u <br>: Introduce un salto de l nea. A diferencia de las etiquetas anteriores, sta no tiene e una etiqueta de cerrado. <hr>:Introduce una l nea 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 ndice los caracteres dentro de esta etiqueta.

G.6. PAGINAS BASICAS EN HTML. <sup>: Convierte en super ndice los caracteres delimitados por la etiqueta.

401

<font>: Etiqueta que permite denir 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 denir los colores de: el texto, los links, links ya usados y el fondo. En html los colores a se especican mediante un cdigo (para conocer el cdigo correspondiente a cada color puede o o consultarse la tabla de colores (G.2) al nal 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 pequeas 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> </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:
3

La cual por razones obvias debe ser vista a color.

402

APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P.

<p align="center">(a<sub>11</sub>+a<sub>22</sub>+....) <sup>2</sup>=(traza)<sup>2</sup></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 seal en la introduccin, la caracter n o o stica 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 Para insertar una imagen existe una etiqueta desapareada4 , en sta debe darse el path e relativo del archivo grco de la siguiente forma: a <img src="path"> Tambin se pueden especicar 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 Los path pueden ser relativos5 si se trata de material presente en la misma mquina; a de tratarse de un enlace externo a la pgina, debe especicarse 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.

403

Una tabla permite administrar el espacio en una pgina de manera eciente y es especiala mente util cuando se quiere una pgina ordenada y sin muchas caracter a sticas grcas. La a tabla es delimitada por la etiqueta <table>, dentro de sta, las las 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 n el proveer de interfaz o grca 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 denido dentro de la etiqueta <form>, la cual contiene algunos atributos que especican qu hacer con la informacin. Sin entrar en complicaciones, e o slo se sealar que para poder recuperar la informacin contenida en un formulario deben o n a o denirse 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

404

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 tmica, 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 diseos 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 nalizado la denicin del formulario, debe agregarse un botn que o o env la informacin, el cual corresponde a otro input type. Adicionalmente, si el formulario e 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

405

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 pequeo 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>

406

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></html> 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 nea 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 de interaccin llamado Sql, del cual tan slo se ensearn las ordenes bsicas. Cabe destacar o o n a a que todo lo que se escriba en la consola de MySql debe nalizar 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:

G.7. MYSQL. mysql> connect base;

407

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 especicarse (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 a 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

408

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 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 especica 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 identicado a quin se quer eliminar mediante e a cualquier otro campo. El administrador se podr preguntar cmo borrar la cantidad a 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 dem 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 co mediante operadores lgicos como OR o AND, los cuales funcionan como se esperar Esto sirve para, o a. 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

409

Orden: La mayor de las veces es necesario saber parcialmente de qu forma vendrn a 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, acompaado 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: a 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 modica 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 especicarse WHERE y truncarse la o frase, se cambiar el telfono de todos los registros por el nuevo nmero. a 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 contraseas, ser necesario algn sistema de seguridad o n a 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

410

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 ecientes lo programado; sin embargo, el a a a alcance del apndice utilizar tan slo las herramientas aqu expuestas. e a o

G.8.

Programacin en PHP. o

Los 2 lenguajes antes vistos no tienen relacin entre s y, de hecho, no podrn funcionar o 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 sealado en la introduccin, el lenguaje en PHP se encuentra inserto dentro n o del html. Esto signica que el script est escrito principalmente en html con trozos en PHP. a Todo el cdigo en PHP queda delimitado por las etiquetas: o <?php... aqui todo el codigo en php .... ?>. Al igual que en bash, las variables van antecedidas por un s mbolo $, por otra parte, al igual que en C++ cada l nea de cdigo debe ir nalizada 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>

411

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 a 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

412

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 tulo 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 ujo.

Las sintaxis de los controles de ujo 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 n de economizar cdigo, a continuacin se ejemplicar el uso del control de ujo 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;

413

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 nsecas 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 ejemplica ampliamente en el ejemplo nal. o

G.8.6.

Sesin. o

PHP tiene la capacidad de denir 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 modicaciones) 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

414

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. ?> <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>

G.8. PROGRAMACION EN PHP. <?php echo $_SESSION[mail]; ?> </em> </b></td></tr> <h1 align="center"> <a href="salir.php"> <font color="red"> finalizar sesin. o </font></a></h1> </table> </body> </html> archivo salir.php <?php session_start(); session_unset(); header("Location:ejemplo4.html"); echo"<html></html>"; exit; ?>

415

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 denir 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 denida 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 denir 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 dene la variable a de sesin $_SESSION[estado]="conectado"; en la primera pgina, una forma de denir 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 e a el objetivo nal 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:

416

APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P.

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 suciente). a 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 Siguiendo la numeracin respectiva, utilizando el nombre de usuario y contrasea 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 a un poco inseguro que aparezca la clave del usuario expl citamente 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 tem anterior, aqu la seleccin de base no se almacena como 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);

G.9. EJEMPLO FINAL.

417

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 identicar a o a a los elementos. Finalmente, cabe sealar 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. //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 nalizado el apndice; sin embargo, se ha escrito un o e ejemplo nal para ver puestas en prctica las herramientas aqu expuestas. Se invita al a lector a tomarlo como una prueba nal de si logr un aprendizaje real. o

G.9.

Ejemplo Final.

Se espera haber recorrido con xito todos los tpicos de una manera supercial. A n 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 nea 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 co, 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 contraseas 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:

418

APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P.

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

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. a 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"> n </td></tr> <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 contrasea 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

G.9. EJEMPLO FINAL. <?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} 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");}?>

419

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 nea 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>

420

APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P.

<?php require(nnota.php);?> </td></tr></table></body></html> Las primeras l neas chequean que el usuario se haya logueado y especica 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 nal (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;?> 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"; a require("acciones.php");} 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");}?>

G.9. EJEMPLO FINAL.

421

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 , 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 <?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 nalizado 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_error()); mysql_select_db(ramo)or die (error al contactar base); $pedir="select nota1, nota2, nota3, nota4, nota5, nota6, nota7, nota8 from notas where nombre=$nombre";

422

APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P.

$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> </h2> <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> </body></html> 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 la (mysql_fetch_row()); o luego la la comienza a ser recorrida utilizando un control de ujo 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 n no es ser operativo, sino explicativo. a Podr parecer que se trata de una gran cantidad de cdigo, sin embargo, la mayor parte a 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 nea.

G.10. CONCLUSIONES. Comunicacin mediante mensajes entre usuarios (un rudimentario chat). o Sistema de encuestas en l nea.

423

En general, cualquier problema de administracin que involucre diferentes usuarios a o distancia se torna en algo solucionable mediante las herramientas aqu desarrolladas. Por ultimo, se deja como ejercicio al lector un par de puntos que restan por mejorar del ejemplo nal.

G.10.1.

Mejoras al Ejemplo nal.

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 a tanto se ha priorizado su funcionalidad.

424

APENDICE G. HERRAMIENTAS BASICAS EN EL USO DE L.A.M.P.

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

You might also like