Está en la página 1de 178

Introduccin informal a Matlab y Octave

guillemborrell@gmail.com http://torroja.dmt.upm.es/guillem/blog/
26 de noviembre de 2007 Guillem Borrell i Nogueras

Ultimas palabras

Los libros envejecen como el tema del que tratan. Si un libro habla sobre la vida, el amor, o poltica probablemente mantenga su vigencia durante siglos. Por desgracia el software es un mundo en constante cambio y este libro empezaba a notar el paso del tiempo de forma peligrosa. Octave ha cambiado; tambin lo ha hecho Matlab, sin duda para mejorar. Era consciente de este peligro mientras lo escriba pero an ms durante el ao y medio en el que no he hecho ningn cambio por falta de tiempo e inters. Las circunstancias que me llevaron a tomarme el tiempo necesario para sentarme a escribir han pasado; vuelvo a ser el to siempre ocupado con mil cosas distintas en la cabeza. No puedo vivir sin algn desafo intelecutal, no por instinto de superacin sino por puro entretenimiento. Mi profesin es la Ingeniera Aeronutica y Octave me mantuvo ocupado cuando me vi obligado a aparcarla durante un tiempo. He vuelto a mi carrera, he encontrado otras preocupaciones y Octave ha sido el primer damnicado. Es por este motivo que he decidido liberarlo con la esperanza que a su alrededor se forme una pequea comunidad entusiasta. No tiene ningn sentido que siga en mis manos donde no tiene futuro alguno. Seguro que en algn lado hay alguien que puede dedicarle el tiempo del que ahora carezco. No tengo la sensacin de haber completado el texto. Obviando las erratas y los posibles errores no he ni mucho menos terminado el que creo que es el captulo ms importante: el uso de Octave en aplicaciones multilenguaje. Tampoco he podido dedicarle el tiempo necesario a describir las funciones de representacin grca, estadstica y matrices sparse. Adems creo que el libro requiere un giro en su planteamiento. Muchas de las explicaciones matemticas son prescindibles porque este no es un libro de texto ni pretende ensear Clculo Numrico. Lo abandono con la sensacin de dejar mucho por hacer pero tambin con la satisfaccin del trabajo bien hecho. No me gustara terminar sin dar mi agradecimiento a todos los que me han demostrado su apoyo en una etapa bastante difcil de mi vida. A mis compaeros de departamento Oscar, Mark, Juan Carlos, Miguel, Sergio, lvaro, Leo, Isabel, Samuel, Jorge, Mario y Yoshi. A Javier Jimnez por conar en m sin darle motivos para ello, a Rafa por darme trabajo y a Vassilis por aguantarme. A Juanjo por invitarme a la Universidad de La Rioja, a la Delegacin de Alumnos de Aeronuticos por su conanza y a Nico (en paz descanse) por ser el nico profesor de mi escuela en felicitarme por el libro. Tampoco quiero olvidarme de Pedro, Virginia, Jose, Miguel, Juan Pedro y Alberto; compaeros a los que aprecio tantsimo. Por ltimo y los ms importantes: mis padres, mi abuela, mi hermana y Jaime; ojal mi sobrina Sara pueda leer este libro y pueda sentirse orgullosa del trabajo que un da su to empez.

Guillem Borrell i Nogueras Madrid, 10 de Noviembre de 2007

Prlogo de la primera edicin

Hay muchos libros de Matlab, algunos muy buenos, pero en ninguno es tratado como un lenguaje de programacin. El enfoque habitual es pensar en Matlab como programa, como un entorno de desarrollo completo. No se habla nunca del intrprete Octave ni a las ventajas y defectos respecto a otros lenguajes de programacin. No son libros, son manuales. Creo que es muy importante aplicar el sentido crtico a cualquier herramienta y todo lo editado hasta a hora no es de gran ayuda. Octave es un programa magnco, lo he usado durante aos. No llega a la magnitud de Matlab pero debe ser tenido en cuenta.

Estos apuntes empezaron como material adicional mal escrito para un curso de seis horas; con tiempo y dedicacin han crecido hasta lo que son ahora. Escribir sobre un lenguaje de programacin es largo, difcil y laborioso; nunca sabes si el lector va entender los conceptos que plasmas sobre el papel. Esto requiere el esfuerzo extra de reducir las ideas a lo ms bsico. Es una experiencia graticante, sobre todo cuando uno mismo tiene que reformular conceptos que ya crea asimilados. Uno aprende a escribir, a explicarse y a tener paciencia. Es un curso informal, pretende ser cercano y ameno incluso cuando se tratan conceptos complejos o abstractos.

Este libro es libre y abierto; quera que fuera as desde un principio. Todo el que quiera participar en l puede hacerlo sin ninguna restriccin. Su nica nalidad es ayudar a los dems. Espero que quien lo sostenga en sus manos aprecie esta pequea muestra de altruismo y decida colaborar; estar siempre abierto a sugerencias y correcciones. Incluso si alguien propone una reescritura o la inclusin de un captulo no tengo ningn reparo en otorgarle la coautora.

Guillem Borrell i Nogueras Calella, 13 de Agosto de 2005

6
Este documento est publicado segn la siguiente licencia:

GNU Free Documentation License


Matlab R y MathWorks R son nombres registrados por MathWorks Versin 0.10 Pendientes de ampliacin las secciones marcadas con (+)

AT X Typeset by L E Escrito en Kubuntu GNU/Linux y Gentoo GNU/Linux. No ha sido necesaria ninguna herramienta comercial
para preparar este texto, sirva como demostracin que el software no por ser ms caro debe ser mejor. Este libro parte del proyecto original de Guillem Borrell Introduccin Informal a Matlab y Octave

//torroja.dmt.upm.es/guillem/libros/

http:

NDICE GENERAL

I Introduccin y elementos del lenguaje Matlab


1. Introduccin
1.1. 1.2. 1.3. 1.4. 1.5. Lenguajes interpretados o de scripting El entorno de desarrollo Matlab. 1.4.1. 1.5.1. 1.5.2. 1.5.3. 1.6. 1.6.1. 1.6.2. 1.6.3. 1.6.4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Un lenguaje de scripting cientco, Matlab. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15
17
17 17 18 20 21 21 21 22 22 23 23 23 23 24

Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . El entorno de desarrollo Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . El ciclo de desarrollo clsico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Rapid Application Development o RAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Otros lenguajes orientados a RAD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Errores tpicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Los proyectos de software y los lenguajes de programacin . . . . . . . . . . . . . . . . . . . . . . . .

Una visin contempornea del desarrollo de aplicaciones de simulacin . . . . . . . . . . . . . . . . . Cul es entonces el espacio de Matlab? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y el espacio de Octave? Los lenguajes pegamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2. MATLAB
2.1. 2.2. El lenguaje y las bibliotecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Convenciones 2.2.1. 2.2.2. 2.3. 2.4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operaciones elementales con Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Algunas palabras clave y atajos de teclado.

27
27 27 28 28 29 29 30 30 30 31 31 32 32 34 35 35 35 36 36 37 37 37 38 39 40

La Ayuda(I) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tipos de archivos en Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1. 2.4.2. 2.4.3. 2.4.4. 2.4.5. Funciones(I) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nuestra primera funcin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nuestro primer script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Una gran diferencia entre Matlab y Octave

2.5.

Argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.1. 2.5.2. Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.1.1. 2.5.2.1. 2.5.2.2. 2.5.3. 2.5.4. 2.5.5. 2.5.6. Tipos de argumentos matriciales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Por qu las secuencias no son vectores? . . . . . . . . . . . . . . . . . . . . . . . . . Contadores no enteros. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Secuencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Submatrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nmeros Complejos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Cadenas de texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Argumentos lgicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operadores aritmticos

2.6.

Operadores 2.6.1. 2.6.2. 2.6.3.

Operadores de comparacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operadores lgicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8
2.6.4. 2.7.

NDICE GENERAL
Operadores de comparacin por bits en enteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 40 41 42 43 43 44 45 46 46 47 48 49 49 49 50 50 50 50 51 52 53 54 54 55 56 56 57 57 57 58 58

Variables 2.7.1. 2.7.2. 2.7.3.

Acceso a las variables: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Funciones dedicadas a variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Contenedores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7.3.1. 2.7.3.2. 2.7.3.3. Estructuras de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Cell Arrays.

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

La necesidad de los cell arrays y los tipos derivados

2.8.

Sentencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8.1. 2.8.2. 2.8.3. 2.8.4. 2.8.5. 2.8.6. 2.8.7.

if . . . . . . . . . . La sentencia switch. . . . . . . . La sentencia for . . . . . . . . . La sentencia while . . . . . . . . La sentencia do-until . . . . . . Las sentencias break y continue La sentencia try . . . . . . . . .
La sentencia Funciones matemticas bsicas La Ayuda(II)

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

2.9.

Funciones (II) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.9.1. 2.9.2. 2.9.3. 2.9.4. 2.9.5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

Argumentos de entrada y salida.

inline
2.9.5.1. 2.9.5.2. 2.9.5.3.

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

Function handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Funciones annimas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Funciones como argumentos de funciones. . . . . . . . . . . . . . . . . . . . . . . . . Acceso a las variables desde las funciones annimas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.9.6. 2.9.7. 2.9.8. 2.9.9.

Funciones recursivas

Encapsulado de funciones

Sobrecarga de funciones.(Octave) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Herramientas tiles para la manipulacin de funciones. . . . . . . . . . . . . . . . . . . . . . .

2.10. Entrada/Salida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.10.1. E/S bsica por pantalla. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.10.2. E/S bsica con archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

II La biblioteca de funciones
3. Matrices y lgebra lineal
3.1. Rutinas de creacin de matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1. 3.2. Tipos de argumentos matriciales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Rutinas de manipulacin de forma. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1. 3.3. Creacin directa de matrices de rango mayor que 2. . . . . . . . . . . . . . . . . . . . . . . .

61
63
63 64 65 66 66 68 69 69 69 70 70 71 72 72 72 72 73 74

Sistemas de ecuaciones lineales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1. 3.3.2. 3.3.3. 3.3.4. Matrices cuadradas regulares. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mtodos directos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mtodos iterativos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Matrices sparse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.4.1. 3.3.4.2. 3.3.4.3. 3.3.4.4. 3.3.5. 3.3.6. Anlisis de matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Almacenamiento de matrices sparse . . . . . . . . . . . . . . . . . . . . . . . . . . .

Creacin de matrices sparse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Manipulacin y operaciones con matrices sparse . . . . . . . . . . . . . . . . . . . .

Matrices tridiagonales (Octave) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Matrices no regulares. 3.3.6.1. 3.3.6.2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Singular Value Decomposition (SVD)

Problemas con defecto o exceso de ecuaciones.

3.4.

Autovalores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

NDICE GENERAL

4. Grcos
4.1. 4.2. 4.3. 4.4. 4.5.

Figure, hold y subplot. . . . Title, xlabel, ylabel, legend

75
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y

text.

75 76 78 80 80 80 80 82

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

Dibujo de curvas en el plano. Grcas tridimensionales. 4.5.1. 4.5.2. 4.5.3.

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

Grcas estadsticas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Un error bastante comn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . La funcin que tenemos que utilizar Las funciones que no tenemos que utilizar . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5. Clculo y Anlisis.
5.1. 5.2. 5.3. 5.4. 5.5. Funciones elementales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Polinomios 5.2.1. Derivadas Integrales 5.5.1. 5.5.2. 5.5.3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Evaluacin de funciones. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

83
83 83 84 84 84 85 85 86 87 88 88 89 91 91 92 92

Ecuaciones diferenciales ordinarias. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Matlab 5.5.3.1. 5.5.3.2. 5.5.4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Integracin del problema no sti (vdp1) . . . . . . . . . . . . . . . . . . . . . . . . . Solucin de la ecuacin de Van der Pol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Integracin del problema sti (vdp1000) . . . . . . . . . . . . . . . . . . . . . . . . .

Inestabilidades y caos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Denicin de variables y funciones simblicas . . . . . . . . . . . . . . . . . . . . . . . . . . . Funciones simblicas elementales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operaciones simblicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5.6.

Clculo simblico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.1. 5.6.2. 5.6.3.

6. Toolkits
6.1. Estadstica descriptiva y anlisis de datos 6.1.1. 6.2. 6.1.1.1. 6.2.1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ajuste de curvas por mnimos cuadrados. Qu calcula el ajuste polinmico por mnimos cuadrados?

93
93 93 95 95 95 96 97 97 98

Interpolacin y aproximacin de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interpolacin polinmica a trozos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2.1.1. 6.2.1.2. 6.2.2. 6.2.3. Splines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Regeneracin de funciones mediante datos discretos

Transformadas rpidas de Fourier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Aproximacin de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6.3.

Resolucin de ecuaciones no lineales y optimizacin. 6.3.1. 6.3.2. 6.3.3. 6.3.4. 6.3.1.1. 6.3.2.1.

. . . . . . . . . . . . . . . . . . . . . . . . . . . 100 . . . . . . . . . . . . . . . . . . . . 102

Resolucin de ecuaciones no lineales. Root nding. . . . . . . . . . . . . . . . . . . . . . . . . 101 Ms incompatibilidades entre Matlab y Octave. Bsqueda de soluciones de sistemas de ecuaciones no lineales. . . . . . . . . . . . . . . . . . . 102 Algunas de las cosas que pueden salir mal . . . . . . . . . . . . . . . . . . . . . . . . 103 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Minimizacin de funciones.(+) Minimizacin de funcionales.(+)

7. Temas avanzados
7.1. 7.1.1. 7.1.1.1. 7.1.1.2. 7.1.2. 7.1.3. 7.2. 7.3. 7.4.

105
El truco ms importante de la programacin en Matlab . . . . . . . . . . . . . . . . 105 Por qu son tan lentos los bucles? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 . . . . . . . . . . . . . . . . . . 107 . . . . . . . . . 107

Aumentar la calidad del cdigo escrito en Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Vectorizar, la clave para aumentar la velocidad . . . . . . . . . . . . . . . . . . . . . . . . . . 105

Control de las variables de entrada y salida en funciones.(+)

Comunicacin entre el entorno de ejecucin global y el entorno de la funcin

Array Masking(+)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 . . . . . . . . . . . . . . . . . . . . . . . . . 110

Introduccin al debbugging 7.4.1. 7.4.2. 7.4.3.

Extender Octave con otros lenguajes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Una advertencia antes de empezar a programar. Extender Octave con C++ 7.4.2.1. 7.4.3.1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

Llamar funciones desde C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Por qu Fortran? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

Extender Octave con Fortran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

Introduccin informal a Matlab y Octave

10
7.4.3.2. 7.4.3.3. 7.4.3.4. 7.4.3.5. 7.4.4. 7.5.

NDICE GENERAL
La difcil comunicacin entre C y Fortran . . . . . . . . . . . . . . . . . . . . . . . . 115 Llamar una funcin de C desde Fortran o la manera ms difcil de sumar 2+2 Punteros y arrays . . . 116

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

Escritura de wrappers para funciones en Fortran. . . . . . . . . . . . . . . . . . . . . 118 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

Extender C++ con Octave

Optimizacin de la evaluacin de funciones.(+) 7.5.1.

Polinomios de Chebyshev. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

7.6.

OCTS (Octave Control Theory Suite) 7.6.1. 7.6.2.

La representacin del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Diagramas de Bloques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 7.6.2.1. Ejemplo de aplicacin. Un sistema realimentado simple . . . . . . . . . . . . . . . . 129

7.6.3.

Anlisis en frecuencia 7.6.3.1.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

Ejemplo de anlisis en frecuencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

7.7.

Resolucin de EDPs, formulacin diferencial.

III Ejercicios
8. Ejercicios resueltos
8.1. 8.1.1. 8.1.2. 8.2. Gua para la resolucin del ejercicio

133
135
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

Ejercicio. Clculo de un gradiente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

Solucin del ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

Ejercicio. Diseo de una tobera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 8.2.1. 8.2.2. Gua para la resolucin del ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

Solucin del ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

8.3.

Ejercicio. El atractor de Lorentz 8.3.1. 8.3.2.

Gua para la resolucin del Ejercicio

Solucin del ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 8.3.2.1. 8.3.2.2. 8.3.2.3. 8.3.2.4. 8.3.2.5. 8.3.2.6. Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

Octave no sti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 Octave y C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 Octave y C++ no sti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Octave, C++ y Fortran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

8.4.

Ejercicio. Clculo de una integral doble 8.4.1. 8.4.2.

Gua para la resolucin del ejercicio

Solucin del ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

8.5.

Ejercicio. Resolucin de la ecuacin de Laplace en un dominio bidimensional . . . . . . . . . . . . . . 141 8.5.1. 8.5.2. Gua para la resolucin del ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141

Solucin del ejercicio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 8.5.2.1. 8.5.2.2. 8.5.2.3. Mejorar la solucin. Clculo de tiempos. . . . . . . . . . . . . . . . . . . . . . . . . . 144 Resolucin del problema mediante matrices sparse(+) . . . . . . . . . . . . . . . . . 144 Resolucin del problema con un mtodo iterativo. . . . . . . . . . . . . . . . . . . . 145

8.6.

Ejercicio. Un problema de calor unidimensional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 8.6.1. 8.6.2. 8.6.3. 8.6.4. Gua para la resolucin del ejercicio Solucin del ejercicio (Octave) Solucin del ejercicio (Matlab) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

Comprobacin de la evolucin temporal

8.7.

Ejercicio. Nociones de turbulencia

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

9. Ejercicios propuestos
9.1. 9.2. 9.3. 9.4. 9.5. 9.6.

151

Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 Programacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 lgebra lineal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Clculo y Ecuaciones Diferenciales Ordinarias. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

Estadstica y anlisis de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Control automtico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

NDICE GENERAL

11

IV Apndices
A. Gua de estilo. Los 10 mandamientos ATEX B. Pequea introduccin a TEX y L
B.1. Tabla con algunos caracteres T EX.

157
159 161 163 165
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

C. Software y formatos libres. D. Lo que no me gusta de Matlab.


D.2. DWIMBNWIW. D.3. Matlab para todo, absolutamente todo. D.5. Python

D.1. Un lenguaje pobre y obsoleto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

D.4. El poder del dinero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

E. GNU Free Documentation License GNU Free Documentation License


1. APPLICABILITY AND DEFINITIONS 2. VERBATIM COPYING 4. MODIFICATIONS 3. COPYING IN QUANTITY 5. COMBINING DOCUMENTS

169 169
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

6. COLLECTIONS OF DOCUMENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 7. AGGREGATION WITH INDEPENDENT WORKS 8. TRANSLATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 9. TERMINATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 10. FUTURE REVISIONS OF THIS LICENSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 ADDENDUM: How to use this License for your documents . . . . . . . . . . . . . . . . . . . . . . . . . . 173

Introduccin informal a Matlab y Octave

12

NDICE GENERAL

NDICE DE FIGURAS

1.1. 1.2. 1.3. 1.4. 1.5. 2.1. 2.2. 2.3. 2.4. 2.5. 3.1. 4.1. 4.2. 4.3. 4.4. 4.5. 4.6. 4.7. 5.1. 5.2. 5.3. 5.4. 6.1. 6.2. 6.3. 6.4. 6.5. 7.1. 7.2. 7.3. 7.4. 8.1. 8.2. 8.3. 8.4. 8.5. 8.6.

Esta es una consola Linux, mucho ms til que el Command Prompt de Windows Ventana principal de Matlab El editor de Matlab

. . . . . . . . . .

18 19 19 20 25 29 31 41 42 42 71 76 77 78 78 79 81 82 88 89 90 90 94 96

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

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

Navegador de ayuda de Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Emacs editando un archivo matlab, uno en C++ y debugeando simultneamente. . . . . . . . . . . . Tab completion en Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Comparacin del desarrollo de Taylor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Comportamiento normal de una variable llamada por una funcin

Comportamiento de una variable global denida en el programa principal

Propiedades de una variable persistente. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Elementos no nulos de una matriz sparse creada con Ejemplo de uso de

sprand

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

subplot text

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

Insercin de nombres en las guras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Insercin de caracteres griegos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ejemplo de uso de Estilos de lnea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Curvas de nivel del resultado de la funcin

peaks.

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

Introduccin de curvas de nivel personalizadas. Solucin de la ecuacin de Van der Pol con Solucin de la ecuacin de Van der Pol con Solucin del dipolo de Rikitake Curva solucin del dipolo de Rikitake

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

=1 . . = 1000

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

Ajuste por mnimos cuadrados de una serie de puntos Demostracin del fenmeno de Runge

Comparacin de los mtodos de interpolacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

Uso de los nodos ptimos de Chebyshev para reducir el error de interpolacin . . . . . . . . . . . . . 100 Representacin de las funciones a resolver. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 Diagrama de bloques del sistema ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

Diagrama de bloques resuelto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Diagrama de Nyquist del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Grca bode del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Resultado del script Resultado del script Supercie solucin Supercie solucin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 . . . . . . . . . . . . . . . . . . . . . . . . . . 145

Patrn de elementos no nulos de la matriz del sistema

Figura solucin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

13

14
8.7. Evolucin del perl de temperaturas

NDICE DE FIGURAS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

Parte I

Introduccin y elementos del lenguaje Matlab

15

CAPTULO 1
Introduccin
1.1. Lenguajes interpretados o de scripting
Un script o guin es una serie de rdenes que se pasan a un intrprete para que las ejecute. No cumplen la denicin de programa porque no son ejecutables por ellos mismos. Un programa se comunica directamente con el sistema operativo mientras que un script lo hace con un intrprete que a su vez enva comandos al sistema operativo. En este proceso de comunicacin

el programa no es el script, el archivo de cdigo, sino el intrprete que

lee lnea por lnea el cdigo y que no ejecuta la siguiente orden hasta que no ha terminado con la anterior. Esta es la diferencia entre los lenguajes basados en cdigo fuente de los lenguajes de scripting. Los primeros son C, C++, Fortran, Ada, Cobol, Pascal... El cdigo fuente escrito es transformado por un compilador en un archivo ejecutable binario que slo es capaz de entender el ordenador. Los lenguajes de scripting ms conocidos son, en el caso de los lenguajes de uso general, Java, Python y Ruby. La popularidad de Java se debe a su naturaleza de producto comercial muy sencillo de administrar mientras que Python y Ruby son Software Libre; de igual o ms calidad pero sin publicidad. Python es un lenguaje basado en la consistencia que ofrece una gran productividad y versatilidad. Ruby es uno de los lenguajes ms recientes, su popularidad est aumentando gracias a la aplicacin Ruby on Rails orientada al desarrollo de pginas web. Existe una gran variedad en los lenguajes de scripting orientado a matemticas. Matlab, Maple, Mathematica, Scilab, Octave, Euler, O-Matrix, R o S son lenguajes de scripting. Los ms conocidos son Matlab, Mathematica y Maple. No debemos considerar Matlab como nicamente un producto. El scripting cientco es una gran herramienta que hay que dominar independientemente del programa. Una vez hayamos aprendido a usar Matlab es posible que se tengamos que aprender a utilizar R, orientado a anlisis de datos, o Scilab si trabajamos en Francia.

1.2. Un lenguaje de scripting cientco, Matlab.


Un lenguaje interpretado se parece a una herramienta que todos conocemos perfectamente, una calculadora. Es incomprensible como alguien se siente completamente cmodo delante de una cajita con una pantalla y muchas teclas y en cambio le invade el miedo delante de una consola como la de la gura 1.1: Si hacemos el esfuerzo de abstraccin y simplicamos la ventana anterior nos queda el smbolo de entrada:

>>
Qu hacemos a parte de quedarnos paralizados? Pues si esto es una calculadora vamos a usarlo como una calculadora:

>> 2+2 ans = 4


Este ejemplo no sirve para nada pero resume perfectamente el uso de Matlab. En el fondo es una calculadora programable con unas posibilidades casi innitas. Si a esto se suma un lenguaje intuitivo y una gran biblioteca de funciones el resultado es una herramienta verdaderamente til para ingenieros y cientcos. Esta manera de trabajar no es un invento de Matlab, los lenguajes interpretados ya existan mucho antes. Lo que s es novedoso es basar la arquitectura del lenguaje en conceptos matemticos; entre ellos uno muy importante: la funcin. Mientras los lenguajes clsicos se basan en subrutinas o objetos Matlab dispone de una biblioteca formada

17

18

1.3. EL ENTORNO DE DESARROLLO MATLAB.

Figura 1.1: Esta es una consola Linux, mucho ms til que el Command Prompt de Windows

exclusivamente por funciones. Este diseo tan simple es lo que ha llevado Matlab a su xito, es un acercamiento matemtico a la programacin orientada a matemticas. Si queremos calcular el seno de llamar a la funcin como se hara sobre el papel:

2 lo que haremos ser

>> sin(pi/2) ans = 1


Entonces nada impide usar el mismo concepto para resolver problemas mucho ms complejos:

>> quad(@(x) besselj(2.5,x),0,4.5) ans = 1.1178


Acabamos de hacer la siguiente integral de la funcin real de Bessel de primera especie:

4 ,5

J2,5 (x)dx
0

quad

besselj

son funciones que se han compuesto del mismo modo que se compondran funciones matem-

ticas. Esta lnea de cdigo puede ser incomprensible pero al nal la entenderemos con todos los detalles.

1.3. El entorno de desarrollo Matlab.


Matlab como programa no se limita a un intrprete en una consola, es un entorno de desarrollo al completo. Al iniciar Matlab nos aparecer la ventana principal con la consola, el navegador de variables y el historial de comandos (gura 1.2) . Evidentemente lo ms importante es la consola; todo lo dems, aunque til, es prescindible. La ventana principal no es ms que la consola con algunas herramientas adicionales. Para completar un entorno de desarrollo son necesarios dos elementos ms: un editor y un navegador de ayuda. El primero aparece cuando editamos un archivo

.m

desde el gestor de archivos o cuando creamos uno nuevo desde la ventana principal. Su

funcin es facilitar la creacin de archivos de cdigo Matlab y para ello cuenta con Syntax Highlighting, tabulado automtico, soporte grco para debugging...

1 En

Unix Matlab puede funcionar tambin desde el intrprete de comandos mediante la funcin

-nojvm.

Es una opcin interesante

cunando no hemos instalado ninguna mquina virtual de Java

CAPTULO 1. INTRODUCCIN

19

Figura 1.2: Ventana principal de Matlab

Figura 1.3: El editor de Matlab

Introduccin informal a Matlab y Octave

20

1.4. OCTAVE
Es muy importante llegar a dominar todas las posibilidades del editor. Cuanto mejor lo conozcamos ms

fcilmente y rpidamente programaremos. Finalmente el navegador de ayuda. Adems de ser el mejor sitio donde buscar ayuda puntual sus tutoras nos servirn para perfeccionar nuestra habilidad con el lenguaje y el entorno. Podemos acceder a l desde el men  Help o mediante el icono con el smbolo interrogante en la barra de herramientas.

Figura 1.4: Navegador de ayuda de Matlab

1.4. Octave
Octave es tambin un lenuaje de scripting cientco. Aunque su nacimiento nada tiene que ver con Matlab ha ido convergiendo hacia la compatibilidad. Octave fue pensado como aplicacin para la consola UNIX. No tiene interfaz grca propia, navegador de ayuda, visor de variables, editor, debugger... Se puede decir que no tiene nada de nada. Es un intrprete muy estable, ligero y orientado a programadores ms experimentados. Octave es Software Libre soportado por una comunidad de desarrolladores sin nimo de lucro. Es un proyecto en colaboracin cuyos miembros nos prestarn ayuda cuando la solicitemos. Sus listas de correo son pblicas y son una gran fuente de informacin. Formar parte del desarrollo de Octave es la mejor manera de conocer Matlab en profundidad. El lenguaje Octave es un poco ms potente y mejor diseado, si no nos importa sacricar la compatibilidad tendremos un poco ms de libertad programando. Como parte del proyecto GNU su integracin en un entorno GNU/Linux es excelente; es por ello que se comunica perfectamente con otros lenguajes de programacin. Puede ser una buena excusa para perfeccionar o utilizar nuestros conocimientos de C++ o para profundizar en UNIX. Tampoco es verdad que Octave sea tan minimista. Existen esfuerzos para dotar a Octave de ms y ms herramientas fuera del paquete ocial. El ms relevante es sin duda Octave-forge. Cualquiera que eche de menos una funcin en Octave puede escribirla y mandarla al proyecto; si lo creen conveniente la incorporarn en la prxima versin de la coleccin. Adems Octave-forge es un gran directorio de cdigo escrito. Puede servirnos para aprender como escribir una funcin como es debido o como implementar algoritmos especialmente complejos. La calidad de las funciones es variable pero la media es muy alta. Otro proyecto interesante Octave Workshop de Sbastien Loisel. Se trata de una interfaz grca a la Matlab para Octave, orientada sobre todo hacia usuarios de Windows. Es un proyecto muy joven pero prometedor; desde el principio ha apostado por una solucin integrada. Llena un vaco muy importante, de otro modo la curva de aprendizaje se alarga por la necesidad de aprender a utilizar herramientas de UNIX en un entorno Windows.

CAPTULO 1. INTRODUCCIN

21

1.4.1. El entorno de desarrollo Octave


Cuando hemos hablado del entorno de desarrollo de Matlab han aparecido tres ingredientes bsicos: la consola, el editor y el naveador de ayuda. Como aplicacin para la consola UNIX debemos conar en las herramientas propias del sistema: un editor polivalente como emacs o vim, pginas de ayuda en formato info... Aunque todas las piezas de este entorno existen en Windows carecen de la misma integracin con el sistema operativo. En este caso optaremos por un entorno de desarrollo integrado como Octave Workshop. El editor que mejor se complementa con Octave es Emacs (gura 1.5), parte esencial del proyecto GNU. Emacs cuenta con un plugin para adecuarlo a la edicin de archivos adecuado para los usuarios de Windows. El programa ms utilizado para dar soporte grco a Octave es GNUPlot. Sus funcionalidades no son comparables a las ofrecidas por Matlab pero son sucientes. Desde hace bastante tiempo se busca un sustituto pero an no ha aparecido ningn candidato adecuado. Probablemente nuestra instalacin de Octave incorpore GnuPlot, si no es as tendremos que instalarlo puesto que es un requerimiento casi indispensable. Sobre el navegador de ayuda es muy conveniente obtener el directorio de Octave-forge. Es un documento HTML comprimido que cualquier navegador puede mostrar. No se acerca a las posibilidades de la ayuda de Matlab pero es una buena herramienta de consulta. En compensacin, la ayuda interactiva de las funciones de Octave suele ser de mayor calidad gracias al uso del formato texinfo.

.m

y la comunicacin con el intrprete Octave. Si

no nos sentimos cmodos con l siempre podemos optar por otros editores como VIM o SciTe, este ltimo muy

1.5. Los proyectos de software y los lenguajes de programacin


Cuando afrontamos un proyecto de sofware, sea del tipo que sea, la primera consideracin que se hace es la eleccin de la herramienta de trabajo. En este caso un lenguaje de programacin. Actualmente existen un centenar de ellos y la eleccin no es sencilla. Cules son los criterios principales? Que todos los miembros del proyecto dominen o conozcan el lenguaje. El acceso a todas las herramientas necesarias. El tiempo total de desarrollo del proyecto. La calidad del resultado nal. La relacin esfuerzo resultado. Aunque estas condiciones parecen obvias no siempre han sido las mismas. Durante las dcadas de los 70 y 80 programar se consideraba una tarea laboriosa y complicada en la que no deba ahorrarse horas de trabajo. Que un ingeniero pasara miles de horas sentado delante de un ordenador no se consideraba tiempo malgastado. Exista la creencia de que ninguna tecnologa era capaz de competir con la pericia y que cualquier aumento en el rendimiento compensaba con creces el tiempo dedicado. Durante los 90 aparecieron multitud de herramientas orientadas a aumentar la productividad y con ellas un cambio esencial de losofa. El criterio era mucho ms pragmtico: todo cuenta. Debemos valorar el tiempo total de desarrollo, la calidad del cdigo escrito, la portabilidad del programa... Ya no era slo el programador y su programa, se haba convertido en una pieza dentro de una gran maquinaria fuera consciente de ello o no. La aparicin de los lenguajes interpretados acentu an ms esta concepcin. Tareas que antes llevaban das podan hacerse en horas y cada vez se haca menos necesario un conocimiento preciso de informtica para programar. El criterio esencial pas de ser la calidad del resultado nal a ser la relacin esfuerzo por resultado. Los lenguajes interpretados suelen mejorar dicha relacin gracias a simplicar la metodologa de trabajo. Hemos hablado de la distincin entre lenguajes de cdigo fuente o compilados y los lenguajes interpretados pero no hemos tratado sus diferencias en el uso. Un lenguaje interpretado elimina la necesidad del ciclo escrituracompilado-debugging.

1.5.1. El ciclo de desarrollo clsico


Todas las herramientas de desarrollo de sofware en general intentan paliar los problemas derivados de este ciclo. Cuando programamos con un lenguaje compilado como C o Fortran nos vemos obligados a convertir el cdigo fuente en un programa, ejecutar el programa, analizar el resultado y, en el caso que sea necesario, realizar un debugging. El debugging es el proceso de depuracin en tiempo de ejecucin. Un programa compilado se ejecuta entero y escupe un resultado nal; si no es el esperado y el cdigo parece correcto nos veremos obligados a analizar los resultados intermedios. Cmo puede hacerse eso en un ejecutable que parece un bloque monoltico? Introduciendo pausas en la ejecucin llamadas breakpoints que paran el hilo para comprobar los resultados intermedios.

Introduccin informal a Matlab y Octave

22

1.5. LOS PROYECTOS DE SOFTWARE Y LOS LENGUAJES DE PROGRAMACIN


Este ciclo es rentable slo en el caso de grandes aplicaciones muy integradas con las libreras o que requieren

una mxima optimizacin. Qu sucede si nuestra aplicacin busca simple y llanamente un resultado despus de un tiempo de desarrollo lo ms corto posible? Entonces sacricaremos los lenguajes de programacin clsicos en favor de los lenguajes interpretados

1.5.2. Rapid Application Development o RAD


La ventaja de los lenguajes interpretados respecto a los compilados es evidente, uno de los pasos del ciclo de desarrollo, la compilacin, desaparece y el debugging es trivial. Esta diferencia que puede parecer irrisoria suele condicionar enteramente el proceso. Los lenguajes de scripting nacieron como una manera sencilla de hacer tareas complejas o repetitivas. Por ejemplo, tenemos en un directorio cualquiera medio centenar de archivos de los que no conocemos el nombre. Nuestro objetivo es aadir al nal de todos los que contengan la combinacin de letras abc el smbolo sistema lo conseguiremos con:

_.

Realizar

manualmente esta tarea puede requerir unos cuantos minutos pero si disponemos de un intrprete de python en el

>>> import os >>> for file in os.listdir('.'): ... if file.find('abc') >= 0: ... os.system('mv %s %s%s' %(file,file,'_'))
Parece fcil. Verdad? Si para los administradores de sistemas conocer un lenguaje interpretado de propsito general es as de til Por qu no iba a serlo para un ingeniero? Cuntas lneas de cdigo seran necesarias para programar lo mismo en C o Fortran? Los ordenadores incrementan exponencialmente su potencia y cada ao los lenguajes interpretados son ms y mas competitivos; ahora se usan para casi cualquier aplicacin y han obligado a todo el mundo a cambiar su punto de vista. Los lenguajes interpretados se utilizaban nicamente cuando se quera una interaccin directa con el usuario, una manera de extender las capacidades de un programa que estaba escrito en un lenguaje compilado. Ahora podemos utilizar lenguajes interpretados para aplicaciones de alto coste computacional y pasaremos a un programa puramente compilado slo en caso de necesidad. Las aplicaciones de simulacin suelen ser programas no muy largos que pueden o no solicitar una optimizacin mxima. En cualquiera de los dos casos se utilizar un lenguaje interpretado porque nuestro objetivo es el RAD o Rapid Application Development. En programas cortos porque es el nico modo de acortar el tiempo de desarrollo y en los largos para la fase de prototipado. Para que un lenguaje interpretado pueda ser utilizado como una herramienta de RAD debe cumplir los siguientes requisitos: 1. Debe ser lo sucientemente polivalente como no necesitar acudir a otros lenguajes de programacin durante del proceso de diseo. 2. Debe poner a nuestra disposicin sucientes herramientas como para que no sea necesario buscar. 3. Debe formar parte de un entorno de desarrollo cmodo y verstil y sencillo. 4. Su sintaxis debe ser clara para que el cdigo sea leble. En la mayora de los casos los cdigos se reciclan y mutan en el tiempo. Si cada vez que cambia de manos requiere ser ledo cinco o seis veces para saber qu est haciendo es cualquier cosa menos rpido. Matlab cumple sobradamente todos estos requisitos. El lenguaje es sencillo, cmodo y leble; las bibliotecas de funciones son enormes y siempre que no nos salgamos del clculo numrico no tenemos que acudir a otros lenguajes de programacin.

1.5.3. Otros lenguajes orientados a RAD.


Matlab tiene competencia, esperada e inesperada. La esperada viene de programas comerciales como Mathematica o Scilab. Adems Mathematica concepto un concepto interesante conocido como Notebook, ya introducido por Maple, para potenciar las sesiones interactivas. Lo que probablemente no esperaban los desarrolladores de Matlab es que la competencia les llegara por parte de los lenguajes interpretados de propsito general. Si nos obligamos a mantener el sentido crtico aplicado a las herramientas debemos tener en cuenta lenguajes como Python o Ruby, sobre todo Python gracias al proyecto SciPy. De momento son opciones poco consolidadas pero puede que en un futuro sean una referencia en el desarrollo de aplicaciones de simulacin.

CAPTULO 1. INTRODUCCIN

23

1.6. Una visin contempornea del desarrollo de aplicaciones de simulacin


Es muy comn que un ingeniero o un cientco tenga que programar a menudo. El desarrollo de aplicaciones de software est ligado a la necesidad de simular un sistema de cualquier tipo. En la mayora de los casos los programadores son ingenieros, matemticos o fsicos sin una formacin terica en lenguajes de programacin. La mayora de ellos son autodidactas sin conocimientos especcos sobre metodologa y prctica de la programacin. En muchos casos se construyen programas decientes con herramientas inadecuadas y del peor modo posible. No se usan bien los editores, los debuggers brillan por su ausencia, no se aplican las metodologas orientadas a la programacin sin errores... La raz de estos problemas es que el jefe del proyecto es el primero en desconocer el entorno ideal. Casi siempre existen carencias en el diseo de la aplicacin y en la eleccin de las herramientas. Cuntos ingenieros han odo hablar del UML ? Y de la refactorizacin? Cuntas aplicaciones de simulacin estn escritas con un lenguaje orientado a objetos? Y en un lenguaje interpretado? Los ingenieros somos tan soberbios como todoterrenos. Somos

tan capaces de arreglar cualquier cosa como incapaces de reconocer que un mejor diseo nos ahorrara muchos quebraderos de cabeza. En programas que requieren desarrollos de horas o de das el coste de empezar de cero por
culpa de un mal diseo no es ningn problema; medida que los tiempos de desarrollo crece las situacin se vuelve ms y ms crtica.

1.6.1. Errores tpicos


El ingeniero tipo escribe un cdigo lamentable, ilegible. Si en la construccin del ala de un avin no se puede hacer una chapuza... Por qu puede serlo el cdigo del programa que simula su inestabilidad? Porque funciona? Otra consideracin fundamental es que si queremos producir una pieza especialmente complicada construiremos antes un prototipo para saber si cumple con los requisitos funcionales. Si aplicramos los mismos principios al desarrollo de simulaciones sera intolerable ponerse a escribir en Fortran ms de 2000 lneas de cdigo sin haber probado antes el algoritmo en Matlab. Esta prctica es tan poco comn en la empresa como en el mbito cientco. Otro error es el de subestimar el tiempo de desarrollo. Un programa de simulacin decente, con requerimientos computacionales medios o grandes, puede desarrollarse en uno o dos aos. Lo que suele hacerse es tomar un lenguaje lo ms rpido posible para minimizar el tiempo de clculo. Los lenguajes rpidos son principalmente dos, C y Fortran. Normalmente se trabaja sin diseo, sin prototipos... Los errores incomprensibles pueden alargar la aparicin del primer ejecutable en un 50 % del tiempo del proyecto, mucho ms que lo que ahorraramos en el tiempo de ejecucin. Quizs la peor prctica de todas es la de no documentar el cdigo a medida que se escribe. Un cdigo sin documentacin o uno sin una documentacin adecuada puede ser un inerno hasta para uno mismo. Si leemos cdigo escrito por nosotros mismos un ao antes es como si lo hubiera escrito alguien que no conocemos de nada. Esto sucede de verdad! Os lo digo por mi propia experiencia. Los comentarios son muy tiles, hay que comentar cualquier estructura que no tenga una lgica aplastante y escribir cdigo obvio no es tan fcil como parece.

1.6.2. Cul es entonces el espacio de Matlab?


3 y sencillo. Todas las herramientas 4 necesarias estn dentro de la misma aplicacin y la documentacin est embebida en el propio programa . Es una
de desarrollo signicativamente adems de ser un lenguaje leble, escalable opcin interesante en el proceso de diseo (cuando existe) y es esencial en el proceso de anlisis de datos, mucho menos exigente computacionalmente. La mayora de los programas que escribe un ingeniero son cortos, y requieren casi siempre las mismas herramientas matemticas (lgebra lineal, representacin de funciones, integracin numrica...). Se busca efectividad, rapidez y pocos errores. Matlab es el lenguaje de programacin y la aplicacin que mejor encaja en todos estos requisitos en lo que a ingeniera se reere. Matlab es absolutamente superior en aplicaciones cortas y sencillas. Reduce la longitud del cdigo y el tiempo

1.6.3. Y el espacio de Octave?


Supongamos que ya dominamos Matlab de un modo razonable. Como es

2 UML 3 Se

son las siglas del Universal Modelling Language. Es un

estndar

para la creacin de diagramas que modelan la estructura de

cualquier cosa, aunque fueron pensados para sistemas altamente lgicos como los programas de ordenador. dice que un lenguaje es escalable cuando todas sus virtudes se mantienen independientemente de la longitud del programa. Matlab es escalable pero hasta un lmite; en aplicaciones especialmente grandes empiezan los problemas de uso de memoria y de acumulacin de archivos de funcin. Los lenguajes compilados son tpicamente escalables y algunos lenguajes interpretados como java y python tambin escalan perfectamente.

4 La

ayuda de Matlab es un ejemplo de cmo se debe documentar una coleccin de funciones.

Introduccin informal a Matlab y Octave

24

1.6. UNA VISIN CONTEMPORNEA DEL DESARROLLO DE APLICACIONES DE SIMULACIN

1.6.4. Los lenguajes pegamento


Otra caracterstica de los lenguajes interpretados es que ellos mismos estn construidos sobre lenguajes compilados. Matlab, por ejemplo, est escrito casi enteramente en C, mientras que Octave lo est en C++. Esto signica que pueden integrarse perfectamente con sus lenguajes padre. Es de sobra sabido que los lenguajes interpretados son entre uno y dos rdenes de magnitud ms lentos que los compilados. La solucin es acoplarles rutinas escritas en algunos lenguajes compilados como C, C++ o Fortran para conseguir un aumento signicativo de velocidad. Matlab empez como una coleccin de subrutinas en Fortran que se acoplaban a un intrprete interactivo. Si este proceso se realiza sistemticamente durante el desarrollo se dice que el lenguaje interpretado sirve de

pegamento entre las unidades de programa. Se puede decir que se buscan las ventajas de los dos planteamientos,
nos acercamos a la velocidad del cdigo enteramente compilado mientras mantenemos la versatilidad de un script. Matlab es capaz de convertir cdigo en C o Fortran en archivos tipo

mkoctfile

mex

y Octave cuenta con el programa

(seccin 7.4) que realiza una labor parecida. Lenguajes ms polivalentes como Python, Ruby o Perl

cuentan con mejores herramientas.

CAPTULO 1. INTRODUCCIN

25

Figura 1.5: Emacs editando un archivo matlab, uno en C++ y debugeando simultneamente.

Introduccin informal a Matlab y Octave

26

1.6. UNA VISIN CONTEMPORNEA DEL DESARROLLO DE APLICACIONES DE SIMULACIN

CAPTULO 2
MATLAB
2.1. El lenguaje y las bibliotecas
Antes de entrar en materia es importante que sepamos qu diferencias hay entre las sentencias de un lenguaje de programacin y la biblioteca de funciones. Las sentencias son las palabras clave independientes. Esto signica que si las eliminaremos del lenguaje no podramos sustituirlas con ninguna combinacin del resto de sentencias del lenguaje. Esta denicin no es estricta; algunas palabras clave comunes se consideran sentencias cuando se hace un uso muy frecuente de ellas. El total de sentencias y de reglas de escritura son lo que forman el lenguaje de programacin descrito en un documento llamado referencia. Como Matlab es un programa comercial no existe tal documento. El resto de funciones y subrutinas son parte de la biblioteca. Son palabras clave que cumplen una tarea y no pueden ser consideradas sentencias porque estn escritas con ellas. Algunas funciones de uso muy frecuente llegan a ser parte del mismo lenguaje, el grupo que forman se llama biblioteca estndar . El conjunto de sentencias y biblioteca estndar se conoce como especicaciones y en el caso que el lenguaje tome vida propia, es decir, sus especicaciones pasen a ser pblicas; se llama estndar. Estos documentos existen para la mayora de los lenguajes de programacin conocidos: C, C++, Ada, Fortran, Python... Matlab no es uno de ellos. Al ser un lenguaje sujeto a una herramienta Matlab es Matlab y punto; sin embargo podemos aplicar estas deniciones estrictas para acercarnos a l como lo haramos con el resto de lenguajes. La organizacin interna de Octave sigue este criterio. Se podra decir que Octave es el conjunto de sentencias mas la biblioteca estndar y que el resto de colecciones de funciones (y hay bastantes) son los toolkits. La Compatibilidad entre los dos se sita slo en las sentencias aunque se extiende en gran manera con la biblioteca de funciones. Por lo menos las funciones bsicas son compatibles, casi idnticas. Matlab tiene muy pocas sentencias. Como lenguaje es muy sencillo aunque cada versin incluye nuevas especicaciones. En los ltimos aos se ha aadido la extensin para programacin orientada a objetos y el diseo de interfaces grcas. Octave es ligeramente distinto en su concepcin; es ms minimista y cuenta con muchas menos funciones pero es ms fcilmente extensible. Son las diferencias tpicas entre los productos libres y los comerciales. Este captulo es la referencia del lenguaje; en l veremos argumentos, variables, operadores y sentencias que nos servirn para programar funciones y scripts as como la arquitectura general del programa. Es con diferencia la parte ms importante del libro y no se ha dividido en varios captulos para no romper el hilo conceptual.

Siempre que se hable exclusivamente de Matlab nos referiremos a las caractersticas comunes de Matlab y Octave. Cuando la palabra Matlab se utilice en una diferencia respecto a Octave nos estaremos reriendo al programa comercial. Por sencillez no se ha diferenciado tipogrcamente la palabra Matlab en los dos contextos.

2.2. Convenciones
A partir de ahora escribiremos un comando escrito en la consola de la siguiente manera:

>> %Esto es un comentario puesto en la consola de Matlab


Escribiremos todas las palabras clave con letra de formato jo como esta funcin:

sin(x).

Veremos que la sintaxis de Matlab no es muy distinta de la de cualquier otro lenguaje; las diferencias sern las de siempre, los smbolos de continuacin, los comentarios... Aunque sea un poco temprano los listamos a continuacin:

27

28

2.2. CONVENCIONES
Comillas simples. Sirven para introducir texto literal, todo lo que se encuentre en este entorno ser tomado como texto y no como el nombre de una variable

'_' _ % #

Comillas dobles. Smbolo de carcter tambin soportado en Octave.

Porcentaje. Es el smbolo del comentario. Todo lo que est por detrs de este smbolo en una lnea es ignorado por el intrprete. Almohadilla. Smbolo del comentario slo soportado por Octave. Es muy til cuando se quieren aadir comentarios en la cabecera de una funcin sin que el parser

1 lo tome como parte de la ayuda.

... \ ;

Tres puntos. Al aadir alguno de estos dos smbolos al nal de una lnea signica que se tomar la posterior como continuacin

Barra invertida. El smbolo de continuacin de C, C++ y Python tambin est soportado en Octave. Punto y coma. Smbolo de retorno de carro. Sirve para concatenar ms de una sentencia en la misma lnea y para inhibir la salida por consola del resultado.

Importante:

El punto y coma al nal de una sentencia explicita el retorno de carro e inhibe que salga el resultado

por pantalla.

2.2.1. Operaciones elementales con Matlab


Las convenciones para las operaciones en Matlab son idnticas que en cualquier otro lenguaje de programacin o que en una calculadora programable. El orden de asociacin de las operaciones es tambin el mismo. Primero se operan las funciones matemticas elementales (senos, cosenos, logaritmos...), las multiplicaciones y divisiones y luego sumas y restas. Por ejemplo, para realizar la siguiente operacin:

2 0,11/2
introduciremos enla consola:

0 ,4 21/3

>> 1/((2/0.1 ^(1/2))-(0.4/2 ^(1/3)))


Evidentemente Matlab no distingue entre elementos numricos y variables, la ecuacin:

b cd

e gf

>> a/(b/c^d-e/g^f)
Los parntesis sirven para variar el orden normal de las operaciones a realizar.

2.2.2. Algunas palabras clave y atajos de teclado.


La consola es un entorno de trabajo ms potente de lo que parece. Editar directamente en ella es un ejercicio cmodo gracias a una serie de atajos de teclado de gran utilidad. Uno de los ms potentes es la capacidad de autocompletar alguna palabra clave con la tecla de tabular, tab completion en ingls. Por ejemplo, si nos encontramos en el intrprete Octave y nos acordamos cmo se escribe exactamente la funcin para trasponer una matriz podemos hacer lo siguiente, escribimos slo el inicio de la palabra y luego presionamos la tecla de tabular:

>> tra<TAB> trace transpose

trapz

Esta es una caracterstica comn de casi todas las consolas existentes, ya sea una consola de UNIX o el Command Prompt de Windows. La consola grca de Matlab es un poco ms potente gracias a su interfaz (gura 2.1): A continuacin una lista de palabras clave y atajos de teclado que pueden hacernos la vida mucho ms fcil:

exit

Cierra el intrprete, equivalente a cerrar la ventana. Corta la ejecucin del comando actual (kill)

<CTRL>-c
1 Todos

los lenguajes interpretados procesan el cdigo con una herramienta llamada parser. El parser lee cada lnea y distingue las

palabras clave, las variables y los argumentos para que el intrprete pueda hacer su trabajo sin problemas.

CAPTULO 2. MATLAB

29

Figura 2.1: Tab completion en Matlab

Reescribe lneas anteriores. A medida que presionemos este carcter aparecern en la lnea actual todos los comandos escritos anteriormente. Una vez estemos viendo los comandos podemos movernos entre ellos mediante los cursores.

<CTRL>+<,> clc

Hace avanzar o retroceder el cursor por palabras en vez de por caracteres.

Limpia la pantalla del intrprete de comandos

2.3. La Ayuda(I)
La manera ms fcil de acceder a la ayuda tanto en Matlab como en Octave es mediante la consola y el comando

help.

funcionalidades . Para acceder a la ayuda de una funcin teclearemos

Cada comando y funcin lleva consigo la informacin necesaria para que conozcamos su uso y sus

>> help {nombre de la funcin}


Esto signica que debemos saber cmo se llama la funcin. Si introducimos

help

sin ningn argumento nos

aparecer una ayuda general desde donde podremos encontrar cualquiera de las funciones disponibles. Uno comando bastante til cuando trabajamos desde una consola o por red es con

more. Si activamos el comando more on activaremos el paginador de modo que cuando el texto que aparezca en pantalla se salga de la misma <Q>.

interrumpir el texto hasta que nosotros le pidamos que contine. Esto evita el comportamiento tan desagradable que tienen las ayudas especialmente largas en las que siempre tenemos que utilizar la barra de desplazamiento para ver el principio. Para salir del texto sin tener que desplazarnos hasta el nal pulsaremos la tecla

2.4. Tipos de archivos en Matlab


Al igual que el intrprete es capaz de entender comandos mediante su consola interactiva, tambin es capaz de leer archivos de cdigo o scripts. En el caso de Matlab los archivos asignados al intrprete son los que terminan con la extensin

.m.

Pero para entender cmo estos archivos interactan con el intrprete es necesario que entendamos

la arquitectura interna de Matlab. Gran parte de la funcionalidad de Matlab se basa en su biblioteca de funciones. Una funcin en Matlab es equivalente a una funcin matemtica; es una tarea encapsulada que puede depender de una o varias variables. Matlab tiene una extenssima biblioteca de funciones, la mayora de ellas son archivos con la extensin consola introducimos:

.m

que lee

el intrprete. Pero el intrprete no puede saber por ciencia infusa dnde se encuentran dichas funciones. Si en la

>> sin(x)
Cmo sabe Matlab dnde se encuentra la funcin seno? La respuesta es que Matlab ya sabe en qu directorios del sistema puede encontrar archivos

.m

desde su instalacin.

Signica esto que si creamos nuestras funciones debemos guardarlas en estos directorios? Ni mucho menos. Matlab cuenta con un directorio especial en el que tambin busca funciones; es el llamado directorio de trabajo. Si estamos utilizando la interfaz grca de Matlab lo seleccionaremos en la barra de herramientas. Si en cambio accedemos a Matlab por consola o optamos por Octave el directorio de trabajo ser el directorio actual (en UNIX el contenido en la variable de sistema PWD). Cada vez que se invoque una funcin en Matlab buscar en los directorios habituales y en el directorio de trabajo.

2 Ms

adelante aprenderemos cmo introducir esta informacin a cualquier funcin que escribamos

Introduccin informal a Matlab y Octave

30

2.4. TIPOS DE ARCHIVOS EN MATLAB

2.4.1. Funciones(I)
Una funcin es una unidad de programa, una tarea independiente que puede o no depender de variables externas. Las unidades de programa tpicas son las funciones, las subrutinas, las clases... Matlab basa toda su potencia y su sencillez en el constante uso de funciones. La razn es bien sencilla; si Matlab es un programa para clculo numrico es normal que la unidad de programa esencial sea la que tiene un signicado ms matemtico En Matlab se dene una funcin del siguiente modo: :

function [variables_de_salida]= nombre(variables_de_entrada) Comandos que terminamos asignando a las variables de salida {end}
Por ejemplo,si queremos implementar una funcin que sume dos escalares debemos hacer lo siguiente:

function [c]=suma(a,b) c=a+b;


Y lo guardaremos en un archivo que se llame igual que la funcin; en el caso del ejemplo ser guardaremos en nuestro directorio de trabajo. El concepto de funcin va ms all pero esta descripcin es suciente para entender su papel dentro de la arquitectura de Matlab.

suma.m.

Luego lo

2.4.2. Scripts
Los scripts hacen la funcin de un programa completo, su hilo de sentencias tiene un principio y un nal y no necesita actuar con ninguna variable externa al cdigo. La diferencia entre un script y un archivo de cdigo fuente es que el script es una transcripcin literal de comandos de consola; se dice que es secuencial. Esto no nos permite explotar las posibilidades de los formatos libres ni utilizar secuencias de control tipo extensin

.m

goto4 .

Tambin tienen la

y se pueden ejecutar de varios modos:

Dentro del intrprete. Si hemos guardado el archivo en alguno de los directorios de bsqueda de funciones el intrprete ejecutar toda la secuencia de comandos introducindole el nombre del script

>> nombre_del_archivo
Fuera del intrprete. Dentro de una consola llamando el intrprete con el nombre de archivo como argumento. Por ejemplo, en una consola cualquiera:

$> matlab nombre_del_archivo


Podemos llamar a funciones en nuestros scripts siempre que sea con variables que hayamos inicializado antes de la llamada. El concepto es el mismo, no es ms que la transcripcin de los comandos que se introduciran en la consola.

2.4.3. Nuestra primera funcin


En esta primera funcin no usaremos ninguno de los elementos caractersticos de la programacin en Matlab. Estos son los que encontramos en cualquier cdigo de simulacin: contadores, funciones elementales, condicionales, casos... Empezaremos con el archivo

aprsin.m,

que es la aproximacin de orden 3 del desarrollo de Taylor en 0 de

la funcin seno. Para ello editamos el archivo nuevo de nombre Octave segn el caso y pondremos en ella lo siguiente:

aprsin.m

en el directorio que nos diga Matlab o

function out=aprsin(x) out=x-x^3/6;


Vemos que asignamos a la variable

out

las operaciones que hacemos sobre la variable de entrada

x.

La idea es

mantener las caractersticas de una funcin matemtica. Una vez la hayamos guardado en el directorio de trabajo esta funcin puede ser llamada por el intrprete de Matlab o por cualquier script. Para probarlo nos vamos a la consola y tecleamos:

>> y=aprsin(1.3)
3 El
comando

end

slo es necesario en Octave cuando queremos acoplar funciones en los scripts o ms de una funcin en un mismo

archivo. En Matlab no es necesario porque cada funcin est asociada a un nico archivo, el nal del mismo hace de textttend.

4 Mejor,

porque este tipo de estructuras no son nada aconsejables.

CAPTULO 2. MATLAB
que debe darnos como resultado:

31

y = 0.93383
An es pronto para algunos conceptos, hay que aclarar un par de cuestiones: Las variables

out

son de uso interno de la funcin. Desde la consola o desde un script podemos usar las

variables que queramos. Esta abstraccin es comn en todos los lenguajes de programacin; la entenderemos cuando hablemos de la diferencia entre variable y argumento. El punto y coma signica lo mismo que el retorno de carro. Tenemos que recordar siempre que la diferencia entre hacer un retorno de carro y poner el punto y coma es que en el segundo caso el programa no nos da ningn output. Llenaremos siempre las funciones de puntos y comas para no recibir resultados intermedios intiles.

2.4.4. Nuestro primer script


Vamos a comparar nuestra aproximacin de la funcin seno con la funcin exacta y lo vamos a escribir en un guin. Para ello creamos el archivo

comparar.m

y escribimos lo siguiente en l:

x=linspace(-pi,+pi,100); for i=1:100 y(i)=aprsin(x(i)); end plot(x,[y;sin(x)])


Para ejecutarlo vamos a la consola y tecleamos:

>> comparar
E inmediatamente va a aparecer la gura 2.2:

Comparacion sin vs aprsin 2 aprsin sin

1.5

0.5

-0.5

-1

-1.5

-2 -3 -2 -1 0 1 2 3

Figura 2.2: Comparacin del desarrollo de Taylor An es temprano para entender exactamente qu hace el script, lo iremos viendo paso a paso; pero ha servido para ver cul es la relacin entre funciones, los scripts y Matlab.

2.4.5. Una gran diferencia entre Matlab y Octave


Matlab no puede denir funciones directamente en el intrprete o en un script. Cualquier funcin debe ser un archivo independiente por simple que esta sea. Por ejemplo, si en Matlab escribimos:

Introduccin informal a Matlab y Octave

32

2.5. ARGUMENTOS

>> function c=suma(a,b) ??? function c=suma(a,b) | Error: Function definitions are not permitted at the prompt or in scripts.
Recibimos un error. En cambio Octave puede denir funciones tanto en el intrprete como en un script, algo que dota a este intrprete alternativo de algo ms de versatilidad. ste es uno de los grandes puntos dbiles de Matlab. Ignoro el hecho por el que an no lo soportan. Lo que no se puede hacer ni en Matlab ni en Octave es poner varias funciones en un mismo archivo de funcin. No es muy difcil ver por qu. El lenguaje Matlab, cuando llama a una funcin, busca por los directorios algn archivo que se llame como la funcin, y luego busca una sentencia ejecutable en l. Esto implica que cada archivo slo puede contener una cabecera . Si pensamos un poco tambin vemos que en Octave se puede usar un pequeo truco para cargar varias funciones sin necesitar una cabecera. Simplemente creamos un script cuyo nombre no coincida con ninguna de las funciones que contiene. ste archivo lo empezamos con algo que no sea la sentencia

function

y a continuacin escribimos todas las funciones que necesitemos. Luego, en el programa principal lo

llamamos con un:

>> source('header.m')

2.5. Argumentos
El concepto preciso de argumento es complejo pero a nosotros nos bastar con saber que es cualquier elemento manipulable en un cdigo. Los argumentos de un programa de simulacin numrica son los nmeros, los ndices, las matrices, las secuencias... Tenemos que hacer el esfuerzo conceptual de separar el concepto de argumento del de variable. Una variable es su contenedor, es lo que les da nombre y sirve para manipularlos. Sucede lo mismo en cualquier frmula matemtica; siempre se expresa mediante variables y toma sentido cuando stas contienen algn argumento. Matlab tiene varios tipos de argumentos y varios tipos de variables; en consecuencia ser valida cualquier combinacin entre ellos. Estos son los tipos de argumentos soportados :

2.5.1. Matrices
Matlab no distingue entre escalares y matrices. Si se dice que Matlab es un lenguaje de clculo matricial es porque todos los nmeros son en el fondo matrices. El nmero ningn problema:

puede ser escalar, vector y matriz a la vez sin

>> a=1 a = 1 >> a(1) ans = 1 >> a(1,1) ans = 1 >> a(1,1,1) ans = 1
Tampoco distingue si sus elementos son enteros o reales, todos los nmeros tienen la misma precisin en coma otante, que es doble precisin siempre que no le indiquemos lo contrario. Las entradas

>> a=105 a = 105 >> a=1.05e+2 a = 105 >> a=1050e-1 a = 105 >> a=105. a = 105
5 Puede 6 Los
contener ms funciones pero slo se puede llamar una. Esta es la funcin que tenga la cabecera en la primera linea cuyo nombre coincida con el nombre del archivo. Esta funcin puede llamar a otras funciones que se pueden encontrar en el mismo archivo, pero nunca podremos acceder desde fuera a las

subfunciones

puesto que Matlab no tiene informacin para saber donde se encuentran que es consistente con la denicin de tensor. Esto permite operar con

fsicos tericos y los matemticos encontraran mucho ms til Python; lenguaje que probablemente desconozcan. La extensin

numrica estndar de Python, Numeric, soporta el tipo

array

tensores de varias dimensiones de una forma mucho ms natural. Es muy recomendable echarle un vistazo, la combinacin de Python y la coleccin de bibliotecas SciPy es una mejor opcin en el caso de aplicaciones ms complejas en las que Matlab escale mal.

CAPTULO 2. MATLAB
son equivalentes. Estas son las dos caractersticas ms importantes del lenguaje.

33

Las matrices se estiran y encogen sin ninguna limitacin ni en el tamao ni en las dimensiones. Si intentamos llenar el dcimo elemento de un vector

inexistente con un 1.

>> foo(10)=1
el programa lo va a hacer sin ningn problema

foo = 0 0 0

0 0

y si ahora le pido

>> foo(11,4)=2
obtengo

foo = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 2

0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0

1 0 0 0 0 0 0 0 0 0 0

Vemos que el comportamiento es un poco extrao. Si nosotros utilizamos nicamente un ndice obtenemos un vector la, mientras que en una matriz la notacin es la usual, el primer elemento es el nmero de la y el segundo el nmero de columna. Esto nos obligar a trasponer vectores ms de una vez, sobretodo para resolver sistemas lineales de ecuaciones . Esta caracterstica facilita la tarea de escribir los algoritmos por primera vez pero tiene grandes peligros inconvenientes.

8 e

Importante:

Cualquier nmero es en realidad una matriz sin fronteras jas.

Las matrices se ordenan en Matlab del mismo modo que en la realidad, por las y columnas. La notacin para diferenciar si una serie de nmeros se encuentran en la misma la o en la misma columna es el siguiente: el espacio y la coma (,) separan elementos de una misma la el retorno de carro y el punto y coma (;) separan elementos de una misma columna Por ejemplo, si queremos escribir el vector la

e = (1 2 3)

lo haremos con:

>> e=[1,2,3] e = 1 2 3 >> e=[1 2 3] e = 1 2 3


En cambio, para escribir el mismo vector pero en forma de columna:

7 En

Octave existe la variable

prefer_column_vectors.

Activando esta variable con

prefer_column_vectors=1

el vector por defecto

ser columna en vez de la emulando el comportamiento de Fortran. Sirva esto para mostrar que Octave es totalmente congurable.

8 El principal peligro de la asignacin dinmica de memoria es que nosotros no sabemos cundo usamos demasiada. Es muy importante

en cdigos no usar ms memoria en ningn momento que la RAM disponible, porque en el caso que 'pisemos' fuera de la RAM, el proceso empezar a escribir sobre el disco duro y el rendimiento puede bajar hasta en dos rdenes de magnitud. El problema es que en ste caso lo hacemos sin querer y adems el programa no nos avisa. Es bueno entonces tener algn monitor del sistema que nos diga cunta memoria estamos usando en tiempo de ejecucin y si estamos pisando fuera, es decir, escribimos en el espacio 'swap'.

Introduccin informal a Matlab y Octave

34

2.5. ARGUMENTOS

>> f=[1;2;3] f = 1 2 3 >> f=[1 > 2 > 3] f = 1 2 3


Esta es exactamente la misma notacin que se sigue para introducir una matriz entera. Lo intentamos con:

1 4 7

2 5 8

3 6 9

>> m=[1,2,3;4,5,6;7,8,9] m = 1 2 3 4 5 6 7 8 9
Aunque cualquier combinacin de las anteriores sera perfectamente vlida, por ejemplo:

>> m=[1 2 3 > 4 5 6 > 7 8 9] m = 1 2 3 4 5 6 7 8 9


La llamada simple a un elemento cualquiera de una matriz se hace indicando su la y su columna por ese orden. En el caso de la matriz

m:

>> m(2,1) ans = 4


Aprenderemos a crear matrices de ms dimensiones en la seccin 3.2.1.

2.5.1.1. Tipos de argumentos matriciales


Cuando se habla del tipo de un argumento no estamos hablando slo de si es una matriz, una cadena de caracteres, un nmero complejo. El concepto en el mbito del clculo numrico va mucho ms all. Se llama tipo a la representacin que tiene un argumento en la memoria del ordenador. Cuando almacenamos un nmero podemos hacerlo en varias representaciones; coma otante de simple precisin, entero de 32 bits... Antes hemos hablado de la conguracin por defecto de Matlab que almacena todos los elementos de una matriz como reales de doble precisin (64 bits o 8 bytes). Todo lo dicho anteriormente para la representacin interna de nmeros es vlida slo por defecto. En ningn momento armamos que el nico tipo de escalar posible es el real de doble precisin. Podemos denir explcitamente nmeros ,es decir, matrices; con tipos distintos al real de doble precisin (DOUBLE). Los tipos soportados por matlab son los mismos que C excepto por el tipo long double (real de 128 bits). Esta representacin tiene una limitacin evidente; como la formulacin de los argumentos en Matlab es matricial slo podremos tener matrices de un nico tipo. No podremos construir matrices con elementos enteros y elementos reales a la vez. Esta es una limitacin comn a todos los lenguajes de programacin y viene dado por la manera en la que cualquier programa reserva (alocatea) memoria. Por ejemplo, si deseamos operar con matrices de nmeros enteros de 8 bits utilizaremos la funcin

int8

del modo siguiente:

>> x=int8([1,2;109237401823056187365,83.0938]) x = 1 2 127 83

CAPTULO 2. MATLAB

35

Llama la atencin el hecho de que el nmero 109237401823056187365 se ha convertido en el 127. Esto es debido a que el mayor entero de 8 bits que podemos almacenar es precisamente 127. Si necesitamos una aritmtica de mayor precisin entera siempre podemos hacer lo siguiente:

x=int64([1,2;109237401823056187365,83.0938]) x = 1 2 9223372036854775807 83
Ni siquiera el mayor entero disponible es capaz de almacenar el nmero anterior. Podemos tener la necesidad de manipular la cantidad de memoria dedicada a cada elemento de una matriz por dos motivos 1. Estamos deniendo matrices de gran tamao y tenemos la necesidad de reducir la precisin de los argumentos reales; ya sea por la necesidad de reservar memoria o por requerimientos de velocidad de clculo 2. Necesitamos operar con tipos de enteros, ya sean con signo o sin signo para realizar con ellos operaciones lgicas por bits o utilizar lgica entera. En Octave slo es posible lo segundo porque el tipo de real es siempre el de doble precisin. Hablaremos un poco ms de los tipos de argumentos escalares en la seccin dedicada a rutinas de creacin de matrices.

2.5.2. Secuencias
Son parecidas a los vectores pero no lo son. Aparecen por todos los elementos del lenguaje, en las submatrices, en los contadores en el funcionamiento interno de muchas funciones... Siempre que necesitemos contar algo aparecern las secuencias porque cuente del

es el mtodo propio Matlab para contar. Si queremos una lista de nmeros que nos

al

10

hacerlo es tan fcil como:

>> secuencia=1:10 secuencia = 1 2 3 4 5


sucesivos:

9 10
1
en

Si queremos manipular el contador para que no sea de

podemos introducir el salto entre dos nmeros

>> secuencia=1:2:10 secuencia = 1 3 5 7 9

2.5.2.1. Por qu las secuencias no son vectores?


Hay una diferencia esencial entre las sentencias y los vectores. La diferencia es que una sentencia no se almacena en memoria. Es un concepto un poco complejo y requiere entender el funcionamiento interno de Matlab pero intentaremos explicarlo de un modo sencillo. Si denimos un vector ste se almacena en memoria; tenemos un argumento que contiene todos los elementos y se pueden llamar del modo usual. En cambio una secuencia es como una funcin que cuenta elementos. Si la llamamos por primera vez (siempre de forma implcita) nos da el primer elemento; si la llamamos por segunda vez nos devuelve el segundo, y as sucesivamente. Todo esto se hace de modo interno y es un proceso muy rpido, por eso se usan muy a menudo.

2.5.2.2. Contadores no enteros.


Las secuencias soportan intervalos distintos a los nmeros enteros. Podemos introducir la secuencia:

>> 0:0.5:4 ans = Columns 1 through 8: 0.00000 0.50000 1.00000 Column 9: 4.00000

1.50000 2.00000

2.50000 3.00000

3.50000

Si el intervalo que introducimos no ajusta exactamente al lmite superior parar de contar sin pasarse.

Introduccin informal a Matlab y Octave

36

2.5. ARGUMENTOS

>> 0:0.52:4 ans = 0.00000 0.52000

1.04000

1.56000 2.08000

2.60000 3.12000

3.64000

Evidentemente este tipo particular de contadores no son adecuados para contar ndices porque genera nmeros no enteros. Su utilidad se encuentra en la discretizacin de intervalos necesaria, por ejemplo, en los ejes de coordenadas.

2.5.3. Submatrices
Para asignar partes de matrices a variables o operar dentro de una matriz con una parte de la misma es necesario asignarles una secuencia de ndices. Se puede decir que la submatriz se genera contando los ndices de la primera Para entender mejor cmo funciona este tipo de asignaciones mejor hacerlo mediante ejemplos. Iniciaremos una sesin en Matlab creando una matriz de nmeros aleatorios:

>> foo=rand(5,5) foo = 0.808048 0.804808 0.114965 0.524531 0.476355 0.544236 0.736103 0.231876 0.807002 0.244172

0.871166 0.210789 0.254009 0.115706 0.507355

0.606412 0.163542 0.818164 0.336303 0.814160 bar

0.867716 0.639094 0.091934 0.478042 0.792253

Ahora crearemos una submatriz llamada tercera a la quinta.

que contendr las las de la segunda a la quinta y columnas de la

>> bar=foo(2:5,3:5) bar = 0.210789 0.163542 0.254009 0.818164 0.115706 0.336303 0.507355 0.814160

0.639094 0.091934 0.478042 0.792253 qwe foo

Pero las secuencias tienen la capacidad de contar de modos distintos, en el caso siguiente contaremos las las de 2 en 2 como muestra el siguiente ejemplo. En l crearemos una submatriz que sean, de la matriz las las de la primera a la quinta de 2 en 2 (la primera, la tercera y la quinta) y las columnas de la primera a la tercera.

>> qwe=foo(1:2:5,1:3) qwe = 0.80805 0.80481 0.87117 0.47635 0.54424 0.25401 0.80700 0.24417 0.50735
Si omitimos los elementos de la secuencia y dejamos slo el smbolo elementos de la la o de la columna.

:,

el resultado ser que tomaremos todos los

2.5.4. Nmeros Complejos


En realidad deberan llamarse matrices cuyos elementos son nmeros complejos, pero se ha abreviado. Las reglas matriciales son exactamente las mismas, lo nico que cambia es el carcter individual de cada elemento. La manera de introducir un nmero complejo como argumento en una variable es el uso del nmero imaginaria.

i que multiplica a la parte

>> numcom=2+3i
Tambin podemos usar otros signos para expresar completo. Adems del nmero nales

como

j, I

J.

Evidentemente tambin podemos crear

vectores, matrices y tensores de nmeros complejos, y al buscar un ndice en ellos tendremos el nmero complejo

como

pi

e.

tenemos otros nmeros relevantes embebidos dentro de Matlab, como los nmeros racio-

CAPTULO 2. MATLAB

37

2.5.5. Cadenas de texto


Podemos asignar a una variable una cadena de texto introducindola entre comillas simples o dobles:

>> saludo='hola que tal';


y si pedimos qu hay en la variable:

>> saludo saludo = hola que tal


En Octave tambin son vlidas las comillas dobles:

>> saludo=''hola que tal'' saludo = hola que tal


Matlab almacena las cadenas de texto como un vector de caracteres. Esto signica que acepta todas las posibilidades de composicin de vectores, la diferencia es que operaremos con caracteres ASCII en vez de con nmeros reales. Para demostrarlo nada mejor que intentar encadenar palabras en la

>> ['me','gusta','el','furbo'] ans = megustaelfurbo


o en columna

>> ['me';'gusta';'el';'furbo'] ans = me gusta el furbo

2.5.6. Argumentos lgicos


Slo tenemos dos variables lgicas que son toma

true y false. Estos nombres son slo interfaces, en realidad Matlab

como falso y cualquier nmero distinto de cero como verdadero.

2.6. Operadores
Cuando operamos elementos en Matlab, como cuando lo hacemos en cualquier lenguaje de programacin, debemos tener en cuenta la dicotoma entre variable y argumento. Es tan importante porque debemos comprender perfectamente la sutileza de que los operadores no operan variables sino argumentos, en el caso de Matlab, matrices. La consecuencia directa es que todos los operadores de Matlab son matriciales. En algunos casos, como la suma o la resta, los operadores matriciales son equivalentes a lo escalares (elementwise cambio la multiplicacin y la potencia generan resultados completamente distintos. Por ejemplo, si tomamos dos matrices cualquiera:

9 o elemento a elemento); en

>> A=[1 2 3;4 5 6;7 8 9]; >> B=[9 8 7;6 5 4;3 2 1];
Su multiplicacin directa va a dar como resultado precisamente la multiplicacin matricial:

>> A*B ans = 30 24 84 69 138 114

18 54 90

Y si queremos una operacin escalar? Todos los operadores de Matlab pasan de matriciales a escalares aadiendo un punto justo antes del smbolo del operador. En el caso de las matrices anteriores:

9 Elementwise

signica literalmente en ingls elemento a elemento.

Introduccin informal a Matlab y Octave

38

2.6. OPERADORES

>> A.*B ans = 9 16 21 24 25 24 21 16 9

La potencia es la operacin que ms errores provoca cuando se es principiante con el Matlab. Cuando
uno piensa en la operacin de la potencia nunca piensa en ella como una operacin matricial; es muy poco intuitivo. No pensamos que la operacin:

>> A^2
Sea equivalente a:

>> A*A;
Operacin que es matricialmente del todo lgica. Este comportamiento provoca dos errores tpicos. 1. El operador se negar a elevar a un exponente matrices que no sean cuadradas. 2. Cuando el exponente es fraccionario da resultados que aparentemente no tienen ninguna lgica Un ejemplo claro es lo que nos encontramos cuando elevamos la anterior matriz a una burda aproximacin del nmero

>> A^3.14 ans = 691.22 1567.33 2443.44 +

0.43i 0.05i 0.34i

850.20 1925.90 3001.60 +

0.12i 0.01i 0.09i

1009.17 + 2284.47 + 3559.76 -

0.20i 0.02i 0.15i

Nmeros complejos? El problema es que en Matlab cualquier argumento puede ser una matriz; olvidarnos el punto antes de utilizar la potencia...

>> A.^3.14 ans = 1.0000 77.7085 450.4098

8.8152 156.5906 685.0189

31.4891 277.5843 991.5657

es uno de los errores ms comunes. Por suerte los errores suelen ser tan evidentes que la sangre raramente llega al ro. El problema llega cuando elevamos al cuadrado matrices cuadradas. Los resultados obtenidos con el operador matricial y escalar son parecidos y del mismo orden de magnitud con lo que pueden ser un gran escollo en el proceso de depuracin.

2.6.1. Operadores aritmticos


x+y x-y x*y
Suma. Si ambos operandos son matrices el nmero de las y columnas debe ser el mismo. Si uno de los dos operandos es un escalar su valor es sumado a todos los elementos del otro Resta. Las consideraciones sobre matrices son las mismas que con el operador suma. Multiplicacin matricial. Si ambos elementos son matrices el nmero de las y de columnas debe ser el mismo. Si uno de los dos operandos es un escalar su valor es multiplicado a todos los elementos del otro.

x.*y x/y

Multiplicacin elemento a elemento. Si ambos operandos son matrices el nmero de las y de columnas debe coincidir.

Divisin de izquierda a derecha. Esta operacin es equivalente a:

(y )1 x
con la diferencia que en este caso no se calcula la inversa. En el caso que la matriz una solucin con la condicin de mnimo error

10 .

no sea cuadrada se da

10 Esto

se hace calculando la pseudo inversa

CAPTULO 2. MATLAB

39

x./y x\y

Divisin de izquierda a derecha elementwise. Se divide cada elemento de la matriz matriz

por cada elemento de la

y.

Divisin de derecha a izquierda. Esta operacin es equivalente a:

x1 y
y sirve para resolver sistemas de ecuaciones lineales. Como en la divisin anterior no se calcula efectivamente la inversa de la matriz, de modo que en el caso que no sea cuadrada seguir dando un resultado. Analizaremos este operador con mucha ms profundidad en el apartado dedicado a lgebra lineal.

x.\y x^y x**y

Divisin de derecha a izquierda elementwise.

Potencia. Si ambos operadores son escalares el resultado es

elevado a la potencia de

y.

Si

es una matriz cuadrada el resultado se calcula a partir de un desarrollo de autovalores. Si

cuadrada e

es un entero el resultado es la multiplicacin de

por ella misma

veces y

x es un escalar y x es una matriz si y es un real se

calcula el resultado por un desarrollo de autovalores. Cuando tanto error. La notacin

**

como

son matrices el resultado es

slo se puede usar en Octave.

x.^y x.**y -x x'


Potencia elementwise. Si los dos operandos son matrices deben ser del mismo tamao. La notacin

.** slo

se puede usar en Octave Negacin Traspuesta compleja conjugada. Si la matriz

mismo que para la traspuesta. Si hay algn argumento complejo el operador es equivalente a hacer

x est compuesta por nmeros reales el resultado es exactamente el conj(x.').

x.'

Traspuesta

11 . Ntese que el uso de la notacin usual elementwise no tiene el mismo sentido.

2.6.2. Operadores de comparacin


x<y
Verdadero si

es menor que

y. y.

x<=y x==y x>=y x>y

Verdadero si Verdadero si Verdadero si

x x x

es menor o igual que es igual que

y. y.

es mayor o igual que

Verdadero si

es mayor que

y.

x!=y x~=y
Verdadero si segundo.

es distinto que

y.

En Octave son vlidos ambos signos mientras que Matlab slo soporta el

11 Esta es una buena manera de perder un da de trabajo tontamente. Es de estos errores que hacen que te rompas la cabeza intentando
entender qu es lo que funciona mal. Cuando se trabaja en el espacio de Fourier es muy normal que todos los coecientes sean complejos. Adems, si los datos que originan los coecientes son reales la matriz que forman es hermitiana que es como la extensin de la matriz simtrica para nmeros complejos. Probando un algoritmo de de resolucin de la ecuacin de Poisson en el plano espectral me puse a probar qu era lo que calculaba la transformada rpida de Fourier (se ver en los temas posteriores) bidimensional y si era equivalente con una combinacin de transformadas unidimensionales. En teora el algoritmo de transformada rpida de Fourier en un plano es transformar por columnas y luego hacerlo por las. Como la funcin transformada rpida de Fourier en Matlab es

fft(fft(a)')' fft2(a)

fft

la operacin sera

Con esto se hace la operacin por columnas, se traspone, se hace la operacin por las y se vuelve a trasponer para

devolver la matriz a su estado inicial. Esta operacin debera ser equivalente a: Cual fue mi sorpresa cuando descubr que los coecientes que daba como resultado eran distintos. No es que el resultado tenga que ser equivalente, es que tiene que ser exactamente el mismo. Despus de me d cuenta que el operador

' no

ocho

horas de revisar una y otra vez los resultados

es la traspuesta sino la traspuesta compleja conjugada y que en este caso no son equivalentes porque

el resultado no es una matriz hermitiana hasta que se ha terminado la transformada. Entonces la operacin sera:

fft(fft(a).').'

Esta tontera bien puede haceros perder un da, como a mi, o un par de ellos por culpa de resultados que parecen vlidos. Mucho cuidado. corregirse como en otros lenguajes donde los operadores tienen su forma abreviada (*) y una forma equivalente como funcin A ttulo de opinin personal creo que este es un gran fallo en la sintaxis general de matlab. Hay ms, incluso peores. Esto debera

Introduccin informal a Matlab y Octave

40

2.7. VARIABLES

2.6.3. Operadores lgicos


Hay dos tipos de operaciones lgicos, los que interactan con matrices y los que lo hacen con expresiones lgicas como las que nos encontramos en las estructuras matriz del mismo tamao, por ejemplo:

if

while.

Los del primer tipo son

&

para y,

para o y

para no. Si decimos que operan con matrices es porque aplicados a matrices de condiciones lgicas devuelven una

>> [1,2;0,1]&[0,1;0,1] ans = 0 1 0 1 >> ![0,1;2,0] ans = 1 0 0 1


La expresin entera para condiciones lgicas es binaria usual. Para componer expresiones lgicas se usan los smbolos funcin

para falso y distinto de

para verdadero, es decir, lgica

&&

para y y

||

para o. La diferencia entre estos y

los anteriores es que el resultado siempre ser booleano. Si se aplica a una matriz colapsar sus elementos con la

all

para llegar a una expresin nica. Como ya hemos dicho antes su aplicacin principal se encuentra en

las estructuras de control de ejecucin como

if

while.

En los captulos posteriores veremos varias aplicaciones de estos operadores.

2.6.4. Operadores de comparacin por bits en enteros


Matlab es tambin capaz de comparar y manipular los bits en enteros. Para eso dispone de las funciones siguientes:

>> bit<TAB> bitand bitmax bitset bitxor bitcmp bitget bitor bitshift >> a=5; %Un numero entero >> dec2bin(a) %Que tiene esta representacion decimal ans = 101 >> a=bitset(a,1,0) %Reset del primer bit a = 4 >> a=bitset(a,6,1) %Set del sexto bit a = 36 >> dec2bin(a) ans = 100100 >> b=bitset(1,6) % Una forma alternativa de set b = 33 >> dec2bin(b) ans = 100001 >> bitand(a,b) % y logico ans = 32 >> dec2bin(bitand(a,b)) % En bits... ans = 100000 >> bitor(a,b) % o logico ans = 37 >> dec2bin(bitor(a,b)) % En bits... ans = 100101 >> bitxor(a,b) % o exclusivo logico ans = 5 >> dec2bin(bitxor(a,b)) % En bits... ans = 101

2.7. Variables
Debemos pensar en ellas como cajas que ocupan memoria, independientemente de lo que lleven dentro. Debe abstraerse la variable del argumento que contenga, en el fondo no es ms que un nombre.

CAPTULO 2. MATLAB

41

Por el hecho de ser un lenguaje de scripting las variables no deben declararse. Esto hace que programar sea mucho ms sencillo, se haga con menos errores y en menos tiempo a costa de un mayor tiempo de ejecucin. Esto tambin signica que la cantidad de memoria asignada a una variable es dinmica, podemos ampliar una matriz

12 sin ningn problema con el simple hecho de llenar un elemento que no exista. 13 Aquello que nosotros asignamos a una variable se llamar argumento . A cada variable le asignaremos uno o
varios argumentos, de modo que la variable no es ms que un nombre por el que llamamos su contenido. Las variables pueden ser cualquier secuencia de letras, no hay limitacin en su nmero, slo que deben empezar con un carcter tipo letra o con _ . Se distingue entre maysculas y minsculas. Los nombres siguientes seran vlidos:

x x15 __hola_que_tal__ fjalsbdgaoqiwbodj


El nombre de una variable es una funcin en s misma, llamada sin argumentos sacar por pantalla el valor de la variable. Algunas variables tienen un valor por defecto como

pi

ans.

Algunas de estas variables son parte de la

conguracin interna del programa as que es importante conocerlas para no tener sorpresas desagradables.

2.7.1. Acceso a las variables:


Si nos dicen que una variable es local por defecto probablemente no entendamos nada. Saber si una variable es accesible o no por una funcin no es una tarea sencilla y depende de cmo se hayan declarado las variables. El esquema normal es el de la gura 2.3. Supongamos que somos una variable en el programa principal y en un instante de la ejecucin somos el argumento de una funcin. No nos sucede absolutamente nada. Otra variable va a tomar nuestro valor en la cabecera de la funcin y su resultado se va a volcar en el programa principal. A no ser que el resultado se nos asigne, cambiando nuestro valor, seguir sin sucedernos nada. En cambio las variables locales para la funcin son eliminadas de la memoria cuando termina su ejecucin.

Figura 2.3: Comportamiento normal de una variable llamada por una funcin Si le damos a una variable el atributo de global con la palabra clave

global

entonces esta variable podr ser

vista por cualquier unidad de cdigo sin necesidad de llamarla en su cabecera. A estas variables no les importa si estn en el programa principal o en una funcin, su contexto es toda la ejecucin; pueden saltar a cualquier hilo como en el esquema de la gura 2.4: Al estar denida como una variable global no slo puede ser vista por la funcin; si adems la funcin cambia su valor tambin cambiar en el programa principal. Un ejemplo de ello es el cdigo siguiente:

>> global x=2 >> x x = 2 >> function f() global x


12 Ampliar 13 El
una matriz es exactamente equivalente que asignar ms memoria a una variable. En Fortran sera dealocatear una variable, ampliarla y alocatearla otra vez. concepto de argumento en programacin es mucho ms extenso, pero creo que es conveniente usarlo de este modo.

Introduccin informal a Matlab y Octave

42

2.7. VARIABLES

Figura 2.4: Comportamiento de una variable global denida en el programa principal

x=3 end >> f() x = 3


Como se ve debemos tener cuidado con los nombres de las variables globales, no es difcil estropear el cdigo llamando una variable global en una funcin sin querer Un tercer atributo es el de

14 .

persistent. Cuando dentro de una funcin indicamos que una variable es persistent

estamos imponiendo que esta variable se guarde en memoria para la siguiente vez que se llame la funcin en vez de hacerla desaparecer, como es normal. El diagrama conceptual es el de la gura 2.5.

Figura 2.5: Propiedades de una variable persistente. No tiene ningn sentido denir una variable como

persistent

en el programa principal porque las variables

locales para el hilo principal no se destruyen hasta que termina la ejecucin.

2.7.2. Funciones dedicadas a variables


Tenemos varias funciones ntimamente relacionadas con el concepto de variable, algunas de ellas son:

is_global clear
14 El

que devuelve un

en el caso que la variable efectivamente lo sea

que borra el contenido de una o varias variables, funciones o variables globales dependiendo del par-

metro que le pasemos


uso de las variables globales es una de las pocas discusiones de estilo abiertas. En otros lenguajes de programacin, sobre todo

los que permiten la programacin orientada a objetos, no es necesario utilizar este tipo de variables. Es una discusin entre dos escuelas. Los que estamos ms acostumbrados a una programacin modular (Fortran) nos sentimos ms cmodos controlando el hilo de ejecucin con variables globales. En cambio, la escuela procedente de C++ y de Java preeren crear mtodos mucho ms ricos en los que las funciones son en realidad mtodos de un objeto que puede haber sido inicializado previamente. Creo que para un principiante el uso de variables globales es un buen ejercicio mental para aprender que hay distintos niveles de ejecucin en la programacin modular sin entrar en conceptos que muchos usan pero slo unos pocos entienden.

CAPTULO 2. MATLAB

43

who

que da una lista de las variables que en aqul mismo momento estn ocupadas por algn argumento.

Tambin acepta parmetros para variar su comportamiento.

whos

, lo mismo que

who

pero nos da ms informacin.

Importante:

Es necesario entender el concepto de variable local y global para comunicar funciones y scripts de

una manera eciente

2.7.3. Contenedores
La limitacin las matrices es que slo pueden contener elementos de un mismo tipo. Una matriz no puede contener una cadena de caracteres y un nmero a la vez. Si sumamos mentalmente dos matrices entenderemos facilmente por qu. Necesitemos entonces denir un tipo ms complejo que un caracter o un escalar. Un tipo derivado es una extensin del concepto de argumento en el que se permite que una variable contenga un argumento mltiple con elementos de distinta naturaleza. Un tipo derivado es lo que permite asignar a una variable un nmero y una cadena de caracteres a la vez. La estructura tpica de los tipos derivados es la que tiene forma de rbol. Son llamadas estructuras de datos. En ellas, una variable primitiva contiene ms variables adicionales que a su vez pueden contener ms ramicaciones. Otro tipo es emular el comportamiento de una matriz o un vector y permitir que sus elementos sean de tipos distintos. Obviamente esta ganancia de potencia se pierde en los operadores. Una matriz puede ser sumada a otra matriz, en cambio un tipo derivado no puede ser sumado a otro tipo derivado ya que Matlab no tiene ninguna informacin de qu contiene cada uno. Esto hace que la lnea divisoria entre el concepto de variable y el de argumento se difumine. Podemos pensar en una matriz como un nico argumento donde todos los elementos son del mismo tipo y los tipos derivados como estructuras de variables. Entrar en sutilezas tericas no es muy conveniente, simplemente debemos centrarnos en la gran utilidad de las estructuras de datos o las celdas de variables ya que permiten agrupar en forma de nica variable estructuras ms complejas de lo habitual.

2.7.3.1. Estructuras de datos


Octave, al igual que la mayora de los lenguajes de programacin modernos, nos permite agrupar variables en estructuras tipo rbol. Podemos entonces agrupar distintos tipos de argumentos dentro de una variable. Para probar esta posibilidad vamos a escribir un script de prueba que se va a llamar

estructura.m.

% estructura.m % ste es el script de prueba para las variables de tipo estructura foo.num=1.234; foo.string='hola mundo'; foo.options.option1=true; foo.options.option2=false;
Lo guardamos en el directorio correspondiente y si nos vamos a la consola y tecleamos pantalla. Si queremos que nos diga qu hay dentro de la variable aparecer lo siguiente:

estructura qu obtenemos? foo


en la consola y nos

Pues nada en absoluto porque le hemos pedido con los puntos y coma que no nos sacara ninguna informacin por

foo

debemos teclear

>> estructura >> foo foo = { num = 1.2340 options = { option1 = 1 option2 = 0 } string = hola mundo }
Introduccin informal a Matlab y Octave

44
que es exactamente la estructura de argumentos que hemos introducido intrprete.

2.7. VARIABLES

tarios en un script de Matlab, con el signo %. Todo lo que escribamos a partir de ste smbolo ser ignorado por el Adems de muchas otras, la mayor utilidad de las variables de tipo estructura es que nos permiten acortar las cabeceras de las funciones. Pongamos como ejemplo un programa que se congura con unos veinte parmetros. Si una funcin necesita quince de ellos signica que cada vez que llamemos a la funcin en nuestro cdigo aparecer una cabecera con quince variables. Esto hara el cdigo ms pesado de escribir y mucho ms difcil de leer y mantener. Podemos poner todos nuestros parmetros dentro de una variable que se llame que siempre que necesitemos un parmetro, por ejemplo dentro del programa nos referimos a

15 . Vemos la manera de introducir comen-

parms.Longitud.

Longitud,

parms,

de tal manera

en cabecera simplemente llamamos a

parms

2.7.3.2.

Cell Arrays

Las celdas son matrices o hiper-matrices de variables. No debemos confundirlas con las matrices usuales que son estructuras de argumentos del mismo tipo. Una celda puede contener matrices, cadenas de texto y argumentos lgicos a la vez siempre que estn en celdas separadas. A diferencia de las estructuras de datos no tendremos que asignar un nombre a cada una de las celdas porque ya se les asignar un grupo de ndices. Podemos construir celdas de dos modos, el primero es declarar una variable como datos

cell y darle una dimensiones.

Por ejemplo construiremos una celda de 2 por 2 cuyos elementos parecidos a los contenidos en la estructura de

foo:

>> foo = cell(2,2) foo = { [1,1] = [] [2,1] = [] [1,2] = [] [2,2] = [] } >> foo{1,1}=1.2340; >> foo{1,2}=[1,2;3,4]; >> foo{2,1}='hola mundo'; >> foo{2,2}=true; >> foo foo = { [1,1] = 1.2340 [2,1] = hola mundo [1,2] = 1 2 3 4 [2,2] = 1 }
Como en el caso de las matrices convencionales podremos ampliar las celdas con slo llenar una que no tenga ningn argumento asignado; las celdas sobrantes quedan vacas:

>> foo{3,1}=false foo = { [1,1] = 1.2340 [2,1] = hola mundo [3,1] = 0 [1,2] = 1 2 3 4 [2,2] = 1 [3,2] = [] }
15 Si
queremos que Octave nos saque cualquier argumento por pantalla podemos usar la funcin

disp().

En este caso al nal de

nuestro script podramos aadir:

disp('nuestra estructura es') disp(foo)

CAPTULO 2. MATLAB

45

El otro modo de iniciar una estructura de celdas es hacer lo mismo que con una matriz pero usando llaves en vez de corchetes. Para iniciar las celdas

foo

pero de modo abreviado:

>> foo={1.2340,[1,2;3,4];'hola mundo',true} foo = { [1,1] = 1.2340 [2,1] = hola mundo [1,2] = 1 2 3 4 [2,2] = 1 }

Importante:

Las celdas pueden almacenar cualquier tipo de argumento, incluso funciones. Es ms fcil y rpido

escribirlos utilizando llaves.

2.7.3.3. La necesidad de los cell arrays y los tipos derivados


No todo en un lenguaje de programacin son aplicaciones sencillas donde escalares, vectores y matrices bastan. Tampoco es cierto que el dato ms complejo suelen ser los argumentos que pasamos a las funciones. Un programa puede requerir variables que contengan tipos de gran complejidad, normalmente obligados por el propio algoritmo. Supongamos que intentamos una poblacin de datos especialmente compleja, algo usual en una base de datos. Pongamos como ejemplo una descripcin de todos los trabajadores de una empresa. Esto es un ejemplo, seguramente no utilizaremos un lenguaje de programacin orientado a clculo numrico para resolver un problema como este pero otras aplicaciones como los algoritmos genticos pueden requerir tipos derivados especialemnte complejos. Sigamos con el ejemplo deniendo nuestro tipo Empleado. Cada empleado de la empresa proporciona los siguientes datos: Nombre completo Nacionalidad Documento de identidad

Tipo Nmero Fecha de expedicin Fecha de caducidad

Direccin de contacto Nmeros de telfono

Nmero de la direccin de contacto Telfono movil de empresa Telfono movil personal

Cuando nuestros datos son muy complejos solemos pensar durante largo tiempo el mtodo ms adecuado de almacenar todos los datos. Crear una variable para cada trabajador no es muy recomendable porque es probable que tengamos que iterar sobre el total de ellos. Tampoco parece muy inteligente partir todos los datos en varias matrices y relacionarlas segn los ndices. La abstraccin llevada a los lenguajes de programacin modernos tiene una consecuencia muy importante:

debemos ser capaces de seguir uilizando las mismas herramientas de programacin sea cual sea el dato con el que estemos trabajando. Si un lenguaje se ha diseado con el paradigma de la abstraccin como prioridad podremos
seguir escalando la complejidad de las estructuras de datos tanto como queramos sin perder las herramientas de clculo. Matlab no es un prodigio en este sentido pero se deende bien. El elemento que mantiene la escalabilidad en las estructuras complejas de datos son los cell arrays. Al seguir una estructura matricial pueden encapsularse tantos cell arrays como queramos. Pueden contener tanto los tipos bsicos (nmeros y cadenas de texto) como estructuras de datos o otras celdas. De este modo podemos denir la estructura empleado del siguiente modo:

Introduccin informal a Matlab y Octave

46

2.8. SENTENCIAS

>> Empleado1={'Paquito Palotes Parrondo';'Deaqui'; ... {'DNI',646843216,12122000,12122000}; ... 'C Buenaesperanza 12 1,2'; ... [666251487,555698541]} Empleado1 = { [1,1] = Paquito Palotes Parrondo [2,1] = Deaqui [3,1] = { [1,1] [1,2] [1,3] [1,4] = = = = DNI 646843216 12122000 12122000

[4,1] = C Buenaesperanza 12 1,2 [5,1] = 666251487 }


Lo novedoso es que mantenemos la escalabilidad de la estructura indenidamente. Podemos sin ninguna restriccin encapsular todos los empleados en la variable Empresa como si fueran elementos de una la en una celda:

555698541

>> Empresa={Empleado1,Empleado2,Empleado3}

2.8. Sentencias
Como se ha dicho antes, las estructuras esenciales del lenguaje son los contadores y los condicionales. Ms comnmente conocidas como las sentencias

do

y las sentencias

if.

Estas estructuras son comunes con el resto de

lenguajes de programacin y de scripting existentes. La primera es un bucle contador que permite ejecutar varias tareas idnticas secuencialmente con la variacin de diversos ndices; se pueden encapsular con otros contadores y con otras sentencias. La segunda permite incluir variaciones en la ejecucin del cdigo segn el cumplimiento de ciertas condiciones lgicas. Estos no son las nicas estructuras de programacin, son las ms bsicas. A partir de ellas se derivan sentencias ms tiles y ms especcas como veremos a continuacin. Al igual que las funciones, las sentencias tienen un principio y un nal denido iniciado por una palabra clave. Matlab utiliza la notacin clave-cuerpo-end al igual que Fortran; C, por ejemplo delimita estas estructuras mediante llaves y Python utiliza el sangrado. En este caso Matlab y Fortran presentan una diferencia esencial. Mientras Fortran tiene un cierre para cada una las estructuras;

end

do

debe cerrarse con un

end do,

Matlab cierra todas ellas con un

puede llevar a confusiones nefastas, es por ello que Octave tambin soporta el uso de

end. El uso sistemtico endfor, endif...

de

2.8.1. La sentencia if
Tenemos tres formas de condicional. La ms simple es:

if (condicin) cuerpo endif


Por ejemplo:

>> esto=1; >> if esto ... disp('es esto'); ... end es esto

CAPTULO 2. MATLAB

47

>> esto=0; >> if esto ... disp('es esto'); ... end


Si queremos que la sentencia no se ignore, y que si la condicin no se cumple impongamos un cuerpo distinto podemos usar la estructura:

if (condicin) cuerpo 1 else cuerpo 2 endif


Ejemplo:

>> esto=1; >> if esto ... disp('es esto'); ... else ... disp('es lo otro'); ... end es esto
En la que se ve perfectamente que si no se cumple la condicin 1 inmediatamente se ejecuta el cuerpo2. Si tenemos ms de una condicin lgica sobre una misma variable podemos usar una condicional mltiple de la siguiente forma:

if (condicin 1) cuerpo 1 elseif (condicin 2) cuerpo 2 ... elseif (condicin n) cuerpo n else cuerpo N endif
16 Debe recalcarse que la condicin debe ser sobre la misma variable para cerrar la lgica del condicional. En el
caso que tengamos condiciones lgicas sobre ms de una variable podemos encapsular los if sin ningn problema:

if (condicin a) if (condicin b) cuerpo a+b else cuerpo a+bN endif else cuerpo aN endif
Es importante que evitemos estructuras lgicas muy complejas, porque son difciles de entender y de depurar; an cuando las ha escrito uno mismo. Se vern ejemplos de estas estructuras en la seccin de ejercicios.

2.8.2. La sentencia switch.


Lo forma general del comando es:

16 Mucho

cuidado los programadores acostumbrados a Fortran, sea cual sea la variante. Si nosotros usamos

else if en vez de elseif,

Matlab va a pensar que tenemos dos sentencias separadas, es decir, primero un else y luego un if dentro del else. Esto signica que tenemos una ejecucin anmala en vez de un error. Es uno de estos casos en los que el programa nos ejecuta, nos da un resultado errneo y nosotros no vemos de ninguna manera el error de programacin

Introduccin informal a Matlab y Octave

48

2.8. SENTENCIAS

switch (variable_switch) case (posible_valor_variable_switch) comandos case (posible_valor_variable_switch) ... otherwise comandos adicionales endswitch
Esta sentencia es la misma que

case

en Fortran y

switch

en C. Un ejemplo de su uso sera:

>> a = 'dos' >> switch (a) case ('uno') disp('has escogido el numero 1') case ('dos') disp('has escogido el numero 2') otherwise disp('no se que numero has escogido') endswitch has escogido el numero 2

2.8.3. La sentencia for


As es como se denomina el contador o sentencia

do

en Matlab. Su estructura es:

for [variable contador]=[secuencia del contador] cuerpo [dependiente o no de la variable contador] endfor
Es decir, para una determinada variable, que avanza de 1 en 1 desde el lmite inferior hasta el lmite superior ejecutamos el cuerpo. El cuerpo puede depender o no de la variable contador, sta puede ser un contador a parte, que simplemente nos imponga que una determinada sentencia se ejecute un nmero jo de veces. La mayora de las veces nuestro cuerpo depender de la variable que usemos como contador, es decir, ser un ndice de nuestro cuerpo. Notemos que lo que utilizamos para contar una secuencia, como en el caso de las submatrices. Lo que har el ndice contador ser tomar sucesivamente todos los valores que tengamos en la secuencia. Por ejemplo, si pedimos que una variable haga un bucle de ese tipo:

for i=1:2:10
dentro del bucle la variable

tomar los valores que salen por pantalla en el caso que llamemos la secuencia:

>> 1:2:10 ans = 1 3


Por ejemplo:

>> for i=5:5:25 ... disp(i),disp('es multiple de 5') ... end 5 es multiple de 5 10 es multiple de 5 15 es multiple de 5 20 es multiple de 5 25 es multiple de 5
Los bucles con contador tambin se pueden encapsular, y ste encapsulado es esencial cuando trabajemos con matrices de rango mayor que 1. Por ejemplo, si queremos asignar una operacin compleja a una matriz de rango 3 debemos encapsular 3 contadores:

CAPTULO 2. MATLAB

49

for i=1:IMAX for j=1:JMAX for k=1:KMAX cuerpo endfor endfor endfor

2.8.4. La sentencia while


En vez de controlar el bucle mediante un contador es muy til controlarlo mediante una condicin lgica. Para eso podemos usar una estructura

while.

while (condicin) cuerpo endwhile


Ejemplo:

>> a=0; >> while a<5 ... disp(a) ... a=a+1; ... end 0 1 2 3 4
Slo debemos tener en cuenta cuando programamos que el uso de un while es mucho ms crtico que el uso de un for. Esto es porque la condicin lgica que controla el bucle debe aplicarse sobre una variable interna en el bucle. Entonces es probable que si programamos mal, la variable que usamos como control nunca llegue a cumplir la condicin que nos para la ejecucin. En Matlab o Octave no suele ser un gran problema, puesto que el sistema puede reaccionar y cortar el proceso de otro modo, pero en otros lenguajes puede tener consecuencias bastante desagradables. Tambin debemos tener en cuenta que los bucles controlados por una condicin lgica no permiten la paralelizacin en el caso que tengamos una versin para varios procesadores de Matlab o Octave.

2.8.5. La sentencia do-until


Esta sentencia es equivalente a

while

con la condicin lgica complementaria.

2.8.6. Las sentencias break y continue


Tanto para el de utilidad. La sentencia

for como para los otros tipos de bucles tenemos variables de control de la ejecucin que pueden ser break dentro de un bucle nos quita el hilo17 del bucle para seguir ejecutando el programa

o un bucle externo. Un ejemplo sera:

num=103; div=2; while (div*div <= num) if (rem (num, div) == 0) break; endif div++; endwhile if (rem (num, div) == 0) printf ('El divisor menor de %d es %d \n', num, div); else printf ('%d es primo \n', num); endif
17 Se
llama hilo precisamente a la lnea de ejecucin. Nos la podemos imaginar como la lnea de cdigo que siguen los procesos. Este concepto va ligado ntimamente a la gestin de procesos y tiende a complicarse en lenguajes como C o Fortran.

Introduccin informal a Matlab y Octave

50
En cambio la sentencia

2.9. FUNCIONES (II)

continue, en vez de sacarnos del bucle, hace que saltemos uno de los pasos del mismo para

ir al siguiente estado del contador.

2.8.7. La sentencia try


Los bloques de estructura

try

son de la forma:

try cuerpo catch alternativa end


Por ejemplo:

>> a=rand(5,5);b=rand(4,4); >> try ... a*b ... catch ... disp('Dimensiones incompatibles') ... end Dimensiones incompatibles
Esta estructura es muy parecida a

if-else

pero con la particularidad que la condicin lgica es si se produce

o no un error. Se usar cuando no sepamos si algo puede ejecutarse bien o no y no queramos que el error afecte al resto de la ejecucin del programa. Primero intentar ejecutar la sentencia que hayamos puesto en devuelve un error ejecutar

alternativa

cuerpo

y si

ignorando el error producido por la primera sentencia.

2.9. Funciones (II)


Tratar la funcin en Matlab slo desde el punto de vista de un archivo auxiliar es un tremendo error. La escritura y manipulacin de funciones es la mayor potencia (probablemente la nica) del lenguaje. Este planteamiento choca con la formulacin bsica de la funcin y se acerca ms a los lenguajes orientados a objetos donde podemos asignar un mtodo a una variable, algo impensable en Fortran. Siendo poco rigurosos podemos decir que si C++ es un lenguaje orientado a objetos Matlab es orientado a funciones.

2.9.1. Funciones matemticas bsicas


Matlab cuenta con una enorme biblioteca de funciones matemticas. Su utilidad depende directamente del conocimiento que tengamos de ellas. Mientras intuitivamente ya hemos usado las funciones trigonomtricas y

cos,

sin

muchas de las presentes en la coleccin ni nos sonarn. Cumple el objetivo principal de ahorrarnos tener

que escribir cualquier funcin mnimamente conocida. El nombre que reciben estas funciones suele ser bastante descriptivo; la funcin

se llamar

Estas funciones no son archivos

gamma y las funciones de Airy se llamarn airy. .m, se escriben en un lenguaje compilado como

C++ o Fortran para que su

velocidad sea mayor. No debemos tener miedo a usarlas tanto como sea posible.

2.9.2. La Ayuda(II)
Ya hemos hablado del comando primera sentencia ejecutable nos ejemplo: de una ayuda parecida de una manera muy fcil. Todas las lneas

help y cmo debe utilizarse. Nosotros tambin podemos dotar nuestras funciones comentadas entre la sentencia function y la saldrn por pantalla si llamamos a la funcin mediante el comando help. Por

function out=derivada_numerica(in) % % funcin derivada_numerica Calcula las diferencias centradas de % primer orden de un vector entrada: in (vector) salida : out (vector) % ... end
Cuando hagamos

help derivada_numerica

obtendremos por pantalla:

CAPTULO 2. MATLAB

51

funcin derivada_numerica Calcula las diferencias centradas de primer orden de un vector entrada: in (vector) salida : out (vector)
Disponemos tambin de dos funciones para manejar los errores de ejecucin,

usage y error. En la seccin 2.9.3

tenemos un ejemplo de cmo se usan. Son de gran utilidad sobre todo cuando hagamos debugging de un programa grande. Si se produce un error en la lectura de los argumentos o en el clculo interno se imprime en pantalla toda la cadena de errores que han provocado el fallo, estos mensajes son a menudo demasiado crpticos. Si intuimos que la ejecucin puede fallar en algn sitio debemos preverlo, es una buena tctica pensar el hilo de ejecucin tanto si funciona correctamente como si no.

18

2.9.3. Argumentos de entrada y salida.


En el apartado anterior dedicado a funciones (2.4.1) hemos sido intencionadamente rigurosos con la sintaxis. Si una funcin retorna slo una variable pueden omitirse los corchetes:

function salida = entrada (arg) salida = ... end


La funcin funcin

nargin retorna el nmero de argumentos entrada que acabamos de denir19 :

de entrada necesarios en una funcin, si lo aplicamos a la

>> nargin('entrada') ans = 1


Mientras que dentro de la funcin es una constante cuyo valor es el nmero de argumentos de entrada:

function retval = avg (v) % retval = avg(v) v :: vector % % Calcula la media de los elementos de un vector retval = 0; if (nargin != 1) usage ('avg (vector)'); endif if (isvector(v)) retval = sum(v) / length(v); else error ('avg: expecting vector argument'); endif end
Este ejemplo adems nos sirve para ver el control de errores de una funcin. Las palabras clave que entendamos ms en profundidad se propone esta sesin de consola:

usage y error son

los mensajes que saldrn por pantalla si se comete un mal uso o existe un error de ejecucin respectivamente. Para

>> help avg avg is the user-defined function from the file /home/guillem/CursoScripting/ejercicios/avg.m retval = avg(v) v :: vector Calcula la media de los elementos de un vector >> v=[1,2,3,4]; >> avg(v) ans = 2.5000 >> u=[4,3,2,1]; >> avg(u,v)
18 En 19 En
Octave tambin podemos escribir la ayuda en formato

texinfo

para incluir caracteres matemticos y fracciones pero es un tema

muy avanzado. breve aprenderemos que la mejor manera de llamar este tipo de funciones es mediante un Function handle

Introduccin informal a Matlab y Octave

52

2.9. FUNCIONES (II)

usage: avg (vector) error: evaluating if command near line 8, column 3 error: called from `avg' in file `/home/guillem/C... >> w=[1,2;3,4]; >> avg(w) error: avg: expecting vector argument error: evaluating if command near line 11, column 3 error: called from `avg' in file `/home/guillem/C... >>
Los corchetes son necesarios slo cuando queramos retornar ms de una variable:

function [salida1,salida2] = entrada (args) salida1 = ... salida2 = ... end


En el caso que dejemos una variable vaca no vamos a obtener un error sino un aviso:

>> function [x,y,z] = f() x=1; y=2; end >> [a,b,c]=f() warning: in f near line 7, column 8: warning: f: some elements in list of return values are undefined a = 1 b = 2 c = [] >>
Si queremos saber cuantas variables de salida tiene una funcin debemos usar muy interesante es la palabra clave inmediatamente retorna la ejecucin a la consola o al programa principal:

nargout. Una variable de control return, Cuando el hilo de ejecucin de una funcin pasa por la palabra return

function out = any_zero(v) % out = any_zero (v) v :: vector % % devuelve un mensaje si algun elemento de v es 0 out = 0; for i = 1:length(v) if (v (i) == 0) out = 1; return endif endfor printf ('No se ha encontrado ningun cero \n') >> u=[1,2,3,0]; >> v=[1,2,3,4]; >> any_zero(u) ans = 1 >> any_zero(v) No se ha encontrado ningun cero ans = 0

2.9.4. inline
Si Matlab no puede denir funciones completas dentro de un script signica que para escribir cualquier expresin matemtica no bsica debemos crear un archivo. Esto no es del todo cierto por la sentencia puntero a una funcin se tratara. Su uso es muy sencillo, pero requiere cierta prctica. Si queremos introducir una funcin escribiremos:

inline.

Lo que hace

es interpretar una cadena de texto en la que escribimos una funcin y la conecta a una variable, como si de un

CAPTULO 2. MATLAB

53

>> foo=inline('sin(x)*cos(x)','x');
En la que obviamente introducimos los elementos como cadenas de texto. Para evaluar la funcin lo haremos del modo usual:

>> c=foo(6)
que nos pondr en la variable

el valor de la funcin en 6, -0.26829.

En el caso que nuestra funcin tenga ms de una variable de entrada podemos explicitarlas como:

>> foo2=inline('sin(x)*cos(y)','x','y');
Entonces los parmetros de entrada para la evaluacin van a ser dos y van a mantener el orden asignado en la sentencia un imperativo para saber cmo se introducen las variables en la evaluacin. Tambin podemos utilizar la sentencia

inline. De hecho, este intrinsic funciona perfectamente con slo la funcin como argumento, pero es casi inline
cuando se nos pida evaluar una funcin. Vimos un ejemplo de

ello en el primer captulo cuando se introdujo el lenguaje:

>> quad(inline('besselj(2.5,x)'),0,4.5) ans = 1.1178


Para integrar necesitamos una funcin de una sola variable de modo que hemos creado una nueva funcin con la sentencia archivo.

inline

para modicar la funcin

besselj.

La nueva funcin (sin nombre) acepta slo un argumento.

Esta prctica es muy frecuente y til, pensemos que por cada vez que utilicemos un

inline

nos ahorramos un

2.9.5. Function handles


Hemos enfatizado en la necesidad de diferenciar los conceptos de variable y de argumento. Ahora introduciremos un concepto an ms complejo, el de la manipulacin de funciones. En Matlab la funcin no es un elemento inerte como en Fortran, se parece bastante ms a las funciones de C. Un ejemplo de esta diferencia es que en C podemos crear matrices cuyos elementos sean funciones gracias al uso de punteros. Fuera de estas consideraciones tericas diremos que Matlab tiene una herramienta para asignar funciones (aunque sera ms correcto llamarlos mtodos) a variables. Esta herramienta se llama Function handle por comparacin con una herramienta real, sera conveniente llamarla asa o mango. Pensemos en un martillo; la herramienta en s es slo la cabeza y lo que nos ayuda a manejarlo es el mango cuya funcin, aunque secundaria, es imprescindible. Lo mismo sucede con las asas de una paellera. Las funciones en un archivo son como paelleras sin asas, cumplen su funcin pero no las podemos manejar. Si utilizamos los Function handles para asignar una funcin a una variable podemos utilizar la funcin sin hacerlo directamente al igual que operamos los argumentos mediante variables. Un Function handle se denota con la letra

@.

Por ejemplo, si queremos asignar a la variable

varsin

la funcin

sin

lo haremos del siguiente modo:

>> varsin = @sin


A partir de ahora la variable sirve de interfaz a la funcin. Da igual que la funcin sea parte de la biblioteca estndar o que la acabemos de escribir nosotros mismos. Por si hay alguna duda de que

varsin

es ahora la funcin seno:

>> varsin(pi/2) ans = 1


Un uso muy interesante de los Function handles es la creacin de estructuras de datos con funciones. Como ejemplo crearemos unas celdas donde los elementos sean las funciones trigonomtricas bsicas:

>> trifun={@sin,@cos,@tan} trifun = { [1,1] = sin [1,2] = cos [1,3] = tan } >> trifun{3}(pi/4) ans = 1.0000
Introduccin informal a Matlab y Octave

54

2.9. FUNCIONES (II)

Esto hace que tengan un papel protagonista en las cabeceras de las funciones. Cuando una funcin necesita a otra como argumento podemos asignarla tambin por nombre o por una sentencia utilizar un Function handle. Por ejemplo, para hacer la siguiente integral mediante la funcin

inline pero lo recomendable es quad:

I=
0

sin(x) dx

>> I=quad('sin',0,pi) I = 2 >> I=quad(inline('sin(x)'),0,pi) I = 2 >> I=quad(@sin,0,pi) # Forma recomendada I = 2


La tercera es equivalente a pasar antes el Function handle con la funcin seno a una variable:

>> fhandle=@sin fhandle = sin >> I=quad(fhandle,0,pi) I = 2


Y as con todas las rutinas que requieran una funcin como argumento.

2.9.5.1. Funciones annimas


La sentencia

inline

se considera obsoleta (aunque no ocialmente). El recurso que la ha apartado es utilizar

un Function handle para declarar una funcin con la siguiente sintaxis:

@(argumentos) sentencia_ejecutable
Por ejemplo, la funcin sigue:

foo2

que en la seccin anterior se ha declarado mediante un

inline

se escribira como

>> foo2 = @(x,y) sin(x)*cos(y)


Con la llamada usual:

>> foo2(6,2) ans = 0.11628


Obviamente tambin podemos utilizarlo en la cabecera de las funciones:

>> quad(@(x) besselj(2.5,x),0,4.5) ans = 1.1178


Alguien puede pensar que el nombre de funcin annima est mal porque si la asignamos a una variable pasar a tener el nombre de la variable. Esta idea, aunque razonable, es completamente errnea. Una y otra vez hemos enfatizado que una variable no es un argumento ni una funcin, es algo completamente distinto. La funcin es annima porque no tiene ningn nombre jo, seguir siendo la misma funcin independientemente del nombre de la variable.

2.9.5.2. Funciones como argumentos de funciones.


Si gracias a los Function handles podemos asignar funciones a variables esto nos servir para pasar funciones como argumentos. Una de las prcticas ms beneciosas en programacin es la de la introspeccin . Es la capacidad de un algoritmo de no depender de los argumentos que utilicemos. La introspeccin ms comn es la aplicada a los nmeros y las matrices; es lo que sucede cuando escribimos cualquier frmula matemtica o funcin en Matlab, pero aplicar la introspeccin a las funciones no es tan sencillo. Es muy fcil integrar una funcin cuando la conocemos, lo que no es integrar una funcin cualquiera. Debemos encontrar automticamente los puntos singulares para concentrar los puntos en ellos, controlar automticamente la precisin y pasar un argumento a la funcin. La introspeccin es intentar hacer un algoritmo lo ms genrico posible y para ello necesitamos llamar funciones como argumentos como sucede con las rutinas de integracin. Si lo pensamos un poco nos daremos cuenta que no es nada fcil llamar a una funcin cuyo nombre no conocemos y sin saber en qu directorio se encuentra. La solucin a este problema son los Function handles, por eso se recomienda encarecidamente su uso. Supongamos que queremos una rutina que calcule el valor de cualquier funcin en el punto

x=1

siendo

su nico argumento:

CAPTULO 2. MATLAB

55

function [out]=fhtest(arg) % % function OUT=fhtest(@arg) % % Calcula el valor de la funcion @arg en 1 @arg debe ser un Function % Handle % out=arg(1);
Es muy importante crear una cabecera de ayuda cuando los argumentos de una funcin no son escalares comunes. Si no ser imposible saber que el argumento de

fhtest

es un Function handle. Lo correcto sera crear tambin un

mensaje de error en el caso que el argumento no fuera del tipo adecuado. Cuando una funcin no devuelve ningn resultado lo primero que haremos ser utilizar la ayuda:

>> help fhtest fhtest is the user-defined function from the file /home/guillem/sync/CursoScripting/ejercicios/fhtest.m function OUT=fhtest(@arg) Calcula el valor de la funcion _arg_ en 1 _arg_ debe ser un Function Handle
ser un alivio comprobar que existe. Para utilizar la funcin podemos llamarla directamente con un Function handle:

>> fhtest(@sin) ans = 0.84147


o como siempre mediante una variable que lo contenga:

>> fhsin=@sin fhsin = sin >> fhtest(fhsin) ans = 0.84147


Esta estructura permite hacer

2.9.5.3. Acceso a las variables desde las funciones annimas.


Otra pequea diferencia entre Matlab y Octave es cmo las funciones annimas entienden las variables dadas en la cabecera. En Octave, una funcin annima es estrictamente una funcin a parte. Las variables internas no tienen ninguna relacin con las variables del resto del entorno de ejecucin. Por ejemplo, si queremos denir la siguiente funcin de dos variables:

f unc = e(x
a partir de una funcin annima debemos hacerlo como

+y 2 )

>> func=@(x,y) exp(-(x. ^2+y. ^2)) func = @(x, y) exp (-(x . ^ 2 + y . ^ 2))
Y llamamos la nueva funcin del modo usual:

>> func(sqrt(log(5)),sqrt(log(5))) ans = 0.040000


Todas estas variables son locales para la funcin. Todas las variables de la funcin deben estar presentes en el interface. Se nos puede ocurrir reducir el nmero de variables de una funcin deniendo algunas de ellas externamente:

>> a=2; >> func=@(x) exp(-(x. ^2+a. ^2)) func = @(x) exp (-(x . ^ 2 + a . ^ 2))
Introduccin informal a Matlab y Octave

56

2.9. FUNCIONES (II)

De este modo estamos pidiendo que la funcin tome una variable que en realidad es externa como propia. En Octave esto da un error en el momento de la llamada:

>> func(2) error: `a' undefined near line 9 column 22 error: evaluating binary operator `. ^' near line 9, column 23 error: evaluating binary operator `+' near line 9, column 21 error: evaluating prefix operator `-' near line 9, column 15 error: evaluating argument list element number 1 error: called from `?unknown?'
Pero si hacemos exactamente lo mismo en Matlab...

>> a=2; >> func=@(x) exp(-(x. ^2+a. ^2)) func = @(x) exp(-(x. ^2+a. ^2)) >> func(2) ans = 3.3546e-04 >>
El programa el intrprete no nos devuelve ningn error. Esto es debido a que mientras Octave preere la denicin de variables globales como apuesta por la seguridad, Matlab es ms laxo con el acceso a las variables en el caso de los function handles. De hecho, este es el modo recomendado por los desarrolladores de Matlab para acortar algunas cabeceras mediante variables externas o para pasar parmetros a funciones dentro de funciones.

2.9.6. Funciones recursivas


Matlab soporta funciones que durante su ejecucin se llaman a ellas mismas porque las llamadas a las funciones se hacen por valor y no por variable. Es muy difcil encontrar un ejemplo donde la manera ms efectiva de resolver un problema sea acudir a la recursin. Es una tcnica peligrosa adems de ser muy agresiva con la memoria y debemos evitarla. Un ejemplo de funcin recursiva sera esta manera tan poco eciente de calcular un factorial

20 .

function out = fact () if (n > 0) out = n* fact (n-1); else out = 1; endif

2.9.7. Encapsulado de funciones


El encapsulado de funciones o nested functions tiene dos utilidades principales: 1. Encapsular partes del clculo en una funcin principal dentro de una funcin secundaria 2. Posibilitar que argumentos de salida sean funciones mediante function handles. El primer uso es trivial. Podemos denir subfunciones siempre que no tengan ninguna repercusin en la cabecera. No es ms que agrupar una tarea repetitiva para no tener que escribirla varias veces. El segundo uso es una de las sutilezas proporcionadas por los function handles. Como podemos denir subfunciones siempre que no inuyan en la cabecera nada nos impide asignarlas a un function handle que se pasar en la salida como argumento. Es exactamente el mismo concepto que el de utilizar funciones como argumentos de funciones pero a la inversa. Por ejemplo, supongamos que estamos diseando un ltro para una seal, un ltro pasa-bajos segn una determinada frecuencia

Lo ms sencillo sera hacer una funcin pasa-bajos que recibiera tres argumentos, el

espectro en frecuencias, la longitud del espectro y la frecuencia de corte. Una solucin mucho ms elegante puede ser denir una funcin de construccin que devuelve un function handle con un ltro que utilizamos como otra funcin por separado. De este modo conseguiramos reducir toda una coleccin de ltros a una nica funcin generadora. Esta prctica se llama introspeccin y es junto con la abstraccin las dos palabras claves de la programacin moderna. La capacidad de Matlab de convertir funciones en argumentos simples es la mayor potencia del lenguaje y a la vez el concepto ms complejo. Dominar bien la abstraccin a nivel de mtodos es dominar Matlab.

20 Existen

varias maneras de calcular un factorial. Las dos ms ecientes probablemente sean

prod(1:n)

gamma(n+1)

CAPTULO 2. MATLAB

57

2.9.8. Sobrecarga de funciones.(Octave)


Este es un tema bastante avanzado slo interesante para la programacin de algoritmos muy complejos. Octave proporciona varias subrutinas para la gestin de la sobrecarga de funciones que no he sido capaz de encontrar en Matlab. La nica herramienta equivalente que Matlab posee son las funciones

inferiorto

superiorto

que

controlan la preferencia de bsqueda de funciones en el rbol de directorios. Dudo que nadie de los que lea este libro tenga necesidad de utilizar la sobrecarga jams pero puede ser til cuando se construyen prototipos de programas en Fortran 95. Tambin son tiles en el caso que estemos programando interfaces a otros programas en C++ donde el tipo de argumento es importante. Imaginemos que acabamos de implementar una funcin en C que se comporta de un modo distinto si el argumento es un nmero real o un complejo. En Octave no tendramos absolutamente ningn problema porque trata ambos tipos del mismo modo pero C es otra historia. Si nuestro cdigo fuera slo C tendramos que programarnos un interfaz que seleccionara la funcin segn la entrada; sobrecargar la funcin desde Octave es una solucin mucho ms elegante.
Los dos conceptos ms importantes de la programacin moderna son la abstraccin y la introspeccin. La primera nos dice que debemos abstraernos de lo que estamos calculando, debemos centrarnos en el concepto y no ver un

2+3

sino un a+b. La introspeccin va un poco ms lejos; la idea es no slo abstraernos del contenido de

cada variable sino abstraerse tambin del mtodo utilizado. La abstraccin la dan las frmulas matemticas y la introspeccin los interfaces. Dentro de los mtodos de introspeccin uno de los ms utilizados es la sobrecarga de funciones. Es un tema bastante avanzado pero puede aportar grandes benecios en cdigos muy complejos. Sobrecargar una funcin es asignar ms de un mtodo a un nombre y aportarle un mtodo adicional para que segn el tipo de argumento se use un mtodo o otro.

dispatch

Funcin que se encarga de gestionar la sobrecarga de mtodos en un nombre. Para saber qu mtodo

llamar utiliza una pequea referencia que asigna cada tipo a una funcin. Tambin nos permite administrar los interfaces para aadir y eliminar funciones a la sobrecarga. Por ejemplo, si utilizamos la funcin sobrecargado dependiente del tipo:

dispatch

con la funcin exponencial vemos que en realidad es un mtodo

octave:1> dispatch('exp') Overloaded function exp exp(fixed complex,...)->fexp(fixed complex,...) exp(fixed complex matrix,...)->fexp(fixed complex matrix,...) exp(fixed matrix,...)->fexp(fixed matrix,...) exp(fixed scalar,...)->fexp(fixed scalar,...) exp(galois,...)->gexp(galois,...) fexp
y

gexp

son funciones llamadas builtin functions que son funciones de un nivel mucho ms bajo que no seran

tiles por s solas.

builtin

Permite acceder a una funcin bsica ignorando el dispatch que tenga sobre ellas.

Todo lo que es potente es complejo y estos conceptos son ambas cosas. Es importante que slo usemos estas herramientas cuando las dominemos.

2.9.9. Herramientas tiles para la manipulacin de funciones.


addpath Aade uno o varios directorios a la lista de la base de datos de funciones. edit Llama al editor descrito en la variable EDIT para editar la funcin pasada como argumento type Muestra informacin rpida sobre la variable o el nombre de la funcin. Si el argumento es una funcin o
una subrutina dentro de un archivo

.m

muestra el contenido del archivo.

2.10. Entrada/Salida
Supongamos que hemos hecho un script para calcular la solucin a un problema de control y necesitamos que en el arranque el usuario nos introduzca los datos de entrada, o pongmonos en la situacin de estar utilizando un cdigo de mecnica de uidos computacional que nos escupe enormes matrices de datos en crudo. Cualquier interaccin de nuestro programa con el exterior necesitar funciones de comunicacin, ya sea un pequeo dilogo en la consola o la lectura de matrices de gran tamao. El primer caso es bastante sencillo pero el segundo requiere conocimientos bsicos de almacenamiento de datos que aprenderemos en breve.

Introduccin informal a Matlab y Octave

58

2.10. ENTRADA/SALIDA

2.10.1. E/S bsica por pantalla.


disp
Es la funcin de salida ms sencilla. Imprime en pantalla el argumento con el que se llama ya sea una cadena de texto o el contenido de una variable.

format

Controla el formato numrico de salida por defecto. Es importante que entendamos que slo cambia la

impresin en pantalla o en un archivo, no estamos cambiando la precisin numrica real. un argumento que determina el tipo de salida:

format se llama con

short long

Formato con 5 cifras signicativas en contenedores de 10 caracteres. Si el punto

decimal se sale de las cifras signicativas en algn caso todos los nmeros pasaran a escribirse segn la notacin cientca. Formato con 15 cifras signicativas en contenedores de 20 caracteres. Si el punto decimal se sale de las cifras signicativas en algn caso todos los nmeros pasaran a escribirse segn la notacin cientca

short e long e El short E long E El

mismo formato que

denotando el exponencial con una

short e.

long

pero usando siempre la notacin cientca y

mismo formato que

denotando el exponencial con una

short E.

long

pero usando siempre la notacin cientca y

short g long g Escoge entre el formato usual o la notacin cientca segn lo requiera cada nmero. En el caso de la notacin cientca la exponencial se denota con una e. short G long G Escoge entre el formato usual o la notacin cientca segn lo requiera cada nmero. En el caso de la notacin cientca la exponencial se denota con una E. free none
Formato libre igual al formato libre de Fortran.

input

Es el equivalente a

disp

pero para la introduccin de valores por teclado. Imprime por pantalla lo pedido

en el argumento y espera a la escritura de un valor por teclado.

menu (tit,op1,...)

Imprime en pantalla el men con un ttulo y las opciones del argumento, cada una de las

opciones se presenta con un nmero y espera que se escoja uno de ellos por teclado. El valor retornado es el nmero de la opcin escogida. Cuando se est utilizando la interfaz grca de Matlab aparece una ventana y que muestra un botn por cada opcin Por ejemplo:

>> choice=menu('Esto es un menu','uno','dos','tres') Esto es un menu [ 1] uno [ 2] dos [ 3] tres pick a number, any number: 3 choice = 3

2.10.2. E/S bsica con archivos


Las palabras clave para guardar variables y sesiones son compatibles pero no idnticas. Esto es porque mientras Matlab tiene sus propios formatos de lectura y escritura Octave ha optado por formatos abiertos

21 .

Matlab puede leer y escribir archivos en formato binario; esto necesita una pequea explicacin. Hay dos maneras principales de almacenar nmeros en memoria, en formato texto y en formato binario. En el primer caso se escriben en un chero que un humano puede leer, normalmente codicado en ASCII de 8 bits. El programa se encarga de alinear las columnas y situar la coma para poder leerlo cuando sea oportuno. El precio de mantener cada nmero como algo leble tiene un coste en memoria mucho mayor, esto nos forzar en algunos casos a utilizar la lectura y escritura en binario. Cuando almacenamos variables en formato binario ya no somos capaces de leer nada, incluso es probable que ni el ordenador sea capaz de hacerlo; esto es porque hay multitud de formatos binarios.

21 Uno

de los apndices trata de la importancia del uso de los formatos abiertos

CAPTULO 2. MATLAB

59

Matlab tiene tres formatos binarios a los que llama segn la versin en la que se introdujeron, la versin 4, la 6 y la 7. No es necesario decir cul es la ms optimizada. La ltima versin de Octave es capaz de leer y escribir en los tres, tiene soporte para utilizar el formato binario abierto hdf5 adems de su tener el suyo propio. Tendremos siempre la posibilidad de guardar o cargar las variables que queramos, el almacenamiento es capaz de reconocer qu variables hemos guardado en l.

save opciones v1 v2 ...


el argumento consultar la ayuda.

opciones.

Guarda las variables solicitadas en el archivo de nombre dado con el formato pedido con Lo mejor para conocer los formatos disponibles y sus posibles incompatibilidades es

load opciones archivo v1 v2

Carga las variables del mismo modo en que las guarda

save.

La recomendacin

vuelve a ser que consultemos la ayuda. Matlab cuenta adems con la funcin le hemos dado con anterioridad.

diary.

Sirve para grabar la sesin literalmente en un archivo cuyo nombre

diary on,o,archivo
Para hacerlo:

Guarda todos los comandos y resultados en un archivo.

>> >> >> >> >>

diary('nombrearchivo') diary on texto='graba todo lo que ponemos aqu'; diary off texto2='ya ha parado la grabacin';
En el archivo de nombre nombrearchivo encontraremos la lnea:

>> texto='graba todo lo que ponemos aqu';

Introduccin informal a Matlab y Octave

60

2.10. ENTRADA/SALIDA

Parte II

La biblioteca de funciones

61

CAPTULO 3
Matrices y lgebra lineal
Se ha dicho y repetido que Matlab es un programa orientado a clculo matricial. Todo nmero en Matlab, hasta los escalares, son en realidad extensiones de matrices o matrices degeneradas. Esta caracterstica hace que todas las funciones puedan tomar matrices como argumento de forma natural. Aunque todas las funciones son en el fondo matriciales podemos clasicar unas cuantas cuyo propsito es precisamente manipular y crear matrices.

3.1. Rutinas de creacin de matrices


eye
Matriz identidad Devuelve un vector la con

linspace(base,limit,n) logspace(base,limit,n)
10
limit
.

elementos equiespaciados entre

base

limit
10base
y

Devuelve un vector la con

elementos espaciados exponencialmente entre

meshdom(x,y) meshgrid(x,y) ones rand

Equivalente a meshgrid. Se usaba en versiones anteriores de Matlab Crea una malla equiespaciada en dos dimensiones a partir de los vectores

y.

Retorna dos

matrices, una con la coordenada

y el otro con la coordenada

y.

Devuelve una matriz de las dimensiones solicitadas cuyos elementos son todos 1 Devuelve una matriz de las dimensiones solicitadas cuyos elementos son nmeros pseudoaleatorios entre

1.

rand* zeros

donde

pueden ser varias letras. Devuelve una matriz de las dimensiones solicitadas cuyos elementos son

nmeros pseudoaleatorios que siguen distintas distribuciones Devuelve una matriz cuyos elementos son todos ceros.

Las funciones que quizs requieran una pequea explicacin son y nos ser muy sencillo dominar su uso:

linspace, logspace

meshgrid.

La primera es

la extensin de la secuencia (2.5.2) cuando los elementos no son nmeros enteros. La usaremos muy frecuentemente

>> linspace(-pi,e,20) ans = Columns 1 through 7: -3.141593 -2.833178 -2.524764 Columns 8 through 14: -0.982692 -0.674277 -0.365863 Columns 15 through 20: 1.176210 1.484624 1.793038 logspace

-2.216349 -0.057448 2.101453

-1.907935 0.250966 2.409867

-1.599520 0.559381 2.718282

-1.291106 0.867795

es exactamente la misma funcin pero con separacin logartmica:

63

64

3.1. RUTINAS DE CREACIN DE MATRICES

>> logspace(-pi,e,20) ans = Columns 1 through 6: 7.2178e-04 1.4683e-03 Columns 7 through 12: 5.1156e-02 1.0407e-01 Columns 13 through 18: 3.6256e+00 7.3756e+00 Columns 19 and 20: 2.5696e+02 5.2274e+02

2.9870e-03 2.1170e-01 1.5004e+01

6.0765e-03 4.3066e-01 3.0523e+01

1.2361e-02 8.7610e-01 6.2092e+01

2.5147e-02 1.7822e+00 1.2631e+02

La funcin meshgrid es un poco ms compleja. Usaremos esta funcin cuando necesitemos una serie bidimensional de puntos equiespaciados que deniremos a partir de dos vectores, las diferencias segn el eje Por ejemplo:

y segn el eje

y.

>> [xx,yy]=meshgrid(1:2:10,1:3:9) xx = 1 3 5 7 9 1 3 5 7 9 1 3 5 7 9 yy = 1 1 1 1 1 4 4 4 4 4 7 7 7 7 7 >> 0.5*(xx+yy) ans = 1.0000 2.0000 3.0000 4.0000 5.0000 2.5000 3.5000 4.5000 5.5000 6.5000 4.0000 5.0000 6.0000 7.0000 8.0000

diag

Extrae e introduce diagonales en matrices.

Probablemente esta ltima sea la de mayor sentido fsico puesto que las matrices por bandas se encuentran muy a menudo en problemas de EDP. El ejemplo que adjunta Matlab en la ayuda de la funcin es perfecto para entender su funcionamiento:

>> m = 5; >> diag(-m:m) ans = -5 1 0 1 -4 1 0 1 -3 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

+ diag(ones(2*m,1),1) + diag(ones(2*m,1),-1) 0 0 1 -2 1 0 0 0 0 0 0 0 0 0 1 -1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 0 1 3 1 0 0 0 0 0 0 0 0 0 1 4 1 0 0 0 0 0 0 0 0 0 1 5

3.1.1. Tipos de argumentos matriciales.


Como vimos en el captulo dedicado a los tipos de argumentos podemos modicar el tipo del argumento matricial (su precisin) de modo explcito. Algunas de las funciones anteriores permiten inicializar una matriz incluyendo el atributo de su tipo, es decir, del tamao que ocupar cada elemento en memoria. Por ejemplo, si denimos la matriz unidad como entera de 8 bits:

>> i8 = zeros(2,2,'int8') i8 = 0 0 0 0

CAPTULO 3. MATRICES Y LGEBRA LINEAL

65

>> i8(1,1)=1023 i8 = 127 0 0 0


Por desgracia los operadores an no disponen de la versatilidad de otros lenguajes ms polivalentes como Fortran o Python; la siguiente operacin nos dar error:

>> i8*[123.534,324.123;123.431,324.123] ??? Error using ==> mtimes Integers can only be combined with...

3.2. Rutinas de manipulacin de forma.


Hay decenas de funciones de manipulacin de forma. No las intentaremos conocer todas porque es un empeo un poco intil. He aqu las ms utilizadas

reshape(A,m,n,...)

Reordena la matriz

A para ajustarse a las dimensiones m n . . .. Esta funcin slo manipula

la forma, en el caso de que queramos ampliar su tamao en vez de aadir ceros dar un error.

transpose Traspuesta. (Ver los operadores aritmticos para su abreviatura) ctranspose Traspuesta conjugada. (Ver los operadores aritmticos para su abreviatura)
Una de las rutinas ms tiles es la siguiente:

cat(opt,a,b,...)

Concatena matrices donde

opt es la dimensin en la que se acoplarn las matrices y los argumentos

siguientes matrices cuyas dimensiones permiten el 'pegado' entre ellas. Un ejemplo del uso de

cat

sera:

>> help cat >> A=ones(2,2); >> B=zeros(2,2); >> cat(1,A,B) ans = 1 1 1 1 0 0 0 0 >> cat(2,A,B) ans = 1 1 0 0 1 1 0 0
En el ejemplo vemos que con la opcin

opt=2

opt=1

las matrices se concatenan en sentido longitudinal mientras que con

se concatenan en sentido transversal. Esta funcin sirve como ejemplo de la gran potencia de la notacin

matricial. Es muy importante no subestimar la potencia del uso de la creacin y la modicacin de matrices con la notacin tpica como vemos en el siguiente ejemplo. Haremos el clculo anterior sin utilizar ninguna funcin:

>> A=ones(2,2); >> B=zeros(2,2); >> [A,B] ans = 1 1 0 0 1 1 0 0 >> [A;B] ans = 1 1 1 1 0 0 0 0
Que sirva como leccin; nunca hay que subestimar la potencia de la notacin matricial.

Introduccin informal a Matlab y Octave

66

3.3. SISTEMAS DE ECUACIONES LINEALES.

3.2.1. Creacin directa de matrices de rango mayor que 2.


La notacin y la salida por pantalla de Matlab est pensada para el clculo matricial, es decir, mantenernos siempre por debajo del rango 3. La notacin est pensada para separar las y columnas pero nada ms; no hay ninguna notacin capaz de separar entre planos matriciales; no hay ninguna extensin tensorial. El mtodo ms intuitivo sera crear la hiper matriz como matriz y luego utilizar la funcin cambiarle la forma. Parece obvio que matlab cuente con mtodos un poco menos artesanales.

reshape A.

para

repmat(A,[n,m,...])

Crea una matriz por bloques de dimensiones

[n,m,...]

con copias de la matriz

Por ejemplo, si queremos crear un cubo de nmeros de lado 5 donde la tapa y el fondo sean matrices unidad y el resto sean ceros podemos hacer lo siguiente:

>> cat(3,eye(5),repmat(zeros(5),[1,1,3]),eye(5)) ans = ans(:,:,1) = 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 ans(:,:,2) = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ans(:,:,3) = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ans(:,:,4) = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ans(:,:,5) = 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1

3.3. Sistemas de ecuaciones lineales.


Un sistema de ecuaciones lineales es:

a11 x1 + a12 x2 + a13 x3 + + a1N xN a21 x1 + a22 x2 + a23 x3 + + a2N xN a21 x1 + a22 x2 + a23 x3 + + a2N xN
. . .

= b1 = b2 = b3 =
. . .

aM 1 x1 + aM 2 x2 + aM 3 x3 + + aM N xN
siempre puede expresarse de la forma

= bM

ax = b

CAPTULO 3. MATRICES Y LGEBRA LINEAL

67

Pero una formulacin tan sencilla suele esconder grandes complicaciones. Todos coincidiremos en que aparentemente la solucin del problema anterior es:

x = a1 b
Pero el problema numrico va mucho ms all. La inversa de una matriz slo existe cuando sta es regular y no siempre tendremos tanta suerte. Buscamos una solucin al problema general de la forma

a(M N ) x(N ) = b(M )


En el que no siempre existe una inversa para

a.

Este anlisis mucho ms general requiere conocimientos que se

escapan en parte de los cursos de clculo numrico y plantea una dicultad adicional: el manejo intuitivo de matrices y vectores. Cuando uno se sumerge en el mundo del clculo matricial es bueno que encuentre modos de equivocarse lo menos posible. Es muy comn que multiplicaciones de matrices incompatibles acaben con un algoritmo brillante. No siempre trabajaremos con vectores columna post multiplicando matrices cuadradas. Un truco bastante utilizado en el clculo numrico es utilizar una notacin parecida a la de Einstein en la que aparecen las las y columnas como coordenadas co variantes y contra variantes:

ai j xi = bj
La regla mnemotcnica es que los ndices que aparezcan repetidos como subndices y superndices

a derecha

de izquierda

representan un sumatorio y desaparecen en el resultado nal. La regla se mantiene en la solucin,

obviamente con permutacin de los ndices:

xi = (a1 )j i bj
Esta notacin es especialmente til porque ayuda a no equivocarse en los clculos, subndice son las y superndice son columnas. Por ejemplo para el producto de dos vectores el producto interno (producto escalar) sera:

xj yj = k
donde k es un escalar. En cambio si los dos vectores aparecen permutados obtenemos el producto externo de dos vectores en el que se amplan los ndices:

yj xi = ai j
Para entender perfectamente la siguiente operacin utilizaremos Matlab:

>> y=ones(3,1); >> x=2*ones(1,3); >> x*y ans = 6 >> y*x ans = 2 2 2 2 2 2 2 2 2
Todo ello es til cuando tenemos operaciones un poco ms complejas como la siguiente:

y k z k ai k xi bj
Cules sern las dimensiones de la matriz (o vector o escalar) resultante? Tenemos claro desde un principio que

es una matriz,

un vector columna e

son vectores la. Sin hacer ningn clculo sabemos que la solucin

tiene la forma:

y k z k ai k xi bj = cj
donde la repeticin de ndices en una misma posicin signica operacin escalar y no matricial. Vamos a exponer un ejemplo de la operacin para conseguir una idea ms grca:

octave:27> y y = 4 4 4 octave:28> z z = 5 5 5 octave:29> a


Introduccin informal a Matlab y Octave

68

3.3. SISTEMAS DE ECUACIONES LINEALES.

a = 2 2 2 2 2 2 2 2 2 octave:30> x x = 3 3 3 octave:31> b b = 1 1 1 octave:32> (((y.*z)*a)*x)*b ans = 1080 1080 1080


Pero centrmonos ms en el problema importante:

aj i xj = bi
Es el problema ms importante del anlisis numrico. Casi todos algoritmos se reducen al planteamiento de un sistema de ecuaciones lineales. Los ms interesantes son los que vienen de una ecuacin en derivadas parciales. Las diferencias nitas, volmenes nitos, elementos nitos y mtodos espectrales terminan en la formulacin de un problema de este tipo. El anlisis preciso de estos problemas es una parte esencial de cualquier curso de anlisis numrico y tiene muchos claros y oscuros dependiendo siempre de la forma de la matriz clasica la mayora de los problemas con su tratamiento:

a.

El siguiente rbol

es cuadrada y regular

no tiene ninguna estructura reconocible

La mayora de los elementos de de la matriz.

a son no nulos. Mtodos directos o iterativos dependiendo del tamao a


son nulos. Matrices sparse. Resolucin por mtodos iterativos.

La mayora de los elementos de

tiene una estructura determinada

a a a a

es tridiagonal. Resolucin por un mtodo directo. No disponible en Matlab. es hermitiana (a

=a

). Resolucin por un mtodo directo. No disponible en Matlab.

es subcondicionada o cuadrada singular. Descomposicin en valores singulares o SVD (pseudoinversa) es sobrecondicionada, es decir, rectangular con ms las que columnas. Es un problema de mnimos cua-

drados o de SVD (pseudoinversa) No disponible en Matlab signica que no tiene ningn mtodo especial para resolver este tipo de problemas.

\.

Debemos utilizar el mtodo de resolucin general,

el operador resolucin de sistemas de ecuaciones lineales

3.3.1. Matrices cuadradas regulares.


Este es el nico caso en el que es rigurosamente cierto que:

x = a1 b
Matlab proporciona con el operador resolucin de ecuaciones lineales un mtodo

universal

para resolver estos

problemas. Aunque Matlab sea capaz de darnos herramientas sencillas para resolver estos sistemas con matrices de gran tamao, en la referencia [3] se mencionan algunas de las dicultades planteadas. Cuando hemos clasicado los mtodos de resolucin segn las caractersticas de la matriz del sistema hemos diferenciado tres maneras de resolver el problema: los mtodos directos, los iterativos y el uso de las matrices sparse. Los tres mtodos no son exclusivos ya que las matrices sparse no son ms que un mtodo de almacenamiento alternativo para ahorrar memoria; hablaremos de ellas ms adelante. Cundo utilizar un mtodo directo o un mtodo iterativo es una sutileza necesaria puesto que ahorra quebraderos de cabeza importantes.

CAPTULO 3. MATRICES Y LGEBRA LINEAL

69

3.3.2. Mtodos directos.


Utilizaremos un mtodo directo de resolucin, es decir, el equivalente a invertir la matriz

a,

cuando la matriz

est densamente llena de nmeros (no estemos utilizando almacenamientos alternativos como matrices sparse) y el tamao sea moderado. En el caso de las matrices sparse los algoritmos de resolucin algebraicos (descomposicin LU o Cholesky) no pueden competir en la mayora de los casos con la rapidez de los mtodos iterativos. Cuando las matrices son demasiado grandes la resolucin puede ser muy costosa. Esto no signica que Matlab sea incapaz de resolver sistemas de ecuaciones de gran tamao. Lo ms importante a parte de todas las consideraciones anteriores es recordar que Matlab cuenta con el operador universal

que permite resolver cualquier sistema de ecuaciones, la regla mnemotcnica es bastante clara. Todos

entendemos fcilmente la regla de la divisin:

f racab

se calculara como sea

a/b.

Esta operacin es idntica a

a b1 ,

aunque en el caso matricial no sera rigurosamente cierto. La barra apunta hacia la variable sobre la que se calcula la inversa. Parece una buena regla que la divisin

a\b

a1 b;

la barra sigue apuntando a la variable invertida.

>> a=rand(1000); >> b=rand(1000,1); >> tic;a\b;toc ans = 1.0539


Acaba de resolver un sistema de ecuaciones con mil grados de libertad en un segundo. Y la precisin?

octave:4> max((a*(a\b))-b) ans = 2.3159e-13


Pues del orden de la precisin de los propios clculos. Los algoritmos de resolucin de Matlab son muy sosticados

y poseen mtodos para mantener un error aceptable en cualquier condicin. El uso de un mtodo directo o uno iterativo se debe principalmente a motivos de velocidad. Utilizaremos un mtodo iterativo slo en el caso de que exista una ganancia de velocidad apreciable o una ventaja en la aplicacin del algoritmo de resolucin como se ve en el ejercicio resuelto 8.5.

3.3.3. Mtodos iterativos.


Utilizaremos un mtodo iterativo cuando no podemos invertir la matriz del sistema en un tiempo razonable. Su objetivo es llegar a la solucin realizando menos operaciones a costa de perder precisin (los mtodos directos son exactos y su precisin depende nicamente de la precisin de la mquina) Los mtodos iterativos llegan a la solucin mediante la evaluacin directa de la matriz del sistema. Si conseguimos llegar a una solucin evaluando la matriz cien veces el nmero de operaciones ser del orden de

100n,

a tener en

cuenta si el nmero de elementos es varios rdenes de magnitud mayor al nmero de iteraciones necesarias. Por supuesto en el caso que casi todos los elementos de la matriz sean distintos de cero. En el siguiente apartado veremos cmo tratar las matrices casi vacas. Quizs el mtodo iterativo ms utilizado es el del Gradiente Conjugado Precondicionado o PGC que analizaremos tambin en la siguiente seccin. Una de las posibilidades de las funciones que implementan mtodos iterativos es que no necesitan una matriz del sistema, les basta con una funcin que calcule

ax.

Esto es ideal para formular los

problemas de un modo alternativo o para utilizar las matrices sparse como veremos a continuacin.

3.3.4. Matrices sparse


Se dice que una matriz es sparse

2 cuando el nmero de elementos no nulos es del orden de

siendo

el

nmero de elementos de la matriz. Hay multitud de casos de sistemas cuyas matrices son sparse, un ejemplo clsico son las matrices generadas por esquemas de elementos nitos tanto en el caso de mallas estructuradas como el de no estructuradas. La nalidad del uso de las matrices sparse es triple. Primero ahorrar la enorme cantidad de memoria desperdiciada almacenando una matriz llena de ceros; segundo, denir mtodos para realizar todas las operaciones disponibles en una matriz pero en el caso de almacenamiento sparse y por ltimo que los errores de resolucin no sean los equivalentes a resolver una matriz con

elementos sino una con

n.

Resumiendo, aprovechar la forma de

la matriz para obtener todas las propiedades beneciosas que se pueda.

1 El operador \ llama 2 Las matrices sparse

las rutinas de las bibliotecas ATLAS y LAPACK, una autntica maravilla de la tecnologa. son parte de los cursos avanzados de anlisis numrico y no suelen entrar en los planes de estudios de las

carreras de ingeniera. Son sin embargo una herramienta muy potente y en algunos casos imprescindible para resolver problemas de ingeniera bastante tpicos. No podramos resolver problemas de grandes estructuras sin la existencia del almacenamiento de matrices

sparse

y su relacin con los mtodos iterativos. Merece la pena echarle un vistazo a la bibliografa aunque lo ms importante es conocer

su existencia y los sntomas que fuerzan su uso.

Introduccin informal a Matlab y Octave

70

3.3. SISTEMAS DE ECUACIONES LINEALES.

3.3.4.1. Anlisis de matrices


Es muy importante saber qu forma tiene nuestra matriz. Si es diagonal superior, tridiagonal o sparse inuir en gran medida el algoritmo de resolucin del problema. Para analizar la naturaleza de las matrices contamos con funciones de gran utilidad:

issparse Si la matriz argumento es sparse retornar verdadero. issquare Si la matriz es cuadrada retorna el nmero de elementos por lado, si no lo es retorna falso. spy Es un mtodo muy utilizado cuando ya sabemos que nuestra matriz va a ser sparse. Pinta un diagrama cuyos
puntos son los elementos de la matriz que son distintos de cero. Un ejemplo de su uso se encuentra en la seccin 3.3.4.3.

3.3.4.2. Almacenamiento de matrices sparse


Existen bastantes mtodos de almacenamiento de matrices sparse. Los ms conocidos son Compressed Row Sto-

rage, Compressed Column Storage, Block Compressed Row Storage, Compressed Diagonal Storage, Jagged Diagonal Storage y Skyline Storage.
Probablemente el ms sencillo sea el primero. El algoritmo descompone la matriz en tres vectores, uno con los elementos de la matriz distintos de cero, otro con el ndice de columna donde se encuentra y un tercero el ndice de los vectores anteriores que inicia una nueva la. Si se descompone la matriz :

A=
los vectores resultado del CRS son:

10 3 0 3 0 0

0 0 0 9 0 0 7 8 7 0 8 7 8 0 9 4 0 0

2 0 0 5 9 2

0 3 0 0 13 1

val = (10, 2, 3, 9, 3, 7, 8, 7, 3, . . . , 13, 4, 2, 1) col_ind = (1, 5, 1, 2, 6, 2, 3, 4, 1, . . . , 5, 6, 2, 5, 6) row_ptr = (1, 3, 6, 9, 13, 17, 20)
El tipo de almacenamiento es oculto en Matlab principalmente por motivos de sencillez. Pero lo ms importante del uso de matrices sparse es que ni sepamos que hemos cambiado el tipo de almacenamiento. Por ejemplo, si a partir de una matriz normal pasamos a almacenamiento sparse gracias a la funcin

sparse,

sparse(M )

Almacena la matriz

como matriz sparse

>> M=[1 0 2 3;0 0 0 3;3 2 0 0] M = 1 0 2 3 0 0 0 3 3 2 0 0 >> SpM=sparse(M) SpM = Compressed Column Sparse (rows=3, cols=4, nnz=6) (1 , 1) -> 1 (3 , 1) -> 3 (3 , 2) -> 2 (1 , 3) -> 2 (1 , 4) -> 3 (2 , 4) -> 3
Nos devolver la informacin de cmo ha almacenado la matriz , nunca los vectores que est utilizando para almacenarla. Lo ms importante es que esta nueva matriz sparse puede operar con matrices de todo tipo ya sean sparse o convencionales transparentemente.

3 Octave

informa del tipo de almacenamiento utilizado, Matlab no dice absolutamente nada.

CAPTULO 3. MATRICES Y LGEBRA LINEAL

71

>> b=[1;2;3;4] b = 1 2 3 4 >> SpM*b ans = 19 12 7

3.3.4.3. Creacin de matrices sparse


El uso de la funcin

sparse

no es nunca una buena opcin para crear una matriz sparse porque no tiene

absolutamente ninguna lgica. El motivo es claro, si la existencia de las matrices sparse es ahorrar memoria y aumentar la velocidad no tiene ningn sentido que tengamos que crear antes la matriz original y luego tener que liberar memoria. Entonces pensamos que sera muy cmodo contar con las mismas funciones de creacin de matrices convencionales para el caso sparse:

speye Crea la matriz unidad en formato sparse spones Crea una matriz sparse con unos en los elementos que deseemos sprand Crea una matriz sparse de nmeros aleatorios en posiciones aleatorias o siguiendo un determinado patrn.
Por ejemplo, si queremos una matriz sparse de nmeros aleatorios con una densidad de 0.01 y de dimensiones

100 100:

>> randsparse=sprand(100,100,0.01);
Para ver cmo se reparten aleatoriamente los nmeros en la matriz utilizaremos la funcin

spy

que ya conocemos:

>> spy(randsparse)
Y como resultado obtenemos la gura 3.1:
0

20

40

60

80

100 0 20 40 60 80 100

Figura 3.1: Elementos no nulos de una matriz sparse creada con

sprand

spdiags

Extrae e introduce diagonales en matrices sparse.

Al igual que su funcin homloga funcin de creacin

spdiags

que

diag tiene diag porque

un gran sentido fsico. De hecho tiene mucha mayor utilidad en la las matrices en banda entran en la denicin de matrices sparse. La

nica consideracin a tener en cuenta es que las matrices en banda se resuelven rpidamente de manera exacta mediante una factorizacin LU diseada para matrices sparse. Utilizaremos los mtodos iterativos con matrices que no cumplan ningn patrn evidente o sencillo.

Introduccin informal a Matlab y Octave

72

3.3. SISTEMAS DE ECUACIONES LINEALES.

3.3.4.4. Manipulacin y operaciones con matrices sparse sphcat Concatena horizontalmente dos matrices sparse de dimensiones compatibles. spvcat Concatena verticalmente dos matrices sparse de dimensiones compatibles. spabs Calcula el valor absoluto de los elementos complejos de una matriz sparse sin
misma.

cambiar el carcter de la

spreal Calcula la parte real de los elementos complejos de una matriz sparse sin cambiar el carcter de la misma. spimag Calcula la parte imaginaria de los elementos de una matriz sparse sin cambiar el carcter de la misma. spinv Calcula la matiz inversa de una matriz sparse.
Sin embargo no es recomendable que utilicemos invertir la matriz del sistema.

spinv

para resolver sistemas de ecuaciones lineales. Como en el

caso de sistemas de ecuaciones en matrices convencionales es recomendable que optemos por el operador

para

3.3.5. Matrices tridiagonales (Octave)


Son uno de los tipos de matrices ms buscadas; tienen un gran sentido fsico (provienen de algunas ecuaciones en diferencias) y son muy adecuadas para el clculo numrico. Son un caso particular de matrices sparse pero al ser tan sencillas pueden resolverse directamente sin realizar demasiados clculos. La funcin de resolucin de sistemas de ecuaciones con una matriz tridiagonal es

trisolve.

3.3.6. Matrices no regulares.


Una de las caractersticas ms importantes del operador es que tambin sirve en el caso de tener un sistema con exceso o defecto de ecuaciones. El operador ya no calcula la matriz inversa sino que busca una solucin cuyo error cumple la condicin de la norma mnima o busca el subespacio solucin. En este caso se dice que en vez de buscar la inversa se calcula una pseudoinversa que resuelve la ecuacin. El tratamiento de este tipo de problemas suele omitirse en la mayora de cursos de lgebra en ingeniera, sin embargo tiene una gran utilidad en clculo numrico y es una herramienta relativamente importante. Creo que no es en vano si intentamos entender con un poco ms de profundidad el tratamiento de estas aplicaciones lineales sin entrar en formalismos.

3.3.6.1. Singular Value Decomposition (SVD)


Se demuestra que cualquier matriz de aplicacin lineal acepta una descomposicin del tipo:

A = U wV
donde

son matrices ortogonales y

una matriz diagonal que contiene los valores singulares. Las matrices

ortogonales, o ms concretamente las matrices de una transformacin ortogonal, tienen la propiedad de mantener los ngulos en la transformacin. Las matrices de giro son un ejemplo de transformacin ortogonal. La matriz

w,

al ser diagonal, no produce ningn tipo de rotacin, simplemente expande o contrae determinadas direcciones. La demostracin de la existencia de esta descomposicin va mucho ms all de los objetivos de este libro. Se utiliza la notacin

para esta matriz debido a que para cumplir la denicin de matiz de transformacin ortogonal sus

columnas deben ser vectores ortogonales; es slo un formalismo porque se demuestra tambin que la inversa de una transformacin ortogonal es tambin una transformacin ortogonal y es equivalente a su traspuesta. Ayuda escribir la anterior ecuacin especicando las dimensiones:

A(N M ) = U(N M ) w(M M ) V(M M )


Vemos tambin que las dimensiones son correctas, aplicando que

V 1 :

A(N M ) V(M M ) = U(N M ) w(M M )


Ahora, un repaso de lgebra de parte de [15]. Si nuestra matriz

es la matriz de una aplicacin lineal

f : S T
podemos denir dos subespacios en reales:

imagen y el subespacio Imagen que es el subespacio

S ; el Ncleo, subespacio que forman los vectores que tienen al vector nulo como f (S )de T . Por ejemplo, sean S y T los siguientes espacios

CAPTULO 3. MATRICES Y LGEBRA LINEAL

73

S T

son las funciones polinmicas el espacio de funciones de

p(x) = a + bx + cx2 + dx3 R

en

Consideremos la aplicacin lineal de independiente; o sea: por los polinomios de constantes.

f : S T denida por f (p(x)) = p (x), la derivada segn la variable f (a + bx + cx2 + dx3 ) = b + 2cx + 3dx2 . La imagen de f es el subespacio de T formado grado menor o igual que 2. El ncleo de f es el subespacio de T que forman los polinomios

Si volvemos a la forma de la descomposicin propuesta por la SVD,

A(N M ) = U(N M ) w(M M ) V(M M ) N < M , es decir, un sistema con menos ecuaciones que incgnitas. En este caso la f : RM RN , si ninguna de las las es combinacin lineal del resto tendremos una imagen de dimensin N y un ncleo de dimensin M N . Se cumple adems que la cantidad de valores singulares no nulos ser N y que las M N columnas asociadas a los valores singulares nulos formarn la base del ncleo. La
Tomemos la condicin de aplicacin lineal ser demostracin de lo anterior est tambin fuera de los objetivos de este libro. Esta operacin es perfectamente vlida tambin para el caso incgnitas. Para obtener las tres matrices de la descomposicin Matlab proporciona la siguiente funcin

N >M

en el que tenemos ms ecuaciones que

svd

Descomposicin en valores singulares. Si se pide nicamente un valor de salida retorna un vector con valores singulares. Con tres valores de salida retorna la descomposicin matricial completa.

Para ejemplicar el uso de la ecuacin vamos a intentar descomponer en valores singulares la ya clsica matriz...

octave:3> a=[1,2,3;4,5,6;7,8,9]; octave:4> [U,w,V]=svd(a) U = -0.21484 0.88723 0.40825 -0.52059 0.24964 -0.81650 -0.82634 -0.38794 0.40825 w = 16.84810 0.00000 0.00000 0.00000 1.06837 0.00000 0.00000 0.00000 0.00000 V = -0.479671 -0.776691 -0.408248 -0.572368 -0.075686 0.816497 -0.665064 0.625318 -0.408248
Efectivamente, uno de los valores singulares es nulo debido a que la matriz es singular. Para analizar ms en profundidad las matrices, Matlab proporciona adems las siguientes funciones:

rank null

Calcula el rango de la matriz, es decir, el nmero de valores singulares no nulos o la dimensin de la imagen de la aplicacin. Calcula la dimensin del ncleo de una aplicacin lineal expresada por una matriz, esto es, el nmero de valores singulares nulos.

3.3.6.2. Problemas con defecto o exceso de ecuaciones.


Si lo nico que nos interesa es resolver pseudoinversa es la siguiente:

ax = b...

Qu calcula exactamente el operador

cuando

N < M?

Lo que hace es calcular la pseudoinversa a partir de la descomposicin en valores singulares. La frmula de la

A+ = V w1 U
Esta matriz da una solucin al problema del tipo:

x = a+ b + v
donde

es una combinacin lineal cualquiera de vectores del ncleo denido por la matriz

a.

Se demuestra que la

solucin que minimiza la norma del error

r |ax b|

(mnimos cuadrados) es precisamente la que cumple

v = 0.

Acabamos de deducir la forma de cualquier solucin hallada por el mtodo de los mnimos cuadrados. En el apartado 6.1.1.1 analizaremos las propiedades de la SVD en el clculo de ajustes polinmicos de series de datos.

Introduccin informal a Matlab y Octave

74

3.4. AUTOVALORES

3.4. Autovalores
eig
Calcula los autovalores y autovectores de una matriz cuadrada.

CAPTULO 4
Grcos
La representacin grca de funciones y de series de puntos es uno de los fuertes de los lenguajes de scripting cientco. Todos ellos tienen rutinas para dibujar, de modo sencillo y rpido, grcas de funciones. Matlab est orientado al dibujo de grcas elementales. Para visualizacin en tres dimensiones ser mejor optar por otra aplicacin ms especializada . Para las necesidades bsicas es ms que suciente. Sus funciones se pueden clasicar en dibujo de lneas, grcos estadsticos, grcas de contornos y supercies. Hay una gran variedad de funciones, aqu slo veremos las ms importantes. Pero antes de dibujar nada es conveniente que conozcamos infraestructura de grcos de Matlab .

4.1. Figure, hold y subplot.


Cuando llamamos alguna funcin de representacin grca Matlab debe antes crear una ventana en el entorno grco, para ello usa la funcin

figure.

No es necesario que usemos esta funcin siempre; cuando no tengamos

ninguna ventana activa Matlab la llamar por nosotros. Ser necesario llamarla cuando queramos utilizar varias ventanas a la vez. Supongamos que acabamos de dibujar una curva en una ventana nueva con

>> plot([1,2,3])
Matlab abrir una ventana de nombre gure 1 tendremos que llamar la funcin activa, por ejemplo:

3 donde va a dibujar todo a partir de ahora. Si llamamos a otra

rutina grca, sea cual sea, la va a dibujar en la ventana activa, gure 1. Si queremos dibujar en otra ventana

figure

usando como argumento el nmero de una ventana que no se encuentre

>> figure(2)
A partir de ahora la ventana 1 va a estar inactiva y todo lo que dibujemos va a expresarse en la ventana 2. el nmero de la ventana; en nuestro caso:

figure

tambin sirve para volver a dibujar en una ventana existente pero inactiva, slo tenemos que darle como argumento

>> figure(1)
1 Matlab
no es un visualizador. Los visualizadores son bibliotecas o programas especializados en la exploracin de datos en 3 dimensiones. Supongamos que tenemos que manejar varios gigabytes en datos y necesitamos lneas de corriente, isosuperfcies transparentes... Si la complejidad es moderada nos servir algn programa de visualizacin pero en casos extremos ni esto ser suciente. La solucin ser crear un programa o una subrutina con algn lenguaje de alto nivel como C++, Java o Python utilizando las funciones de la biblioteca de visualizacin. Muchos de los visualizadores son interfaces grcos para ayudarnos a manipular estas funciones sin tener que escribir cdigo. Una empresa que durante muchos aos ha comercializado las mejores herramientas de visualizacin, tanto a nivel de hardware como de software, es SGI (Silicon Graphics). Esta empresa creci vendiendo estaciones de trabajo y desarroll una de las libreras ms conocidas para grcos 3D, OpenGL. Las herramientas de visualizacin estn encima de la capa bsica de OpenGL que es lo que manipula las funciones bsicas del dibujo. Tres de las bibliotecas ms importantes son OpenInventor de SGi, Data explorer o DX de IBM y VTK (Visualization ToolKit).

2 Octave

no tiene rutinas grcas propias, usa una aplicacin a parte llamada Gnuplot. Si nuestra instalacin de Octave no va

acompaada de Gnuplot no podremos dibujar absolutamente nada. Gnuplot es un programa bastante limitado y tiene una sintaxis distinta a Matlab, sin embargo Octave ofrece una capa de compatibilidad bastante decente que ir mejorando en futuras versiones. Algunas de las funciones comentadas tienen una implementacin distinta en Octave.

3 Octave

llama a las ventanas contando a partir del cero, Matlab las cuenta a partir del uno.

75

76

4.2.

TITLE, XLABEL, YLABEL, LEGEND

TEXT.

Cuando dibujamos en una ventana activa en la que ya haba previamente una grca Matlab la borra automticamente. Lo que hace es llamar implcitamente la funcin usaremos la funcin

hold.

clf.

Para que la nueva grca se superponga a la anterior

Para conseguir superponer grcas en la gura 1, la gura activa:

>> hold on
Y cuando hayamos terminado:

>> hold off


Podemos tener la necesidad de dibujar varias grcas en una misma ventana, para ello existe la funcin Funciona exactamente igual que

figure

subplot.

pero opera dentro de la misma ventana. Se llama con tres argumentos, el

primero son el nmero de subgrcas por la, el segundo el nmero de subgrcas por columna y el tercero es la subgrca que activamos en cada momento. Por ejemplo el script:

x=linspace(-pi,pi,100) subplot(2,2,1) plot(x,sin(x)) subplot(2,2,2) plot(x,cos(x)) subplot(2,2,3) plot(x,sinh(x)) subplot(2,2,4) plot(x,cosh(x))


Produce la gura 4.1:

1.0 0.5 0.0 -0.5 -1.0 -4 15 10 5 0 -5 -10 -15 -4 -3 -2 -1 0 1 2 3 4

1.0 0.5 0.0 -0.5 -1.0 -4 12 10 8 6 4 2 0 -4 -3 -2 -1 0 1 2 3 4

-3

-2

-1

-3

-2

-1

Figura 4.1: Ejemplo de uso de A todos los efectos cada apartado de

subplot

subplot

es como una ventana a parte, incluso en lo referente a ttulos y

nombres de ejes como veremos a continuacin. Para activar y desactivar la cuadrcula se usa la funcin activarla y

grid off

grid

del mismo modo que

hold,

con

para desactivarla. Para ajustar los ejes a los valores deseados tenemos la funcin

grid on para axes a la

que hay que pasarle un vector de datos. Encontraremos un ejemplo en la seccin 4.3.

4.2. Title, xlabel, ylabel, legend y text.


Otro de los requerimientos de una grca cualquiera es poder aadir un ttulo y nombres a los ejes y a las curvas. el nombre de la grca, del eje

title, xlabel, y ylabel funcionan de manera idntica; si les pasamos una cadena de texto la tomarn por x y del eje y respectivamente. Lo vemos en el ejemplo siguiente y en la gura 4.2:

CAPTULO 4. GRFICOS

77

x = linspace(0, 500, 10000) plot(x,exp(-x/100)*sin(x)) title('Una funcion cualquiera') xlabel('Tiempo') ylabel('Amplitud')

1.0

Una funcion cualquiera

0.5

Amplitud

0.0

-0.5

-1.0 0

100

200 Tiempo

300

400

500

Figura 4.2: Insercin de nombres en las guras

En el caso que tengamos varias curvas en la misma grca podemos dar un nombre a cada una de ellas mediante la funcin

legend.

Veremos un ejemplo ms adelante. Tambin podemos introducir en los grcos caracteres

especiales o letras griegas. Para hacerlo hay que tener nociones bsicas de T EX . Matlab por defecto interpreta todos los caracteres empezados con una barra invertida \ como palabras clave en T EX como en el script siguiente que produce la gura 4.3:

x = linspace(0, 500, 10000) plot(x,exp(-x/100)*sin(x)) title('{ \it A e} ^{- \alpha \it t}sin \beta{ \it t} \alpha<< \beta') xlabel('Tiempo ( \mu s)') ylabel('Amplitud (mV)')

Para introducir caracteres de manera arbitraria tenemos la funcin

text.

Nos permite introducir texto o ca-

racteres especiales en cualquier punto de una gura. Como es de esperar es una funcin que requiere muchos argumentos de modo que tendremos que leer la ayuda cuidadosamente. Es una funcin que nos permite hacer cosas muy interesantes como la que se muestra en la gura 4.4. Es un ejercicio muy interesante que intentemos programarlo; el sombreado se consigue con la funcin

fill.

4 Podis

encontrar una pequea introduccin a T EX en los apndices

Introduccin informal a Matlab y Octave

78

4.3. DIBUJO DE CURVAS EN EL PLANO.

Ae
1.0

sint <<

0.5

Amplitud (mV)

0.0

-0.5

-1.0 0

100

200 300 Tiempo (s)

400

500

Figura 4.3: Insercin de caracteres griegos

f(x)

b Z f(x)dx a

Figura 4.4: Ejemplo de uso de

text

4.3. Dibujo de curvas en el plano.


Ya hemos visto la funcin ms bsica para la representacin grca de datos, funciones tiles para la representacin de curvas en dos dimensiones.

plot. Veremos ahora sta y otras

plot

Esta funcin dibuja curvas en dos dimensiones. Soporta mltiples combinaciones de argumentos. La llamada ms sencilla es:

>> plot (Y)


donde Y es la serie de ordenadas mientras que como coordenada X se toma la serie correspondiente a contar los puntos empezando desde 1. Si queremos pasarle ms argumentos plot los va a interpretar de la forma:

>> plot(X,Y,FMT,X,Y,FMT,X...)

CAPTULO 4. GRFICOS

79

Los elementos X e Y son interpretados del modo siguiente: si ambos argumentos son vectores se representa la serie de puntos denida por los dos; esto implica que deben ser de la misma longitud. Si el primer argumento es un vector y el segundo es una matriz se representan las curvas correspondientes al vector junto con cada una de las las o columnas de la matriz. Se prueban primero las columnas, si es imposible la representacin luego se prueban las las; si ambos fallan se obtiene un mensaje de error. Si el primer argumento es una matriz y el segundo es un vector se acta de la misma manera. Si ambos argumentos som matrices se toman como datos para curva las columnas; requerir que tengan una forma idntica. FMT es el argumento que dene el tipo de lnea. Es una cadena de texto y en su ausencia se tomar como formato bsico la lnea slida. Para saber los tipos y colores de lneas disponibles mediante el formato consultaremos la ayuda.

x=linspace(-pi,pi,100); plot(x,sin(x),'m:',x,cos(x),'k ^',x,tan(x),'bx') axis([-pi,pi,-2,2]) grid on legend('linea de puntos magentas','triangulos negros','cruces azules')

Dibuja en pantalla la el equivalente a la gura 4.5:

2.0 1.5 1.0 0.5 0.0 -0.5 -1.0 -1.5 -2.0

linea de puntos magentas triangulos negros cruces azules

-3

-2

-1

Figura 4.5: Estilos de lnea

semilogx semilogy loglog errorbar


Dibuja una curva bidimensional utilizando una escala logartmica en el eje x e y respectivamente.

Dibuja una curva bidimensional utilizando una escala logartmica en ambos ejes. Dibuja una curva bidimensional con las barras de error correspondientes. Las combinaciones de argu-

mentos son parecidas a las de la funcin

plot.

La llamada ms sencilla es:

>> errorbar (Y,EY) error

Si la funcin plot acepta dos argumentos antes de dar el formato de curva, su uso.

acepta seis, dos para los datos y

cuatro para cada direccin de error en el punto. Al igual que en el caso anterior utilizaremos la ayuda para entender

polar

Dibuja una curva sobre el plano con coordenadas polares.

Introduccin informal a Matlab y Octave

80

4.4. GRFICAS ESTADSTICAS.

4.4. Grcas estadsticas.


Las grcas especiales para expresar datos estadsticos son los histogramas y los diagramas tipo tarta. En Matlab se controlan con los comandos siguientes

hist

Dibuja un histograma. Con un nico argumento el resultado es un histograma con diez contenedores. El intervalo de datos de cada contenedor se calcula a partir del argumento. El segundo argumento es siempre el vector de puntos donde debe centrar cada uno de los contenedores. Las fronteras se determinarn como el punto medio entre el centro dado y el siguiente. El tercer argumento es siempre un escalar que sirve para normalizar el histograma de tal manera que la suma de todas las barras ser igual al mismo.

pie

Muestra los valores dados en una grca tipo tarta. Matlab normaliza los datos automticamente para que la suma de los datos sea el total de la tarta. Para separar alguna de las porciones podemos utilizar la opcin

explode;

como siempre, consultaremos la ayuda

4.5. Grcas tridimensionales.


4.5.1. Un error bastante comn.
Que podamos hacer algo no signica que sea necesario hacerlo. Sin embargo cuando uno posee una herramienta tan potente como Matlab tiene la impresin de que est obligado a utilizar supercies en tres dimensiones a todo color. Cuando hemos terminado de poner la leyenda y de posicionar los ejes estamos tan satisfechos que no nos hemos parado a pensar si es conveniente utilizar una supercie paramtrica. La respuesta suele ser no. El modo ms simple de dar un dato es siempre el mejor. Cuando no podemos dar un resultado numrico damos una curva. Cuando no podemos dar una curva y pensamos en dar una supercie es que no lo estamos pensando bien. Las recomendaciones siguientes parten de la larga experiencia de los que me han enseado Matlab; suelen ser prcticas muy tiles porque auydan a no meter la pata. Los colores son bastante tiles pero cualquier exceso es malo. Siempre es mejor dibujar contornos que colorear un plano porque los mapas de colores no tienen fronteras denidas. El lector tiende a verlas como una imagen, no como un mtodo para presentar datos. Las supercies paramtricas son siempre intiles para mostrar datos; esto es casi una verdad universal. Slo tenemos que mirar un poco de bibliografa (bien escrita). A no ser que estemos representando justamente una supercie deformada no tiene ningn sentido representar datos de esa forma. La razn es bien sencilla, las supercies se presentan siempre en perspectiva con lo que es mucho ms complicado ver el valor en un punto. Siempre ser mejor dar curvas de nivel. Los mapas de vectores, esos diagramas de echas usados para representar campos vectoriales, suelen ser contraproducentes. Si el campo es irregular las echas dan informacin confusa porque slo dan el dato en un punto. Si el campo es bastante regular sern mucho ms tiles las curvas de nivel. Los perles son muy tiles para reducir variables. Supongamos que tenemos datos en funcin de dos variables y que la variacin respecto a una de ellas es mucho menor. Lo mejor que podemos hacer es calcular la media sobre la variable que cambia menos y representar el resultado en dos curvas, una con la media (el perl) y la otra con la desviacin tpica. Representar grcamente no es fcil. Dar un resultado de forma errnea o confusa es tan grave como equivocarse en el mismo.

4.5.2. La funcin que tenemos que utilizar


contour
Dibuja las lneas de nivel de una supercie paramtrica tridimensional denida por sus puntos. La representacin grca por curvas de nivel cumple sistemticamente los requisitos expresados anteriormente para cualquier tipo de representacin tridimensional. Tiene la gran virtud de expresar de modo muy simple una gran cantidad de informacin. El hecho de que podamos escoger qu lineas de nivel queremos representar es adems una gran ayuda para explorar una solucin que no llegamos a entender. Es muy normal despreciar esta funcin y utilizar las espectaculares supercies paramtricas. Es un error. La funcin que genera una matriz de

contour es congurable, rpida y muy fcil de utilizar. El ejemplo ms sencillo es utilizar la funcin peaks 49 49 representando las alturas de una supercie paramtrica:

>> contour(peaks)

CAPTULO 4. GRFICOS
Esto genera la grca 4.6.

81

45

40

35

30

25

20

15

10

5 10 15 20 25 30 35 40 45

Figura 4.6: Curvas de nivel del resultado de la funcin

peaks.

Tambin podemos introducir tres vectores correspondientes a las coordenadas de los puntos en el espacio. Esta opcin es muy til en el caso de estar trabajando con datos estadsticos o de representar resultados obtenidos con mallas no estructuradas. Probablemente la opcin ms interesante sea la de poder introducir las curvas de nivel que deseemos en cada caso. En el siguiente ejemplo quince curvas de nivel:

>> contour(peaks,linspace(max(max(peaks)),min(min(peaks)),15))
Introduccin informal a Matlab y Octave

82

4.5. GRFICAS TRIDIMENSIONALES.

45

40

35

30

25

20

15

10

10

15

20

25

30

35

40

Figura 4.7: Introduccin de curvas de nivel personalizadas.

4.5.3. Las funciones que no tenemos que utilizar


Todas las funciones que veremos a continuacin tienen su utilidad pero la mayora de ellas se usan sin sentido o sin necesidad.

quiver Dibuja un campo de vectores bidimensional. Suele utilizarse con la funcin gradient. mesh Dibuja una malla representando la superfcie paramtrica tridimensional dada por los argumentos surf Equivalente a mesh pero dando una apariencia slida a la superfcie meshc Funcin que combina mesh con contour, es decir, dibuja la malla de la superfcie tridimensional mientras
que en el plano

z=0

dibuja las curvas de nivel.

view

Cambia la vista segn los ngulos respecto al eje

en una grca tridimensional. Suele se ms preciso que

el ratn ya que nos ayuda a controlar las rotaciones con ngulos conocidos.

CAPTULO 5
Clculo y Anlisis.
Este captulo trata de todas las funciones dentro de la biblioteca relacionadas con el clculo innitesimal y el anlisis matemtico. Matlab no es un lenguaje de clculo simblico, no calcula ni derivadas ni primitivas. Todas las rutinas de este captulo estn enfocadas al clculo numrico.

5.1. Funciones elementales.


Ya hemos comentado que Matlab posee una importante biblioteca de funciones, es el momento de conocerla con un poco ms de detalle

5.2. Polinomios
En Matlab los polinomios se almacenan como vectores de coecientes. Cada componente del vector es un coeciente ordenado del trmino de mayor a menor orden. La manera ms habitual de iniciar un polinomio es utilizar la siguiente funcin:

poly

Inicia un polinomio. Si el argumento es una matriz cuadrada devuelve el polinomio caracterstico, si es un vector devuelve un polinomio cuyas races son los elementos del vector.

Tambin nos sern muy tiles las funcines:

roots Devuelve las races del polinomio cuyos coecientes son los elementos del vector argumento. polyval Calcula el valor del polinomio en el punto dado polyout (Octave) Escribe un polinomio en un formato ms leble:
Por ejemplo, si queremos escribir el polinomio

s5 8s4 + 3s2 + 16:

>> polinomio = [1,-8,0,+3,0,16] >> polyval(polinomio,44) ans= 134937280


Los polinomios se pueden manipular analticamente con las siguientes funciones:

polyder Deriva un polinomio. polyint Integra analticamente un polinomio. conv Multiplica dos polinomios. deconv Dados dos polinomios a e y halla b y r que cumplen:
y = (a b) + r

residue

Descompone el cociente de dos polinomios en fracciones con un nico polo. Por ejemplo, dados los poli-

nomios

p = s2 + s + 1

q = s3 5s2 + 8s 4

la descomposicin sera:

s3

s2 + s + 1 2 7 3 = + + 5s2 + 8s 4 s 2 (s 2)2 s1
83

84

5.3. DERIVADAS

5.2.1. Evaluacin de funciones.


Los polinomios son una parte importantsima del clculo numrico porque son su nexo fundamental con el clculo simblico. Uno de los elementos fundamentales en el clculo numrico es la aproximacin de una funcin analtica por otra con una expresin numrica lo ms equivalente posible. Todas las funciones analticas no existen realmente dentro de un programa de clculo numrico por limitaciones del propio ordenador; la aritmtica exacta es algo prohibitivo. La evaluacin de funciones se realiza por series de potencias almacenadas por sus coecientes; este es el funcionamiento de la evaluacin de cualquier funcin analtica en un programa de clculo numrico. Las series de potencias acotan el error con el nmero de trminos y el orden de la serie; a mayor precisin ms trminos a evaluar. Por ejemplo, si Matlab quiere obtener el valor de la funcin seno en un punto evaluar la serie:

sin x =
k=0

(1)k 2k+1 x (2k + 1)!

O si quiere evaluar la funcin de Bessel de primera especie:

x Jn (x) = 2

n k=0

2 k ( 1 4x ) k !(k + n)!

Si este es el funcionamiento interno de Matlab ser muy benecioso que tengamos esto en cuenta cada vez que tengamos que evaluar funciones especialmente pesadas. No necesitamos aritmtica exacta, evaluar una precisin mayor a la de la mquina es malgastar recursos. Supongamos que tenemos una funcin con una gran cantidad de funciones trigonomtricas. Es probable que alguna vez en nuestra vida tengamos funciones de dos y tres lneas de cdigo. Evaluarla entera es una prdida de recursos. Imaginemos adems que estemos integrando una ecuacin diferencial cuyo trmino es esta misma funcin. Evaluando todos los trminos no estamos ganando precisin; estamos sumando y restando polinomios de un orden mayor al que queremos con valores que se cancelan continuamente. Utilizando la interpolacin polinmica podemos acelerar cualquier cdigo hasta en un rden de magnitud.

5.3. Derivadas
Todas las funciones de este apartado se reeren a la derivada numrica. No son derivadas de una funcin analtica sino el resultado de aplicar las ecuaciones de diferencias de orden ensimo a una serie discreta de puntos.

di

Aplica la frmula de diferencias ensimas a una serie de puntos Calcula el gradiente numrico de una matriz. Esta funcin es muy interesante por su relacin ntima con

gradient

la funcin

quiver.

Si queremos expresar un determinado campo vectorial a partir de su funcin potencial,

siendo el potencial la funcin

este campo vectorial slo tenemos que hacer

(x, y ) entonces el campo es en cada punto (x , y ), es decir, . Para pintar quiver(gradient(phi)) .

5.4. Integrales
La integracin numrica es un vasto campo del clculo numrico y as se reeja en Matlab. Podemos hacer tanto integrales en una dimensin como en dos. Las rutinas ms relevantes son:

quad

sentencia

inline, es en este tipo de funciones donde el inlining tiene ms utilidad. Por ejemplo, para integrar 10 4 exp( x ) dx haremos quad(inline('exp(-x^4)'),0,10). La funcin nos permite introducir la tolerancia 0 requerida para el resultado, cuando pasemos este argumento es importante que no sea mayor que la precisin
numrica con la que estemos trabajando o haremos que el programa produzca un error. Tambin podemos pasarle otros argumentos para aumentar la precisin como marcar ciertos puntos donde la funcin puede presentar singularidades.

Integracin numrica de una funcin analtica introducida a travs de un archivo de funcin o por una

quadl

Su uso es idntico que la funcin anterior pero contiene un algoritmo de cuadratura de mayor precisin.

dblquad

quad2dc y quad2dg en Octave. Calcula la integral doble de una funcin de dos variables. Obviamente la
No existe an en Octave. Calcula la integral de volmen de una funcin de tres variables.

frontera de integracin sern cuatro constantes.

triplequad trapz

Aplica la regla del trapecio para calcular la integral numrica de una serie discreta de puntos.

CAPTULO 5. CLCULO Y ANLISIS.

85

5.5. Ecuaciones diferenciales ordinarias.


Se podra decir que hay un mtodo de integracin para cada problema. Existen multitud de esquemas de integracin y escoger uno de ellos no es fcil. Uno de los objetivos de las funciones de Matlab es intentar ser lo ms universales posible. La funcin perfecta sera la que sin conguracin alguna integrara cualquier EDO con una precisin aceptable; desgraciadamente no existe y probablemente no exista nunca. Una consideracin esencial antes intentar resolver una EDO es saber si el paso temporal viene condicionado por la precisin numrica o por criterios de estabilidad. El segundo caso es bastante ms preocupante que el primero. Cuando la funcin introduce gradientes elevados que acortan signicativamente el paso de la iteracin se dice que el problema es sti . En estos casos ser apropiado utilizar un esquema de integracin implcito que a costa de mayor coste computacional por paso permite llegar al resultado con muchas menos iteraciones. Saber si un problema es sti o no es tan laborioso o ms que resolverlo. Para saber si utilizar un esquema explcito o implcito la estrategia ser la siguiente: 1. Represenataremos la funcin a integrar para comprobar si tiene discontinuidades o gradientes muy elevados 2. Si no tiene ninguna singularidad utilizaremos un esquema explcito (no sti ) calculando el tiempo de proceso. 3. Si el tiempo nos parece demasiado elevado cambiaremos a un esquema implcito 4. Si el tiempo sigue siendo demasiado elevado y la programacin es correcta puede ser que la funcin sea demasiado costosa de evaluar. Para solucionarlo escribiremos la funcin en otro lenguaje de programacin como C, C++ o Fortran y la convertiremos en un archivo que Matlab entienda. La precisin numrica es tambin muy importante pero el mismo esquema de integracin es capaz de controlarla. Daremos como vlido que a mayor precisin numrica mayor dicultad para obtener una solucin estable. Las diferencias entre Matlab y Octave en este caso son ms que signicativas. Octave dispone de las funciones de integracin de Matlab pero existen slo por motivos de compatibilidad, son mucho ms lentas y no se pueden congurar. Sin embargo Octave integra la suite ODEPACK, uno de los paquetes de integracin de EDOs ms robusto y efectivo.

5.5.1. Octave
Octave cuenta con las funciones de integracin de Matlab pero estn programadas como archivos como parte de una biblioteca binaria. Es muy recomendable que utilcemos la funcin sti y una BDF (Backward Dierentiation Formula) para los problemas sti.

lsode

.m

y no

(Livermore Solver for

Ordinary Dierential Equations), parte de ODEPACK. Utiliza un mtodo multipaso Adams Para problemas no

lsode

(Octave) Es el driver general de integracin de ecuaciones diferenciales ordinarias.

[X, ISTATE, MSG] = lsode (FCN, X_0, T, T_CRIT)


Resuelve el problema de Cauchy de la forma:

dy = f (x, t) dt
dadas las condiciones iniciales.

FCN

Matriz de dos elementos tipo cadena de caracteres. El primero es el nombre de la funcin que queremos integrar y el segundo la funcin que calcula el jacobiano.

La funcin a integrar debe denirse necesariamente mediante una funcin, ya sea dentro del script o en un archivo a parte. La cabecera tendr slo dos variables y su forma ser

XDOT=FUNC(X,T)
donde tanto

como

XDOT

pueden ser escalares o vectores. El jacobiano tambin tendr la forma

JAC=FJAC(X,T)
donde

X.

JAC ser la matriz que implemente las funciones derivadas parciales segn el orden establecido por la variable

Se usa para acelerar la integracin en problemas sti. Vector de condiciones iniciales.

X_0

1 Personalmente creo que ste es uno de los pocos casos en el que Octave es superior a Matlab. Ni entiendo ni comparto la organizacin
de las rutinas de integracin de Matlab, me parece confusa, desacertada y poco ptima.

Introduccin informal a Matlab y Octave

86

5.5. ECUACIONES DIFERENCIALES ORDINARIAS.


Vector que determina los instantes temporales en los que se dar una solucin. Puntos en los que la rutina no debe integrar por la existencia de singularidades.

T_CRIT X

Vector de soluciones en los instantes

T ISTATE
devolver el valor 2 y

Si la integracin no ha sido satisfactoria

MSG

nos dar ms informacin.

lsode_options

Funcin de conguracin de

lsode

lsode_options index{lsode options} (OPT, VAL)


Llamada con un nico argumento (OPT) nos dir el valor de la opcin de conguracin que hayamos solicitado. Pasando dos argumentos podremos cambiarlos. Las opciones disponibles son los de la tabla siguiente: Parmetro de conguracin Valores admitidos Error absoluto para cada caso de integracin. Un escalar o un vector cuyo tamao debe ser el mismo que el nmero de puntos a calcular Error relativo permitido para cada paso de integracin. Es un escalar Valor por defecto

'absolute tolerance' 'relative tolerance' 'integration method' 'initial step size' 'maximum order' 'minimum step size' 'step limit'

1,4901 108 1,4901 108

'adams' o 'non-stiff' para un esquema explcito o 'bdf' o 'stiff' para un esquema implcito
El valor del primer paso de integracin. Es un escalar Un nmero del 1 al 12 para 5 para

'stiff'
automtico rdenes mximos 0 100000

'stiff'

'non-stiff'

y del 1 al

Paso de integracin mnimo. Un escalar Mximo nmero de iteraciones admitidas.

Cuadro 5.1: Valores de conguracin de

lsode_options

Pronto veremos un ejemplo de cmo usar esta funcin.

5.5.2. Matlab
El planteamiento de las rutinas para ODEs de Matlab es completamente distinto. En vez de tener una funcin que sirve ms o menos para todo nos permite escojer el mtodo de integracin. Disponemos de los presentes en la tabla 5.2: Funcin Tipo de problema no sti no sti no sti sti sti sti no sti/sti sti Observaciones Esquema Runge Kutta (4,5). Debe ser la primera opcin Esquema Runge Kutta de menor orden. Mayor estabilidad que

ode45 ode23 ode113 ode15s ode15i ode23s ode23t ode23tb

ode45.

Mtodo multipaso de mayor precisin Para problemas sti. Mtodo completamente implcito. Lo usaremos en casos puntuales Primera opcin para problemas sti. -

Cuadro 5.2: Funciones de integracin de EDOs de Matlab

La llamada bsica es la misma para todas ellas y tiene la forma:

[T,Y] = solver(odefun,tspan,y0) [T,Y] = solver(odefun,tspan,y0,options) [T,Y,TE,YE,IE] = solver(odefun,tspan,y0,options)

CAPTULO 5. CLCULO Y ANLISIS.

87

odefun

es la llamada convencional a una funcin, preferiblemente un function handle. A diferencia de

lsode

la

funcin debe tener la forma:

dy = F (t, x) dt
y su resultado

debe ser un vector columna. tspan es un vector de dos componentes con el tiempo inicial y nal
y0
es el vector con la condicin inicial. Los parmetros de salida son los usuales,

de integracin; nalmente

son respectivamente los vectores tiempo y solucin del problema. En breve propondremos un ejemplo Tambin es necesario que conozcamos la funcin de conguracin mayor a las disponibles en

lsode

odeset.

La cantidad de opciones es bastante

de modo que lo ms sensato ser consultar la ayuda.

5.5.3. Solucin de la ecuacin de Van der Pol


La ecuacin diferencial de Van der Pol es:

mx x + (x ) + kx = 0
No es ms que el movimiento de una masa oscilante con amortiguamiento lineal y no lineal a la vez. Adimensionalizando el problema llegamos a la ecuacin.

x + x + (x 2 1)x = 0
Esta ecuacin tiene la particularidad de que a medida que el parmetro un

aumenta

el problema se vuelve sti. Con

de orden unidad el sistema puede considerarse no sti mientras que si aumenta hasta ser del orden del millar

la ecuacin introduce gradientes muy acusados. Este comportamiento tan particular la hace perfecta para ensayar los distintos mtodos de integracin. Lo primero es descomponer la ecuacin en un problema que Matlab pueda entender:

dy1 dt dy2 dt
con condiciones de contorno Octave en C++:

= y2 2 = y2 (1 y1 ) y1

Matlab ya cuenta con estas funciones (vdp1 y

y1 (0) = 2

y:2 (0) = 0. Resolveremos el problema para = 1 y = 1000 porque vdp1000). Para agilizar los clculos escribiremos las funciones para

#include <octave/oct.h> DEFUN_DLD (vdp1,args, , "Ecuacion de Van der Pol para mu=1 ") { ColumnVector xdot (2); ColumnVector x (args(0).vector_value()); float mu=1; xdot(0) = x(1); xdot(1) = mu*x(1)*(1-x(0)*x(0))-x(0); return octave_value (xdot); }
Y la funcin para

= 1000:

#include <octave/oct.h> DEFUN_DLD (vdp1000,args, , "Ecuacion de Van der Pol para mu=1000 ") { ColumnVector xdot (2); ColumnVector x (args(0).vector_value()); float mu=1000; xdot(0) = x(1); xdot(1) = mu*x(1)*(1-x(0)*x(0))-x(0); return octave_value (xdot); }
Introduccin informal a Matlab y Octave

88

5.5. ECUACIONES DIFERENCIALES ORDINARIAS.

5.5.3.1. Integracin del problema no sti (vdp1)


Integrar un problema no sti es mucho ms sencillo que un problema sti. La inestabilidad numrica tiene efectos mucho ms importantes que la prdida de precisin. Los esquemas de integracin que manejaremos son de paso variable. Esto signica que la propia subrutina calcula el paso de integracin para, sea cual sea la funcin y el esquema utilizado, el resultado sea numricamente correcto. Octave

>> lsode_options('integration method','non-stiff') >> y=lsode('vdp1',[0 2],linspace(0,20,1000));


Matlab

>> [tout,xout]=ode45(@vdp1,[0 20],[2 0]);


La diferencia esencial entre Octave y Matlab es que el primero pide por defecto los puntos en los que queremos la solucin. Matlab preere resolver el problema y dar los puntos en el tiempo en los que se ha pasado durante la integracin. Es por ese motivo por el que el argumento tiempo es en el primer caso un vector de un millar de elementos mientras que en el segundo es tan solo un par de escalares. La superposicin de ambas soluciones es un ejemplo perfecto para ver trabajar los esquemas de paso variable. Apreciamos en la gura 5.1 que el paso de integracin disminuye segn la curvatura de la solucin
2.5 2 1.5 1 0.5 0 -0.5 -1 -1.5 -2 -2.5 line 1

10

15

20

Figura 5.1: Solucin de la ecuacin de Van der Pol con

=1

5.5.3.2. Integracin del problema sti (vdp1000)


Como los problemas sti introducen gradientes elevados en la solucin el paso de integracin de un esquema explcito se va haciendo tan pequeo que su avance es demasiado corto. Es precisamente lo que ensayamos en este caso. Si intentamos resolver la ecuacin de Van der Pol con Octave

= 1000 y t [0, 3000] mediante un esquema explcito:

>> lsode_options('integration method','non-stiff') >> y=lsode('vdp1000',[0 2],linspace(0,3000,100000));


Matlab

>> [tout,xout]=ode45(@vdp1000,[0 3000],[2 0]);

CAPTULO 5. CLCULO Y ANLISIS.

89

nos encontramos con la desagradable sorpresa de que el calculo no termina nunca. Esto es porque la solucin, aunque es regular, tiene puntos con gradiente casi innito. La solucin es utilizar un esquema implcito o semimplcito. Por ejemplo: Octave

>> lsode_options('integration method','stiff') >> ystiff=lsode('vdp1000',[2 0],linspace(0,20,1000));


Matlab

>> [tout,xout]=ode23s(@vdp1000,[0 3000],[2 0]);


Efectivamente, la solucin demuestra por qu el problema es sti (Figura 5.2):
2.5 2 1.5 1 0.5 0 -0.5 -1 -1.5 -2 -2.5

line 1

500

1000

1500

2000

2500

3000

Figura 5.2: Solucin de la ecuacin de Van der Pol con

= 1000

5.5.4. Inestabilidades y caos.


Uno de los casos en los que el clculo numrico es una herramienta imprescindible es en la resolucin de ecuaciones diferenciales no lineales, tanto ordinarias como en derivadas parciales. La no linealidad de las ecuaciones hace que el carcter de los problemas de evolucin sea mucho ms complejo que en el caso lineal. Uno de los fenmenos observados es la aparicin de caos.

Supongamos que queremos resolver la ecuacin del dipolo de Rikitake de ecuaciones:

x 1 x 2 x 3
Despues de introducirlo en la funcin

= x1 + x3 x2 = x2 + (x3 3,75)x1 = 1 x1 x2

rikitake.m:

function xdot=rikitake(x,t) % % Ecuacion de la dinamo de Rikitake % xdot(1,1)=-x(1)+x(3)*x(2); xdot(2,1)=-x(2)+x(1)*(x(3)-3.75); xdot(3,1)=1-x(1)*x(2);


2 Esta
seccin es slo una pequea introduccin a los efectos del caos. No soy un absoluto un experto en el tema pero se comenta en esta seccin porque puede tener efectos desconcertantes en la solucin. Pido disculpas si existe algun fallo garrafal en alguna de las armaciones.

Introduccin informal a Matlab y Octave

90
Y resolver el problema utilizando la funcin

5.5. ECUACIONES DIFERENCIALES ORDINARIAS.

ode45

Octave :

>> [t,x]=ode45(@rikitake,[0 300],[1 2 3],pair=0,ode_fcn_format=1); plot(t,x(:,1),';x_1;',t,x(:,2),';x_2;',t,x(:,3),';x_3;')


Nos encontramos con la desagradable sorpresa de que nuestra solucin es completamente errtica (gura 5.3).
8

x_1 x_2 x_3

-2

-4

-6

50

100

150

200

250

300

Figura 5.3: Solucin del dipolo de Rikitake

A primera vista puede parecer que la solucin est mal. Si representamos exactamente el mismo resultado pero mediante una curva paramtrica:

>> plot3 (x(:,1),x(:,2),x(:,3))


llegamos a la gura 5.4.

line 1

7 6 5 4 3 2 1 2 3

-6

-4

-2

6 -3

-2

-1

Figura 5.4: Curva solucin del dipolo de Rikitake

De este ejemplo aprendemos que las ecuaciones diferenciales no lineales pueden tener un comportamiento extrao. Un ejemplo claro de ello son las ecuaciones de Navier Stokes. Si simplicamos las ecuaciones para ujo incompresible nos encontraremos un trmino lineal (el viscoso) y uno no lineal (el convectivo). El estudio analtico

3 Por

qu hemos tenido que utilizar el argumento adicional

ode_fcn_format?

CAPTULO 5. CLCULO Y ANLISIS.

91

de estas ecuaciones an no ha llegado a la conclusin sobre la existencia y la unicidad de la solucin , sin embargo se resuelven por mtodos numricos. La turbulencia, uno de los fenmenos fsicos ms complejos, aparece de forma espontanea cuando intentamos resolver las ecuaciones de N-S. Parte de la disciplina de la CFD (Computational Fluid Dynamics) es estudiar los ujos turbulentos a partir de la resolucin numrica de las ecuaciones de N-S. La conclusin es que la integracin numrica de ecuaciones diferenciales es un problema complejo no slo por la fsica del problema sino porque adems se suman muchos otros factores. En esta pequea introduccin slo hemos visto los problemas sti y un caso muy sencillo de caos pero los problemas pueden complicarse muchsimo ms.

5.6. Clculo simblico


La armacin repetida hasta la saciedad de que Matlab es un programa estrictamente de clculo matricial no es del todo correcta. Se basa en la aplicacin del sentido crtico a una herramienta. La versin completa de Matlab incluye el programa de clculo simblico ms utilizado actualmente, Maple. Los problemas generados por el uso del clculo simblico en Matlab son dos:

1. Tenemos acceso al ncleo de clculo de Maple, pero dicho acceso no es completo. Podemos efectuar las operaciones bsicas como derivar, buscar primitivas, crear desarrollos de Taylor... Nunca dispondremos de la potencia de este tipo de programas. 2. La arquitectura de matlab

no est pensada para el clculo simblico. Los programas de clculo simblico

suelen incluir un interfaz llamado notebook que sirve para ver las frmulas de entrada y salida en una notacin mucho ms matemtica. Las diferencias en el diseo de un programa de clculo numrico y otro de clculo simblico son a mi parecer irreconciliables.

Esto no signica que sea un crimen utilizar las funciones de clculo simblico cuando uno disponga de ellas. Somos libres de hacer lo que queramos pero debemos ser conscientes de hasta qu punto no estamos utilizando la herramienta ideal para nuestro fn. Octave tambin dispone de un soporte muy limitado para realizar operaciones simblicas. Se podra decir que lo nico que puede hacer es derivar y resolver sistemas de ecuaciones lineales. Tampoco parece que en un futuro cercano estas funcines se amplen hasta un soporte equivalente al de Matlab. No son compatibles pero las funciones son tremendamente parecidas. Los siguientes apartados sirven como introduccin general al uso de variables simblicas pero no conseguiremos ms que araar la supercie del total de las posibilidades del toolkit.

5.6.1. Denicin de variables y funciones simblicas


Una de las diferencias ms esenciales entre Matlab y Octave en lo que respecta a clculo simblico es que en Octave es necesario activar el toolkit con el siguiente comando :

>> symbols
Tanto en Matlab como en Octave el modo ms fcil de denir una variable simblica es crear una variable que contenga un argumento simblico del mismo nombre:

sym

Dene una variable que contiene un argumento simblico. Es muy recomendable que la variable y el argumento tengan el mismo nombre para evitar confusiones

>> x = sym('x')

poly2sym

Dene un polinomio simblico a partir de sus coecientes.

>> poly2sym([1 2 3 -2 10]) ans = 10.0+(-2.0+x*(3.0+(2.0+x)*x))*x


4 El
estudio de existencia y unicidad de la solucin de las ecuaciones de Navier Stokes para el caso incompresible es uno de los grandes problemas no resueltos de las matemticas.

Introduccin informal a Matlab y Octave

92

5.6. CLCULO SIMBLICO

5.6.2. Funciones simblicas elementales.


La aplicacin de funciones elementales a variables simblicas es completamente distinta en Matlab y en Octave. Mientras Matlab no diferencia las funciones simblicas de las numricas Octave preere llamarlas de un modo distinto. Esta distincin suele ser que la primera letra de la funcin es una mayscula . Entonces, para conseguir la funcin simblica

sin x

en Matlab haremos:

>> x=sym('x') x = x >> y=sin(x) y = sin(x)


Mientras que en Octave haremos lo siguiente:

>> x=sym('x') x = x >> y=Sin(x) y = sin(x)


En la coleccin podemos encontrar todas las funciones trigonomtricas, exponenciales, logaritmos...

5.6.3. Operaciones simblicas


Casi todas las operaciones disponibles en el paquete simblico de Octave estn dedicadas a la manipulacin simblica de polinomios (muy interesante en el clculo numrico). En cambio Matlab dispone de la mayora de las operaiciones simblicas existentes... Derivadas, primitivas, desarrollos en serie... La nica funcin interesante en lo referente a clculo simblico que tiene Octave es la siguiente:

subs Substituye una o varias variables de una expresin simblica. collect Agrupa los trminos polinmicos en una variable dada. expand Desarrolla una expresin simblica. dierentiate Slo en Octave. Calcula la n-sima derivada de una expresin simblica.
Funcin que en Matlab recibe un nombre distinto:

di

Slo en Matlab. Calcula la n-sima derivada de una expresin simblica.

Matlab dispone adems de las siguientes operaciones:

int Encuentra la primitiva de una funcin simblica limit Calcula el lmite hacia un determinado valor de una funcin simblica. taylor Calcula el desarrollo en serie de Taylor respecto a un punto dado de una funcin simblica. symsum Calcula la suma de dos series.
Una de las pocas operaciones compatibles es la representacin de una curva determinada por una funcin simblica:

splot

Dibuja la curva representacin de una funcin simblica de una variable. El segundo argumento es un vector de dos elementos con el intervalo de la variable independiente.

5 Siempre

viene bien recordar que la arquitectura de Matlab distingue entre maysculas y minsculas

CAPTULO 6
Toolkits
Las funciones que que aparecen en este captulo no son necesariamente parte de un toolkit de Matlab. No es ms que una clasicacin articial de las funciones con una nalidad concreta que no justica la creacin de un captulo a parte. Esta seccin es mucho menos amplia de lo que debera, se ha sacricado a propsito a favor de temas ms bsicos como el clculo el lgebra o el dibujo de grcas. Mientras todo lo escrito hasta aqu es casi denitivo este captulo no se considerar nunca como terminado.

6.1. Estadstica descriptiva y anlisis de datos


Matlab es un lenguaje muy utilizado en anlisis de datos, tanto experimentales como producidos por otros programas. En el caso de las series de datos experimentales habr que importar un archivo almacenado en un formato compatible y asignar todos los valores a una variable; ms adelante aprenderemos a hacerlo. Supongamos el caso ideal de que ya tenemos todos los datos cargados en una variable. Matlab tiene una cantidad enorme de rutinas que facilitan el anlisis de datos de modo interactivo. las funciones son tan de alto nivel que es posible sacar cualquier resultado secundario sin necesidad de pensar un script; directamente con la consola. las funciones ms tiles son:

mean std min max sort

Calcula la media de una muestra de datos:

x =

1 n

n n=1

xi .
1 n1 n i=1 (xi

Calcula la desviacin tpica de una muestra de datos: Calcula la mediana de la muestra.

s=

x )2 .

median

Valor mnimo de la muestra. Valor mximo de la muestra. Ordena los elementos de menor a mayor. Resta el valor medio de la serie de datos.

center

6.1.1. Ajuste de curvas por mnimos cuadrados.


Supongamos que tenemos una serie de datos obtenidos mediante un experimento y queremos hacer clculos con ellos. El principal impedimento es que ya no disponemos de una serie continua de datos sino de medidas discretas. Las dicultades que se presentan son numerosas; no podemos poner dichos datos en un sistema de ecuaciones no lineales porque no es diferenciable, tampoco en una ecuacin diferencial. La solucin es convertir estos datos en una muestra contnua que nuestras herramientas numricas puedan manejar. La prctica ms comn es la de utilizar un ajuste polinmico. El polinomio resultante se obtiene resolviendo el problema de mnimos cuadrados. El grado del polinomio es uno de los datos que debemos escoger. Suele ser una regla vlida que polinomios de mayor rden consiguen menor error pero no es siempre cierta.

Es bastante usual utilizar erroneamente el ajuste por mnimos cuadrados; sirven para crear un modelo polinmico de una funcin, no para conseguir una curva a travs de unos puntos; para esto est la interpolacin.
Por ejemplo, supongamos que disponemos de la siguiente serie de datos: 93

94

6.1. ESTADSTICA DESCRIPTIVA Y ANLISIS DE DATOS


x 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 y 2.0000 2.1850 2.2011 2.5762 2.5780 2.9711 2.7816 3.0766 2.8277 3.6763 3.6933

polyt

Devuelve los coecientes del polinomio del grado que queramos y soluciona el problema de ajuste por

mnimos cuadrados. Introducimos ahora las dos series de datos e intentamos ajustarlo por mnimos cuadrados para crear un modelo

lineal de los datos adquiridos. Lo conseguimos con la siguiente lneas de cdigo:


fit=polyfit(linspace(0,1,11),y,1) fit= 1.5928 1.9828
Ahora tenemos dos nmeros en un vector llamado

fit, este vector son los dos coecientes del polinomio que ajusta

los datos; una recta. Ahora representaremos grcamente los datos del siguiente modo

plot(linspace(0,1,11),y,'b*') hold on plot(linspace(0,1,11),polyval(fit,linspace(0,1,11)))


El resultado es la gura 6.1

3.6

3.4

3.2

2.8

2.6

2.4

2.2

2 0 0.2 0.4 0.6 0.8 1

Figura 6.1: Ajuste por mnimos cuadrados de una serie de puntos Resolver un problema de mnimos cuadrados es en el fondo resolver un problema mal condicionado. Si se plantean las ecuaciones del problema llegamos a un sistema lineal mal condicionado. El criterio de resolucin suele ser el de minimizar el error cuadrtico de la solucin dada (por eso el nombre de mnimos cuadrados). Este es exactamente el mismo problema planteado en la pseudoinversa, operacin que tambin se realiza por mnimos cuadrados. Nada nos obliga a ajustar los datos mediante un polinomio; la condicin de minimizacin del error cuadrtico puede utilizarse con cualquier funcin aunque siempre ser ms sencillo hacerlo con polinomios. Una prctica muy habitual es utilizar un ajuste exponencial, tctica para la que Matlab no ha escrito ninguna funcin. El motivo es bien sencillo, si tenemos una nube de puntos que creemos sigue un modelo exponencial lo nico que debemos hacer es calcular el logaritmo de la serie de datos para lo que recuperaremos automticamente el ajuste polinmico.

CAPTULO 6. TOOLKITS

95

6.1.1.1. Qu calcula el ajuste polinmico por mnimos cuadrados?


Cuando hemos hablado de mnimos cuadrados en realidad nos referimos a los Mnimos Cuadrados Lineales Generales. El problema planteado es el de ajustar una serie de datos cualquiera a una funcin de la forma:

y (x) = a1 + a2 x + a3 x2 + . . . + aN xN 1
Este no es ms que el tipo ms sencillo de ajuste. Podramos utilizar tambin series de funciones armnicas o funciones arbitrarias de la forma

y (x) =
k=1
en las que expresin

ak Xk (x)

representa una base de funciones. El objetivo es minimizar el funcional error representado por la

=
i=1
donde

yi

N k=1

ak Xk (xi )

es la desviacin estndar de la muestra i-sima. Esta formulacin permite generar una matriz para una

aplicacin lineal:

Aij =
tan simple como una aplicacin lineal (ax sistema.

Xj (xi ) i

Matriz que posee muchas ms las que columnas. La buena noticia es que acabamos de generar un problema

= b),

la mala es que la matriz no es cuadrada y no servirn los mtodos

de resolucin convencionales. Una de las posibles estrategias de resolucin es utilizar una SVD para resolver el

6.2. Interpolacin y aproximacin de funciones


La aproximacin local o global de funciones es una parte esencial del clculo y del anlisis. Esta seccin supone que ya conocemos los desarrollos de Taylor o las transformadas de Fourier. Algunos de los mtodos planteados no son ms que la extensin discreta de mtodos comunes. Aunque no sea del todo riguroso dividiremos este tema en tres partes segn las caractersticas del desarrollo de nuestros datos. En clculo numrico siempre nos veremos obligados a describir una funcin de un modo discreto, ya sea por el valor que toman en algunos puntos o por los coecientes de un desarrollo. Dichas descripciones son ms o menos adecuadas segn la nalidad que busquemos. Hablaremos de la interpolacin polinmica a trozos cuando sean dados los valores de la funcin en unos puntos o nodos jos. Utilizaremos funciones sencillas para intentar hallar una funcin continua que pase por todos los puntos. Hablaremos de interpolacin polinmica cuando queramos modelar una funcin conocida o desconocida mediante funciones ms simples buscando el mnimo error posible. Se diferencia de la anterior en que nuestro dato es una funcin y no una serie de puntos, esto nos permitir escoger los nodos para buscar el mnimo error de interpolacin. Por ltimo trataremos a parte los desarrollos en serie de funciones sea cual sea la base (funciones armnicas, polinomios) En el primer caso buscaremos convertir unos datos de naturaleza discreta en una funcin continua, en el segundo y el tercer caso intentaremos describir una funcin de un modo discreto, ya sea por sus valores o por unos coecientes, por ejemplo para hallarla cuando es el resultado de una ecuacin en derivadas parciales. Los mtodos numricos no son exclusivos de cada uno de los objetivos, los splines, por ejemplo, sirven tanto para hallar una curva contnua como para describir una funcin mediante unos coecientes. El uso de estas distinciones es que Matlab se basa ms en la utilidad del mtodo numrico que en su naturaleza. Si queremos splines para interpolar utilizaremos una funcin distinta de la dedicada a hallar sus coecientes.

6.2.1. Interpolacin polinmica a trozos


La interpolacin polinmica a trozos ser para nosotros la tcnica de hallar una curva que pase por unos puntos dados. Se dice que es a trozos porque se utilizan polinomios de bajo orden denidos a intervalos.

interp1

Usa los puntos para interpolar en una dimension. Soprota interpolacin discreta, lineal, cbica, hermitiana

y por splines cbicos. Un ejemplo grco es el siguiente script:

Introduccin informal a Matlab y Octave

96

6.2. INTERPOLACIN Y APROXIMACIN DE FUNCIONES

xf=0:0.05:10;yf=sin(2*pi*xf/5); xp=0:10 ;yp=sin(2*pi*xp/5); lin=interp1(xp,yp,xf); spl=interp1(xp,yp,xf,'spline'); cub=interp1(xp,yp,xf,'cubic'); near=interp1(xp,yp,xf,'nearest'); title('Comparacion de las opciones de interp1') plot(xf,yf,xf,lin,xf,spl,xf,cub,xf,near) legend('real','lineal','splines','cubica','discreta')
Cuyo resultado es la gura 6.2.

1 real lineal splines cubica discreta 0.5

-0.5

-1 0 2 4 6 8 10

Figura 6.2:

Comparacin de los mtodos de interpolacin

interp2

Interpolacin polinmica bidimensional.

De entre todos los mtodos de interpolacin a trozos el ms efectivo suele ser siempre el uso de splines. Un spline es una curva cbica; de este modo reduciremos en gran medida el error en el caso que los puntos sean de una funcin

suave, cosa que no sabemos. Cuando interpolamos por trozos es importante conocer algo de informacin sobre la
funcin que representan, no sirve ninguna formula universal Sera muy lgico en este punto plantearse la siguiente pregunta. Por qu escoger una funcin denida a intervalos y no un nico polinomio de grado igual al nmero de puntos menos 1? La respuesta aparece cuando intentamos realizar el clculo. Los polinomios de alto orden tienen tendencia a oscilar en sus extremos, es el llamado fenmeno de Runge. Como patrn diremos que todo lo relacionado con polinomios de alto orden suele acarrear problemas. Trataremos con ms profundidad la interpolacin polinmica en un dominio nito en la seccin 6.2.3.

6.2.1.1. Splines
La interpolacin polinmica a trozos ms comn en Matlab es la interpolacin mediante splines. Un spline es una curva denida mediante polinomios en intervalos nitos, la interpolacin ser entonces del orden que deseemos segn el polinomio aunque lo ms frecuente ser utilizar splines cbicos. Como en muchos otros casos los splines no sirven nicamente para convertir en continua una serie de datos discreta, funcin que cumple en derivadas parciales. Para quien desee algo de rigor matemtico denimos un spline como el conjunto de polinomios ajustan una determinada funcin

interp1.

Pueden

servir tambin para analizar ms profundamente los datos estimando sus derivadas e incluso para resolver ecuaciones

f (x)

en

[a, b],

donde cada polinomio tiene validez en un intervalo

pj (x) que j [a, b].

Adems de imponer que la curva pase por todos los puntos podemos imponer tambin que dichos polinomios se unan suavemente al nal de sus intervalos de denicin. Podemos representar el conjunto mediante sus coecientes y los nodos ( pp form )

CAPTULO 6. TOOLKITS

97

pj (x) =
i=1

(x j )ki cij

o como B-spline, generalizacin de las curvas de Bzier. Matlab, en su spline toolkit, proporciona funiones para calcular y evaluar con toda libertad los coecientes de una interpolacin a trozos mediante splines, piecewise spline interpolation. Algunas de las funciones disponibles son las siguientes:

spline ppval csapi csape

Llamada con dos parmetros retorna la matriz de coecientes de la interpolacin. Llamada con tres par-

metros retorna el valor de la interpolacin en los valores dados. Evala la interpolacin mediante splines en los puntos dados dada su representacin en coecientes. Dene Dene

Un posible uso de los splines es la interpolacin de curvas en ms de una dimensin. Es un mtodo muy habitual en diseo y es la base de las herramientas de CAD con las NURBS (Non-Uniform Rational B-Splines). Mediante puntos de control y unas pocas transformaciones geomtricas los splines denen casi todas las piezas producidas industrialmente.

6.2.1.2. Regeneracin de funciones mediante datos discretos


Como ya hemos mencionado con anterioridad, uno de los problemas de tratar con series discretas de datos es precisamente su no continuidad. Hay varias maneras de pasar los datos a una funcin y hemos analizado que el ajuste polinmico no siempre es una buena opcin. Una solucin ms o menos universal es la de crear una funcin mediante una interpolacin y un function handle. Para ello slo tenemos que denir las series de datos y pasarlos como argumento a la vez que denimos una variable independiente adicional. Por ejemplo, suponemos que tenemos la siguiente serie de datos:

x=[1 2 3 4 5 6 7 8] y=[2 4 3 5 4 6 5 7]
Y queremos generar una funcin que sea capaz de proporcionar los datos de forma continua. La solucin es la creacin del siguiente function handle:

>> newfunc=@(z) interp1d([1 2 3 4 5 6 7 8],... [2 4 3 5 4 6 5 7],z,'spline');


A todos los efectos esto es una nueva funcin que pasa por todas las parejas de puntos

(x, y ):

>> newfunc(3.443) ans = 3.9162


La tcnica de reducir variables mediante function handles no es vlida en Octave, donde los FH son estrictamente funciones independientes.

6.2.2. Transformadas rpidas de Fourier


Un desarrollo posible de una funcin

periodica es el desarrollo de Fourier. En l las funciones ortogonales que


k .
El desarrollo de la funcin

nos sirven de base son funciones armnicas que llamaremos

es entonces:

k=

u=
k=
donde

u k .

son los coecientes de Fourier que

suelen ser nmeros complejos. Si la funcin admite el desarrollo


k= N 2 1

anterior tambin admitir una serie truncada de fourier. Esta serie tiene la forma:

PN u =
k= N 2

u k eikx

Introduccin informal a Matlab y Octave

98

6.2. INTERPOLACIN Y APROXIMACIN DE FUNCIONES

que constituye la serie truncada de Fourier de orden

N.

Los coecientes se calculan exactamente del mismo modo

que la anterior con la diferencia que truncamos el desarrollo a partir de un cierto nmero de onda. En el clculo numrico nunca trabajaremos con desarrollos con una cantidad innita de trminos; esto es dominio del clculo simblico. Si aproximamos la funcin inicial por un polinomio interpolante denido a partir de una serie de puntos llegamos a la serie discreta de Fourier. Se dice discreta porque tiene como datos los puntos en los que se evale la funcin. Exactamente del mismo modo podramos estar trabajando con una serie de puntos experimentales. Esto generar un desarrollo discreto porque slo con unos cuantos puntos no tenemos suciente informacin como para llegar a una serie innita. Como estamos obteniendo toda la informacin posible normalmente se habla de transformada discreta de Fou-

rier. El algoritmo para calcularla es la t ansformada rpida de Fourier o Fast Fourier Transform (FFT).

t it

Aplica la transformada rpida de Fourier a una serie de puntos utilizando como funciones base Calcula la antitransformada rpida de Fourier.

x (x) = eikx .

Las t's se usan muchsimo en los mtodos espectrales, resolucin de ecuaciones en derivadas parciales lineales y no lineales, anlisis de datos y ltrado de seales. Muchos de los problemas de la fsica con condiciones de contorno periodicas son mucho ms sencillos en su formulacin espectral. madas de fourier

Disponemos tambin de otras funciones que encapulan tareas comunes en las que estn involucradas transfor-

tshift tlt t2 tn

Mueve el primer nmero de onda (frecuencia cero) al centro del espectro.

Aplica directamente un ltro espectral.

Transformada rpida de Fourier bidimensional. Tambin disponemos de una antitransformada para esta funcin Transformada rpida de Fourier n-dimensional. Existe

ifftn.

Las libreras de transformadas rpidas de Fourier suelen disponer de transformadas del seno y del coseno para cubrir los casos de condiciones de contorno no periodicas. Los drivers para estas bibliotecas no son tan completos en Matlab y tendremos que convertir la transformada exponencial en transformada de seno o de coseno manualmente.

6.2.3. Aproximacin de funciones


Esta tcnica, aunque coceptualmente muy parecida a la interpolacin polinmica a trozos, suele tener usos completamente distintos. La aproximacin de una funcin o de una serie de puntos por un nico polinomio en un dominio dado se acerca ms al desarrollo en serie de Fourier que a la interpolacin polinmica a trozos. Los polinomios de Lagrange, de Legendre o de Chebyshev fueron creados para desarrollar funciones continuas en dominios nitos mediante una base polinmica. Tienen un uso esencial en la evaluacin de funciones complejas en dominios nitos y en los mtodos espectrales de resolucin de ecuaciones en derivadas parciales. La interpolacin polinmica no suele utilizarse para ajustar una serie de puntos dados por culpa del fenmeno de Runge. Supongamos que tenemos la siguiente serie de puntos

en funcin otra serie equiespaciada de puntos

x.

1 La
de

gran ventaja de las transformadas rpidas de Fourier es que son una operacin especialmente rpida cuando tenemos series

2n

puntos. En estos casos se hacen del rden de

N log N

operaciones para calcularla. Esto las hace muy tiles en la resolucin de

ecuaciones en derivadas parciales lineales (ecuacin de ondas) o por mtodos espectrales. Un caso especialmente importante es el de la ecuacin de Poisson (2

= f (x)).

Supongamos que tenemos las ecuaciones de Navier-Stokes en dos dimensiones. Se demuestra que se pueden reescribir en funcin de

y de

la vorticidad y la funcin de corriente de la siguiente manera:

1 2 + = t x y y x Re 2 =
Imaginemos entonces que queremos resolver un problema de turbulencia 2D istropa con condiciones de contorno peridicas. Esto nos obliga a resolver una ecuacin de Poisson por cada paso temporal, operacin bastante costosa porque requiere la inversin de una matriz. Podemos ahorrarnos gran cantidad de operaciones si hacemos la transformada de Fourier de la segunda ecuacin:

(i, j ) exp((kx + ly )) (i, j ) exp((kx + ly )) 2 2 + = exp((kx + ly )) 2 x y 2 (i, j )(k2 + l2 ) = (i, j )


Que es un sistema de ecuaciones de resolucin trivial. Acto seguido hacemos la antitransformada de los coecientes pasar al paso de la ecuacin parablica.

(i, j ) y ya podemos

CAPTULO 6. TOOLKITS

99

x = Columns 1 through 8: -1.00000 -0.87500 -0.75000 Columns 9 through 16: 0.00000 0.12500 0.25000 Column 17: 1.00000 y = Columns 1 through 8: 0.058824 0.075472 0.100000 Columns 9 through 16: 1.000000 0.800000 0.500000 Column 17: 0.058824

-0.62500 0.37500

-0.50000 0.50000

-0.37500 -0.25000 0.62500 0.75000

-0.12500 0.87500

0.137931 0.307692

0.200000 0.200000

0.307692 0.500000 0.137931 0.100000

0.800000 0.075472

Supongamos ahora que queremos ajustarla por un polinomio de grado de la serie. El polinomio ser entonces:

N 1

suponiendo

el nmero de puntos

p(x) =
i
problema que se cerrar con la condicin de que

ai xi1
Al nal se llega a la misma ecuacin de siempre:

p(xi ) = yi .

Ac = y
donde

es la matriz de Vandermonde generada con los puntos

xi , c

el vector de incgnitas de los coecientes y

el vector de puntos de la serie

yi .

El vector de coecientes se genera con este cdigo:

>> c=vander(x) \y' c = 6.4739e+03 3.6848e-11 -2.1040e+04 -1.0123e-10 2.7271e+04 1.0430e-10 -1.8231e+04 -5.0934e-11 6.8268e+03 1.2373e-11 -1.4741e+03 -1.4184e-12 1.8795e+02 6.5051e-14 -1.5402e+01 -8.4500e-16 1.0000e+00
Si representamos este polinomio de orden 16 con los puntos que tiene interpolar junto con la funcin solucin

y (x) =

1 1+16x2 (gura 6.3): Como vemos, la funcin interpolante cumple los requisitos impuestos, pasa por todos los puntos; pero no hace

nada ms bien. Cul es entonces el problema? Qu hay que hacer para solucionarlo? La interpolacin polinmica es un problema global, es decir, intenta aproximar toda una funcin con una cantidad limitada de datos (los puntos de los que tenemos valores). A la funcin interpolante los rboles no le dejan ver el bosque, si quiere ajustar con unos puntos dados (nodos) es incapaz de capturar la funcin de la que provienen. La solucin es comprender las implicaciones globales del problema. Ya no estamos intentando hacer pasar una curva por una serie de puntos, estamos intentando resolver la aproximacin de la misma curva. La solucin la encontramos desde el punto de vista global... Por qu los nodos deben ser equiespaciados? Y si acercamos los nodos entre ellos (clustering) en las zonas donde los errores son ms elvados? Sean cuales sean los tipos de polinomios que utilicemos as como el orden del que sean hay nodos ms adecuados para minimizar el error del problema global, por ejemplo los nodos de Chebyshev de la forma:

xj = cos(j/N ),

j = 0, 1, ..., N
Introduccin informal a Matlab y Octave

100

6.3. RESOLUCIN DE ECUACIONES NO LINEALES Y OPTIMIZACIN.

nodos real interpolacion

0.8

0.6

0.4

0.2

-1

-0.5

0.5

Figura 6.3: Demostracin del fenmeno de Runge

puntos de Chabyshev-Lobatto o puntos extremos de Chebyshev. Esta formula es la proyeccin de los puntos equiespaciados en una circunferencia de radio unidad en el eje de abcisas. Si ahora en vez utilizar los nodos equiespaciados utilizamos los nodos ptimos de Chebyshev llegamos a que el polinomio de interpolacin es sensiblemente mejor (gura 6.4):

nodos real interpolacion

0.8

0.6

0.4

0.2

-1

-0.5

0.5

Figura 6.4: Uso de los nodos ptimos de Chebyshev para reducir el error de interpolacin Vemos entonces que recurrir a una eleccin ptima de nodos permite utilizar polinomios como base de desarrollos de funciones con un error ms que aceptable con todas las ventajas que implica trabajar con polinomios en nuestros clculos.

Importante:

La interpolacin polinmica es un problema global. No depende nicamente del nmero de puntos

sino de su eleccin. Una demostracin de hasta dnde llega la importancia de elegir bien los nodos es pensar que el error que se comete con un polinomio de grado mayor no necesariamente se reduce con lo que estamos malgastando tiempo y potencia de clculo sin ganar precisin. Hay que hacer las cosas con cuidado.

6.3. Resolucin de ecuaciones no lineales y optimizacin.


Este apartado merece un pequeo comentario de entrada. Matlab posee una ms que amplia seleccin de funciones orientadas a la optimizacin. Matlab contiene funciones para hacer casi todo lo imaginable como buscar ceros de funciones n-dimensionales y no lineales, mnimos de funciones condicionados, programacin cuadrtica...

CAPTULO 6. TOOLKITS

101

El gran problema es que todas estas herramientas estn en un toolkit que no forma parte de la instalacin bsica del programa. En el caso que estemos delante de una versin comercial o de estudiante del Matlab es posible que no dispongamos de ninguna de las funciones anteriormente mencionadas. No tiene mucho sentido entrar los detalles del Optimization Toolkit porque la ayuda en formato HTML que se incluye en el paquete es ms que suciente. Se podra decir que es una buena introduccin a la optimizacin en general. Este tema es difcil de encajar en el planteamiento general del libro. Siempre hemos buscado un planteamiento agnstico respecto a los dos intrpretes muy difcil de mantener en este caso. Octave slo contiene las funciones bsicas de optimizacin, la coleccin es pobre si se compara con el Optimization Toolkit; pero en la mayora de los casos es ms que suciente. Veremos entonces slo una introduccin bsica a la optimizacin, minimizacin de funciones, programacin lineal y no lineal y bsqueda de races de sistemas de ecuaciones no lineales.

6.3.1. Resolucin de ecuaciones no lineales. Root nding.


La resolucin de sistemas de ecuaciones no lineales podra considerarse como una disciplina independiente de la optimizacin. Algunos de los mtodos de resolucin no tienen absolutamente nada que ver con los algoritmos de minimizacin de funciones. Sin embargo hemos decidido mantener un rden consistente con el de los paquetes de funciones de Matlab. Root nding es el trmino ingls para la prctica de la resolucin de una ecuacin que no tiene una solucin analtica o con una solucin exacta demasiado costosa de encontrar. Fue uno de los primeros casos en los que se aplic el clculo numrico porque es donde se hace imprescindible. Todos los mtodos se basan en la aproximacin mediante un desarrollo en serie de la funcin en un punto inicial. Lo que los diferencia es el tipo de desarrollo y cmo aproximan la funcin en el punto. El mtodo ms bsico de todos es el mtodo de Newton que se basa en la aproximacin lineal de la funcin en cada punto para obtener la siguiente raz para iterar. El mtodo de la secante no es ms que una aproximacin grosera de la derivada mediante dos puntos. Luego nos encontramos con los mtodos Regula-falsi, Ridders... o ms sosticados como el

Van Wijngaarden-Dekker-Brent.
Todos los mtodos se usan de la misma manera, se les da una funcin, un punto inicial y se cruzan los dedos. Lo nico que debemos saber del Root nding en Matlab es que todo lo lleva la funcin...

fzero

Busca la solucin ms cercana al punto inicial dado de cualquier ecuacin dada.

Lo nico que debemos recordar es que como cualquier funcin a la que hay que dar otra funcin como argumento nos obligar a utilizar un function handle. Por ejemplo, queremos encontrar el cero de la siguiente ecuacin:

ln x sin x = 0
Esta ecuacin no tiene una solucin analtica con lo que el uso del clculo numrico se hace imprescindible. Suele ayudar representar grcamente las dos funciones (gura 6.5) para saber si se cruzan en algn punto; si buscamos una solucin inexistente es probable que el mtodo nos devuelva soluciones complejas o espreas. La funcin que se resolver ser siempre de la forma

f (x) = 0,

de modo que nuestro function handle ser:

>> eq=@(x) log(x)-sin(x); >> sol=fzero(eq,1); >> sol sol = 2.2191


que es consistente con la solucin intuida basndonos en la grca. Una ms que buena prctica es pedir una solucin dentro de un intervalo puesto que en muchos casos las ecuaciones no lineales pueden tener varias e incluso innitas soluciones. Slo hay que cambiar el punto inicial de iteracin por un intervalo de bsqueda:

>> eq=@(x) log(x)-sin(x); >> sol=fzero(eq,[1 4]); >> sol sol = 2.2191
Introduccin informal a Matlab y Octave

102

6.3. RESOLUCIN DE ECUACIONES NO LINEALES Y OPTIMIZACIN.

1.5

1.0

0.5

0.0

-0.5

-1.0

-1.5

Figura 6.5: Representacin de las funciones a resolver.

6.3.1.1. Ms incompatibilidades entre Matlab y Octave.


En la versin 2.1 de Octave el soporte para los function handles es bastante limitado. Muchas de las funciones, sobretodo las que no son ms que llamadas a rutinas en fortran o C, deben obtener las funciones por su nombre y no mediante un function handle. La funcin

fzero

en Octave es una vctima bastante desafortunada de esta

limitacin. Si intentamos resolver la ecuacin anterior por el primer mtodo propuesto recibiremos un error, a priori incomprensible, mientras que con el segundo script llegaremos a la solucin. El motivo es el extico comportamiento de a la funcin

fsolve

fsolve

en Octave. Si le pasamos slo un parmetro,

de la que hablaremos en el siguiente apartado.

fsolve

fzero

llamar

no tiene soporte para function handles

de modo que tendremos que pasarle la funcin por su nombre despues de haberla denido, por ejemplo:

>> function y=eq(x) ... y=log(x)-sin(x); ... end >> fzero('eq',1) ans = 2.2191
Tampoco es una gran dicultad aadida ya que Octave soporta la denicin de funciones mediante el intrprete a diferencia de Matlab. En cambio, si denimos un intervalo de bsqueda de soluciones s le podremos pasar un function handle como argumento porque usa un mtodo de resolucin alternativo :

>> eq1=@(x) log(x)-sin(x); >> fzero(eq1,[1,4]) ans = 2.2191

6.3.2. Bsqueda de soluciones de sistemas de ecuaciones no lineales.


Se dene como solucin de un sistema de ecuaciones como la

que cumple:

f (x) = 0
siendo

la funcin vectorial representa al sistema.

El objetivo de la bsqueda de soluciones de sistemas de ecuaciones no lineales es siempre el mismo. Llegar a una solucin vlida del sistema con el mnimo coste computacional posible. La no linealidad de las ecuaciones puede provocar todo tipo de catstrofes como la no convergencia o que el error se dispare hacia el innito. Siempre se

2 fsolve

utiliza el mtodo Powell mientras que

fzero

utiliza un mtodo Brent.

CAPTULO 6. TOOLKITS

103

parar automticamente la iteracin y se nos dar un mensaje de error. El coste computacional es una complicacin menor. Depende de dos aspectos, la eleccin del punto inicial y el algoritmo de evaluacin del gradiente de la funcin. Los mtodos ms sencillos de resolucin de ecuaciones no lineales se basan en la aproximacin lineal de la funcin en un punto. Si hacemos el desarrollo de Taylor de primer orden en el punto inicial tenemos que:

f (x) = f (x0 ) + (x x0 )J(x0 )


frmula a la que le siguen trminos de mayor rden.

J(x0 )

es el gradiente de la funcin evaluado en el punto

x0 .

Si suponemos que el resultado de la aproximacin es la verdadera raz de nuestra funcin:

f (x0 ) + (x x0 )J(xo ) = 0
obtendremos el siguiente punto de la iteracin, en este caso

x = x1 :

x1 = x0 J1 (x0 )f (x0 )
Iteracin que se llevar a cabo hasta que se una norma de la solucin sobrepase una cota de error. Este mtodo es conocido como Newton-raphson. Esto nos recuerda que una de las operaciones con mayor coste computacional es precisamente la inversin de una matriz. Adems la matriz es el gradiente de la funcin en un punto, gradiente que puede ser en algunos casos casi imposible de calcular. Nos encontramos ante el problema de evaluar de una manera ptima un gradiente para luego evaluarlo e invertirlo. Todo esto considerando que el punto inicial nos lleve ms o menos directamente a la solucin que buscamos. Nada de esto debe hacernos perder la referencia de que lo realmente importante de los mtodos de resolucin es la facilidad con la que converjan a una solucin ms que la rapidez con que lo hagan. Al igual que en el caso unidimensional, Matlab apuesta por la simplicidad. La funcin que nos realizar la tarea es:

fsolve

Busca una solucin de un sistema de ecuaciones dado. Esta funcin es diferente segn se use en Matlab o en

Octave; la versin de Matlab llamar al sistema de ecuaciones mediante su nombre o con un function handle mientras que la versin de Octave slo podra llamarlo por nombre. Las diferencias entre ambas slo se maniestan en el modo en el que llamaremos a la funcin, no en el modo en el que la deniremos porque es imposible expresar todo un sistema de ecuaciones slo con un function handle. Ser imprescindible denir una funcin propiamente dicha lo que en Matlab signicar crear un archivo de funcin.

6.3.2.1. Algunas de las cosas que pueden salir mal


Resolver ecuaciones escalares no lineales o sistemas de ecuaciones no lineales no es numricamente muy complejo, pero los problemas son muy a menudo mal condicionados. Innidad de factores pueden llevarnos a soluciones errneas o a problemas de convergencia. Algunos de ellos son muy simples como el siguiente:

>> eq=@(x) log(x)-sin(x); >> fzero(eq,[0 4]) Warning: Log of zero. > In @(x) log(x)-sin(x) In fzero at 218 ??? Error using ==> fzero Function values at interval endpoints must be finite and real.
Obviamente debido a que

ln 0 = .

Otros problemas debidos a la convergencia pueden ser un autntico dolor de cabeza

6.3.3. Minimizacin de funciones.(+) 6.3.4. Minimizacin de funcionales.(+)

Introduccin informal a Matlab y Octave

104

6.3. RESOLUCIN DE ECUACIONES NO LINEALES Y OPTIMIZACIN.

CAPTULO 7
Temas avanzados
Este captulo nace de la necesidad de recojer todos los argumentos no necesariamente ligados al uso de Matlab. La mayora de ellos estn relacionados con la programacin general o en clculo numrico, sin embargo son de gran utilidad para escribir buenos programas. La teora que contiene este captulo es de un nivel mucho ms elevado al resto, estais avisados; esto no signica que todo est explicado del modo ms sencillo posible.

7.1. Aumentar la calidad del cdigo escrito en Matlab


Que el cdigo funcione no suele ser suciente. Debemos intentar en cualquier caso escribir cdigo de calidad, debemos convertir en hbitos ciertas prcticas de programacin orientadas a hacer ms fcil el uso de las funciones y los scripts. No todo termina en escribir una pequea ayuda en cada funcin. Hay estrategias muy tiles para aumentar signicativamente la potencia del cdigo escrito sin necesidad de aumentar el esfuerzo. Debemos entender que si Matlab es una plataforma de desarrollo rpido de aplicaciones dispondr de funciones para escribir cdigo de un modo ms eciente.

7.1.1. Vectorizar, la clave para aumentar la velocidad


Hay muchas maneras de asignar un argumento a una variable. Cuando se crearon los ordenadores y empezaron a surgir los lenguajes de programacin casi todos los procesos eran escalares. Todo estaba gobernado por operaciones lgicas que operaban unidades muy pequeas de memoria. A medida que los ordenadores iban creciendo en potencia y versatilidad se empez a pensar en una manera ms eciente de calcular. Uno de los conceptos era la vectorizacin.

Se dice que una operacin es escalar cuando se hace elemento a elemento. Una suma escalar de dos vectores es tomar los elementos de cada uno de ellos, sumarlos y asignar el resultado a un tercer vector. Una operacin es vectorial cuando se hace por bloques mayores en la memoria. Una suma vectorial de dos vectores sera tomar partes del los vectores o los vectores enteros y sumarlos de golpe. Los compiladores modernos son capaces de vectorizar automticamente. Advierten que dos bucles pueden combinarse perfectamente y realizan la operacin por bloques ahorrando memoria y tiempo de clculo. Como Matlab es un programa secuencial carece de esta capacidad de optimizacin. Si nosotros le pedimos un bucle con operaciones escalares lo va a realizar sin ningn tipo de optimizacin. Si en cambio asignamos operamos las matrices mediante la notacin matricial y las submatrices Matlab s va a ser capaz de vectorizar la operacin. En la seccin 7.1.1.1 explicaremos la importancia que todas estas consideraciones tienen sobre la velocidad de ejecucin.

7.1.1.1. El truco ms importante de la programacin en Matlab


El truco ms importante para que nuestros scripts tengan una velocidad aceptable es evitar los bucles con contador. Es la estructura ms lenta que existe en el lenguaje. El siguiente ejemplo nos ayudar a entenderlo perfectamente. Crearemos dos matrices de nmeros aleatorios y las sumaremos creando una tercera matriz. Primero lo haremos mediante un bucle que sume con dos ndices y luego utilizando el operador suma elemento a elemento. Utilizaremos la funcin

rand

para crear las matrices y la pareja

tic

toc

para calcular el tiempo de clculo.

Un nombre propio en la arquitectura de ordenadores es Seymour Cray, su biografa est ntimamente ligada al los ordenadores

vectoriales. Su inuencia es tremenda en el campo de la computacin a gran escala.

105

106

7.1. AUMENTAR LA CALIDAD DEL CDIGO ESCRITO EN MATLAB

>> a=rand(66); #matriz de 66 x 66 >> b=rand(66); >> tic;for i=1:66;for j=1:66;c(i,j)=a(i,j)+b(i,j);end;end;toc ans = 0.17925 >> tic;c=a.+b;toc ans = 0.00058100
Donde el nmero que obtenemos como resultado es el tiempo transcurrido entre la llamada de diferencia entre los dos mtodos es de :

tic

y la de

toc.

La

>> 0.17925/0.00058500 ans = 306.41


Utilizar los operadores matriciales y las submatrices generar cdigo del orden de 100 veces ms rpido. Para una EDP esto es la diferencia entre un rato de espera y una semana de clculos, slo un contador mal puesto puede acabar con un cdigo globalmente bien escrito. La lentitud de los bucles llega hasta lmites insospechados. Supongamos que queremos multiplicar todas las las de una matriz por un escalar distinto. En un alarde decidimos convertir la serie de nmeros en un vector y utilizar un bucle contador para operar la matriz por las del siguiente modo:

>> a=1:66; >> b=rand(66); >> tic;for i=1:66;c(i,:)=a(i)*b(i,:);end;toc ans = 0.0032920


Para eliminar este bucle tenemos que convertir la secuencia de nmeros en una matriz de

6666 y luego multiplicarla

por una matriz. Qu sorpresa nos llevamos cuando observamos que el tiempo de proceso es menor:

>> tic;c=a'*ones(1,66).*b;toc ans = 0.00067000


Eliminando un bucle que pareca completamente justicado acabamos de reducir el tiempo de proceso a la dcima parte. A partir de ahora nos lo pensaremos dos veces antes de escribir la palabra

for.

Si nos acostumbramos pensar

con submatrices nos ahorraremos tiempo de clculo y la engorrosa tarea de migrar cdigo a Fortran intilmente.

7.1.1.2. Por qu son tan lentos los bucles?


Lo que hace que los bucles sean tan lentos no es nicamente la ausencia de vectorizacin en el clculo. Los bucles escalares son muy rpidos sea cual sea la arquitectura y el lenguaje de programacin. Si analizamos con un poco ms de precisin el cdigo de los ejemplos anteriores observamos que no slo se estn multiplicando dos matrices o dos escalares, adems se est reservando la memoria correspondiente al resultado. Imaginemos que queremos sumar dos vectores y asignar el resultado a un tercero y que para ello utilicemos un bucle. Primero tomaremos el los primeros ndices de cada vector y los situaremos en una posicin de memoria nueva. Esto suceder a cada paso con lo que cada iteracin implicar una operacin de reserva de memoria al nal de un vector. Cada vez que ampliamos un vector llenando una posicin vaca Matlab debe comprobar que el elemento no existe, ampliar la memoria reservada al vector para poder situar el nuevo elemento donde debe y rellenar el resto con ceros y nalmente almacenar los datos del nuevo vector. Cuando sumamos dos vectores escalarmente el ciclo de vericacin-reserva -asignacin-cierre se realiza una sola vez. Podemos concluir entonces que la operacin de ampliacin de una matriz en Matlab es especialmente lenta. Aunque no estemos obligados a declarar las variables antes de inicializarlas es siempre una buena prctica comprobar que cada matriz se dena entera o mediante bloques lo sucientemente grandes. Este comportamiento est ligado al funcionamiento de los arrays en C; un buen texto para comprenderlo mejor es [3] donde encontraremos un captulo inicial sobre qu es verdaderamente un array y qu relacin tiene con un puntero. Como curiosidad diremos que mientras las operaciones de reserva y liberacin de memoria son bastante lentas, las operaciones de manipulacin de forma como la funcin de ejecucin.

reshape

son especialmente rpidas. No debemos tener

miedo a cambiar la forma de las matrices segn nuestras necesidados pensando que estamos sacricando tiempo

2 El

ordenador con el que han sido efectuadas las pruebas es un Athlon XP 2600+ (1.920 GHz, bogomips=3301.37) con 512 Mb de

RAM a 400 MHz y Octave 2.1.72. Matlab es ligeramente ms rpido con el manejo de bucles aunque de ningn modo se acerca a la velocidad de los operadores matriciales. Con la optimizacin mxima Matlab y Octave tienen resultados equivalentes. Las pruebas se han efectuado diez veces y se da el tiempo medio de la muestra.

CAPTULO 7. TEMAS AVANZADOS

107

7.1.2. Control de las variables de entrada y salida en funciones.(+)


La necesidad de pasar una cantidad ja de argumentos a una funcin en forma de variables no es una limitacin para Matlab. Uno de los puntos dbiles de la denicin de las cabeceras de las funciones es que no pueden denirse, tal como lo hacen otros lenguajes de programacin, valores por defecto para las variables de entrada. Matlab cuenta con la siguiente serie de funciones dedicadas a manipular las variables de entrada y salida de las funciones:

nargin Da el nmero de argumentos con el que se ha llamado una funcin nargoun Retorna el nmero de argumentos de salida de una funcin varargin Permite que las funciones admitan cualquier combinacin de argumentos de entrada. varargout Permite que las funciones adimitan cualquier combinacin de argumentos de salida. inputname Retorna el nombre de la variable que se ha pasado como argumento de entrada en una funcin.
nargout
reciban, Estas funciones son una ayuda esencial cuando escribimos funciones muy polivalentes. Los mtodos

nargin

varargin y varargout hacen que no tengamos que preocuparnos de escribir largas cabeceras de funciones

sirven para que las funciones se comporten de un modo distinto segn la cantidad de argumentos que

cuando estas reciben muchos argumentos, es como si recibiera una variable tipo celda de un modo automtico.

7.1.3. Comunicacin entre el entorno de ejecucin global y el entorno de la funcin


En el lxico utilizado por Matlab se habla de dos entornos de ejecucin o workspaces. Existen slo dos workspaces en los que habitan varibles inicialmente independientes. El modo usual de comunicar los dos entornos es mediante variables globales, una vez denimos una variable como global en todos los workspace la hacemos visible para todas las unidades de programa. Matlab dene dos workspace, base y caller. Base es el nombre del entorno de ejecucin principal; sera el intrprete en una sesin interactiva. Caller es la funcin que se est activa en algn momento de la ejecucin. Los dos mtodos siguientes son interfaces entre las variables en base y las variables en caller.

evalin

Evalua una variable o una expresin en cualquier entorno.

Por ejemplo, vamos a crear una funcin que intente capturar una variable del entorno de ejecucin principal en una funcin. Para ello escribiremos la siguiente funcin:

function out=testfunc() out=evalin('base','dummy');


Ahora en una sesin del intrprete deniremos la variable

evalin

var

y veremos cmo queda capturada por la sentencia

sin que aparezca en la cabecera:

>> testfunc() error: `dummy' undefined near line 23 column 1 error: evaluating assignment expression near line 2, column 4 error: called from `testfunc'
Nos ha dado un error porque an no hemos denido la variable variable y llamamos la funcin:

dummy

en el entorno base. Si ahora denimos la

>> dummy='hola' >> testfunc() ans = hola


Acabamos de comuncar de un modo bastante elegante los dos entornos de ejecucin. Los programadores experimentados estn acostumbrados a lidiar con los punteros. nos podemos imaginar esta funcin como una manera razonable de emular el comportamiento de un puntero

3 y as aadir algo de potencia a nuestros algoritmos. No ser

literalmente un puntero porque en vez de apuntar una posicin de memoria apuntar a una variable pero como es la manera normal de denir los punteros podemos hacer que se comporte del mismo modo. Por ejemplo, en el caso anterior hemos denido una funcin que extrae el valor Qu sucede si cambiamos la variable

dummy.
3 Un

dummy?

out

que apunta al valor contenido en la variable

Pues que en tiempo de ejecucin la variable

out

cambiar

inmediatamente de valor:
puntero es un tipo especial de variable cuya misin es apuntar a una direccin de memoria, normalmente expresada por

otra variable. El puntero no es una variable convencional, es loscamente algo distinto. el contenido de una variable slo podemos cambiarlo nosotros, en cambio el valor al que apunte el puntero puede cambiar si as lo exige la ejecucin. El concepto de un puntero es abstracto y requiere comprender qu es una posicin en la memoria fsica de un ordenador. Es un concepto interesante y requiere comprenderlo.

Introduccin informal a Matlab y Octave

108

7.2. ARRAY MASKING(+)

>> dummy='adios' dummy = adios >> testfunc() ans = adios


Vemos que esto no es exactamente una asignacin de una misma posicin de memoria pero la ejecucin emula el mismo comportamiento, es como hacer un

out==dummy

implcito.

assignin

Asigna un valor dado a una variable de cualquier entorno de ejecucin.

Estas dos funciones es el mtodo recomendado para establecer una comunicacin entre el entorno de ejecucin de las funciones y el entorno principal. Se sugiere sacricar el uso de las variables globales en favor de la asignacin y la evaluacin entre workspaces. Sin embargo es una sutileza sujeta al estilo de programacin. Personalmente encuentro las variables globales mucho ms intuitivas.

7.2. Array Masking(+)


lgicas solemos utilizar una estructura condicional (if). Cuando dichas condiciones lgicas adquieren un alto grado de complejidad, con ms de seis o siete opciones que pueden ser complementarias entre ellas, la implementacin de la estructura suele ser harto complicada. En programacin suelen evitarse este tipo de estructuras, son lentas, difciles de programar, difciles de entender y propensas a generar errores en tiempo de ejecucin que cuesta bastante resolver. En otros lenguajes de programacin los defectos de forma suelen ser los ms importantes pero ya hemos aprendido que en Matlab es una buena prctica programar con la velocidad en mente. Una solucin especialmente eciente es ver que los grupos de nmeros binarios son un conjunto no intersectado en los que las operaciones de adicin, sustraccin y combinacin lgicas son triviales. Esto sirve para constuir encima de cada matriz una mscara lgica que permite asignar una etiqueta a cada elemento de la matriz. Cuando necesitamos controlar el ujo de ejecucin de un programa y este ujo necesita ciertas condiciones

7.3. Introduccin al debbugging


La traduccin de la palabra debugging es quitar los bichos. Un bug o bicho es un error en el cdigo, sus efectos pueden ser evidentes o sutiles y la tarea de encontrarlos es mucho ms complicada que eliminarlos. Los debuggers son programas especiales para esta tarea de uso en lenguajes compilados. Lo que hacen es ejecutar los procesos paso a paso para conocer su funcionamiento de un modo ms interactivo. Matlab ya es en s mismo interactivo pero algunas herramientas del debugging clsico sern tiles en programas muy grandes. El debugging se basa en los breakpoints que no son ms que puntos en los que podemos detener la ejecucin del programa para analizar su estado actual. La posicin de los breakpoints es ms una labor de experiencia que una ley tanto en los lenguajes compilados como interactivos. Solemos poner uno antes de llamar una funcin y unos cuantos antes de que aparezca el error. El editor de Matlab es adems el interfaz para el debugger. Podremos poner y quitar los breakpoints con el ratn y recuperar el control del proceso con la consola. Pero cuando uno se siente cmodo con el debugging preere realizar todo el proceso manualmente mediante las funciones propias. Estas funciones son casi las mismas en Matlab y Octave.

keyboard

Esta palabra clave no es parte del debugging en sentido estricto pero puede ser muy til para resolver

errores del cdigo. Si introducimos esta funcin en un programa pararemos su ejecucin y pasaremos a tener el control en el punto de ejecucin donde nos encontremos. Se abrir un intrprete mediante el cual accederemos al estado actual del programa para poder acceder a las variables de modo interactivo. Una vez salgamos del intrprete continuaremos la ejecucin conservando los cambios que hayamos introducido. Este es el modo ms sencillo de hacer debugging en scripts porque las funciones para debugging clsicas slo operan dentro de funciones.

echo

Traducido eco. Controla si los comandos en archivos aparecen o no en pantalla. Esta sentencia slo tiene efecto dentro de un archivo o de una funcin. Normalmente los comandos ejecutables de funciones y scripts no aparecen en pantalla, slo aparece su resultado si no hemos puesto un punto y coma al nal de la lnea. Con

echo on los comandos de los scripts se escriben como si los hubieramos introducido a travs del intrprete.

on Activa el eco en los scripts off Desactiva el eco en los scripts on all Activa el eco en scripts y funciones off all Desactiva el eco en scripts y funciones

CAPTULO 7. TEMAS AVANZADOS

109

type

Saca por pantalla el texto correspondiente a cualquier funcin que est en el rbol de directorios dentro de un archivo no abrir el archivo con el editor.

.m. Es til cuando disponemos de una coleccin propia de funciones bastante extensa y preferimos polyadd.m
que implementa la suma de

Como ejemplo del uso de las funciones de debugging utilizaremos el script dos polinomios. Las rutinas bsicas para el debugging de funciones son:

dbtype

Muestra la funcin con los nmeros de lnea para facilitar la inclusin de breakpoints

Para usarlo con nuestra funcin sera

>> dbtype polyadd 1 function poly=polyadd(poly1,poly2) 2 if (nargin != 2) 3 usage('polyadd(poly1,poly2)') 4 end 5 if (is_vector(poly1) && is_vector(poly2)) 6 if length(poly1)<length(poly2) 7 short=poly1; 8 long=poly2; 9 else 10 short=poly2; 11 long=poly1; 12 end 13 diff=length(long)-length(short); 14 if diff>0 15 poly=[zeros(1,diff),short]+long; 16 else 17 poly=long+short; 18 end 19 else 20 error('both arguments must be polynomials') 21 end
Ahora queremos colocar dos breakpoints, uno en la lnea 14 y otro en la lnea 16. Para ello usaremos la siguiente funcin:

dbstop(func,line)

Introduce un breakpoint en una funcin.

>> dbstop('polyadd','14') ans = 14 >> dbstop('polyadd','16') ans = 17


Fijmonos que la funcin no nos ha dejado poner el breakpoint en la lnea 16 porque no es ejecutable. Para comprobar el estado de la funcin:

dbstatus

Devuelve un vector cuyos elementos son las lneas con breakpoints.

>> dbstatus polyadd ans = 14 17


Ahora utilizamos la funcin del modo usual. La ejecucin avanzar hasta que encuentre un breakpoint, entonces se abrir una consola que nos dar el control de la ejecucin.

>> polyadd([3,2,1,3],[3,2,0]) polyadd: line 14, column 8 diff debug>


La consola

debug

es local, es decir, slo contiene las variables de la ejecucin de la funcin. Lo ms lgico en este

punto es utilizar la funcin

who

para saber qu variables han sido iniciadas:

Introduccin informal a Matlab y Octave

110

7.4. EXTENDER OCTAVE CON OTROS LENGUAJES.

debug> who *** local user variables: __nargin__ argn long __nargout__ diff poly
Aprovechamos para conocer algunas de ellas:

poly1 poly2

short

debug> long long = 3 2 1 3 debug> poly1 poly1 = 3 2 1 3 debug> poly2 poly2 = 3 2 0 debug> __nargin__ __nargin__ = 2 __nargin__
es el nmero de argumentos de entrada. Si salimos de la consola avanzaremos hasta el siguiente breakpoint o nalizaremos la ejecucin. En este caso llegaremos hasta la lnea 17. Para eliminar alguno de los breakpoints:

dbclear(func,line)

Elimina el breakpoint de la lnea solicitada.

>> dbclear('polyadd','17') polyadd symbol_name = polyadd >> dbstatus polyadd ans = 14


Hay ms comandos para debugging pero estos son los ms importantes.

7.4. Extender Octave con otros lenguajes.


Gran parte de esta seccin, sobre todo los ejemplos, se basa en el tutorial Dal segno al Coda de Paul Thomas. Podeis encontrarlo en el Wiki del proyecto Octave.
Octave est escrito en C++, adems es el lenguaje desde el que es ms sencillo extenderlo. Ahora deberamos preguntarnos cundo queremos extender Octave. Si Matlab es un lenguaje de programacin completo deberamos ser capaces de programar cualquier cosa. El problema es que programar cualquier cosa no se hace a cualquier precio, los bucles son un ejemplo de ello. Imaginemos que tenemos un programa que va demasiado lento, que casi todo el tiempo de proceso se debe a la evaluacin de una funcin miles de millones de veces y el coste de implementarla en otro lenguaje no es demasiado grande. La solucin a nuestro problema ser escribir la funcin en C++ o en Fortran y luego hacer un interfaz para que Octave pueda entenderla. Para hacerlo antes tendremos que asegurarnos que disponemos de las cabeceras (headers) de Octave. No se encuentran en algunos paquetes y puede ser que tengamos que instalarlos a parte. Preparar la infraestructura es un poco complejo, tambin necesitaremos un compilador en el entorno accesible por consola, preferentemente los de la coleccin gcc (gcc, g++, g77 y gfortran). Las cabeceras sirven tanto para escribir pequeas funciones como para crear interfaces completos a libreras escritas en C, C++ o Fortran. terminados en

.oct

mkoctfile

es la herramienta bsica del desarrollo de Octave, todos los archivos

han sido creados con dicha funcin. Algunas de las libreras utilizadas son FFTW para las

transformadas rpidas de Fourier, ODEPACK para resolver ecuaciones diferenciales ordinarias, UMFPACK para las matrices sparse y ATLAS para el clculo matricial. Los respectivos interfaces son una gran fuente de informacin de cmo adecuar Octave a nuestras necesidades.

7.4.1. Una advertencia antes de empezar a programar.


Es posible que cuando probemos alguno de los ejemplos que se expondrn a continuacin recibamos un segmen-

tation fault o un resultado sin ninguna lgica en vez de lo esperado. Muchas veces los programas no son compilar y
listo, los programadores experimentados en C y C++ saben de lo que hablo. Otra de las ventajas de los lenguajes

CAPTULO 7. TEMAS AVANZADOS

111

interpretados es que el intrprete es un binario standalone . Octave es un programa que depende de varias libreras externas, glibc, atlas, readline... Todas estas libreras deben ser compiladas previamente de tal modo que sean compatibles con el intrprete de Octave. Es normal que alguna de las dependenicas se construya con un compilador distinto al que se utilice para Octave. Normalmente no tendremos ningn problema pero esto no implica que no se produzcan jams. Un ejemplo de ellos es cuando intentamos aadir cdigo externo a Octave con el programa mkoctle. Lo que estamos haciendo es compilar un archivo escrito en C++ con el compilador del sistema que puede ser distinto al que se utiliz para Octave. Es incluso probable que los compiladores sean incompatibles como por ejemplo el GCC4 y el intel C++ compiler. Debemos tener en cuenta que Octave es a partir de ahora un verdadero entorno de desarrollo, nico y monoltico. Si queremos ponernos a jugar de verdad lo mejor ser que compilemos nosotros mismos Octave con el compilador del sistema. Si somos incapaces de hacerlo instalaremos el compilador con el que se construy nuestro Octave as como las libreras propias de C y C++ sobre las que funciona. Si podemos tener problemas con los compiladores de C++ con los de Fortran debemos prepararnos para sufrir de lo lindo. Octave se compila con gcc3, sin soporte para Fortran 95. Si queremos utilizar cdigo en este dialecto tendremos que utilizar gcc4 pero entonces las versiones de las libreras de C++ sern incompatibles. Disponemos de dos opciones: 1. Seguir con gcc3, escribir cdigo en Fortran 77 y compilar con g77. 2. Pasarnos a la rama inestable de Octave, compilarla con gcc4 y gfortran y rezar para que no rompa nada. Por suerte estos problemas desaparecern cuando gcc4 se consolide.

7.4.2. Extender Octave con C++


Una vez tengamos toda la infraestructura preparada podemos acoplar cualquier funcin escrita en C++ a Octave. La diferencia entre los archivos nos permiten manipular directamente los argumentos de Octave. El header principal es las deniciones de todos los argumentos necesarios. Empezaremos con el siguiente archivo de ejemplo que llamaremos

.oct y los .mex de Matlab es que en este caso contamos con cabeceras que oct.h, en l se encuentran eqlorentz.cc:

#include <octave/oct.h> DEFUN_DLD (eqlorentz,args, , "Ecuacion de Lorentz en C++") { ColumnVector xdot (3); ColumnVector x (args(0).vector_value()); int a=10; int b=28; double c=8./3; xdot(0) = a*(x(1)-x(0)); xdot(1) = x(0)*(b-x(2))-x(1); xdot(2) = x(0)*x(1)-c*x(2); return octave_value (xdot); }
Esta es la funcin de la ecuacin diferencial del atractor de Lorentz:

x = a(y x) y = x(b z ) y z = xy cz

con

a = 10, b = 28, c =

8 3

Encontraremos el script que resuelve el problema en el ejercicio 8.3. Tenemos que evaluar la ecuacin del atractor un mnimo de 5000 veces, nos ahorraremos algo de tiempo escribiendo la funcin en C++ y convirtindola en una funcin de Octave con:

bash ~/> mkoctfile eqlorentz.cc


El resultado ser un archivo llamado

eqlorentz.oct

que es equivalente a cualquier archivo de funcin:


es el adjetivo que recibe un programa que despues de ser

4 Este

trmino informtico proveniente de la expresin

to stand alone

compilado ya no tiene ninguna dependencia externa; puede tenerlas en tiempo de compilacin pero no en tiempo de ejecucin. En un sistema operativo tipo UNIX esto es imposible porque todo depende como mnimo de la librera estndar de C.

Introduccin informal a Matlab y Octave

112

7.4. EXTENDER OCTAVE CON OTROS LENGUAJES.

>> help eqlorentz eqlorentz is the dynamically-linked function from the file /home/guillem/sync/CursoScripting/ejercicios/eqlorentz.oct Ecuacion de Lorentz en C++ >> eqlorentz([1,1,1],1) ans = 0.00000 26.00000 -1.66667
Otra posibilidad interesante es la de crear subrutinas optimizadas para un tipo determinado de hardware. No es lo mismo llamar a una subrutina que funcionara en cualquier PC que optimizarla para utilizar todas las posibilidades de un Xeon o de un Opteron.

mkoctfile

no es ms que un interface a los compiladores de la famlia

gcc, podemos pasarle parmetros de compilacin para conseguir una optimizacin mxima.

7.4.2.1. Llamar funciones desde C++


A medida que nos introduzcamos en la programacin de extensiones para Octave es probable que tengamos la necesidad de tomar funciones como argumentos. Un posible ejemplo de ello sera una rutina de integracin de una EDO; sin la funcin es imposible integrar nada. Llamar una funcin desde Octave no es difcil pero tampoco es trivial. Disponemos del tipo puntero. Un

octave_function

que contiene todos los mtodos necesarios, el problema (si es que lo es) es que debe referirse al argumento como un la denicin hecha anteriormente; una funcin se llama mediante el mtodo

octave_function va a ser siempre un puntero a una funcin. Lo dems es ser un poco congruente con do_multi_index_op que recibe como argumentos el nmero de variables de entrada y un octave_value_list con los mismos. La salida ser tambin un octave_value_list. inline,
de otro modo Octave no sabr que uno de los argumentos es una funcin. Para que la propia rutina lo compruebe se utilizan los mtodos

Ya en octave, para pasar las funciones debemos utilizar un function handle, una funcin annima o la funcin

is_function_handle

is_inline_function.

Para ilustrar todo lo anterior utilizaremos el siguiente ejemplo:

/*testfh.cc*/ # include <octave/oct.h> DEFUN_DLD(testfh,args, , "testing how C++ can call an octave function") { octave_value_list tmp; octave_value_list inval; octave_function *input_fcn=0; if (args(0).is_function_handle() || args(0).is_inline_function()) input_fcn = args(0).function_value(); else { error("this is not a function handle nor an inline function"); return octave_value(-1); } double x = args(1).double_value(); inval.append(octave_value(x)); tmp = input_fcn->do_multi_index_op(1,inval); return tmp; }
Esta funcin recibe un function handle o un inline y un escalar de doble precisin. Retorna la funcin evaluada en el punto denido por el escalar. Para compilarlo haremos:

bash~/> mkoctfile testfh.cc


Ya dentro de Octave ensayaremos su funcionamiento:

>> testfh('sin',.123) error: this is not a function handle nor an inline function

CAPTULO 7. TEMAS AVANZADOS

113

>> testfh(@sin,pi/2) ans = 1 >> testfh(@(x) sin(x)*exp(x/2),pi/4) ans = 1.0472 >> testfh(inline('sin(x)*exp(x/2)'),pi/4) ans = 1.0472
Como vemos es capaz de entender function handles, function handles y funciones inline. Esta capacidad abre signicativamente el abanico de posibilidades de octave. Las funciones escritas en C++ ya no son algo monoltico, es decir, una subrutina tonta que slo es capaz de recibir y devolver valores. Ahora podemos interactuar con toda la plataforma de octave, incluso con las funciones pasadas por cabecera.

7.4.3. Extender Octave con Fortran


Fortran es el lenguaje de clculo cientco por excelencia. Se ha abandonado paulatinamente durante los ltimos aos por el hecho de que no haba ningn compilador libre de Fortran 95. Este hueco ha sido llenado por los compiladores G95 y gfortran . Ahora cualquier desarrollador puede programar en Fortran sin necesidad de aceptar licencias restrictivas sobre su cdigo. Evidentemente el lenguaje de extensin natural de Octave es C++ pero disponemos de la cabecera

f77-fcn

para comunicarnos con subrutinas escritas en Fortran. Siendo Fortran tan popular en el mbito cientco es lgico que Octave le de un trato especial. Desgraciadamente la capacidad de integracin de Fortran en Octave es bastante limitada debido sobre todo a las dicultades de comunicacin entre C y Fortran. Otros lenguajes interpretados cumplen mucho mejor la labor de comunicarse con sus primos compilados como Python, Java o Ruby.

7.4.3.1. Por qu Fortran?


Las subrutinas escritas en Fortran no son ms rpidas en Octave que las escritas en C++ sin embargo Fortran tiene otras muchas ventajas. Fortran es, adems de un lenguaje para aplicaciones cientcas por excelencia, el nico en el que el uso de memoria es puramente matricial. Cuando declaramos un array en Fortran 95 lo hacemos con rango, no slo con la cantidad de memoria necesaria. Fortran es claramente mejor que cualquier otro lenguaje de programacin cuando hay que calcular con variables de gran tamao. Cuando operamos con vectores, matrices y tensores a la vez es muy fcil equivocarse en los ndices o pisar fuera de la matriz. Fortran reserva memoria de una manera estricta y no tolera un mal uso de ella. Otro motivo de peso es la manera radicalmente distinta en la que Fortran y C tratan los arrays. Mientras en Fortran el uso de la memoria est detrs del concepto de array, en C no es ms que una sucesin de posiciones de memoria contiguas. Cuando uno aprende C sin ser un experto en ordenadores el concepto de puntero se le hace tremendamente antinatural; ms an si la experiencia previa es en Fortran. C es un lenguaje especialmente pequeo, esa es su gran ventaja; pero no por ello es ms simple o genera menos sutilezas. Veamos por ejemplo los dos programas siguientes en C++. En ellos se pretende llamar a la ecuacin diferencial de Lorentz y sacar el resultado por pantalla.

#include <iostream> using namespace std; void lorentz(double t,double *y,double *yp) { const int a=10; const int b=28; const double c=8./3; yp[0]=a*(y[1]-y[0]); yp[1]=y[0]*(b-y[2])-y[1]; yp[2]=y[0]*y[1]-c*y[2]; } int main(int argc,char *argv[]) { double y[3]; double yp[3];
5 gfortran
es un fork del proyecto G95 por desavenencias en el desarrollo con su creador. gfortran est dentro de gcc mientras que

G95 es un proyecto a parte.

Introduccin informal a Matlab y Octave

114

7.4. EXTENDER OCTAVE CON OTROS LENGUAJES.

y[0]=1.; y[1]=1.; y[2]=1.; lorentz(1.,y,yp); int i; for (i=0;i<3;i++) { cout << yp[i] << '\n'; } return 0;

La salida por pantalla es la siguiente:

guillem@desktop:~$ ./a.out 0 26 -1.66667


Que es precisamente el resultado de la ecuacin diferencial. Llama la atencin el hecho que en la cabecera no hemos denido ningun array sino punteros. En la cabecera de la funcin las deniciones

*double double[3] double[]


Son equivalentes. Ahora pensamos que a lo mejor C++ es muy listo y que podemos ahorrarnos el bucle para obtener el resultado. Probamos lo siguiente:

#include <iostream> using namespace std; void lorentz(double t,double *y,double *yp) { const int a=10; const int b=28; const double c=8./3; yp[0]=a*(y[1]-y[0]); yp[1]=y[0]*(b-y[2])-y[1]; yp[2]=y[0]*y[1]-c*y[2]; } int main(int argc,char *argv[]) { double y[3]; double yp[3]; y[0]=1.; y[1]=1.; y[2]=1.; lorentz(1.,y,yp); int i; cout << yp << '\n'; } return 0;

Y al ejecutar el programa:

0xbfce1360

CAPTULO 7. TEMAS AVANZADOS

115

El programa ha escupido una direccin de memoria. Para un programador experimentado en C esto resultar tan obvio como desconcertante para el resto de los mortales. La relacin entre los arrays y los punteros es de amor-odio. Salpica cualquier programa escrito en C o en C++ y puede llegar a ser una tortura cuando slo nos interesan los arrays. Fortran no slo es ms seguro sino que ayuda a programar con pocos errores tanto en la implementacin del algoritmo como en el uso de la memoria. Otra ventaja importante es que la biblioteca estndar de Fortran contiene funciones orientadas al clculo cientco y que la mayora de las bibliotecas de clculo numrico estn pensadas para comunicarse con Fortran y no con C o C++.

7.4.3.2. La difcil comunicacin entre C y Fortran


Fortran y C son lenguajes diametralmente opuestos, sobretodo en el uso de la memoria. Mientras C permite al usuario jugar con las direcciones de memoria de un modo transparente, incluso accediendo explcitamente a los registros; Fortran utiliza la memoria en sentido estricto y dejando pocas libertades al usuario. La gran diferencia entre ambos es sin duda las llamadas a funciones y subrutinas, C llama por valor y Fortran por referencia. Qu signica eso? No olvidemos que Matlab est escrito en C y Octave en C++, ambos utilizan una infraestructura equivalente a cualquier programa en C. Para entender bien qu es una llamada por valor y una llamada por referencia es necesario que entendamos qu es una direccin de memoria y qu es un puntero. Los ordenadores tienen tres tipos de memoria: la memoria cache, la memoria fsica y la memoria virtual. La ms importante de ellas para un programa es la memoria fsica y es en la que debemos pensar cuando programamos. Entrar en ms disquisiciones sobre arquitectura de ordenadores ahora sera intil. Los programas no son ms que procesos de gestin de memoria; es almacenar algo en un sitio y decir qu hay que hacer con ello. Si queremos sumar 2 ms 2 tendremos que almacenar un 2 en una posicin de memoria, un 2 en otra, pasarlas por un sumador y luego almacenar el resultado. Los lenguajes de programacin de alto nivel permiten escribir programas sin tener que pensar en todas estas sutilezas. Cuando en un cdigo asignamos una variable a un argumento:

a=2
estamos haciendo dos cosas: primero reservamos el espacio en memoria necesario para almacenar un 2 y luego le estamos asignando el nombre de una variable. El nombre est slidamente unido a la posicin de memoria. Ahora supongamos que queremos referirnos a la variable a. Podemos hacerlo de dos maneras. La primera es llamar el contenido de a, es decir, 2. La segunda es referirnos a la variable segn la posicin de memoria que ocupa. Llamamos posicin de memoria a el punto de la memoria fsica en el que se encuentra realmente contenida la variable y se expresa mediante una direccin de memoria que suele ser una cadena de 8 caracteres. Esto nos permite distinguir entre dos tipos esenciales de variables, las que contienen un valor y las que apuntan a una determinada direccin de memoria. Las primeras se llaman variables y las segundas reciben el nombre de

punteros. Los programadores experimentados en C y C++ dominan el concepto de puntero pero los que no lo
hayan odo en su vida lo entendern mejor con este pequeo programa en C:

#include <stdio.h> int a; int *ptr; int main(int argc, char *argv[]) { a=2; ptr = &a; printf("a es %i \n",a); printf("la direccion de a es %p \n",ptr); printf("el puntero ptr contiene %i \n",*ptr); return 0; }
Primero declaramos una variable de tipo entero y luego un puntero del mismo tipo, luego le asignamos a la variable el valor de 2 y el puntero a la posicin de memoria de la variable. Imprimimos en pantalla el resultado para saber qu contiene cada una de ellas y el resultado es el siguiente:

a es 2 la direccion de a es 0x403020 el puntero ptr contiene 2


Introduccin informal a Matlab y Octave

116

7.4. EXTENDER OCTAVE CON OTROS LENGUAJES.


Una vez hemos entendido la diferencia entre una posicin de memoria y el valor que esta contiene daremos

el siguiente paso. Supongamos que acabamos de escribir una funcin o una subrutina. Esta unidad de programa necesita argumentos adicionales para funcionar especicados en su cabecera. Si la funcin no recibe los argumentos necesarios en tiempo de ejecucin recibiremos un error. Pero acabamos de ver que para el ordenador es equivalente recibir un valor que la posicin de memoria del bloque que la contiene. En un programa parecido al anterior denimos la una funcin suma:

#include <stdio.h> int a,b; int sum(int a,int b) { int result; result=a+b; return result; } int main(int argc, char *argv[]) { a=2; b=3; int resultado=sum(a,b); printf("la suma de %i y %i es %i \n",a,b,resultado); return 0; }
Qu hace C para pasar los valores a la funcin? C pasa los argumentos a las funciones por valor. Esto signica que las memoria utilizada por la funcin y por el programa principal son independientes. Cuando pasamos los argumentos a la funcin suma se copia su valor a las variables locales sin tocar las globales; la funcin espera un valor, no una direccin de memoria; espera un 2, no un 0x748361. Fortran es diametralmente opuesto a C en este sentido. Todas las variables de Fortran son en realidad punteros. Fortran no sabe de valores reales, slo est interesado en posiciones de memoria. La identicacin entre la memoria y la variable es absoluta. Vamos a descifrar lo dicho hasta ahora mediante un programa ejemplo:

program test integer :: a,b,c a=2 b=3 call sum(a,b,c) write(*,*) c end program test subroutine sum(arg1,arg2,resultado) integer, intent(in) :: arg1,arg2 integer, intent(out) :: resultado resultado=arg1+arg2 end subroutine sum
Cuando llamamos a la subrutina sum no estamos pasando los valores 2 y 3 sino que estamos identicando las posiciones de memoria. Le estamos diciendo a la subrutina que su arg1 se encuentra en la posicin de a y arg2 en la de b. Por eso tenemos que declarar las variables en las subrutinas con el atributo intent; estamos operando con las mismas posiciones de memoria, si nos equivocamos no podemos volver atrs. Esto se llama pasar los argumentos por referencia. Este punto de vista es mucho menos versatil pero evita el uso de ms memoria de la necesaria. Por eso Fortran es un lenguaje muy indicado para manejar variables de gran tamao. Esto signica que programando en C tendremos que pasar punteros y no variables a las funciones escritas en Fortran.

7.4.3.3. Llamar una funcin de C desde Fortran o la manera ms difcil de sumar 2+2
Para entender mejor el signicado de la llamada por referencia en Fortran vamos a aprovechar que los archivos objeto creados con el GCC son independientes del frontend utilizado. La estrategia es la siguiente, crearemos una

CAPTULO 7. TEMAS AVANZADOS

117

funcin en C que sume la primera y la segunda variable y retorne el resultado en la tercera. El cdigo es el siguiente:

void c_function_(int *a,int *b,int *c) { *c=*a+*b; }


Algunas observaciones importantes: 1. Las funciones del tipo

void

son equivalentes a las subrutinas en Fortran.

2. El nombre de la funcin va seguido de una barra baja (trailing underscore) para que el nombre de la subrutina generada sea compatible con Fortran. Ignoro el por qu pero de otro modo no funciona. 3. Como la funcin espera una asignacin de argumentos por referencia espera punteros a las variables. En la funcin debemos ser consecuentes y utilizar el operador de retorno de referencia para hacer la operacin. Compilamos la funcin con:

bash$~/> gcc -c c_function.c


Slo falta crear el programa que implemente la llamada. Es el siguente:

program fortran_c_call integer :: a,b,c a=2 b=2 call c_function(a,b,c) write(*,*) c end program fortran_c_call
Lo compilamos y lo ejecutamos:

bash$~/> gfortran fortran_c_call.f90 c_function.o bash$~/> a.out 4


Esta operacin es imposible si el cdigo objeto generado es incompatible. Por muy extrao que parezca este tipo de interoperabilidad es tpica de un sistema UNIX. Aunque C y Fortran puedan parecer a veces agua y aceite no debemos olvidar que los compiladores de Fortran no son ms que programas escritos en C.

7.4.3.4. Punteros y arrays


El tipo esencial de Fortran es el array. Un array es un bloque de memoria que contiene elementos del mismo tipo. Denimos un array siempre con el apellido de su tipo; hablamos de array de enteros, array de reales de doble precisin... En las variantes de Fortran ms recientes los arrays tienen rango. Fortran no trata del mismo modo un array de rango 2 que uno de rango 3, ordenar los elementos de un modo distinto para optimizar la lectura y la escritura. Hemos dicho que todas las variables son en realidad punteros; un array es un puntero al primer elemento, una sentencia de reserva de la memoria necesaria y una regla de lectura y escritura. Si intentamos leer un elemento fuera de los lmites del array Fortran nos dar un error en tiempo de ejecucin C no tiene ningn mtodo para denir arrays, C slo sabe reservar memoria. Si intentamos emular el comportamiento de Fortran debemos tener mucha precaucin. Por mucho que intentemos reservar la memoria justa y no llamar ningn elemento que no exista dentro de la variable el rango desaparece. Para C estas dos declaraciones:

array[15]; array[3][5];
son equivalentes. Ser muy importante utilizar las cabeceras de Octave porque nos proporcionarn los tipos necesarios para utilizar cmodamente matrices y arrays.

Introduccin informal a Matlab y Octave

118

7.4. EXTENDER OCTAVE CON OTROS LENGUAJES.

7.4.3.5. Escritura de wrappers para funciones en Fortran.


Aunque este es un conveniente importante no se requieren grandes conocimientos de C++ para escribir uno. Para escribir un wrapper a la ecuacin diferencial del atractor de Lorentz:

subroutine eqlorentzfsub(x,xdot) real(8),dimension(:),intent(in) :: x real(8),dimension(:),intent(out) :: xdot real(8) :: a=10d0,b=28d0 real(8) :: c c=8d0/3d0 xdot(1)= a*(x(2)-x(1)) xdot(2)= x(1)*(b-x(3)-x(2)) xdot(3)= x(1)*x(2)-c*x(3) end subroutine eqlorentzfsub
El wrapper correspondiente para esta funcin es el siguiente:

#include <octave/oct.h> #include "f77-fcn.h" extern "C" int F77_FUNC (eqlorentzfsub, EQLORENTZFSUB)(double*,double*); DEFUN_DLD(eqlorentzf,args, ,"xdot=eqlorentz(x)") { octave_value_list retval; ColumnVector wargin(args(0).vector_value()); ColumnVector wargout(3); F77_FUNC(eqlorentzfsub,EQLORENTZFSUB)(wargin.fortran_vec(), wargout.fortran_vec()); retval.append(wargout); return retval; }
Hacemos siempre uso de los objetos propocionados por las cabeceras de octave, para ello se supone que tenemos nociones de programacin orientada a objetos. El wrapper sirve nicamente para pasar las variables de entrada y salida a punteros que Fortran sea capaz de reconocer. Las variables de entrada y salida de la funcin para octave van a ser

xdot

y las someteremos siempre a las mismas transformaciones hasta ser punteros:

1. Recogeremos la variable de entrada de la funcin que Octave dejar en la variable propio de Octave. En el caso del wrapper anterior declaramos un con la variable

args.

Si es un escalar

podemos utilizar una variable propia de C, si queremos un vector o una matriz tendremos que utilizar un tipo

args(0)

ColumnVector llamado wargin inicializado

en forma de vector.

2. Declararemos la variable de salida, en este caso otro

Tambin declararemos la variable de retorno de la funcin de Octave, siempre como 3. Llamaremos la funcin previamente compilada en Fortran mediante argumentos los punteros que hemos creado para ella, en nuestro caso de la funcin

ColumnVector, al que tambin asignaremos un puntero. octave_value_list. F77_FUNC a la que pasaremos como argin y argout. Previamente y fuera

punteros a las variables de entrada y salida.


wargout

DEFUN_DLD

declararemos la funcin externa donde deniremos

todos los argumentos como

4. Pasaremos la variable de salida

a la variable

retval

de retorno de la funcin en Fortran.

un compilador compatible con el que se ha compilado octave. El wrapper llamar al cdigo objeto que se haya creado con
Una vez tengamos la funcin y el wrapper escritos compilaremos la funcin en Fortran con el archivo de Fortran. Los comandos son los siguientes:

bash$~/> gfortran -c eqlorentzfsub.f bash$~/> mkoctfile eqlorentzf.cc eqlorentzfsub.o


Una vez realizado el proceso aparecer un archivo llamado

eqlorentzf.oct

que ya es una funcin que Octave es

capaz de entender. La llamaremos en Octave del modo usual:

CAPTULO 7. TEMAS AVANZADOS

119

>> eqlorentzf([1,2,3]) ans = 10 23 -6


La necesidad de que los dos compiladores sean compatibles es un gran contratiempo. De momento Octave slo se puede compilar con la versin 3 del compilador GCC que slo es capaz de compilar cdigo en Fortran 77. Si intentamos mezclar archivos compilados con gcc 4, que entiende Fortran 95, y gcc 3 muy probablemente tendremos un Segmentation Fault. De momento nos conformaremos con escribir cdigo en Fortran 77, aunque no por mucho tiempo. Slo como ejemplo la misma funcin en Fortran 77 se escribira como:

subroutine eqlorentzfsub(x,xdot) real*8 x(*),xdot(*) real*8 a,b,c a=10d0 b=28d0 c=8d0/3d0 xdot(1)= a*(x(2)-x(1)) xdot(2)= x(1)*(b-x(3)-x(2)) xdot(3)= x(1)*x(2)-c*x(3) end subroutine eqlorentzfsub
Podemos escribir wrappers que sean capaces de retornar los mensajes de error de la subrutina. Para ello es necesario que el wrapper llame a la funcin siguiente :

F77_XFCN

en vez de

F77_FUNC.

Por ejemplo, un wrapper para la subrutina

C C

SUBROUTINE TNINE (IOPT, PARMOD, PS, X, Y, Z, BX, BY, BZ) INTEGER IOPT DOUBLE PRECISION PARMOD(10), PS, X, Y, Z, BX, BY, BZ Este es un ejemplo para probar un wrapper. Asigna la suma de PARMOD a PS, y X, Y, Z a BX, BY, BZ INTEGER I PS = 0D0 DO I=1, 10 PS = PS + PARMOD (I) END DO BX = X BY = Y BZ = Z END

sera:

#include <octave/oct.h> #include "f77-fcn.h" extern "C" { int F77_FUNC (tnine, TNINE) (const int & IOPT, const double* PARMOD, double & PS, const double & X, const double & Y, const double & Z, double & BX, double & BY, double & BZ ); } DEFUN_DLD (t96, args, ,
6 La
subrutina est escrita en Fortran 77. Aunque se considere una variante obsoleta de Fortran es necesario conocer sus particularidades porque es el lenguaje en el que estn escritas la mayora de las bibliotecas de funciones. Es por ello que Octave preere utilizar una nomenclatura orientada a Fortran 77. Esto no genera ningn problema porque el cdigo objeto generado por los compiladores de Fortran 77 es compatible con los de Fortran 95. Wrappers ms sosticados como f2py ya incorporan una sintaxis parecida a Fortran 95.

Introduccin informal a Matlab y Octave

120

7.4. EXTENDER OCTAVE CON OTROS LENGUAJES.

"- Loadable Function: [PS, BX, BY, BZ] = t96 (PM, X, Y, Z) \n\ \n\ Returns the sum of PM in PS and X, Y, and Z in BX, BY, and BZ.") { octave_value_list retval; const int dummy_integer = 0; Matrix pm; const double x = args(1).double_value(), y = args(2).double_value(), z = args(3).double_value(); double ps, bx, by, bz; pm = args(0).matrix_value (); F77_XFCN (tnine, TNINE, (dummy_integer, pm.fortran_vec(), ps, x, y, z, bx, by, bz) ); if (f77_exception_encountered) { error ("unrecoverable error in t96"); return retval; } retval(0) = octave_value (ps); retval(1) = octave_value (bx); retval(2) = octave_value (by); retval(3) = octave_value (bz); return retval; }
Para convertir el archivo y el wrapper en una funcin de Octave introducimos en la consola:

bash $~/> mkoctfile t96.cc tnine.f


Y ya podemos llamarla como cualquier otra funcin de la coleccin:

>> help t96 t96 is the dynamically-linked function from the file /home/guillem/Desktop/sandbox/t96.oct - Funcion: [PS, BX, BY, BZ] = t96 (PM, X, Y, Z) Asigna la suma de PM a PS y X, Y, Z a BX, BY, BZ. >> [uno,dos,tres,cuatro]=t96(1:10,pi,e,4) uno = 55 dos = 3.1416 tres = 2.7183 cuatro = 4
Hemos declarado todas las variables de la subrutina, tanto las internas como las externas, para que si se produce un error en la parte escrita en Fortran Octave sea capaz de encontrarlo. El wrapper se encarga de tomar los argumentos de entrada, convertirlos en algo que Fortran sea capaz de entender y recoger el resultado. Octave tambin soporta la denicin de los tipos derivados de Fortran. Para la subrutina:

subroutine f95sub2(din,dout) type :: mytype real*8 :: mydouble integer*4 :: myint end type mytype type (mytype) :: din , dout dout%mydouble = din%mydouble ** float( din%myint ) dout%myint = din%myint * din%myint end subroutine f95sub2
Primero la compilaremos con

bash $ ~/> gfortran -c f95sub.f90


Escribiremos el wrapper:

CAPTULO 7. TEMAS AVANZADOS

121

#include <octave/oct.h> #include <octave/f77-fcn.h> struct mystruct { double mydouble; int myint; }; extern "C" int F77_FUNC (f95sub,f95SUB) ( mystruct &, mystruct &); DEFUN_DLD (f95demo, args , ,"[w,z] = f95demo( x , y ) \ returns w = x ^y and z = y * y for integer y") { octave_value_list retval; mystruct dinptr , doutptr; dinptr.mydouble = args(0).scalar_value(); dinptr.myint = int( args(1).scalar_value() ); F77_FUNC (f95sub,f95SUB) (dinptr,doutptr ); retval.append( octave_value( doutptr.mydouble ) ); retval.append( octave_value( double( doutptr.myint ) ) ); return retval; }
Y nalmente llamaremos a

mkoctfile:

bash$~/>mkoctfile f95demo.cc f95sub.o

7.4.4. Extender C++ con Octave


Octave es un proyecto de software libre con un diseo bastante acertado. Tanto es as que las libreras de extensn de Octave junto con la capacidad de incrustar el intrprete en una aplicacin hace que Octave sea una biblioteca de lo ms completa. Esto proporciona a Octave una cualidad no tan esperada;

puede utilizarse como extensin natural de C++ para el clculo cientco. La cabecera oct.h proporciona todos los tipos necesaros para el
clculo numrico, matrices, vectores la y columna, operaciones matriciales y vectoriales... Incluso resolucin de EDOs! Para abrir boca nada mejor que un pequeo experimento con un programa de lo ms simple:

/*testoctavestandalone.cc*/ #include <iostream> #include <oct.h> int main(void) { std::cout << "Octave y c++ \n"; Matrix a=identity_matrix(2,2); std::cout << a; }
Para compilarlo utilizaremos la aplicacin para generar un ejecutable.

mkoctfile como viene siendo habitual pero con la opcin --link-stand-alo

$ mkoctfile --link-stand-alone testoctavestandalone.cc -o test.exe


Y lo ejecutaremos, en un entorno UNIX...

$ ./test.exe Octave y c++ 1 0 0 1


La biblioteca en C++ de Octave es mucho ms potente como demuestra el siguiente ejemplo:

/*test2.cc*/ #include <iostream> #include <oct.h> int main(void) { Matrix a=Matrix(2,2); ColumnVector b=ColumnVector(2);
Introduccin informal a Matlab y Octave

122

7.5. OPTIMIZACIN DE LA EVALUACIN DE FUNCIONES.(+)

a(0,0)=2.; a(1,0)=5.; a(0,1)=-6.; a(1,1)=3.; b(0)=1.; b(1)=0.; std::cout << a.solve(b); return 0;

donde resolvemos el siguiente sistema de ecuaciones:

2 6 5 3

x=

1 0

$ mkoctfile --link-stand-alone test2.cc -o test.exe $ ./test.exe 0.0833333 -0.138889

7.5. Optimizacin de la evaluacin de funciones.(+)


En la seccin 5.2.1 hemos planteado la necesidad de optimizar el proceso de evaluacin de funciones especialmente complejas. El coste de la evaluacin de una funcin muy compleja puede reducirse signicativamente con la interpolacin polinmica. Un caso muy llamativo son las funciones con gran cantidad de trminos armnicos (senos, cosenos y tangentes) que en la evaluacin suelen cancelarse. Aunque la evaluacin de funciones no es una de las tareas ms optimizadas de Matlab no est de ms utilizar los conocimientos adquiridos para aumentar su rendimiento . Los polinomios de Chebyshev son un recurso bastante habitual porque implican un error de interpolacin pequeo. Tambin podramos pensar en utilizar un desarrollo de Taylor, pero tienen el inconveniente de que slo aproximan la funcin en un punto, mientras que lo que nos interesa es un error controlable en todo un intervalo. Otra caracterstica interesante es que cuando desarrollamos una funcin en serie, ya sea de Fourier o Polinmica, las operaciones elementales como las derivadas o las integrales son triviales y, lo que es ms importante, fciles de implementar .

7.5.1. Polinomios de Chebyshev.


Este es un resumen del tratamiento del desarrollo en polinomios de Chebyshev hecho en [3].
Los polinomios de Chebyshev cumplen la siguiente formula:

Tn (x) = cos(n cos1 x)


Esta expresin genera la siguiente serie de polinomios:

T0 (x) = 1 T1 (x) = x T2 (x) = 2x2 1 T3 (x) = 4x3 3x T4 (x) = 8x4 8x2 + 1 Tn+1 (x) = 2xTn (x) Tn1 (x) n1

7 Estas consideraciones no son un caso nico de Matlab. El uso de un polinomio interpolante de alto orden para aproximar una funcin
analtica es efectivo en cualquier lenguaje de programacin. Es una prctica de optimizacin muy utilizada en los cdigos antiguos escritos en fortran cuando los compiladores no eran sucientemente listos como para evaluar las funciones de un modo eciente. Los cdigos altamente optimizados no tenan ninguna funcin que no estuviera escrita cada

8 El

op

a mano

por el programador. Los tiempo en los que

era valioso ya han pasado pero siempre podemos encontarnos en la necesidad de optimizar una funcin en concreto

grado de optimizacin en los inicios de la informtica era tal que en un mismo bucle se aprovechaban los trminos calculados

para la evaluacin de una funcin para evaluar a la vez su derivada; en el caso que fuera necesario.

CAPTULO 7. TEMAS AVANZADOS


Estos polinomios tienen la particularidad de contar con

123

ceros en los puntos:

x = cos
y

(k 1/2) n k n

k = 1, 2, . . . , n

n + 1extremos

relativos en:

x = cos
acotados por el intervalo la funcin peso

[1, 1]. Estos polinomios, adems, tienen la caracterstica de ser (1 x2 )1/2 . Se demuestra que los coecientes del desarrollo de la forma:
N

ortogonales segn

f (x)
k=1
se calculan mediante:

1 ck Tk1 (x) c1 2

cj =

2 N

f
k=1

cos

(k 1/2) N

cos

(j 1)(k 1/2) N

Evidentemente no necesariamente nos interesa un desarrollo que contenga todos los puntos posibles; lo ms normal es calcular un desarrollo truncado de Chebyshev. Con el cambio de variable

y
conseguimos un desarrollo en el intervalo la ayuda en formato texinfo

1 x 2 (b + a) 1 ( b a) 2

[a, b],

mucho ms til que el

[1, 1]

original.

La siguiente es una funcin escrita en C++ que implementa el desarrollo. Es interesante jarse en cmo escribir

/* chebyexpand.cc */ #include <octave/oct.h> #include <math.h> static double PI=4.*atan(1.); DEFUN_DLD(chebyexpand,args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{c}]=} chebyexpand\ (@var{f},@var{a},@var{b},@var{n})\n\ \n\ Chebyshev fit:\n\ \n\ Given a function @var{f} and the interval @var{a},@var{b} computes\n\ the @var{n} coefficients of the Chebyshev polynomial expansion.\n\ \n\ @example\n\ >> chebyexpand(@@(x) 2*x^2-1,-1,1,5)\n\ ans =\n\ -2.6645e-16\n\ 1.1948e-17\n\ 1.0000e+00\n\ 7.9786e-17\n\ -1.0426e-16\n\ @end example\n\ \n\ Note that @var{f} must be a function handle or an anonymous function\n\ \n\ @end deftypefn") { int j,k;

Introduccin informal a Matlab y Octave

124

7.5. OPTIMIZACIN DE LA EVALUACIN DE FUNCIONES.(+)

octave_value_list tmp; octave_value_list inval; octave_function *input_fcn=0; if (args(0).is_function_handle() || args(0).is_inline_function()) input_fcn = args(0).function_value(); else { error("this is not a function handle nor an inline function"); return octave_value(-1); } double a=args(1).double_value(); double b=args(2).double_value(); int n=args(3).int_value(); ColumnVector f=ColumnVector(n); ColumnVector c=ColumnVector(n); for (k=0;k<n;k++) { inval(0)=octave_value(cos(PI*(k+0.5)/n)*\ 0.5*(b-a)+0.5*(b+a)); tmp=input_fcn->do_multi_index_op(1,inval); f(k)=tmp(0).double_value(); } for (j=0;j<n;j++) { double sum=0.; for (k=0;k<n;k++) { sum += f(k)*cos(PI*j*(k+0.5)/n); } c(j)=sum*2./n; } } return octave_value(c);
Como ejemplo de cmo debe ser la ayuda de una funcin de octave iremos al intrprete y teclearemos:

-- Loadable Function: [C]= chebyexpand (F,A,B,N) Chebyshev fit: Given a function F and the interval A,B computes the N coefficients of the Chebyshev polynomial expansion. >> chebyexpand(@(x) 2*x^2-1,-1,1,5) ans = -2.6645e-16 1.1948e-17 1.0000e+00 7.9786e-17 -1.0426e-16 Note that F must be a function handle or an anonymous function
Ahora nos falta crear la funcin que dados los coecientes nos recupere el valor de la funcin de un modo eciente. Para ello utilizamos la siguiente recurrencia tambin denida en [3]:

dm+2 dm+1 0 dj = 2xdj +1 dj +2 + cj j = m, m 1, . . . , 2

CAPTULO 7. TEMAS AVANZADOS

125

1 f (x) d0 = d2 d3 + c1 2
Pero una funcin recurrente nos obliga a implementar un bucle, algo que rompe completamente el objetivo de crear una funcin que sea muy rpida. Sin embargo el esfuerzo de programarla en cualquier otro lenguaje es mnimo . Por ejemplo, en C++ para octave (crear un archivo .mex sera an ms fcil): El programa tiene un bug

#include <octave/oct.h> DEFUN_DLD(chevyval,args, , "Calcula el valor del desarrollo de Chevyshev en x") { ColumnVector c (args(0).vector_value()); double a (args(1).double_value()); double b (args(2).double_value()); double x (args(3).double_value()); double xx; double y; double ynm1; double dummy; int i; int n =c.length(); xx=(2.*x-a-b)/(b-a); if ((x-a)*(x-b)>0) { error("chevyval: bad input point"); return octave_value_list(); } else { ynm1= c(n-1); y=2.*xx*ynm1+c(n-2); for (i=n-3;i<0;i--) { dummy=y; y=2.*xx*y+ynm1+c(i); ynm1=dummy; } y=xx*y-ynm1+0.5*c(0); return octave_value(y); } }

7.6. OCTS (Octave Control Theory Suite)


El control automtico es una de las disciplinas ms importantes de la ingeniera de sistemas. Se aplica tanto a la aeronautica, el diseo de sistemas mecnicos, el control de redes... Es adems una herramienta bastante sencilla con resultados sorprendentes. A medida que el sistema de control va creciendo se complica su tratamiento analtico pero tratandose de polinomios es sencillo disear herramientas numricas para ello. Cuando afrontamos un problema de control automtico solemos empezar con su representacin en un diagrama de bloques. Cada uno de los bloques representa una parte de las ecuaciones en forma de funciones de transferencia y encontrar un modo sencillo de crear, manipular y calcular el sistema no es ms que un problema de diseo. Encontramos bastantes programas especializados en el tratamiento de sistemas dinmicos. Podemos dividirlos en dos tipos, las herramientas por lnea de comandos y las herramientas grcas. Las primeras suelen ser tanto o ms potentes que las segundas pero su curva de aprendizaje es ms larga, incluso puede ser que demasiado larga. En el segundo grupo nos encontramos un programa verdaderamente popular construido sobre Matlab, Simulink. Simulink fue creado para el tratamiento fcil de sistemas dinmicos pero rpidamente se convirti en una herramienta de modelado verdaderamente potente. Casi cualquier programa de Matlab puede ser planteado en un diagrama de bloques de Simulink. Diramos que es la extensin natural de los problemas de control aplicados a

9 Octave

cuenta con la funcin cheb.m pero est escrita en cdigo Matlab.

Introduccin informal a Matlab y Octave

126

7.6. OCTS (OCTAVE CONTROL THEORY SUITE)

Matlab. Simulink es una herramienta fabluosa pero no es parte del lenguaje de programacin. Es una aplicacin, no una extensin del lenguaje. Mantener los programas de simulacin en el espacio del cdigo fuente suele ser una prctica bastante benecisa pero requiere tiempo de desarrollo y experiencia. Este curso pretende ser una ayuda precisamente para adquirir rpidamente esta experiencia. La manipulacin de sistemas dinmicos puede ser un buen ejemplo de cmo programar bien en Matlab. No analizaremos Simulink. Para esto estn los libros de Simulink. A cambio trataremos uno de los toolkits ms tiles y peor documentados de Octave, La Suite de Teora del Control de Octave (OCTS).

7.6.1. La representacin del sistema


Cada parte de un sistema dinmico puede ser expresada de muchas maneras, en forma de funcin de transferencia, en el espacio de las variables de estado y proporcionando sus ceros y sus polos. Una de las particularidades del OCTS es que almacena cada parte del sistema en una estructura de datos. La consecuencia directa de este planteamiento es que para interactuar con lo almacenado estamos obligados a utilizar las funciones diseadas para ello:

tf Crea un bloque mediante su funcin de transferencia ss Crea un bloque mediante su representacin en el espacio de sus variabels de estado zp Crea un bloque mediante la informacin proporcionada por sus ceros y sus polos
El propio proceso de creacin se encarga de calcular las representaciones alternativas y almacenarlas dentro de la estructura. Por ejemplo, para introducir:

block (s) =
con

s2 (s

K (s + 0,5)(s + 1) + 0,1)(s + 5)(s + 10)

K=1

>> block=zp([-0.5,-1],[-0.1,-5,-10,0,0],1)
El resultado es el siguiente sistema

block = { inname = { [1,1] = u_1 } k = 1 n = 5 nz = 0 outname = { [1,1] = y_1 } pol = -0.10000 stname = { [1,1] [1,2] [1,3] [1,4] [1,5] = = = = = x_1 x_2 x_3 x_4 x_5 -5.00000 -10.00000 0.00000 0.00000

sys =

CAPTULO 7. TEMAS AVANZADOS

127

0 1

tsam = 0 yd = 0 zer = -0.50000 } -1.00000

sysout

Muestra las distintas representacoiones del sistema:

Esta funcin es bastante til para conocer funciones en tiempo real. Como ya est todo almacenado dentro de la estructura de datos del sistema no tenemos ms que solicitar cualquiera de ellas:

>> sysout(block,'tf') Input(s) 1: u_1 Output(s): 1: y_1 transfer function form: 1*s^2 + 1.5*s^1 + 0.5 ----------------------------------------------1*s^5 + 15.1*s^4 + 51.5*s^3 + 5*s^2 + 0*s^1 + 0 >> sysout(block,'zp') Input(s) 1: u_1 Output(s): 1: y_1 zero-pole form: 1 (s + 0.5) (s + 1) -----------------------------s^2 (s + 0.1) (s + 5) (s + 10) >> sysout(block,'ss') Input(s) 1: u_1 Output(s): 1: y_1 state-space form: 5 continuous states, 0 discrete states State(s): 1: x_1 2: x_2 3: x_3 4: x_4 5: x_5 A matrix: 5 x 5 -10.00000 -4.50000 0.00000 -5.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.00000 1.00000 -0.10000 0.00000 0.00000 0.00000 0.00000 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.00000 0.00000
Introduccin informal a Matlab y Octave

128

7.6. OCTS (OCTAVE CONTROL THEORY SUITE)

B matrix: 5 0 0 0 0 1 C matrix: 1 -9.00000 D matrix: 1 0

x 1

x 5 -4.50000 x 1

1.00000

0.00000

0.00000

7.6.2. Diagramas de Bloques


La representacin por diagramas de bloques es una parte esencial de la teora de control. Es lo que da una idea intuitiva del sistema, un buen diagrama de bloques es una parte muy importante del problema. Podramos pensar que para crear y manipular un diagrama de bloques es estrictamente necesario una herramienta grca. Esto es completamente falso como veremos a continuacin. Uno de los principios de la programacin es que las estructuras deben expresarse en el cdigo pero no deben estar contenidas en l. No es difcil convertir intuitivamente un bloque en un objeto con una funcin de transferencia y unas entradas y salidas asociadas. Esto es precisamente lo que tenemos que intentar programando con el OCTS. Con los mtodos de la seccin anterior hemos aprendido a introducir la funcin de transferencia en un bloque pero si queremos que introducirlo en un sistema dinmico tendremos que etiquetar sus entradas y salidas convenientemente. Supongamos que tenemos un bloque con la siguiente funcin de transferencia.

dcha1(s) =

1 2s + 4

Al bloque decidimos llamarlo dhca1 por su posicin en el hipottico diagrama de bloques. Un ejemplo de bloque bien denido sera:

10

>> dcha1=tf([1,0],[2,4],TSAM=0,'dcha1in','dcha1out')
Evidentemente los bloques denidos por sus funciones de transferencia o por sus ceros y sus polos tendrn slo una entrada y una salida. Una vez hemos visto cmo crear bloques elementales pasamos a conocer las funciones que permiten a los bloques interacturar entre ellos. Son las siguientes:

Operaciones aritmticas de bloques sysadd

Combina dos bloques en paralelo de modo que la salida del conjunto es la suma de ambos. Para

comprender mejor el clculo revisar la ayuda de la funcin

sysmult Combina dos bloques en serie de modo que la salida del conjunto es el producto de ambos syssub Combina dos bloques en paralelo de modo que la salida del conjunto es la resta de ambos Operaciones de comunicacin entre bloques sysconnect
una salida de un bloque cualquiera. :

Conecta dos bloques deniendo una puerta de cada uno de ellos. Una puerta es una entrada o

sysgroup Agrupa varios bloques en uno que conserva sus entradas y salidas. sysdup Duplica las salidas y las entradas de un bloque. sysprune Elimina las entradas y las salidas espreas del sistema sysidx Extrae los nombres de las puertas de un bloque. Muy til cuando se utiliza con sysconnect. sysappend Introduce nuevas puertas de entrada o salida a un bloque ya existente buildssic Constructor de sistemas dinmicos. Para aprender ms sobre esta funcin es necesario utilizar la
demo de creacin de sistemas,

bddemo.

10 La

constante

TSAM

no es ms que el tiempo de muestreo. En el caso de sistemas continuos

TSAM

es igual a cero.

CAPTULO 7. TEMAS AVANZADOS


+

129

G
-

Figura 7.1: Diagrama de bloques del sistema ejemplo

7.6.2.1. Ejemplo de aplicacin. Un sistema realimentado simple


Las ayudas de las funciones de listadas en la seccin anterior son bastante explicativas pero sin un conocimiento aproximado de un kit de anlisis de sistemas dinmicos puede costarnos dar el primer paso. Una de las pocas consideraciones a tener en cuenta es que no se pueden acoplar ramas en los diagarmas de bloques, tenemos que crear las uniones duplicando las entradas y salidas en los mismos bloques. Esto es porque en cualquier kit de anlisis las ramas no son ms que conexiones, no tienen ninguna identidad propia. Tambin debemos tener en cuenta que hay operaciones que se realizan entre bloques del mismo sistema y operaciones entre sistemas. Si bien

sysprune, sysdup

sysconnect
F =

slo permiten operar en el mismo sistema,

sysadd

sysmult

relacionan dos bloques independientes. Para ver todo lo anterior aplicado nada mejor que un ejemplo. Supongamos que tenemos el siguiente sistema dinmico expresado por la gura 7.1 con

10 s2 (s+3) y G = s + 2: Primero construiremos el bloque de la derecha, el ms cercano a la salida. Su funcin de transferencia es: DCHA(s) = s2 (10 s+3) de modo que empezaremos deniendo su bloque bsico:

>> DCHA=zp([],[0,0,-3],10,TSAM=0,'DCHAIN','DCHAOUT');
El paso siguiente es duplicar su salida

>> DCHAdup=sysdup(DCHA,[],'DCHAIN'); DCHAdup = { a = -3 0 0 b = 0 0 1 c = 10 d = 0 0 0 0 0 0 1 1 0 0 0 1 0

inname = { } [1,1] = DCHAIN [1,2] = DCHAIN(dup)

n = 3 nz = 0 outname = {
Introduccin informal a Matlab y Octave

130

7.6. OCTS (OCTAVE CONTROL THEORY SUITE)

[1,1] = DCHAOUT

stname = { [1,1] = x_1 [1,2] = x_2 [1,3] = x_3

sys = 2 0 0 1

tsam = 0 yd = 0

Como vemos ha aparecido una nueva entrada llamada

DCHAIN(dup),

copia de

DCHAIN.

Ahora ya podemos crear la

recirculacin del primer estadio no sin antes cambiar el signo de la nueva puerta de salida:

>> DCHAdup=sysscale(DCHAdup,[],diag([1,-1]));
Este es un modo abrevidado de utilizar la funcin

syscale,

consultando la ayuda aprenderemos a utilizarla de un

modo ms intuitivo. Ahora conectamos la seal a la salida con la nueva puerta de entrada y nalmente simplicamos el sistema par que tenga una nica entrada. Como paso nal comprobaremos que el resultado es realmente el deseado escribiendo la funcin de transferencia del sistema.

>> DCHAend=sysconnect(DCHAdup,'DCHAOUT','DCHAIN(dup)'); >> DCHAend=sysprune(DCHAend,'DCHAOUT','DCHAIN'); >> sysout(DCHAend,'tf') Input(s) 1: DCHAIN Output(s): 1: DCHAOUT transfer function form: 10 ---------------------------------1*s^3 + 3*s^2 + 1.554e-15*s^1 + 10
La denicin del bloque de la izquierda es la nica limitacin del OCTS. No puede denir bloques cuyo nmero de ceros sea mayor a su nmero de polos. Esto es debido a la forma que tiene de hacer los clculos internos para crear la estructura de datos. Para seguir con el ejemplo tendremos que romper la estructura de datos creada por el primer bloque con recirculacin, multiplicarla por el polinomio del bloque de la izquierda y nalmente crear la ltima recirculacin. Esto no signica ningn problema porque podemos pasar de la representacin como estructura a funcin de transferencia slo con aplicar la funcin

sys2tf

>> [num,den]=sys2tf(DCHAend);
Para multiplicar el numerador de la funcin de transferencia por el nuevo trmino utilizamos la funcin ya vimos en la seccin dedicada al clculo con polinomios.

conv

que

>> num=conv([1,2],num);
El paso siguiente es reconvertir la funcin de transferencia en el tipo estructura.

>> TOTAL=tf(num,den,TSAM=0,'IN','OUT'); >> sysout(TOTAL,'tf') Input(s) 1: IN

CAPTULO 7. TEMAS AVANZADOS


+

131

k
-

SYS

Figura 7.2: Diagrama de bloques resuelto

Nyquist plot from u1 to y1, w (rad/s) in [1.000000e-01, 1.000000e+02] 6 +w -w 4

2 Im( G(jw) )

-2

-4

-6 -3 -2 -1 0 Re( G(jw) ) 1 2

Figura 7.3: Diagrama de Nyquist del sistema

Output(s): 1: OUT transfer function form: 10*s^1 + 20 ---------------------------------1*s^3 + 3*s^2 + 1.554e-15*s^1 + 10

7.6.3. Anlisis en frecuencia


De nada serviran todas las funciones de construccin de bloques si luego no podemos analizar el comportamiento de nuestro sistema. Esta parte del toolkit es sin duda su punto fuerte. Una de las pocas cosas que debemos tener en cuenta es que el sistema que se estresolviendo cuando se hace el anlisis en frecuencias no es el original sino el de la gura 7.2:

bode

Hace el anlisis bode del sistema. En el caso que no se soliciten argumentos de salida se dibuja el diagrama bode

nyquist Hace el anlisis nyquist de sistema. nichols Hace en anlisis nichols del sistema. 7.6.3.1. Ejemplo de anlisis en frecuencia
Aprovechando que ya hemos creado un sistema en la sesin para hacer el diagrama de Nyquist basta con:

>> nyquist(TOTAL)
Lo que genera la gura (7.3). Los diagramas de bode son igualmente sencillos de conseguir (gura 7.4):

>> bode(TOTAL)
Introduccin informal a Matlab y Octave

132

7.7. RESOLUCIN DE EDPS, FORMULACIN DIFERENCIAL.

|[Y/U](jw)|, u=u1, y=y1 10 0 -10 -20 -30 -40 -50 -60 0.1 1 Frequency in rad/sec phase([Y/U](jw)), u=u1, y=y1 10 100

Gain in dB Phase in deg

150 100 50 0 0.1

1 Frequency in rad/sec

10

100

Figura 7.4: Grca bode del sistema

7.7. Resolucin de EDPs, formulacin diferencial.

Parte III

Ejercicios

133

CAPTULO 8
Ejercicios resueltos
Este captulo se basa en los ejemplos. Se propondrn una serie de ejercicios, se comentarn los algoritmos necesarios para resolverlos y nalmente se dar la solucin a cada uno de ellos.

Metodologa de programacin
Quizs el mayor punto fuerte de Matlab o Octave no es su sencillez o su productividad sino la gran cantidad de funciones tiles que nos proporcionan. El ncleo de Matlab son slo unos pocos Mbytes, en cambio la instalacin completa ocupa tres CD-ROMs. Todo son funciones y archivos cuya razn de ser es hacernos la vida mucho ms fcil. Esto genera una ley un poco paradjica:

cuanto menos programemos mejores sern nuestros scripts.

Uno puede pensar que el cdigo que escribe uno mismo es mejor, que si al intuitrprete le pasamos todas las lneas que debe usar ir ms rpido. Que si tenemos que cargar ms funciones en memoria haremos que la ejecucin vaya ms lenta... Es justo lo contrario. La mayora de las funciones en Octave, por ejemplo, son funciones escritas en C++ o en Fortran compiladas de una manera especial para que Octave las interprete. Signica que la velocidad de ejecucin de estas subrutinas ser mucho ms cercana a la velocidad de los programas binarios que a la del intrprete.

8.1. Ejercicio. Clculo de un gradiente


Un clculo muy comn con una muestra de datos bidimensional es calcular una especie de gradiente numrico denido como:

grad(M ) =

M (i,j +1)M (i,j 1) 2 M (i+1,j )M (i1,j ) 2

x (M ) y (M )

Que genera una matriz de menor tamao al perder los extremos. Escribir la funcin que devuelve el resultado en una variable tipo estructura:

grad.x=x (M )

grad.y=y (M ).

8.1.1. Gua para la resolucin del ejercicio


Lo ms complicado de este ejercicio es entender el enunciado. En el fondo es exactamente el mismo clculo que un gradiente numrico con la diferencia de que en este caso no nos importa la distancia entre los puntos. Lo ms prctico para calcular la frmula es construir una submatriz por cada elemento de la ecuacin en diferencias; para calcular la submatriz es necesario saber que el ltimo elemento de cualquier matriz o vector se puede llamar Por ejemplo, si nosotros queremos los elementos del quinto al ltimo del vector en vez de calcularlo lo ms prctico es hacer

> >u(5:end).

end. u pero no sabemos sus dimensiones,

8.1.2. Solucin del ejercicio


function[grad]=mygradient(M) grad.x = 0.5*(M(:,3:end)-M(:,1:end-2));

135

136

8.2. EJERCICIO. DISEO DE UNA TOBERA

grad.y = 0.5*(M(3:end,:)-M(1:end-2,:));

8.2. Ejercicio. Diseo de una tobera


Queremos disear una tobera convergente divergente. Para ello impondremos que el radio de salida sea 10 veces mayor que el radio de la garganta, y que la tobera se forma mediante dos parbolas, una con eje en eje en

y otra con

x.

Las condiciones sern que en el punto de empalme de los dos arcos haya continuidad tanto de la funcin

como de la derivada primera. Las dos funciones a ajustar sern entonces (con el problema convenientemente adimensionalizado)

y = P x2 + 0,1

y+ = l

Ax + B x
donde se empalman los dos arcos:

Entonces tenemos el sistema de ecuaciones siguiente, donde

es el punto en

A 2P l = 2 Al + B P l2 + 0,1 = Ax + B A+B =1
Donde se demuestra que existe solucin para

aproximadamente

0,9 < P < 1,2. P = 0,9, P = 1


y

1. Resolver el sistema de ecuaciones anterior y representar las soluciones de

P = 1,2

8.2.1. Gua para la resolucin del ejercicio


Lo primero que debemos hacer es entender el enunciado, para ver ms claro lo que se pide, es bueno dibujar las dos curvas que se nos proponen, para ello haremos;

octave:1> fplot('[x. ^2+0.1,sqrt(x)]',[0,1])


Para resolver numricamente sistemas de ecuaciones lineales usaremos la funcin teclearemos en la lnea de comandos:

fsolve. Para saber cmo funciona

octave:2> help fsolve

8.2.2. Solucin del ejercicio


El script que nos resuelve el problema es el siguiente:

function[f]=ttb(x) global Pi f(1)=x(1)/(2*sqrt(x(1)*x(3)+x(2)))-2*Pi*x(3); f(2)=Pi*x(3)**2+0.1-sqrt(x(1)*x(3)+x(2)); f(3)=sqrt(x(1)+x(2))-1; end function[f]=tobera(x,a,b,l,P) if x<l f=P*(x*x)+0.1; else f=sqrt(a*x+b); endif end x0=[1 1 1]; P=[0.9 1 1.2]; hold on for i=1:3 global Pi Pi=P(i); [res]=fsolve('ttb',x0); xcoord=linspace(0,1,100);

CAPTULO 8. EJERCICIOS RESUELTOS

137

for j=1:100 tob(j)=tobera(xcoord(j),res(1),res(2),res(3),P(i)); end plot(xcoord,tob) end hold off


El resultado lo vemos en la gura 8.1.
1.1 1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1

line 1 line 2 line 3

0.2

0.4

0.6

0.8

Figura 8.1: Resultado del script

8.3. Ejercicio. El atractor de Lorentz


Se quiere integrar la ecuacin diferencial del Atractor de Lorentz , de ecuaciones:

x = a(y x) y = x(b z ) y z = xy cz
y representarla en el espacio.

con

a = 10, b = 28, c =

8 3

8.3.1. Gua para la resolucin del Ejercicio


Primero escribimos la funcin correspondiente a la ecuacin diferencial. En las subrutinas de resolucin de EDOs siempre tenemos que introducir la funcin de la forma variables un vector. La rutina de Octave que nos integra la ecuacin diferencial es ecuacin diferencial. El comando para representar curvas paramtricas en 3 dimensiones es Escribiremos todo en un script y lo ejecutaremos

dx dt

= f (x, t)

pudiendo ser cualquiera de las

lsode;

en Matlab utilizaremos

ode45

porque

el problema no es sti. Utilizar la ayuda para saber de qu manera tenemos que escribir la funcin de la

plot3.

8.3.2. Solucin del ejercicio


8.3.2.1. Octave
x=0; function xdot=func(x,t) a=10;b=28;c=8/3;
Introduccin informal a Matlab y Octave

138

8.3. EJERCICIO. EL ATRACTOR DE LORENTZ

xdot(1,1)=a*(x(2)-x(1)); xdot(2,1)=x(1)*(b-x(3))-x(2); xdot(3,1)=x(1)*x(2)-c*x(3); end x0=[1;1;1]; t=linspace(0,50,5000); tic;x=lsode( "func ",x0,t);toc plot3(x(:,1),x(:,2),x(:,3))
dando como resultado la gura 8.2:

line 1

50 45 40 35 30 25 20 15 10 5 0 30 20 -20 10 -15 -10 0 -5 0 5 -10 10 15 -20 -30 20

Figura 8.2: Resultado del script y el tiempo necesario para resolver la EDO que es de La funcin

3,1488

lsode

segundos

es mucho ms verstil que las funciones para la integracin de ecuaciones diferenciales de en forma de vector columna como nos obliga Matlab pero aceptara igualmente el uso de

Matlab. Tambin lo es en el sentido que es menos rigurosa en la manera de escribir la funcin, en este caso hemos escrito la variable

xdot

un vector columna. Octave permite denir la funcin en el script de modo que podemos resolver el problema con un nico archivo.

8.3.2.2. Octave no sti


El mtodo de integracin por defecto es explcito de modo que podemos acelerar el proceso si utilizamos un esquema Adams-Bashforth incluyendo este comando en el script:

lsode_options('integration method','non-stiff')
Podemos hacerlo sin miedo porque el problema del atractor de Lorentz, aunque es catico, no es sti. El tiempo de ejecucin desciende a

2,0016

segundos.

8.3.2.3. Octave y C++


Ya hemos visto que podemos utilizar funciones escritas en otros lenguajes para aumentar la velocidad de nuestros scripts. En el caso de este ejercicio la velocidad conseguida por la funcin hemos aprendido a hacerlo en la seccin 7.4. Supongamos que ya bastante ms escribiendo la funcin de la ecuacin diferencial en C++ y utilizando la aplicacin usaremos del mismo modo que cualquier funcin. El script que resuelve el problema es:

lsode es aceptable pero podemos rebajarla mkoctfile. Ya disponemos del archivo eqlorentz.oct que

t=linspace(0,50,5000); tic;x=lsode( "eqlorentz ",[1;1;1],t);toc plot3(x(:,1),x(:,2),x(:,3))

CAPTULO 8. EJERCICIOS RESUELTOS


La nueva versin del script es capaz de resolver el problema en tan slo tiempo anterior.

139

0,28444

segundos que es el 10 % del

8.3.2.4. Octave y C++ no sti


La mxima optimizacin se consigue de este modo. El tiempo se rebaja hasta

0,17314

segundos. Aunque todas

estas consideraciones sobre velocidad pueden parecer intiles debemos tener en cuenta que la integracin de EDOs y EDPs son los problemas numricos ms exigentes en lo que respecta a uso de CPU. Entrar en este tipo de discusiones a menudo comporta grandes benecios aunque en este caso sean irrisorios. Este ltimo tiempo es comparable al obtenido con cdigo enteramente escrito en C++ y slo un poco ms lento que el escrito en C o Fortran y el esfuerzo necesario para escribir el programa ha sido mucho menor.

8.3.2.5. Octave, C++ y Fortran


Fortran es el lenguaje del clculo matricial por excelencia. Hemos visto ya la manera de producir wrappers para funciones en Fortran. Su utilidad, ms que para escribir pequeas funciones donde el wrapper puede ser ms largo que el cdigo til, es la de acoplar subrutinas que hagan uso de grandes cantidades de memoria con distintas precisiones en coma otante. La velocidad de Fortran es aproximadamente la misma que la de C++ pero aporta ventajas distintas a la velocidad por lo dicho anteriormente.

8.3.2.6. Matlab
(lorentz.m): En Matlab necesitaremos dos archivos. El archivo de funcin devuelve el resultado en forma de vector columna

function xdot=lorentz(t,x) a=10;b=28;c=8/3; xdot(1,1)=a*(x(2)-x(1)); xdot(2,1)=x(1)*(b-x(3))-x(2); xdot(3,1)=x(1)*x(2)-c*x(3); end x t

Fijmonos que el orden de las variables de la cabecera

cambian segn la rutina que usemos. El script ser:

x=0;t=0; tic;[t,x]=ode45(@lorentz,[0,50],[1,1,1]);toc plot3(x(:,1),x(:,2),x(:,3))

8.4. Ejercicio. Clculo de una integral doble


La integral

I=

tiene como resultado

e(x

+y 2 )

dx dy

Calcular la solucin

con un nico comando.

1 El

uso de lenguajes pegamento es una prctica cada da ms habitual. Escribir un cdigo enteramente en C o Fortran es bastante

costoso tanto por el tiempo de desarrollo como por el esfuerzo necesario. Muchas veces se empieza con un prototipo escrito con un lenguaje de RAD (Rapid Application Development) y posteriormente se reescriben sus partes. El mayor obstculo en los proyectos grandes es que deben participar varios desarrolladores. Cada uno puede tener sus preferencias y las guas de estilo no siempre son una solucin efectiva porque slo arreglan el formato del cdigo escrito. Todas estas dicultades unidas al aumento de velocidad de lenguajes como Python o Matlab ha llevado a la creacin del concepto de lenguaje pegamento. Se trata de dejar a medias el cdigo entre el prototipo y el programa denitivo. Partiendo del prototipo se van analizando las partes que consumen ms recursos y, sin cambiar las cabeceras ni el esquema de variables, se reescriben en algn lenguaje rpido. Se para cuando se consigue un equilibrio entre nivel de interactividad, velocidad y coste de mantenimiento de cdigo. Probablemente el mejor lenguaje pegamento sea Python gracias a Pyrex, SWIG y F2Py. El primero es capaz de convertir el cdigo Python en C++ automticamente (rendimiento mximo y coste cero) y el segudo y el tercero son generadores automticos de interfaces, SWIG para C y C++ y F2Py para Fortran 77 y Fortran 95.

Introduccin informal a Matlab y Octave

140

8.4. EJERCICIO. CLCULO DE UNA INTEGRAL DOBLE

8.4.1. Gua para la resolucin del ejercicio


La funcin que implementa la integral doble en matlab es

dblquad mientras que en Octave es quad2dg. Ambas inline


o con una funcin annima. Las rutinas

funciones tienen una cabecera idntica, las nicas diferencias son el nombre y el algoritmo de clculo. Para pasarles la funcin a integrar como argumento usaremos una sentencia de integracin tienen muchos problemas con las singularidades porque trabajan con una precisin limitada, esto nos impide usar lmites de integracin demasiado grandes y ni mucho menos podremos usar

Inf

. Con

[10, 10]

[10, 10]

vamos a conseguir 5 cifras signicativas.

Por si alguien an no est trabajando con Octave esta es la ayuda de la funcin

quad2dg.

>> help quad2dg quad2dg is the user-defined function from the file /usr/share/octave/2.1.64/site/m/octave-forge/integration/quad2dg.m usage: int = quad2dg('Fun',xlow,xhigh,ylow,yhigh) or int = quad2dg('Fun',xlow,xhigh,ylow,yhigh,tol) This function is similar to QUAD or QUAD8 for 2-dimensional integration, but it uses a Gaussian quadrature integration scheme. int -{}- value of the integral Fun -{}- Fun(x,y) (function to be integrated) xlow -{}- lower x limit of integration xhigh -{}- upper x limit of integration ylow -{}- lower y limit of integration yhigh -{}- upper y limit of integration tol -{}- tolerance parameter (optional) Note that if there are discontinuities the region of integration should be broken up into separate pieces. And if there are singularities, a more appropriate integration quadrature should be used (such as the Gauss-Chebyshev for a specific type of singularity).

8.4.2. Solucin del ejercicio


Tenemos mltiples opciones: Con

inline
Matlab:

>> dblquad(inline('exp(-(x.*x+y.*y))'),-10,10,-10,10) ans = 3.1416

Octave:

>> quad2dg(inline('exp(-(x.*x+y.*y))'),-10,10,-10,10) ans = 3.1416


Con una funcin annima:

Matlab:

>> dblquad(@(x,y) exp(-(x. ^2+y. ^2)),-10,10,-10,10) ans = 3.1416

CAPTULO 8. EJERCICIOS RESUELTOS

141

Octave:

>> quad2dg(@(x,y) exp(-(x. ^2+y. ^2)),-10,10,-10,10) ans = 3.1416

8.5. Ejercicio. Resolucin de la ecuacin de Laplace en un dominio bidimensional


Resolver la ecuacin de Laplace en un dominio rectangular por diferencias nitas con condiciones de contorno Dirichlet. La ecuacin de Laplace es la ecuacin elptica ms sencilla: se convierte en:

2 = 0,

que formulada en dos dimensiones

2 2 + 2 =0 x2 y
Si se toman diferencias nitas centradas de segundo orden para puntos dependiendo de en diferencias siguiente:

iyj

llegamos a la ecuacin

(i + 1, j ) 2(i, j ) + (i 1, ) (i, j + 1) 2(i, j ) + (i, j 1) + =0 x2 y 2


Esta ecuacin puede ser expresada en forma de sistema de ecuaciones lineales independiente que aparece al aplicar las condiciones de contorno y

A = b,

donde

es la matriz de incgnitas

b es un trmino expresada en

forma de vector columna. La traslacin del problema bidimensional a un vector de incgnitas es un paso que nos puede costar de entender pero si tenemos una matriz de incgnitas el tensor del sistema tendr tres dimensiones con lo que ya no tendremos rutinas escritas para resolver el sistema. Usaremos como parmetros matriz del sistema va a tener

quedaramos sin memoria. Esta matriz de incgnitas se va a convertir en un vector Sera un buen caso de aplicacin de matrices sparse

dx=2, dy=3, n=50, m=50. No podemos utilizar muchos ms elementos porque se nos n m, lo que signica que la (n m)2 elementos. Para un dominio de 100 por 100 puntos llegamos a 108 puntos.

8.5.1. Gua para la resolucin del ejercicio


1. Escribir una funcin ndices

posterior:

place que implemente la transformacin de la matriz al vector. La entrada sern los j y el nmero de elementos por columna n. La salida de la funcin ser la posicin en el vector place=i+n(j-1).

2. Crear la matriz del sistema con la ecuacin en diferencias y la funcin creada en el apartado anterior 3. Poner las condiciones de contorno al gusto en el vector del trmino independiente y resolver el sistema lineal

a ) Para resolver el sistema lineal del modo usual basta con hacer

b ) Para resolver el sistema con matrices sparse primero creamos la matriz sparse con:

A.

spA=sparse(A)
memoria.

y luego resolveremos el sistema del modo usual. Es una buena idea eliminar la matriz del sistema de la

8.5.2. Solucin del ejercicio


Primero denimos las constantes del problema

dx=2;dy=3;n=50;m=25;
A continuacin creamos una funcin que reordena cualquier elemento de una matriz bidimensional en un vector en el que se concatenan las columnas.

function place=place(i,j,n) place=i+n*(j-1); end


Introduccin informal a Matlab y Octave

142 8.5. EJERCICIO. RESOLUCIN DE LA ECUACIN DE LAPLACE EN UN DOMINIO BIDIMENSIONAL


Ahora denimos la matriz del sistema teniendo en cuenta que la incgnita no va a ser una matriz de dos dimensiones sino un vector. Esto hace que la matriz del sistema tenga en realidad

nm nm

elementos.

A=zeros(n*m,n*m); for i=1:n*m A(i,i)=1; end for i=2:n-1 for j=2:m-1 A(place(i,j,n),place(i,j,n))=-2*(1/(dx*dx)+1/(dy*dy)); A(place(i,j,n),place(i-1,j,n))=1/(dx*dx); A(place(i,j,n),place(i+1,j,n))=1/(dx*dx); A(place(i,j,n),place(i,j-1,n))=1/(dy*dy); A(place(i,j,n),place(i,j+1,n))=1/(dy*dy); end end

Una vez denida la matriz del sistema creamos el vector del trmino independiente que contiene las condiciones de contorno.

i=1; for j=1:m b(place(i,j,n))=sin(pi*(j-1)/(m-1)); end i=n; for j=1:m b(place(i,j,n))=-sin(pi*(j-1)/(m-1)); end j=1; for i=1:n b(place(i,j,n))=sin(pi*(i-1)/(n-1)); end j=n; for i=1:n b(place(i,j,n))=0; end

Y nalmente resolvemos el sistema lineal.

T=A \b'; T=reshape(T,n,m); contour(T);

El resultado del script son las guras 8.3 y 8.4.

CAPTULO 8. EJERCICIOS RESUELTOS

143

line 1

1 0.8 0.6 0.4 0.2 0 -0.2 -0.4 -0.6 -0.8 -1

1 0.8 0.6 0.4 0.2 0 -0.2 -0.4 -0.6 -0.8 -1

10

15

20

25

30

35

40

45

10

15

20

25

30

35

40

45

50

Figura 8.3: Supercie solucin

En el captulo dedicado a la representacin grca de soluciones hemos hablado sobre lo poco tiles que suelen ser las superfcies coloreadas para dar un resultado. Aunque una de estas representaciones pueda parecer muy explicativa e intuitiva nunca debemos perder de vista que lo que nos importa es mostrar un resultado y una superfcie no lo consigue. Por muy bien que coloquemos los colores o las barras no conocemos el valor de cada punto con precisin y si encima colocamos lneas de nivel dotamos al grco de un exceso de informacin. Aunque sea mucho ms espartano y pueda parecer inapropiado la solucin al problema son las curvas de nivel, en ingls contours . Aunque en un principio cueste un poco ms entender la solucin estamos ofreciendo muchsima ms informacin de un modo netamente ms simple. Se podra decir que no hay motivos para no utilizar las curvas de nivel a parte de intentar demostrar nuestra pericia en el uso de Matlab.

50 45 40 35 30 25 20 15 10 5 0 5 10 15 20 25 30 35 40 45 50 0

0.8 0.6 0.4 0.2 0 -0.2 -0.4 -0.6 -0.8

Figura 8.4: Supercie solucin

Los grcos de curvas de nivel pueden ajustarse perfectamente a nuestras necesidades. Una prctica muy comn y beneciosa es la de embeber el valor de cada curva dentro de la misma para no obligar al lector a mirar la leyenda.

Introduccin informal a Matlab y Octave

144 8.5. EJERCICIO. RESOLUCIN DE LA ECUACIN DE LAPLACE EN UN DOMINIO BIDIMENSIONAL

8.5.2.1. Mejorar la solucin. Clculo de tiempos.


Si analizamos el cdigo de la solucin es evidente que estamos utilizando pocas funciones de la biblioteca. Adems estamos haciendo una de las pocas cosas casi prohibidas en Matlab que es crear una matriz por fuerza bruta. Un primer paso para mejorar la ejecucin de un cdigo es comprobar qu partes consumen ms recursos e intentar mejorarlas aisladamente. Si no somos capaces de conseguirlo nos replantearemos la solucin de un modo global. Para calcular los tiempos llenaremos el cdigo con las funciones

tic

toc.

dx=2; dy=3; n=50; m=50; function place=place(i,j,n) place=i+n*(j-1); end A=zeros(n*m,n*m); tic for i=1:n*m ... end toc;disp('Creacion de la matriz del sistema'),disp(toc);tic; i=1; for j=1:m b(place(i,j,n))=sin(pi*(j-1)/(m-1)); ... b(place(i,j,n))=0; end toc;disp('Creacion del vector b'),disp(toc);tic; T=A \b'; toc;disp('Resolucion del sistema'),disp(toc); T=reshape(T,n,m);
Los tiempos en cada paso son:

>> ejercicio4 Creacion de la matriz del sistema 1.0611 Creacion del vector b 0.017038 Resolucion del sistema 2.1457
Parece que debemos mejorar la construccin de la matriz del sistema y la resolucin del mismo. Cmo? El primer paso suele ser analizar la forma de la matriz con la funcin

spy.

>> spy(A)
Que tiene como resultado el siguiente patrn (gura 8.5): Esto nos demuestra que es una matriz n-diagonal por bandas lo que entra en la denicin de matriz sparse. Parece que la solucin a nuestros ligeros problemas de velocidad pueden solucionarse con el uso de este tipo de matrices.

8.5.2.2. Resolucin del problema mediante matrices sparse(+)


Uno de los errores cometidos en la primera solucin propuesta es que no utiliza las rutinas de creacin de matrices disponibles. La alternativa es utilizar bucles utilizaremos

for

para crearla por fuerza bruta, solucin de ningn modo

recomendable. La mejor opcin suele ser utilizar la funcin

spdiags.

diag

pero como estamos tratando con matrices sparse

CAPTULO 8. EJERCICIOS RESUELTOS


2500

145

2000

1500

1000

500

500

1000

1500

2000

2500

Figura 8.5: Patrn de elementos no nulos de la matriz del sistema

8.5.2.3. Resolucin del problema con un mtodo iterativo.


Para resolver el problema por un mtodo directo es estrictamente necesario romper la matriz para convertirla en un vector. Esto hace que no podamos utilizar los operadores diferenciales en forma de matriz tal como veremos en el ejercicio 8.6. Un truco para mantener la integridad de la matriz y poder utilizar estos operadores es resolver el problema con un mtodo iterativo. Aunque estemos multiplicando una matriz llena por matrices casi vacas el resultado se acelera considerablemente. La teora de este mtodo es bastante sencilla. Si aplicamos el operador laplaciano a la matriz bidimensional el problema numrico se reescribe del siguiente modo.

Dx + Dy

=0

Este planteamiento carece de solucin analtica pero sirve para plantear un problema iterativo en el que slo hay que evaluar la expresin. Empezaremos la subrutina del mismo modo que la anterior, deniendo la funcin que recoloca los elementos de la matriz bidimensional.

dx=2;dy=3;global n=50;global m=50; % resolucion del problema con un solver iterativo construccion de los % operadores en diferencias function place=place(i,j,n) place=i+n*(j-1); end
Ahora deniremos las matrices de los operadores diferenciales. Las denimos como variables globales al igual que las dimensiones de la matriz porque son necesarios dentro de la funcin que calcula el paso de iteracin y sta puede tener slo un argumento de entrada.

global DX=diag([1,-2/(dx*dx).*ones(1,n-2),1],0).+... diag([0,1/(dx*dx).*ones(1,n-2)],1).+... diag([1/(dx*dx).*ones(1,n-2),0],-1); global DY=diag([1,-2/(dy*dy).*ones(1,n-2),1],0).+... diag([0,1/(dy*dy).*ones(1,n-2)],1).+... diag([1/(dy*dy).*ones(1,n-2),0],-1);


A continuacin la funcin que calcula el trmino en cada iteracin. Notemos el hecho de que el argumento que recibe la funcin debe ser un vector por requerimientos de la rutina de resolucin. Para calcular sobre las matrices utilizamos la funcin

reshape.

function global global global global

[AT]=calcstuff(T) n m DX DY
Introduccin informal a Matlab y Octave

146

8.6. EJERCICIO. UN PROBLEMA DE CALOR UNIDIMENSIONAL

rT=reshape(T,n,m); AT=reshape((DX*rT)+(rT*DY'),n*m,1); end


Ahora es el turno del trmino independiente que se dene gracias a la funcin

place

denida anteriormente.

i=1;j=1;b=1; for j=1:m b(place(i,j,n))=sin(pi*(j-1)/(m-1)); end i=n; for j=1:m b(place(i,j,n))=-sin(pi*(j-1)/(m-1)); end j=1; for i=1:n b(place(i,j,n))=sin(pi*(i-1)/(n-1)); end j=n; for i=1:n b(place(i,j,n))=0; end
Y nalmente resolvemos el sistema.

tic;T=pcg('calcstuff',b',tol=1e-6,maxit=100); disp('Tiempo de calculo'),disp(toc)


El mtodo utilizado para resolver el problema es el del Gradiente Conjugado Precondicionado. Para utilizarlo debemos tener en cuenta que el nmero de iteraciones por defecto no es sufciente; lo corregimos y lo situamos en 100. El tiempo de proceso ha pasado de ms de tres segundos a 0.24929 . Este programa no sera posible sin el uso inteligente de las variables globales tal como las hemos utilizado en otros ejemplos.

8.6. Ejercicio. Un problema de calor unidimensional


Este ejercicio requiere la funcin

trisolve

que est disponible en Octave. Matlab no tiene ninguna rutina para para montar la matriz sparse y luego resolveremos el sistema

resolver directamente sistemas tridiagonales porque trata este tipo de matrices como sparse. Para resolver el mismo problema en Matlab utilizaremos la funcin de ecuaciones del modo usual.
Este ejercicio es una pequea demostracin de hasta dnde puede llegar el ahorro de cdigo con Matlab. Se trata de resolver la ecuacin del calor unidimensional con condiciones de contorno Dirichlet. La discretizacin espacial sern diferencias nitas de sevundo rden y la temporal ser un esquema Crank Nicholson. Tomaremos este esquema porque permite usar saltos de tiempo ms grandes, de hecho nos permitir llegar al resultado sin tener que calcular ninguna iteracin temporal. La solucin propuesta tiene slo unas pocas lneas. Una solucin tan breve requiere algo de preparacin matemtica de modo que hay que estar muy atento al planteamiento analtico del problema.

spdiags

Discretizacin de la ecuacin completa


La ecuacin del calor unidimensional es la EDP parablica ms sencilla:

t = xx
Como cualquier EDP parablica se puede formular de la siguientes manera:

d = F (x, t) dt
Si utilizamos un esquema Crank Nicholson la discretizacin temporal ser de la forma:

n+1 n 1 = F n+1 + F n t 2
2 Este
ejercicio se ha resuelto en un AMD Athlon 3000+.

CAPTULO 8. EJERCICIOS RESUELTOS

147

Discretizando tambin el lado derecho de la ecuacin con diferencias nitas de segundo orden llegamos a la ecuacin discretizada:

+1 n i

t 2

+1 n+1 +1 n + n i+1 2i i1 x2

= n i +

t 2

n n n n+1 2i + i1 2 x

Formulacin matricial del problema.


La ecuacin anterior puede escribirse del modo siguiente:

n+1

t t An+1 = n + An 2 2 B = I
t 2 A y utilizando un

Agrupando trminos, diciendo que

x = 1

(en el fondo es slo adimensionalizar):

B n+1 = B+ n
donde la matriz

tiene la forma:

A= . . . 0 0

2 1 0

1 2 1

0 1 2 0 0

0 0 1
.. .

1 0

2 1

. . . 1 2

0 0 0

Condiciones de contorno e iniciales.


Condiciones de contorno:

=0

en

x=0

=1

en

x = 10

Condiciones iniciales:

(x) = 0

en los puntos interiores.

Dar una solucin al problema para cualquier tiempo inferior a

t = 10.

8.6.1. Gua para la resolucin del ejercicio


La dicultad de la resolucin de este problema radica en la correcta situacin de las condiciones de contorno en la matriz, el uso correcto de las submatrices y entender el funcionamiento de

trisolve.

8.6.2. Solucin del ejercicio (Octave)


Parte del ejercicio es entender qu estamos haciendo para llegar a la solucin. Lo bueno de abreviar en la escritura es que adems el cdigo resultante suele ser mucho ms rpido.

phi=zeros(10,1); phi(10,1)=1; dt=0.1; for i=1:50 #Activate loop in case of precision leak phi(2:9)=(1-dt)*phi(2:9)+0.5*dt*phi(1:8)+0.5*dt*phi(3:10); phi=trisolve(-[0.5*dt*ones(8,1);0],[1;(1+dt)*ones(8,1);1],... -[0;0.5*dt*ones(8,1)],phi); end
De este modo llegamos al resultado del problema con una precisin aceptable. La gura del perl de temperaturas es:

Introduccin informal a Matlab y Octave

148

8.6. EJERCICIO. UN PROBLEMA DE CALOR UNIDIMENSIONAL

Solucion de la ecuacion del calor unidimensional 1

0.8

Temperatura

0.6

0.4

0.2

0 0 0.2 0.4 Longitud


Figura 8.6: Figura solucin

0.6

0.8

8.6.3. Solucin del ejercicio (Matlab)


Aunque la resolucin de sistemas tridiagonales es un clsico del clculo numrico Matlab no cuenta con ninguna funcin para ello. El motivo es que decidieron incluir las matrices tridiagonales dentro de las matrices sparse. Las matrices tridiagonales o con pocas bandas se resuelven ecientemente mediante un mtodo directo con lo que en este caso Matlab tiene un error de diseo. No tendra ningn sentido programarse una funcin que resolviera sistemas tridiagonales en Matlab porque todas estas rutinas son en el fondo interfaces a bibliotecas en Fortran y en C por motivos de velocidad. En este caso la dimensin de la matriz no justica el uso del almacenamiento sparse de modo que utilizaremos la funcin

diag

para crear una matriz segn sus diagonales:

phi=zeros(10,1); phi(10,1)=1; dt=0.1; B=diag([1,(1+dt)*ones(1,8),1],0)+... diag(-[0.5*dt*ones(1,8),0],-1)+... diag(-[0,0.5*dt*ones(1,8)],1); for i=1:50 phi(2:9)=(1-dt)*phi(2:9)+0.5*dt*phi(1:8)+0.5*dt*phi(3:10); phi=B \phi; end

8.6.4. Comprobacin de la evolucin temporal


La siguiente modicacin del programa permite comprobar la evolucin de los pasos temporales sacando por pantalla varios estados temporales de la solucin. Aunque el problema es estable para saltos temporales muy grandes preferiremos acortarlo por motivos de precisin. Representaremos la solucin en los tiempos

t =

[0,1, 1, 2, 5, 10, 20, 50, 100].

Muy atentos al modo de denir la condicin lgica que indica cundo pintar la curva:

phi=zeros(10,1); phi(10,1)=1;dt=0.1; # times to output tout=[0.1,1,2,5,10,20,50,100]; hold on for i=1:500 phi(2:9)=(1-dt)*phi(2:9)+0.5*dt*phi(1:8)+0.5*dt*phi(3:10); phi=trisolve(-[0.5*dt*ones(8,1);0],[1;(1+dt)*ones(8,1);1],... -[0;0.5*dt*ones(8,1)],phi);

CAPTULO 8. EJERCICIOS RESUELTOS

149

if sum((dt*i)*ones(1,length(tout))==tout)==1 plot(phi) end end hold off title('Solucion de la ecuacion del calor unidimensional') xlabel('Longitud (adimensional)') ylabel('Temperatura (adimensional)') legend({'0.1','1','2','5','10','20','50','100'},2)
Llegamos nalmente a la siguiente grca:

Soluciones de la ecuacion del calor unidimensional 1

0.8

Temperatura

0.6

0.4

0.2

0 0 0.2 0.4 Longitud


Figura 8.7: Evolucin del perl de temperaturas

0.6

0.8

8.7. Ejercicio. Nociones de turbulencia

Introduccin informal a Matlab y Octave

150

8.7. EJERCICIO. NOCIONES DE TURBULENCIA

CAPTULO 9
Ejercicios propuestos
9.1. Matrices
1. Dado el vector tales.

x = [3, 1, 5, 7, 9, 2, 6], intentar prever a mano el resultado de las siguientes operaciones elemen-

a) b) c) d) e) f) g)

x(3) x(1:7) x(1:end) x(1:end-1) x(6:-2:1) x([1,6,2,1,1]) sum(x)


A = [2, 4, 1; 6, 2, 7; 3, 5, 9],
calcular:

2. Dada la matriz

a ) El vector

x1

que es la primera la de

A.

b ) Asignar las 2 primeras las de

a un vector llamado

y.
A.

c ) Calcular la suma de los elementos de las columnas de d ) Calcular la suma de los elementos de las las de

A. A. 9 5 2 8 7 6 5 7

e ) Calcular la desviacin estndar de cada columna de


3. Dada la matriz:

2 3 A= 8 4
a ) Asignar los elementos impares de la matriz b ) Asignar los elementos pares de la matriz

7 1 1 2

a otra matriz

a otra matriz

c ) Calular la raz cuadrada de cada elemento de la matriz

9.2. Programacin
1. Dado el vector

x=[3 15 9 2 -1 0 -12 9 6 1]

escribir los comandos que darn los siguientes resultados,

preferiblemente en un nico comando:

a ) Devolver un vector que convierta los elementos de

en 0

b ) Convertir los elementos mltiples de 3 del vector en 3. c ) Multiplicar los valores impares de x por cinco.

151

152
d ) Asignar los valores de mdulo mayor a 10 a otro vector. e ) Convertir los elementos que son menores a la media en cero f ) Convertir los elementos que son mayores a la media en la media.
2. Escribir una funcin cuyo resultado sea:

9.2. PROGRAMACIN

y (x)

2 x4 36 x

x<6 6 x 20 20 x 36

representarla grcamente para ver que tiene forma triangular con 3. Calcular el nmero

fplot.

mediante la seguiente serie:

2 8 1 = 2 (2n + 1)2 16 (2 n 1) n=1


Cuntos trminos son necesarios para llegar a una precisin de de 100 trminos? 4. Podemos calcular una serie de Fibonacci mediante la siguiente relacin recursiva:

1 1012 ?

Cunta es la precisin de la suma

Fn = Fn1 + Fn2
Fn Fn1 se va aproxi 1+ 5 a medida que n aumenta. En qu trmino de la serie de Fibonacci nos mando al nmero ureo = 2 12 acercamos al nmero ureo con una precisin de 1 10 ?
con

F0 = F1 = 1 .

Calcular los 10 primeros nmeros de la serie de Fibonacci. La relacin

5. Los polinomios de Legendre

Pn (x)

se denen con la siguiente relacin recurrente:

(n + 1)Pn+1 (x) (2n + 1)Pn (x) + nPn1 (x) = 0


con

P0 (x) = 1, P1 (x) = x

P2 (x) =

3x2 1 . Cacular los tres siguientes polinomios y representarlos grca2 1 , 2

mente en el intervalo [-1,1] 6. Se plantea el siguiente algoritmo para calcular el nmero

Primero iniciar las constantes:

a = 1, b =

1 t= 4 y x = 1. Repetir y = a a = (a+b)/2 b = sqrt(b*y) t = t-x*(y-a)^2 x = 2*x

la siguiente secuencia de comandos hasta que llegamos a la precisin deseada:

pi_est = ((a+b)^2)/(4*t)

Por ltimo se toman los valores de

a, b,

para estimar

con:

Cuntas iteraciones son necesarias para llegar a una precisin de

1 1012 ?

7. Escribir un programa que pida por lnea de comandos un entero (n) y luego calcule lo siguiente. 1. Mientras el valor de

sea mayor que 1, cambiar el entero por la mitad de su valor si el entero es par; si es

impar cambiarlo por tres veces su valor mas 1. 2. Repetir estas operaciones cclicamente y obtener el nmero de iteraciones hasta que el algoritmo se para en 1. Por ejemplo, para

n = 10

la secuencia es 5, 16, 8, 4, 2 y 1; entonces el nmero de iteraciones han sido 6.

3. Representar la longitud de las secuencias en funcin del entero de entrada de 2 a 30 e intentar descubrir un patrn. Si no se deduce intentarlo con ms nmeros. 4. Hay algn nmero para el que la secuencia sea interminable? 8. Escribir un programa que convierta nmeros romanos en decimales. La tabla de conversion es: Romanos I V X L C D M Decimales 1 5 10 50 100 500 1000

9. Escribir un programa que haga la funcin inversa, que pase de nmeros decimales a romanos. En ambos casos el nmero se pedir por pantalla.

CAPTULO 9. EJERCICIOS PROPUESTOS

153

9.3. lgebra lineal


1. Resolver el siguiente sistema de ecuaciones lineales:

x 2y x + 3y 2x 5y
2. Sean

+ +

3z 5z

= = =

9 4 17
bases en

B = {(1, 0, 0), (0, 1, 0), (0, 0, 1)}

B = {(1, 1, 0), (1, 1, 0), (0, 0, 1)} 1 3 0 A= 3 1 0 0 0 2


en la base

R3 ,

y sea

la matriz de la aplicacin lineal

T : R3 R3 P
de

B,

base cartesiana ortogonal se pide:

a ) La matriz de cambio de base b ) La matriz de camnio de base c ) La matriz d ) Sea

B B B
.

P 1 de B A

que es la matriz

expresada en la base

[v ]B
encontrar

1 = 2 3 P 1 [T (v )]B
y luego como

[v ]B

[T (v )]B
de dos maneras, primero como tal que:

e ) Encontrar

[T (v )]B

A [v ]B

3. Crear la matriz de

55 T

Tkl = k l
y calcular sus autovalores y autovectores 4. Un proceso para encriptar un mensaje secreto es usar cierta matriz cuadrada con elementos enteros y cuya inversa es tambin entera. Se asigna un nmero a cada letra (A=1, B=2... espacio=28) y se procede como sigue a continuacin. Supongamos que la matriz es:

A=

1 2 1 1 2

2 5 2 1 4

3 8 2 0 6

4 5 8 9 7 9 6 12 8 11

y el mensaje que queremos enviar es ALGEBRA LINEAL. Para codicar el mensaje romperemos la cadena de nmeros en vectores de cinco elementos y los codicaremos.

a ) Cul ser la cadena de datos encriptada que enviaremos? b ) Descifrar el mensaje: 48 64 -40 300 472 61 96 -90 346 538 16 -5 71 182 332 68 131 -176 322 411 66 125
-170 301 417.

9.4. Clculo y Ecuaciones Diferenciales Ordinarias.


1. Hallar el rea

de la regin del plano comprendida entre la curva

y=
y su asntota. (2 ) 2. Hallar la longitud

x2 1 x2 + 1

del arco de cicloide

x = a(t sin t) y = a(t cos t)


(8a)

0 t 2

Introduccin informal a Matlab y Octave

154
3. Hallar el centro de masas de la cardioide

9.5. ESTADSTICA Y ANLISIS DE DATOS

= a(1 + cos )
(Sobre el eje de simetra y en

x=

4a 5 )

4. El pndulo esfrico tiene de ecuaciones:

sin cos g sin = l l = cos 2 sin

Integrarlas con una condicin inicial cualquiera y representar grcamente las trayectorias. 5. Resolver el sistema de ecuaciones diferenciales siguiente:

dx dt dy dt
donde

= ax + bxy cx2 = dxy ey

ecuacin y utilizando el comando

a = 0,05, b = 0,0002, c = 0,00001, d = 0,0003 y e = 0,06. Crear el mapa de fases linealizando la quiver. Resolverlo para t [0, 300] con distintos valores iniciales y ver que

las soluciones siguen el camino marcado por el gradiente numrico. 6. Resolver el siguiente sistema que representa un modelo depredador-presa:

x1 x2
con condicin inicial

= x1 (15 x2 ) = x2 (15 + x1 x2 )
Si los depredadores vienen dados por y

x1 (0) = 10

x2 (0) = 15.

x1 ,

las presas por

x2

y el

tiempo est medido en meses, cuntos predadores y presas hay al cabo de un ao? Se extingue alguna de las especies en algn momento? Representar

x1 x2

x1

en funcin de

x2 .

9.5. Estadstica y anlisis de datos


1. Generar una muestra de 1000 elementos que sigan una distribucin normal de media

10 y desviacin tpica 9.

2. Generar una muestra de 1000 elementos que sigan una distribucin uniforme de media cero y desviacin tpica

10.
3. Calcular y representar los caminos de un grupo de partculas con movimiento aleatorio connadas por un par de barreras

B+

unidades del orgen que es desde donde salen las partculas. Un movimiento aleatorio

se calcula mediante la frmula;

xj +1 = xj + s s es el nmero obtenido de una distribucin normal estandarizada de nmeros aleatorios segn la randn. Por ejemplo, N movimientos de la partcula se calcularan con el fragmento de cdigo siguiente: x(1)=0; for j = 1:N x(j+1) = x(j) + randn(1,1); end
donde funcin Se cambiarn las condiciones de contorno de la siguiente manera: 1. Reexin. Cuando una partcula se encuentre fuera de la frontera se devolver al interior del dominio como si hubiera rebotado en una pared 2. Absorcin. La partcula muere cuando entra en contacto con la pared. 3. Absorcin parcial. Es la combinacin de los dos casos previos. La partcula rebota en la pared y la perfeccin de la colisin depende de una determinada distribucin de probabilidad. Calcular una serie relevante de trayectorias y calcular:

a ) La posicin media de las partculas en funcin del tiempo. b ) La desviacin tpica de las posiciones de las partculas en funcin del tiempo. c ) Inuyen las condiciones de contorno en las distribuciones? d ) Para los casos de absorcin y absorcin parcial representar grcamente el nmero de partculas supervivientes en funcin del nmero de saltos temporales. 4. Desarrollar en serie de Fourier la funcin

f (x) = x2

< x < .

CAPTULO 9. EJERCICIOS PROPUESTOS

155

9.6. Control automtico


1. Determinar la respuesta a un impulso y a un escaln del sistema expresado mediante la funcin discreta siguiente:

y (n) = x(n) 2 cos(/8)y (n 1) + y (n 2)

Introduccin informal a Matlab y Octave

156

9.6. CONTROL AUTOMTICO

Parte IV

Apndices

157

APNDICE A
Gua de estilo. Los 10 mandamientos
En muy bueno para un lenguaje de programacin que tenga una gua de estilo asociada. Cmo formatear el cdigo debe ser algo ms que una marca de estilo personal, un estndar que todo el mundo siga a rajatabla. En algunos lenguajes la sintaxis viene acoplada a unas ciertas reglas de escritura, por ejemplo Python nos obliga a tabular las estructuras; si no ordenamos bien el inicio de las lneas el cdigo no funcionar. C, C++ y Java usan corchetes para agrupar niveles de ejecucin y se recomienda dejar slo el corchete en la lnea y tabular todo lo que contenga. En muchos casos estas reglas son en realidad recomendaciones. En Fortran recomiendan marcar los niveles de ejecucin con tabulados de dos espacios, algo parecido se recomienda en Matlab. Pero tanto en Fortran como en Matlab estas normas son sistemticamente ignoradas. El programador cientco no ha recibido ninguna educacin sobre las reglas de escritura y tiene muy poca experiencia con lenguajes ms fuertemente estructurados como C o Java. El resultado es un cdigo plano, desestructurado, desorganizado y mal comentado. Una de las herramientas esenciales para evitar este desastre es el editor de texto. Sera muy largo describir el funcionamiento de un editor de texto, simplemente diremos que es un programa que edita cdigo fuente y que tiene todas las herramientas disponibles para que sea mucho ms fcil. Colorea las palabras clave, tabula el cdigo automticamente, corrije algunos fallos comunes... Matlab posee un buen editor de textos, pero no le llega ni a la suela del zapato a Emacs o VIM. El funcionamiento de Emacs puede resultar hasta sorprendente. Imaginemos que abrimos un archivo de cdigo escrito en Fortran 95. Est lleno de archivo con Emacs slo tenemos que pulsar

if

do

sin ordenar y mal tabulado. Adems

el compilador nos dice que hay una estructura que est sin cerrar; que nos falta un

<Alt><Control><Q>

end.

Si estamos editando el

y todo el texto se tabula automticamente.

Sin embargo el estilo de un buen programador es insustituible. Matlab no tiene ninguna gua de estilo, sin embargo puede decirse que existen una serie de normas no escritas para que el cdigo sea ms leble y, no menos importante, ejecute rpido. Estas normas parecen inservibles para pequeos scripts que escribimos para consumo propio. He aprendido que cuando se recupera un script que se ha escrito seis meses antes es como si lo hubiera escrito otro. Siempre que escribamos un programa tomaremos esta actitud; lo estamos escribiendo para que un desconocido lo entienda. Todas las buenas prcticas se resumen en diez tcnicas, los 10 mandamientos del Matlab.

1.

Utilizar funciones

inline

siempre que se pueda.

Ya hemos visto que en Matlab (que no en Octave) denir una nueva funcin signica crear un archivo. Esto hace que el cdigo de el programa principal sea ms difcil de entender y de comentar. Aunque Matlab escala bien no es muy recomendable escribir programas demasiado largos y si tenemos demasiadas funciones y archivos es que no estamos haciendo las cosas bien. Las sentencias

inline

y los function handles nos ayudan a mantener el cdigo compacto y leble.

2.

Usar bucles

for

slo donde sea indispensable

Esta es la gran diferencia entre Matlab y Fortran. Una de las grandes decepciones de los programadores en Fortran cuando utilizan Matlab es la gran diferencia de velocidad. Esta diferencia existe y es de entre uno y dos rdenes de magnitud. El problema es que es gravemente acentuada por usar el estilo de Fortran en el cdigo Matlab. En Fortran los bucles

do son endiabladamente rpidos. Cuando se compila el cdigo los contadores se optimizan como

estructura entera, incluso algunos compiladores advierten cuando los bucles encapsulados no son dependientes y paralelizan la tarea automticamente. El programador en Fortran encapsula porque sabe que el compilador le va a ayudar.

159

160
Matlab no es capaz de optimizar el cdigo de esta manera porque su arquitectura no lo permite. La solucin para obtener una velocidad aceptable es usar siempre submatrices.

3.

Usar estructuras

if

planas.

Cuando hablamos de condicionales dijimos que el encapsulado tipo matroska no era recomendable porque complica mucho la lectura del cdigo. Adems disminuye la velocidad de ejecucin por la creacin de ms variables adicionales. Si utilizamos condiciones lgicas compuestas (siempre dentro de un lmite) el resultado ser ms leble y posiblemente ms rpido.

4.

Utilizar las funciones de creacin de matrices.

Las funciones como

zeros, ones, eye, linspace

meshgrid

son tremendamente tiles. El cdigo de un buen

programador estar siempre lleno de composicin de estas funciones para generar matrices. La alternativa es utilizar bucles, prohibido por el segundo mandamiento.

5.

Denir las variables de las cabeceras in situ.

Cuando se pasan los argumentos a una funcin lo habitual es crear primero las variables que los contienen y luego poner las variables en la cabecera. Si lo hacemos es casi obligado hacerlo justo antes de llamar a la funcin. De otro modo tendremos que navegar por el cdigo hasta encontrar dnde se dene la variable que pasa el argumento. Es recomendable tambin que las constantes o los argumentos simples se denan directamente en la cabecera. Puede parecer que el resultado es difcil de leer, pero cuando uno se acostumbra resulta ser todo lo contrario. Es mucho mejor una lnea con varios comandos que no repartir sentencias asociadas por todo el cdigo.

6.

Utilizar submatrices siempre que se pueda.

Este es el No matars de los mandamientos de Matlab. La alternativa es utilizar bucles con un puntero que vaya rastreando la matriz; demasiado lento. El equivalente de esta recomendacin en Fortran sera utilizar el vez de los bucles simples. Esta prctica slo tiene ventajas. El cdigo es ms leble, es plano, mejor encapsulado, se entiende perfectamente y es ms rpido. Cuando se dice que Matlab es un programa de clculo matricial no se dice gratuitamente. No hay que pensar contando ndices con la notacin del sumatorio como en Fortran, hay que pensar matricialmente.

forall en

7.

Tabular bien los bloques de ejecucin

Aunque ya hemos aprendido que lo ms importante es evitar el encapsulado de estructuras de ejecucin en algunos casos no tendremos ms salida. En ese caso el tabulado de cada uno de los bloques es muy recomendable. Adems de obteber un resultado ms leble evitaremos los errores tontos como los bucles o los condicionales sin cerrar.

8.

Comentar cualquier operacin que lo precise.

Lo repito, cuando recuperemos cdigo escrito unos meses antes ser como si lo hubiera escrito otro. puede ser que una sentencia especialmente brillante sea adems crptica; comentaremos sistemticamente todo lo que sea necesario.

9.

Escribir una cabecera de ayuda en cada funcin.

Este mandamiento es directamente derivado del octavo. A medida que escribamos funciones terminaremos con una pequea biblioteca personal. El resultado ser que tendremos que usar funciones sin recordar ni la forma de su cabecera. El comando que escribamos nosotros mismos.

help es imprescindible no slo para las funciones de la biblioteca; tambin nos servir en las

10.

Usar Octave en vez de Matlab y colaborar en el proyecto.

Las soluciones ms justas no siempre son las ms fciles. Octave es ms espartano y difcil pero ha sido posible gracias al esfuerzo de muchos desarrolladores que han colaborado desinteresadamente en el proyecto. El resultado es un programa de gran calidad que no para de mejorar da a da. El hecho de que se trate de software libre es un valor aadido. Podremos escudriar en sus entraas para descubrir su funcionamiento, extenderlo con otros lenguajes de programacin, ayudar en proyectos secundarios. Una vez se entra en este juego no se para de aprender.

El ltimo mandamiento que los recoje a todos:


Escribirs lo menos posible usando todas las funciones que puedas.

APNDICE B

ATEX Pequea introduccin a TEX y L


A X una coleccin de macros que simplican enormemente T E EX es un lenguaje de programacin de textos y L T AT X es un lenguaje dedicado a tipografa matemtica con cierto parecido a HTML. Durante muchos aos su uso. L E
ha sido muy utilizado y sigue siendo el estndar para la edicin de artculos cientcos. Es sido tan popular dentro de su mbito que sus cdigos para denir caracteres se han extendido a otros lenguajes y a los editores de frmulas.

AT X es capaz de preparar documentos con un acabado profesional con cualquer PC como nica herramienta. L E El aprendizaje no es sencillo debido a la gran inuencia que actualmente tienen los procesadores de texto y el AT X hay que compilar un archivo de documento WYSIWYG . Cuando nos dicen que para obtener un documento L E y que la salida es en formato DVI probablemente tengamos un escalofro. Lo que pasa es que hemos ganado potencia
a base de bajar el nivel de la aplicacin. Si nos miramos un procesador de texto detenidamente veremos que en realidad no estamos escribiendo lo que sale en pantalla; en realidad el procesador escribe un documento en formato

AT X sera como si nos pusieramos a XML que tiene muy poco que ver con el resultado en pantalla. Escribir en L E teclear directamente XML y pasramos del procesador de textos.
Cuanto ms potente es una herramienta ms esfuerzo requiere dominarla, an as para hacer los primeros

AT X no se requieren ms de unas horas. Para empezar es importante tener un libro o una gua. pasos con el L E Es un lenguaje que se basa en comandos con lo que tener un listado convenientemente explicado es esencial.

//filemon.mecanica.upm.es/CervanTeX/.

AT X de Espaa, Para encontrar algn tutorial se puede acceder a la pgina del grupo de usuarios de L E

http:

AT X, una especie de hbrido entre procesador de textos y Otra opcin es optar por algn procesador de textos L E AT X directa. No hay mucha variedad, suelen llamarse procesadores WYSIWYM2 porque en pantalla no escritura L E se ve el output denitivo, sigue siendo necesario compilar el documento. Los dos ms conocido son LyX y Scientic
Word. Este documento ha sido preparado con LyX. Es un gran procesador de textos libre y gratuito y completamente multiplataforma; esto es, tiene versiones para todos los sistemas operativos mayoritarios. Es um programa de gran calidad, con mucha documentacin adjunta y una comunidad muy activa. Merece la pena probarlo. Scientic Word, al igual que su hermano mayor Scientic Workplace, es un entorno parecido a LyX pero ms orientado hacia Windows. Tiene cierta compatibilidad con Microsoft Oce y soporta mejor los formatos de este sistema operativo. La diferencia entre Scientic Word y Scientic Workplace es que el segundo cuenta adems con un sistema de clculo simblico embebido. Slo existe versin para Windows.

AT X porque Matlab soporta sus smbolos en los grcos Es muy importante tener nociones de la sintaxis de L E y porque la mayora de los editores de ecuaciones basan el lenguaje de su intrprete en las mismas palabras clave.

1 What You See Is What You Get 2 Whay You See Is What You Mean

161

162

B.1. TABLA CON ALGUNOS CARACTERES T EX.

B.1. Tabla con algunos caracteres TEX.


cdigo \alpha \beta \gamma \delta \epsilon \zeta \eta \theta \vartheta \iota \kappa \lambda \mu \nu \xi \phi \rho \sigma \varsigma \tau \equiv \Im \otimes \cap \supset \int \roor \loor \perp \wedge \rceil \vee \langle smbolo cdigo \simeq \upsilon \varphi \chi \psi \omega \Gamma \Delta \Theta \Lambda \Xi \Pi \Sigma \Upsilon \Phi \Psi \Omega \forall \exists \ni \rightleftharpoons \approx smbolo cdigo \sim smbolo

\leq \infty \clubsuit \diamondsuit \heartsuit \spadesuit \leftrightarrow \leftarrow \uparrow \rightarrow \downarrow \circ \pm \geq \propto \partial \bullet \div \neq \mp

\hbar \oint \supseteq \subset \nabla \cdots \ldots \prime \top \mid \sum \iint

\Re \oplus \cup \subseteq \in \lceil

...

\cdot \neg \times \varpi \rangle

Adems de estos caracteres es importante conocer algunas convenciones de la escritura de frmulas. Antes de cada clave se puede aplicar un atributo para modicar el tipo de letra, por ejemplo el subndice se denota con el superndice con

^,

la cursiva con

\it

y la negrita con

\bf.

Para escribir la frmula siguiente:

j A =
i
haremos

i Aij

\nabla_j \cdot \bf A = \sum_j \partial_j \bf A_{ij}

APNDICE C
Software y formatos libres.
Para escribir este curso he usado una de las herramientas de publicacin ms potentes que hay en la actualidad,

A X. No he escrito directamente cdigo L AT X T EX. Es un poco ms conocida una coleccin de macros llamada L T E E sino que he usado un editor de textos llamado LyX. La calidad del documento nal es apreciable; las fuentes son
claras y la tipografa es perfecta. Probablemente a alguno le sorprenda saber que estas herramientas son gratuitas. No me reero a que las haya pirateado ni que me las hayan regalado; podemos descargarnos todos estos programas e instalarlos en nuestro ordenador de forma gratuita (siempre que respetemos la licencia adjunta). Adems no solo podemos descargar el programa, sino que el cdigo fuente tambin est disponible con una licencia que permite su modicacin y su redistribucin. T EX es quizs el ejemplo ms llamativo por ser el primero. Lo program Donald E. Knuth porque estaba muy descontento con la calidad de la tipografa de algunas editoriales con las que tena tratos. A partir de entonces la cantidad de proyectos cuya mxima es la posibilidad de compartir y redistribuir el cdigo libremente no ha hecho ms que aumentar. Otros ejemplos conocidos (algunos ms otros menos) son Linux, implementacin libre y gratuita de un ncleo de sistema operativo tipo UNIX; Emacs, posiblemente el editor ms completo y extensible que existe; Apache, el servidor web ms usado; PostgreSQL, una base de datos muy popular; KDE, un entorno de escritorio completo que rivaliza en calidad con WindowsXP y Mac OSX... El software libre tiene dos grandes ventajas respecto al comercial, el coste cero sin garanta y (ventaja poco valorada) ser proyectos llevados en comunidad. Una vez un programa comercial sale al mercado se independiza completamente de sus desarrolladores; el mantenimiento pasa a ser labor del servicio tcnico. Si el programa funciona mal o de un modo distinto al supuesto habr que llamar por telfono y solicitar ayuda. Una comunidad es una estructura completamente distinta. Supongamos que encontramos un bug en Octave, uno grave que no nos permita seguir con nuestro trabajo. A quin llamamos? No hay ninguna empresa que ofrezca garanta, adems en la licencia pone bien claro que Octave no es un producto mercantil y por tanto no est sujeto a ninguna normativa concreta. La frase usada es use this software at your own risk. Lo que haremos ser ir a google e investigar si alguien ha tenido antes el mismo problema; si la respuesta es negativa pasaremos a las listas de correo. Las listas de correo son la base de una comunidad de desarrolladores junto con los canales IRC. Para quien no lo sepa una lista de correo es una direccin de correo electrnico que manda lo que recibe a todos los miembros de la lista. Si vemos que somos los primeros en detectar el fallo debemos suscribirnos a la lista de usuarios de Octave (bastante activa, por cierto), describir el fallo y pedir amablemente que alguien nos ayude. Si tenemos suerte es probable que John W. Eaton, creador de Octave, nos responda. Si adems le damos nosotros la solucin y esto sucede unas cuantas veces puede ser que nos de permiso de escritura en el repositorio de cdigo y que nos de una cuenta de desarrollador. En Octave todo se hace a pequea escala; en proyectos grandes como KDE el proceso de desarrollo involucra a unas mil personas y varias empresas. Este fenmeno ha crecido gracias a dos pequeos detalles, el uso de licencias copyleft y el uso de estndares abiertos. He publicado este texto bajo una licencia Creative Commons, creada por una fundacin cuyo n es la publicacin de licencias de distribucin copyleft. Lo he hecho por la creencia personal de que el conocimiento debe ser pblico y gratuito. Este afn altruista puede provocar consecuencias bastante desagradables en el caso que no sea perfectamente planeado. Es aqu donde entran las licencias libres o de copyleft. Una licencia libre asegura la mxima libertad de uso; es un blindaje comercial absoluto que puede ser tan bebecioso en algunos casos como perjudicial en otros. Luego nos encontramos varias licencias que limitan las libertades de uso, siempre intentando preservar primero los derechos del autor. En este caso he utilizado una licencia no comercial pero sin posibilidad de

163

164
un trabajo derivado. Esto signica que cedo la libertad de copiar literalmente el texto sin ningn coste econmico pero que me reservo el derecho de cobrar por ello cuando quiera. Tambin impide que cualquier otro autor que copie partes del libro pueda hacerlo sin citarme. Cuando alguien con este afn altruista, normalmente acompaado de un desprecio total por el lucro, pretende programar una aplicacin o publicar un libro en comunidad nunca inventar su propio formato de distribucin. Lo que har ser buscar el formato ms extendido para que su trabajo llegue a la mayor cantidad de gente posible. Esto est asegurado con el uso de estndares abiertos. Los estndares abiertos son tipos de archivos o protocolos de comunicacin cuyas especicaciones tcnicas se han publicado enteras. Ejemplos de estndares abiertos son los protocolos TCP/IP, HTTP, FTP, SSH; los lenguajes C, C++, Python; los tipos de documentos HTML, SGML, RTF, PS, PDF, OD*... Permiten que dos programas que no tienen ninguna lnea de cdigo en comn puedan entenderse a la perfeccin. El software libre o de cdigo abierto (hay una diferencia muy sutil entre los dos) utiliza casi siempre estndares abiertos porque es absurdo no hacerlo. Cuando alguien publica un programa con su propio estndar debe hacerlo desde una posicin de fuerza para conseguir imponerlo. He aqu el gran enemigo del software libre, los estndares cerrados. Los ejemplos de estndares cerrados ms maniestos son los impuestos por Microsoft. Cada producto que sacan al mercado tiene su propio formato de archivo incompatible con los ya existentes. Es una prctica monopolstica muy habitual y las consecuencias han sido nefastas para el mundo de la informtica. Slo hace poco han decidido publicar parte de las especicaciones porque as lo han requerido varios gobiernos por motivos de seguridad nacional.

Todos los formatos cerrados son nocivos; cuanto ms extendidos ms perjudiciales. El archivo .doc ha hecho un dao irreparable. Microsoft Word es el nico procesador de textos existente que no exporta a PDF. Por qu? Porque Microsoft intenta imponer el archivo DOC para distribucin de archivos de texto. Si uno usa Windows en su ordenador es su problema, si usa Explorer all l pero si usa Microsoft Oce el problema es de todos. Utilizar un programa de software libre es una garanta
de uso de estndares abiertos. Si uno preere seguir utilizando productos de Microsoft que consiga un plugin de salida a PDF o que use el formato RTF (Rich Text Format). Todos los que no seamos esclavos de Microsoft se lo vamos a agradecer eternamente. No estoy sugiriendo que todo el mundo instale Linux en su ordenador (aunque as viviramos en un mundo mejor). Lo que s recomiendo encarecidamente es que se usen formatos abiertos para compartir documentos. Hace muy poco se publicaron las especicaciones tcnicas de la alternativa a los formatos de Microsoft Oce llamados Open Document. Los programas que lo soportan son, de momento, OpenOce y Koce. OpenOce es una suite de omtica muy completa de un invel equivalente a Microsoft Oce. Tiene versiones nativas para Linux, Windows, Solaris y Mac OSX. Koce es la suite particular de KDE y es un proyecto a una escala menor. Otro ejemplo agrante es el del estndar html. Es el lenguaje de marcas en el que estn escritas las pginas web. Todos los navegadores estn diseados para soportar todas las especicaciones del estndar excepto uno. Esta oveja negra es el Microsoft Internet Explorer. Adems los desarrolladores de este navegador han asegurado que no pretenden soportar enteramente el formato html ms actual en un futuro cercano. Esto obliga a los desarrolladores de pginas web a utilizar las especicaciones del html soportado para el Internet Explorer y no las que marca el estndar de la w3c, organizacin sin nimo de lucro que vela por los estndares de publicacin en Internet. Esta situacin vergonzosa es provocada por la maniesta falta de calidad del navegador de Microsoft y por la aplicacin de tcnicas monopolsticas en el mercado de el diseo de pginas web. Cuntas pginas en el mundo estn optimizadas para el Internet Explorer? Cuntas llevan el sello de w3c? Espero que este apndice ayude a concienciar a alguien de lo importante que es no ceder al chantaje de ciertas empresas cuyo nico objetivo es enriquecerse a costa manipular al consumidor.

APNDICE D
Lo que no me gusta de Matlab.
Matlab no es ni mucho menos mi lenguaje de programacin favorito. Empec con Matlab tras unos aos de Fortran; poco tiempo despus me lanc con Python. Cuando estaba completamente emocionado con Python me vi obligado a programar ms en Matlab lo que me permiti compararlos profundamente. Matlab sali perdiendo por goleada. Adems, cuando hago algn pequeo script uso el intrprete GNU/Octave. Llevo muchos y felices aos programando en entorno Linux donde la instalacin de Octave es trivial. ste interprete no te deja hacer muchas maravillas, simplemente soporta la parte matemtica; nada de grcos renderizados y sombreados o interfaces de usuario. Para m es ms que suciente, en programas ms complicados no lo uso. Matlab es una gran ayuda para un ingeniero y es perfecto para clculos de complejidad media. Esto no impide que seamos crticos, Matlab tiene defectos, algunos de ellos muy grandes; aunque donde yo digo defectos alguien puede decir virtudes.

D.1. Un lenguaje pobre y obsoleto.


Matlab va sobre trucos. Fue muy frustrante ver como me era imposible plasmar lo aprendido durante aos con otros lenguajes. En vez de crear estructuras cada vez ms sosticadas iba aprendiendo cmo hackear el cdigo descaradamente. El lenguaje no daba para ms. No es un lenguaje de programacin general y no pretende serlo pero tiene carencias que a mi parecer justicaran una revisin exhaustiva. Lo peor de todo es que Mathworks va extendiendo el lenguaje a base de aadidos que no tienen ninguna lgica. Por ejemplo la orientacin a objetos. De qu sirve crear una clase si no hay absolutamente ninguna en ningn toolkit? Estn diciendo desde Mathworks que quieren que hagamos su trabajo? Otro aspecto que me sorprendi muy negativamente fue la manera en la que se manejaba la precisin numrica, sobretodo cuando se trabaja con

Inf

0.

Matlab es incapaz de manejar integrales impropias del modo correcto

como lo consigue por ejemplo Python o Java. La precisin de los clculos internos es algo preocupante, adems de la velocidad. Cuando Matlab era el nico lenguaje de scripting cientco decente aguantar su lentitud era algo asumido. Hoy en da otros lenguajes de scripting son del orden de tres veces ms rpidos. El funcionamiento de Matlab es fuertemente imperativo y no soporta ningn otro paradigma de programacin; ni siquiera la programacin modular. Todo es una funcin, incluso los mtodos para pasar variables entre unidades de programa. Este paradigma resulta especialmente molesto cuando los programas se complican. Mantener la sintaxis del lenguaje minima e ir aadiendo una funcin tras otra no es siempre la solucin porque tiende a empobrecer el lenguaje y obliga a aprender centenares de funciones que uno utiliza una vez en su vida. El hecho de que por cada funcin denida del modo usual se tenga que crear un archivo me saca de quicio. Si eso desembocara en una ganancia espectacular de velocidad estara hasta cierto punto justicado, pero no es as. Es una tarea cansina partir un algoritmo en decenas de archivos porque ir juntando las piezas en function handles convierten el cdigo en un jeroglco. Tambin lo es tener que jugar con las variables para pasar argumentos a funciones de una manera eciente o crear estructuras de variables articiales porque a Matlab le faltan tipos como listas o diccionarios. No se pueden usar estructuras complejas de datos porque no se pueden hacer asignaciones

165

166

D.2. DWIMBNWIW.

por grupo, no se pueden crear iteradores ni iterar sobre listas y muchas cosas ms. En una comparacin con otros lenguajes de scripting como Python o Ruby, Matlab sale netamente perdedor.

D.2. DWIMBNWIW.
Estas son las iniciales de Do What I Mean But Not What I Write. Es un paradigma de los lenguajes de programacin en el que el resultado de nuestro cdigo no depende del modo en el que se ha escrito. Signica que el compilador o el intrprete es tan listo que entiende lo que queremos decir aunque no hayamos sido capaces de plasmarlo en un cdigo ptimo. Podemos preocuparnos ms de escribir un cdigo elegante y leble sin pensar demasiado en una optimizacin mxima. Fortran es quizs el lenguaje de programacin que se acerca ms a este objetivo. Matlab hace literalmente lo que escribimos sin ningn tipo de optimizacin automtica. La consecuencia inmediata es que, tal como hemos visto durante los ejemplos en el libro, la velocidad de ejecucin depende directamente de nuestro estilo de programacin. Un bucle mal puesto o una funcin sin optimizar puede aumentar el tiempo de ejecucin en varios ordenes de magnitud. La optimizacin en directo no es algo ni imposible ni nuevo en lenguajes interpretados. Optimizar los bucles no es tan difcil y en Matlab slo se hace si compilamos las funciones. La consecuencia indirecta es que la escritura del programa queda condicionada por el resultado. Este defecto es un motivo suciente como para calicar a Matlab de mal lenguaje de programacin. Algunos lenguajes imponen un estilo pero nunca por motivos relacionados con el resultado y siempre por elegancia o coherencia. Para que un cdigo en Matlab funcione bien debemos evitar los bucles... Cmo pueden pedirnos que evitemos una de las dos estructuras esenciales de la programacin? Para conseguir el mximo rendimiento debemos encapsular los comandos lo mximo posible... Al nal el cdigo es difcilmente leble. Para evitar las prdidas de memoria debemos utilizar la menor cantidad de variables posibles... No sera mejor dotar a Matlab de automatic garbage collection ?

D.3. Matlab para todo, absolutamente todo.


Cuando aprend programar de verdad fue cuando domin ms de un lenguaje de programacin. Fortran me maravilla porque en ningn momento ha querido salir del mbito cientco; si quieres herramientas grcas programalas en C++ o en Java. En cambio Matlab te permite hacer absolutamente de todo, pero mal. Un ejemplo es el mdulo para la creacin de interfaces grcas. Un programador experimentado sabe que cuando programa un interfaz lo ms importante es saber en qu toolkit lo est haciendo porque puede que no funcione bien en algunos ordenadores. Un ejemplo claro son las mquinas Linux o BSD donde no hay una mquina virtual de Java por defecto. Cul es el toolkit de Matlab? Para programar interfaces grcas es muy conveniente irse a otro lenguaje. De acuerdo, se puede hacer en Matlab; pero no convencern a nadie si dicen que es la solucin ms adecuada. Hoy en da no se concibe una API para interfaces grcas que no soporte orientacin a objetos. Otro ejemplo es el toolkit de proceso de imgenes, muy inferior a Imlib que tiene bindings a casi todos los lenguajes de programacin (excepto Matlab), es gratuita, rpida y con una API deliciosamente bien escrita. El ingeniero Matlab-monkey es un patrn que se est extendiendo peligrosamente. Matlab puede hacer de todo, bien o mal; esto acaba muchas veces con el sentido crtico de que siempre hay que escoger la herramienta adecuada para una tarea. Para procesar datos o para pequeos scripts matemticos Matlab es simplemente perfecto. Para trabajar con tipos complejos, crear grandes estructuras lgicas o hacer clculos agresivos con la precisin del ordenador debemos buscar otra solucin. El fenmeno Matlab-monkey nace de la facilidad con la que se programa en Matlab y es agravado por la creencia que aprender un lenguaje de programacin nuevo es costoso e intil. Todos los programadores que dominen, y con dominar me reero a ser capaces de escribir programas de miles de lineas que funcionen, admiten que usar regularmente tres o cuatro lenguajes de programacin dota de unos recursos impagables; en el fondo todos son iguales.

D.4. El poder del dinero


En el tema de licencias Microsoft es una hermanita de la caridad al lado de Mathworks. Matlab es un programa caro, muy caro. Si compramos alguna versin de estudiante a un precio econmico nos podemos encontrar con la desagradable sorpresa de que no est la funcin

fsolve.

El motivo es que Matlab est dividido en multitud de

1 En

un lenguaje donde se van creando y destruyendo variables y donde las funciones reciben los argumentos por valor en vez de

por referencia es muy til tener un mecanismo que libere la memoria que no se vuelve a utilizar. Automatic Garbage Collection es el nombre que recibe el mecanismo de bsqueda y eliminacin de variables intermedias intiles. Matlab slo dispone del comando

clear.

APNDICE D. LO QUE NO ME GUSTA DE MATLAB.

167

toolkits por motivos econmicos y algunos de los esenciales estn ausentes en el paquete bsico. Ahora pensamos que no hay ningn problema, que siempre se puede conseguir pirateado... Pero si tenemos una empresa no hay pirateo que valga, hay que comprar el software. Un Matlab completamente operativo puede costarnos:

2400 1150 1000 1000

Matlab. Slo el intrprete, las funciones bsicas y la interfaz grca. Optimization toolkit. Sin esto no tenemos

fsolve

Statistics toolkit. Sin esto no tenemos funciones estadsticas Signal processing toolkit. Sin esto nada de convoluciones y FFT.

Stateow (3500) la suma puede salirnos por la friolera de

Y si encima queremos el Matlab Compiler para que el cdigo vaya rpido de verdad (6250), Simulink (3500) y

18800.

Y ms nos vale ponerlo en un buen servidor

de aplicaciones porque esto es el coste por puesto de trabajo. Si lo comparamos con el coste cero de muchas de los programas que podemos encontrar por Internet, algunas de ellos de tanta calidad o ms que Matlab, es probable que cambiemos de herramienta de uso cotidiano.

D.5. Python
Programo en Matlab a menudo pero esto no signica que sea mi lenguaje favorito. Aprecio su carcter directo y su sencillez pero cuando tengo que programar aplicaciones ms serias me voy a otro lenguaje interpretado, Python. Tiene absolutamente todo lo que se le puede pedir a un lenguaje de programacin, adems est creciendo en adeptos. Es muy recomendable echarle un vistazo, probablemente alguien vea la luz con Python; incluso puede ser que descubra que programar es divertido. El mdulo orientado a matemticas ms verstil y completo es SciPy. Aunque est an incompleto se ha convertido en una referencia entre los programadores en Python. A los recin llegados a este lenguaje les resulta raro encontrar rutinas para funciones de interpolacin implementadas con orientacin a objetos. Una vez se supera la sorpresa inicial el cdigo resultante se vuelve cada vez mejor, incluso puede volverse ms directo que Matlab.

Introduccin informal a Matlab y Octave

168

D.5. PYTHON

APNDICE E
GNU Free Documentation License
Version 1.2, November 2002 Copyright c 2000,2001,2002 Free Software Foundation, Inc.

51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble
The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the eective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modications made by others. This License is a kind of copyleft, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

1. APPLICABILITY AND DEFINITIONS


This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The  to any such manual or work. Any member of the public is a licensee, and is addressed as  A  A 

Document, below, refers you. You accept the

license if you copy, modify or distribute the work in a way requiring permission under copyright law.

Modied Version

of the Document means any work containing the Document or a portion of it, either

copied verbatim, or with modications and/or translated into another language.

Secondary Section is a named appendix or a front-matter section of the Document that deals exclusively

with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The 

Invariant Sections are certain Secondary Sections whose titles are designated, as being those of Invariant

Sections, in the notice that says that the Document is released under this License. If a section does not t the above denition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

169

170
The 

Cover Texts

are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover

Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A 

Transparent copy of the Document means a machine-readable copy, represented in a format whose speci-

cation is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent le format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modication by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not Transparent is called 

Opaque.

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modication. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The 

Title Page

means, for a printed book, the title page itself, plus such following pages as are needed to

hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, Title Page means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. A section 

Entitled XYZ

means a named subunit of the Document whose title either is precisely XYZ

or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specic section name mentioned below, such as  

History.) To  Preserve the Title

Acknowledgements,  Dedications,  Endorsements, or

of such a section when you modify the Document means that it remains a

section Entitled XYZ according to this denition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no eect on the meaning of this License.

2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies.

3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to t legibly, you should put the rst ones listed (as many as t reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computernetwork location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

APNDICE E. GNU FREE DOCUMENTATION LICENSE

171

4. MODIFICATIONS
You may copy and distribute a Modied Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modied Version under precisely this License, with the Modied Version lling the role of the Document, thus licensing distribution and modication of the Modied Version to whoever possesses a copy of it. In addition, you must do these things in the Modied Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modications in the Modied Version, together with at least ve of the principal authors of the Document (all of its principal authors, if it has fewer than ve), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modied Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modied Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled History, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modied Version as given on the Title Page. If there is no section Entitled History in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modied Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the History section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled Acknowledgements or Dedications, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled Endorsements. Such a section may not be included in the Modied Version. N. Do not retitle any existing section to be Entitled Endorsements or to conict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. If the Modied Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modied Version's license notice. These titles must be distinct from any other section titles. You may add a section Entitled Endorsements, provided it contains nothing but endorsements of your Modied Version by various partiesfor example, statements of peer review or that the text has been approved by an organization as the authoritative denition of a standard. You may add a passage of up to ve words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modied Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modied Version.

Introduccin informal a Matlab y Octave

172

5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under the terms dened in section 4 above for modied versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodied, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but dierent contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled History in the various original documents, forming one section Entitled History; likewise combine any sections Entitled Acknowledgements, and any sections Entitled Dedications. You must delete all sections Entitled Endorsements.

6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS


A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an aggregate if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

8. TRANSLATION
Translation is considered a kind of modication, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled Acknowledgements, Dedications, or History, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

10. FUTURE REVISIONS OF THIS LICENSE

APNDICE E. GNU FREE DOCUMENTATION LICENSE

173

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may dier in detail to address new problems or concerns. See http://www.gnu.org/copyleft/. Each version of the License is given a distinguishing version number. If the Document species that a particular numbered version of this License or any later version applies to it, you have the option of following the terms and conditions either of that specied version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

ADDENDUM: How to use this License for your documents


To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

Copyright

YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this

document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled GNU Free Documentation License.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the with . . . Texts. line with this:

with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

Introduccin informal a Matlab y Octave

174

BIBLIOGRAFA

[1] Turbulence and Vortex Dynamics; Javier Jimnez; July 26, 2004; http://torroja.dmt.upm.es/ [2] Fortran 95/2003 Explained; Michael Metcalf, John Reid, Malcolm Cohen; Oxford University Press; 2004. [3] Numerical Recipes in Fortran 77, The Art of Scientic Computing; Second Edition; William H. Press, Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery; Cambridge University Press, 1997 [4] Fluid Flow Phenomena, A Numerical Toolkit; Paolo Orlandi; Kluwer Academic Publishers, 2000. [5] Computational Fluid Dynamics; T.S. Chung; Cambridge University Press, 2002 [6] C++: The Complete Reference; Herbert Schildt; Tata Mc Graw-Hill ,1999 [7] Scary Octave; http://wiki.octave.org/ [8] The Octave Language for Numerical Computations; John W. Eaton; http://www.octave.org/ [9] Python Documentation; Guido van Rossum; http://www.python.org/doc/ [10] MathWorld; Eric W. Weisstein; http://mathworld.wolfram.com/ [11] Mecnica de Fluidos; Amable Lin; Publicaciones ETSIA, Universidad Politcnica de Madrid. [12] Clculo Numrico I; Varios; Publicaciones ETSIA, Universidad Politcnica de Madrid. [13] Anlisis y Clculo Numrico en Ecuaciones en Derivadas Parciales; Juan A. Hernndez, Eusebio Valero; Publicaciones ETSIA, Universidad Politcnica de Madrid. [14] Spectral methods in MATLAB; Lloyd N. Trefethen; SIAM, 2000 [15] Algebra Lineal y Geometra Cartesiana; Juan de Burgos; McGraw Hill, 2000 [16] Fortran 95: Programacin Multicapa para la simulacin de sistemas fsicos; Juan A. Hernndez, Mario A. Zamcnik; ADI, 2001. [17] Wikipedia, the free encyclopedia:http://en.wikipedia.org/wiki/Wikipedia

175

NDICE ALFABTICO

lgebra, 63 addpath, 57 Argumentos, 32 assignin, 108 Ayuda, 50 BDF, 85 biblioteca, 27 biblioteca estndar, 27 bode, 131 break, 49 buildssic, 128 builtin, 57 caos, 89 celdas, 44 cell arrays, 44 center, 93 clear, 42 collect, 92 compilador, 17 Contenedores, 43 continue, 49 contour, 80 conv, 83 csape, 97 csapi, 97 ctranspose, 65 dbclear, 110 dblquad, 84 dbstop, 109 dbtype, 109 deconv, 83 Derivadas, 84 diag, 64 diary, 59 di, 84, 92 dierentiate, 92 dispatch, 57 Divisin, 39 do-until, 49 echo, 108 ecuaciones diferenciales, 85 edit, 57

EDO, 85 eig, 74 error, 51 errorbar, 79 Estructuras, 43 evalin, 107 expand, 92 eye, 63 factorial, 56 t, 98 t2, 98 tlt, 98 tn, 98 tshift, 98 Figure, 75 ll, 77 for, 48 free, 58 fsolve, 103 funcin, 30 funciones annimas, 54 function handles, 53 fzero, 101 global, 41 Grcos, 75 gradient, 84 grid, 76 help, 29, 50 hist, 80 hold, 75 if, 46 it, 98 inline, 52 input, 58 inputname, 107 int, 92 intrprete, 17 Integrales, 84 interp1, 95 interp2, 96 introspeccin, 54 issparse, 70

176

NDICE ALFABTICO
issquare, 70 LaTeX, 161 legend, 76 limit, 92 linspace, 63 load, 59 loglog, 79 logspace, 63 long, 58 Lorentz, 137 lsode, 85 Matlab, 17 Matrices, 32 max, 93 mean, 93 median, 93 men, 58 mesh, 82 meshc, 82 meshdom, 63 meshgrid, 63 min, 93 more, 29 Multiplicacin, 38 Nmeros Complejos, 36 nargin, 51, 107 nargoun, 107 nargout, 52 Negacin, 39 nichols, 131 no, 40 none, 58 null, 73 nyquist, 131 o, 40 Octave, 20 Octave-forge, 21 ode113, 86 ode15i, 86 ode15s, 86 ode23, 86 ode23s, 86 ode23t, 86 ode23tb, 86 ode45, 86 ODEPACK, 85 ones, 63 Operadores, 37 Operadores aritmticos, 38 operadores de comparacin, 39 operadores lgicos, 40 parser, 28 persistent, 42 pie, 80 plot, 78 polar, 79 poly, 83 quad, 84 quad2dc, 84 quad2dg, 84 quadl, 84 quiver, 82 rand, 63 rank, 73 recursivas, 56 referencia, 27 repmat, 66 reshape, 65 residue, 83 Resta, 38 return, 52 Rikitake, 89 roots, 83 save, 59 script, 30 scripting, 17 semilogx, 79 semilogy, 79 Sentencias, 46 short, 58 sort, 93 spabs, 72 sparse, 69, 70 spdiags, 71 speye, 71 sphcat, 72 spimag, 72 spinv, 72 spline, 97 splot, 92 spones, 71 sprand, 71 spreal, 72 spvcat, 72 spy, 70 ss, 126 std, 93 sti, 85 Submatrices, 36 subplot, 75 subs, 92 Suma, 38 surf, 82 svd, 73 switch, 47 sym, 91 symsum, 92 poly2sym, 91 polyder, 83 polyt, 94 polyint, 83 polyout, 83 polyval, 83 Potencia, 39 ppval, 97

177

Introduccin informal a Matlab y Octave

178
sysadd, 128 sysappend, 128 sysconnect, 128 sysdup, 128 sysgroup, 128 sysidx, 128 sysmult, 128 sysout, 127 sysprune, 128 syssub, 128 taylor, 92 TeX, 77, 161 text, 76 texto, 37 tf, 126 tipo, 43 tipo derivado, 43 Title, 76 transpose, 65 trapz, 84 Traspuesta, 39 triplequad, 84 trisolve, 72 try, 50 type, 57, 109 usage, 51 Van der Pol, 87 varargin, 107 varargout, 107 Variables, 40 variables lgicas, 37 vdp1, 88 vdp1000, 88 view, 82 while, 49 who, 43 whos, 43 xlabel, 76 y, 40 ylabel, 76 zeros, 63 zp, 126

NDICE ALFABTICO

También podría gustarte