notas octave

65
Cálculo numérico con Octave Guillem Borrell i Nogueras Rafael Rodríguez Galván 27 de mayo de 2008

Upload: jorge2917

Post on 24-Jun-2015

763 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Notas Octave

Cálculo numérico con Octave

Guillem Borrell i NoguerasRafael Rodríguez Galván

27 de mayo de 2008

Page 2: Notas Octave

2

Versión 0.16

Copyright c© 2008Guillem Borrell i NoguerasRafael Rodríguez Galván.

Este documento es libre. Se otorga permiso para copiarlo, distribuirlo y/o modificarlo bajo lostérminos de la licencia FDL (GNU Free Documentation License) versión 1.2 o posterior, publicadapor la Fundación de Software Libre1. No contiene secciones invariantes, texto de portada ni derespaldo.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU FreeDocumentation License, Version 1.2 or any later version published by the Free Software Foundation; withno Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

Las fuentes LATEX pueden conseguirse en la siguiente dirección web: https://forja.rediris.es/projects/ciencialibre/

1http://www.gnu.org/licenses/fdl.html

Page 3: Notas Octave

Índice general

1. Introducción 5

2. Primeros pasos con la interfaz qtOctave 7

3. El lenguaje común de Matlab y Octave 113.1. Convenciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.1.1. Operaciones elementales con Matlab . . . . . . . . . . . . . . . . . . . . . . . 123.1.2. Algunas palabras clave y atajos de teclado. . . . . . . . . . . . . . . . . . . . 13

3.2. La Ayuda(I) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.3. Tipos de archivos en Matlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.3.1. Funciones(I) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.3.2. Nuestra primera función . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.3.3. Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.3.4. Nuestro primer script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.3.5. Una gran diferencia entre Matlab y Octave . . . . . . . . . . . . . . . . . . . 17

3.4. Argumento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.4.1. Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.4.2. Secuencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.4.3. Submatrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.4.4. Números Complejos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.4.5. Cadenas de texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.4.6. Variables lógicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

3.5. Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.5.1. Operadores aritméticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.5.2. Operadores de comparación . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.5.3. Operadores lógicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.5.4. Operadores de comparación por bits en enteros . . . . . . . . . . . . . . . . 28

3.6. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293.6.1. Acceso a las variables: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293.6.2. Funciones dedicadas a variables . . . . . . . . . . . . . . . . . . . . . . . . . 313.6.3. Contenedores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.7. Sentencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353.7.1. La sentencia if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363.7.2. La sentencia switch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373.7.3. Las sentencias for y while . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383.7.4. La sentencia do-until . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403.7.5. Las sentencias break y continue . . . . . . . . . . . . . . . . . . . . . . . . 403.7.6. La sentencia try . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

3.8. Funciones (II) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413.8.1. Funciones matemáticas básicas . . . . . . . . . . . . . . . . . . . . . . . . . . 413.8.2. La Ayuda(II) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413.8.3. Argumentos de entrada y salida. . . . . . . . . . . . . . . . . . . . . . . . . . 42

Page 4: Notas Octave

4 ÍNDICE GENERAL

3.8.4. inline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443.8.5. Function handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453.8.6. Funciones recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493.8.7. Encapsulado de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493.8.8. Herramientas útiles para la manipulación de funciones. . . . . . . . . . . . 49

3.9. Entrada/Salida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503.9.1. E/S básica por pantalla. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503.9.2. E/S básica con archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

4. Más allá del lenguaje: biblioteca de funciones y extensión de Octave 534.1. La biblioteca de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

4.1.1. Álgebra Lineal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534.1.2. Gráficos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544.1.3. Otras utilidades de la biblioteca de funciones . . . . . . . . . . . . . . . . . . 57

4.2. Toolkits en Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574.3. Creación de extensiones dinámicas en Octave . . . . . . . . . . . . . . . . . . . . . . 57

A. Análisis crítico del lenguaje Matlab 61A.1. Paréntesis y corchetes. Tuples y celdas . . . . . . . . . . . . . . . . . . . . . . . . . . 61A.2. La notación del punto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62A.3. Versatilidad o por qué prefiero el intérprete Octave. . . . . . . . . . . . . . . . . . . 62A.4. La orientación a objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63A.5. Módulos y funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63A.6. Matlab 2 y otros lenguajes de programación . . . . . . . . . . . . . . . . . . . . . . . 63

Referencias 65

Page 5: Notas Octave

1Capítulo

Introducción

Octave es un lenguaje de ordenador de alto nivel, orientado al cálculo numérico. Y su vezes un programa que permite interpretar este lenguaje de forma interactiva, mediante órdenes ocomandos1. Estas órdenes pueden ser introducidas a través de un entorno en forma de terminal oconsola de texto (figura 1.1). Por supuesto, Octave incluye, además, la posibilidad de ser utilizadode forma no interactiva, interpretando las órdenes contenidas en un fichero.

Estas características se pueden resumir diciendo que Octave es un lenguaje interpretadoorientado al cálculo numérico matricial. Por supuesto, existe una gran variedad de lenguajesinterpretados orientados a las matemáticas, algunos de ellos con licencia libre, como Maxima,Axiom, Scilab, EULER, Sage o R y otros con licencia privativa, como Matlab, Maple, Mathemati-ca o S.

Los lenguajes interpretados, entre los cuales destaca la menor velocidad de proceso que len-guajes compilados como C, C++, Fortran, etc. Sin embargo, Octave y el resto de los lenguajesinterpretados presentan una serie de ventajas muy significativa: la razón entre el esfuerzo em-pleado en el desarrollo del programa y el resultado final es muy pequeña, es decir, permitenobtener resultados razonables con un esfuerzo no demasiado importante. Este hecho, que es-tá relacionado con la eliminación de la segunda etapa dentro del ciclo clásico de desarrollo deprogramas (escritura-compilado-depurado), es vital en

Desde sus orígenes, Octave es software libre, gracias a lo cual, su comunidad de desarro-lladores y usuarios ha ido creciendo hasta llegar a ser muy significativa. Es un proyecto encolaboración cuyos miembros nos prestarán ayuda cuando la solicitemos, a través de suslistas de correo. Éstas son públicas y una gran fuente de información [4].

Su lenguaje de programación es altamente compatible con el de Matlab, el conocido en-torno de cálculo numérico (con licencia privativa) desarrollado por The MathWorks, Inc. Dehecho, la mayor parte de la materia desarrollada en las siguientes páginas es, de hecho,un análisis del amplio lenguaje que es común a Matlab y Octave y al que, indistintamente,denominaremos “lenguaje Octave” o “lenguaje Matlab”.

Está disponible en numerosos plataformas, entre ellas sistemas Unix (para los que fue origi-nalmente desarrollado), Windows y MacOsX. Su código fuente contiene una potente libre-ría de cálculo matricial para C++. De hecho, ha sido diseñado de forma que sea extensibledinámicamente, a través de nuevos procedimientos escritos en C++. Estas extensiones sonprogramas “especiales” que tienen la extensión .oct y, como programas compilados, cuen-tan con un rendimiento mucho mayor que las funciones escritas en el lenguaje interpretadode Octave. Esto se estudiará en el capítulo 3.

Para instalar Octave, solamente tenemos que acceder a su página web[5] y descargar el pro-grama a nuestro ordenador. Además, en la mayoría de las distribuciones de GNU/Linux, esteprograma está listo para su instalación, de forma muy sencilla, a través del sistema estándar depaquetería, lo que habitualmente es el método de instalación recomendado.

Una vez instalado, tenemos a nuestra disposición la interfaz básica de Octave, que podemosutilizar para interactuar con este programa. Para ello, en sistemas GNU/Linux, podemos abrirla terminal del sistema2 y escribir la orden octave. En sistemas Windows, podemos acceder a la

1Aunque el diccionario de la Real Academia de la Lengua no incluye ésta entre sus acepciones, en la literatura técnicase suele emplear esta traducción del vocablo inglés command

2Por ejemplo, en el entorno Gnome, podemos utilizar el menú ”Aplicaciones”→”Accesorios”→”Terminal”

Page 6: Notas Octave

6 Introducción

Figura 1.1: La interfaz básica de GNU Octave

terminal de Octave a través del menú Inicio. En cualquier caso, se obtendrá una ventana similar ala mostrada en la figura 1.1, en el que, después de un mensaje de bienvenida (en el que se indicadistinta información de interés, como el número de versión actual), Octave nos indica que estáesperando una primera intervención del usuario, que puede comenzar a teclear órdenes paraOctave:

octave:1>

Por ejemplo, podemos realizar una sencilla multiplicación para calcular el número de horas quehay en un año:

octave:1> 365*24ans = 8760octave:2>

Octave calcula el resultado, lo almacena en una variable llamada ans (de la palabra inglesa ans-wer, respuesta) y queda a la espera de que el usuario teclee una segunda orden.

Por supuesto, podemos realizar operaciones mucho más complejas. En los siguientes capítu-los se estudiarán con mayor detalle los detalles del del lenguaje de Octave.

Page 7: Notas Octave

2Capítulo

Primeros pasos con la interfaz qtOctave

A pesar de que la consola de Octave tiene características bastante avanzadas1 y permite ac-ceder a toda la funcionalidad de este lenguaje, muchos usuarios preferirán emplear una interfazgráfica que, por ejemplo, facilite editar y almacenar en el disco series de órdenes o programascompletos, o bien acceder a determinadas funcionalidades mediante menús o barras de herra-mientas.

Para ello, en el mundo del software libre, existen distintas posibilidades. Por ejemplo, el po-tente editor Emacs dispone de un modo específico que puede significar una opción muy suge-rente para interaccionar con GNU Octave. Ahora bien, en las siguientes secciones, nos centrare-mos en una de las interfaces gráficas de usuario que, en la actualidad, ofrece prestaciones másinteresantes para un usuario medio: qtOctave.

Este programa recibe su nombre de las bibliotecas QT. desarrolladas con la finalidad de faci-litar la creación de interfaces gráficas.

Instalación

Esta sección ha sido, en gran parte, desarrollada por Lorena Gutiérrez Madroñal.

qtOctave está disponible:

A través de su página web, http://qtoctave.wordpress.com/. Esta página es el cen-tro de comunicación con el autor y la comunidad de usuarios de qtOctave.

En la forja Forja de RedIris (CICA). https://forja.rediris.es/projects/csl-qtoctave/Esta forja es es el centro de desarrollo de qtOctave. Para descargas, pulsar botón “Ficheros”

En las páginas web de la universidad de Cádiz:

• http://software.uca.es/

• ftp://guadalinex.uca.es/Octave/

• http://softwarelibre.uca.es/Octave/

La mayoría de los usuarios de Windows y GNU/Linux preferirán utilizar el programa ejecu-table, ya compilado para su sistema, aunque los usuarios más avanzados cuentan con la posibi-lidad de descargar y compilar el código fuente.

Instalación en sistemas Windows

En sistemas Windows, se recomienda utilizar el instalador disponible2. Éste guiará al usuarioa través de un sencillo proceso, al final del cual se instalarán tanto Octave como qtOctave, ademásde todos los paquetes adicionales o toolkits de octave-forge.

El instalador colocará un acceso directo en el escritorio a la vez que una entrada de menú paraqtOctave. Utilizando cualquiera de ellos, se puede arrancar el programa.

1Utiliza la biblioteca GNU readline, ofrece la posibilidad de acceder a las líneas de órdenes anteriores mediante teclas[flecha arriba]/[flecha abajo], completar los comandos con la tecla [tabulador], etc

2Actualmente, QtOctave-0.7.2.exe

Page 8: Notas Octave

8 Primeros pasos con la interfaz qtOctave

Figura 2.1: Secciones de qtOctave

Instalación en sistemas GNU/Linux

En sistemas GNU/Linux, la opción recomendada es instalar la versión que esté disponibleen la distribución preferida por el usuario. Por ejemplo, en la actualidad, los sistemas Debiandisponen de un paquete que instala la última versión de qtOctave.

Sin embargo, es posible que la distribución usada por el usuario no disponga de un paqueteqtOctave o bien que esté empaquetada una versión demasiado antigua. En tal caso, recomenda-mos utilizar qtOctave binario.

La instalación de qtOctave binario es muy sencilla, ya que sólo tenemos que dar los siguientespasos:

1. Descargarnos la última versión de qtOctave binario en la página (por ejemplo): https://forja.rediris.es/frs/download.php/745/qtoctave-0.7.4_bin.tar.gz

2. Una vez descargado, tendremos que descomprimirlo y se nos aparecerá una carpeta con elnombre “qtoctave-version_bin”.

3. Dentro de esta carpeta, encontraremos otra carpeta y varios ficheros, entre ellos encontra-remos un ejecutable llamado “qtoctave.sh”, el cual tenemos dos formas de ejecutarlo:

Dando doble click sobre el mismo

Abriendo una consola de comandos y tras situarnos mediante la orden “cd” en lacarpeta donde se ubica, escribir la orden “./qtoctave.sh”.

Para utilizar el paquete binario se presupone que están instaladas las bibliotecas QT (versión4), disponibles en todas las distribuciones de GNU/Linux.

El entorno qtOctave

La primera vez que iniciamos qtOctave, tendremos un entorno confortable, (figura 2 ), en elque podemos distinguir distintas secciones:

1. Barra de menú: Nos permite utilizar a algunas funciones de Octave mediante el ratón, utili-zando ventanas de diálogo específicas para la introducción de parámetros.

2. Barra de iconos: Facilita el acceso a algunas entradas del menú y las distintas a ventanas.Podemos agruparlos en cuatro bloques:

Page 9: Notas Octave

9

Ejecución y control de procesos en la terminal.

Acceso a la tabla para la introducción de matrices.

Acceso a la ayuda

Control de ventanas embebidas (ventanas de utilidades que están contenidas dentrode qtOctave).

3. Utilidades: Ventanas de listado de variables, de lista de comandos y navegador de archivos.

Lista de variables activas

Lista de órdenes anteriores

Navegador de archivos

4. Terminal Octave, o Consola. Ventana para teclear comandos directamente en Octave, inte-grando ayudas como la recuperación de comandos anteriores (mediante la tecla [↑]) y elauto-completado de comandos (mediante la tecla [TAB]).

5. Editor: Para escribir programas que serán ejecutados por Octave. Entre sus características seencuentran el resaltado de sintaxis, facilidades para deshacer los últimos cambios, depura-ción integrada, etc.

Page 10: Notas Octave

10 Primeros pasos con la interfaz qtOctave

Page 11: Notas Octave

3Capítulo

El lenguaje común de Matlab y Octave

Este capítulo se dedica a estudiar el lenguaje común de Matlab y Octave señalando, cuandosea conveniente, aquellos detalles que los puedan diferenciar. El estudio de la amplia bibliotecade funciones de estos lenguajes (en concreto las funciones dedicadas a matrices, álgebra lineal,gráfico así como a distintos ámbitos del cálculo numérico) queda fuera del objetivo marcado yse estudiará en al siguiente capítulo (aunque, no en profundidad, debido a las características delpresente curso).

Cuando hablemos de Matlab (o de Octave), nos referiremos a las características del lenguajecomún que ambos comparten. Cuando la palabra Matlab se utilice en una diferencia respecto aOctave (o viceversa) nos estaremos refiriendo exclusivamente a uno de estos programas. Por sen-cillez, no se han diferenciado tipográficamente las palabras Matlab y Octave en los dos contextos.

El texto de este capítulo está extraído (con algunas modificaciones) del segundo capítulo dellibro “Introducción Informal a Matlab y Octave”[2], que publica Guillem Borrell i Nogueras conlicencia libre (GFDL).

3.1. Convenciones

Antes de entrar en materia es importante que sepamos qué diferencias hay entre las sentenciasde un lenguaje de programación y la biblioteca de funciones.

Las sentencias son las palabras clave independientes. Esto significa que si las eliminaremosdel lenguaje no podríamos sustituirlas con ninguna combinación del resto de sentencias del len-guaje. Esta definición no es estricta; algunas palabras clave comunes se consideran sentenciascuando se hace un uso muy frecuente de ellas.

El total de sentencias y de reglas de escritura son lo que forman el lenguaje de programacióndescrito en un documento llamado referencia. Como Matlab es un programa comercial no existetal documento.

El resto de funciones y subrutinas son parte de la biblioteca. Son palabras clave que cumplenuna tarea y no pueden ser consideradas sentencias porque están escritas con ellas. Algunas fun-ciones de uso muy frecuente llegan a ser parte del mismo lenguaje, el grupo que forman se llamabiblioteca estándar. El conjunto de sentencias y biblioteca estándar se conoce como especificacionesy en el caso que el lenguaje tome vida propia, es decir, sus especificaciones pasen a ser públicas;se llama estándar. Estos documentos existen para la mayoría de los lenguajes de programaciónconocidos: 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 podemosaplicar estas definiciones estrictas para acercarnos a él como lo haríamos con el resto de lenguajes.La organización interna de Octave sigue este criterio. Se podría decir que Octave es el conjuntode sentencias mas la biblioteca estándar y que el resto de colecciones de funciones (y hay bas-tantes) son los toolkits. La Compatibilidad entre los dos se sitúa sólo en las sentencias aunque seextiende en gran manera con la biblioteca de funciones. Por lo menos las funciones básicas soncompatibles, casi idénticas.

El lenguaje de Matlab tiene muy pocas sentencias. Como lenguaje es muy sencillo aunquecada versión incluye nuevas especificaciones. En los últimos años se ha añadido la extensiónpara programación orientada a objetos y el diseño de interfaces gráficas. Octave es ligeramentedistinto en su concepción; es más minimista y cuenta con muchas menos funciones pero es másfácilmente extensible. Son las diferencias típicas entre los productos libres y los comerciales.

Page 12: Notas Octave

12 El lenguaje común de Matlab y Octave

Este capítulo es la referencia del lenguaje; en él veremos argumentos, variables, operadores ysentencias que nos servirán para programar funciones y scripts así como la arquitectura generaldel programa.

3.1.1. Operaciones elementales con Matlab

Las convenciones para las operaciones en Matlab son idénticas que en cualquier otro lenguajede programación o que en una calculadora programable. El orden de asociación de las opera-ciones es también el mismo. Primero se operan las funciones matemáticas elementales (senos,cosenos, logaritmos...), las multiplicaciones y divisiones y luego sumas y restas. Por ejemplo,para realizar la siguiente operación:

12

0,11/2 − 0,421/3

introduciremos en la consola la línea que aparece detrás del indicador sistema (que denotamoscomo “>>”).

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

Evidentemente, Matlab y Octave no distinguen entre elementos numéricos y variables, laecuación:

abcd − e

gf

1 >> a/(b/c^d-e/g^f)

Los paréntesis sirven para variar el orden normal de las operaciones a realizar. En las va-riables, se distinguen las mayúsculas de minúsculas y, como en la mayoría de los lenguajes descripting científicos, su tipo no se define de forma explícita (más sobre el tipo de las variablesnuméricas en el próximo capítulo).

Octave y Matlab operan, de forma nativa, con números complejos:

1 >> % Trabajando con complejos...2 >> x = 1+2*i;3 >> y = 1/24 y = 0.500005 >> x+y6 1.5000 + 2.0000i

Algunos comentarios sobre el ejemplo anterior:

1. Como en la mayoría de los lenguajes, para las asignaciones se utiliza el operador =.

2. Podemos introducir comentarios mediante el carácter “%”. En Octave (no en Matlab), aligual que en Python, UNIX shell y muchos otros lenguajes de scripting, también podemosutilizar “#”.

3. El punto y coma (utilizado en la segunda línea del listado anterior) significa lo mismo queel retorno de carro, pero con una diferencia: si usamos punto y coma, el programa no nosda ninguna salida.

4. Obsérvese que la expresión 1/2 devuelve el valor 0.5. A diferencia de otros muchos len-guajes de programación, Octave y Matlab actúan por defecto con aritmética de punto flo-tante.

Page 13: Notas Octave

3.1 Convenciones 13

Además de la variable i (unidad imaginaria), tenemos predefinidas otras variables numéricascomo pi y e.

Los comandos realmin y realmax devuelven, respectivamente, los menores y mayores nú-meros reales representables en Octave, del mismo modo que eps representa al epsilon de lamáquina, es decir, la distancia entre 1 y el siguiente número mayor que 1 que es representable1.

3.1.2. Algunas palabras clave y atajos de teclado.

La consola es un entorno de trabajo más potente de lo que parece gracias a una serie de atajosde teclado de gran utilidad. Uno de los más potentes es la capacidad de auto-completar algunapalabra clave con la tecla de tabular, tab completion en inglés. Por ejemplo, si nos encontramos enel intérprete Octave y nos acordamos cómo se escribe exactamente la función para trasponer unamatriz podemos hacer lo siguiente, escribimos sólo el inicio de la palabra y luego presionamos latecla de tabular:

1 >> tra<TAB>2 trace transpose trapz

Esta es una característica común de casi todas las consolas existentes, ya sea una consola deUNIX o el Command Prompt de Windows. La consola gráfica de Matlab, así como Octave a travésde entornos gráficos como qtOctave, cuentan además del apoyo de su interfaz (por ejemplo, enMatlab, figura 3.1):

Figura 3.1: Tab completion en Matlab

A continuación una lista de palabras clave y atajos de teclado que pueden hacernos la vidamucho más fácil:

exit Cierra el intérprete, equivalente a cerrar la ventana.

<CTRL>-c Corta la ejecución del comando actual (kill)

↑ Reescribe líneas anteriores. A medida que presionemos este carácter aparecerán en la líneaactual todos los comandos escritos anteriormente. Una vez estemos viendo los comandospodemos movernos entre ellos mediante los cursores.

<CTRL>+<→,←> Hace avanzar o retroceder el cursor por palabras en vez de por caracteres.

clc Limpia la pantalla del intérprete de comandos

1Estos valores, junto a otros como Inf y NaN, están establecidos por el estándar de la IEEE para aritmética en puntoflotante, aproximadamente: 2.2e-308, 1.7e+308, 2.2e-16

Page 14: Notas Octave

14 El lenguaje común de Matlab y Octave

3.2. La Ayuda(I)

La manera más fácil de acceder a la ayuda tanto en Matlab como en Octave es mediante laconsola y el comando help. Cada comando y función lleva consigo la información necesariapara que conozcamos su uso y sus funcionalidades2. Para acceder a la ayuda de una funciónteclearemos

1 >> help {nombre de la funcion}

Esto significa que debemos saber cómo se llama la función. Si introducimos help sin ningúnargumento nos aparecerá una ayuda general desde donde podremos encontrar cualquiera de lasfunciones disponibles.

Uno comando bastante útil cuando trabajamos desde una consola o por red es more. Si ac-tivamos el comando con more on activaremos el paginador de modo que cuando el texto queaparezca en pantalla se salga de la misma interrumpirá el texto hasta que nosotros le pidamosque continúe. Esto evita el comportamiento tan desagradable que tienen las ayudas especialmen-te 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 final pulsaremos la tecla <Q>.

Además, el entorno qtOctave ofrece acceso a la extensa ayuda de Octave, a través del menú”Ayuda” .

3.3. Tipos de archivos en Matlab

Al igual que el intérprete es capaz de entender comandos mediante su consola interactiva,también es capaz de leer archivos de código o scripts. En el caso de Matlab los archivos asignadosal intérprete son los que terminan con la extensión .m. Pero para entender cómo estos archivosinteractúan con el intérprete es necesario que entendamos la arquitectura interna de Matlab.

Gran parte de la funcionalidad de Matlab se basa en su biblioteca de funciones. Una funciónen Matlab es equivalente a una función matemática; es una tarea encapsulada que puede depen-der de una o varias variables. Matlab tiene una extensísima biblioteca de funciones, la mayoríade ellas son archivos con la extensión .m que lee el intérprete. Pero el intérprete no puede saberpor ciencia infusa dónde se encuentran dichas funciones. Si en la consola introducimos:

1 >> sin(x)

¿Cómo saben Matlab u Octave dónde se encuentra la función seno? La respuesta es que saben enqué directorios del sistema puede encontrar archivos .m desde su instalación. Se puede conseguirmás información sobre este asunto consultando la ayuda para la función path.

¿Significa esto que si creamos nuestras funciones debemos guardarlas en estos directorios? Nimucho menos. Matlab cuenta con un directorio especial en el que también busca funciones; es elllamado directorio de trabajo. Si estamos utilizando la interfaz gráfica de Matlab lo seleccionaremosen la barra de herramientas. Si en cambio accedemos a Matlab por consola o optamos por Octaveel directorio de trabajo será el directorio actual (en UNIX el contenido en la variable de sistemaPWD). Cada vez que se invoque una función en Matlab buscará en los directorios habituales yen el directorio de trabajo.

Los entornos gráficos de Matlab y qtOctave disponen de facilidades para la selección deldirectorio de trabajo. Por ejemplo, en Octave, podemos utilizar el menú ”File”→”Change Direc-tory” , o bien la ventana ”Navigator” (figura 3.3)

2Más adelante aprenderemos cómo introducir esta información a cualquier función que escribamos

Page 15: Notas Octave

3.3 Tipos de archivos en Matlab 15

Figura 3.2: qtOctave: Selección del directorio de trabajo

3.3.1. Funciones(I)

Una función es una unidad de programa, una tarea independiente que puede o no dependerde variables externas. Las unidades de programa típicas son las funciones, las subrutinas, lasclases... Matlab basa toda su potencia y su sencillez en el constante uso de funciones. La razónes bien sencilla; si Matlab es un programa para cálculo numérico es normal que la unidad deprograma esencial sea la que tiene un significado más matemático

En Matlab se define una función del siguiente modo:3:

1 function [variables_de_salida]= nombre(variables_de_entrada)2 Comandos que terminamos asignando a las variables de salida3 {end}

Por ejemplo,si queremos implementar una función que sume dos escalares debemos hacer losiguiente:

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

Y lo guardaremos en un archivo que se llame igual que la función; en el caso del ejemplo serásuma.m. Luego lo guardaremos en nuestro directorio de trabajo.

Las funciones pueden devolver varias variables a través de un array, de la siguiente forma:

1 function [m,M]=minmax(a,b)2 m=min(a,b);

3El comando end sólo es necesario en Octave, cuando queremos definir alguna función en los scripts o bien más deuna función en un mismo archivo. En Matlab no es necesario, porque no soporta esta posibilidad (como comentaremosen la sección 3.3.5), de forma que el fin de del archivo en el que se define la función sirve como end.

Page 16: Notas Octave

16 El lenguaje común de Matlab y Octave

3 M=max(a,b);4 end

En este caso, podemos utilizar la función de la siguiente forma4:

1 >> [m,M]=minmax(pi,e)2 m = 2.71833 M = 3.1416

El concepto de función va más allá, pero esta descripción es suficiente para entender su papeldentro de la arquitectura de Matlab.

3.3.2. Nuestra primera función

En esta primera función no usaremos ninguno de los elementos característicos de la progra-mación en Matlab. Estos son los que encontramos en cualquier código de simulación: contadores,funciones elementales, condicionales, casos... Empezaremos con el archivo aprsin.m, que es laaproximación de orden 3 del desarrollo de Taylor en 0 de la función seno. Para ello editamos elarchivo nuevo de nombre aprsin.m en el directorio que nos digan Matlab u Octave, según elcaso, y pondremos en ella lo siguiente:

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

Vemos que asignamos a la variable out las operaciones que hacemos sobre la variable deentrada x. La idea es mantener las características de una función matemática. Una vez la hayamosguardado en el directorio de trabajo esta función puede ser llamada por el intérprete de Matlabo por cualquier script. Para probarlo nos vamos a la consola y tecleamos:

1 >> y=aprsin(1.3)

que debe darnos como resultado:

1 y = 0.93383

Aún es pronto para algunos conceptos, hay que aclarar un par de cuestiones:

Las variables x y out son locales, al igual que todas aquellas definidas en el cuerpo de lafunción.

En general, es conveniente utilizar puntos y comas en todas las líneas de código contenidasen las funciones, para no recibir resultados intermedios inútiles.

3.3.3. Scripts

Los scripts hacen la función de un programa completo, su hilo de sentencias tiene un principioy un final y no necesita actuar con ninguna variable externa al código. La diferencia entre unscript y un archivo de código fuente es que el script es una transcripción literal de comandos deconsola; se dice que es secuencial. Esto no nos permite explotar las posibilidades de los formatoslibres ni utilizar secuencias de control tipo goto5. También tienen la extensión .m y se puedenejecutar de varios modos:

4Es necesario explicitar un array como [m,M] para recoger a las dos variables devueltas por la función5Mejor, porque este tipo de estructuras no son nada aconsejables.

Page 17: Notas Octave

3.3 Tipos de archivos en Matlab 17

Dentro del intérprete. Si hemos guardado el archivo en alguno de los directorios de bús-queda de funciones el intérprete ejecutará toda la secuencia de comandos introduciéndoleel nombre del script

1 >> nombre_del_archivo

Fuera del intérprete. Dentro de una consola llamando el intérprete con el nombre de archivocomo argumento. Por ejemplo, en una consola cualquiera6:

1 $ octave nombre_del_archivo

3.3.4. Nuestro primer script

Vamos a comparar nuestra aproximación de la función seno con la función exacta y lo vamosa escribir en un guión. Para ello creamos el archivo comparar.m y escribimos lo siguiente en él7:

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

Para ejecutarlo vamos a la consola y tecleamos:

1 >> comparar

E inmediatamente va a aparecer la figura 3.3:Aún es temprano para entender exactamente qué hace el script, lo iremos viendo paso a paso;

pero ha servido para ver cuál es la relación entre funciones, scripts y Octave.

3.3.5. Una gran diferencia entre Matlab y Octave

Matlab no puede definir funciones directamente en el intérprete o en un script. Cualquier función debeser un archivo independiente por simple que esta sea.

Por ejemplo, si en Matlab intentamos escribir una función dentro del intérprete, recibiremosun error:

1 >> function c=suma(a,b)2 ??? function c=suma(a,b)3 |4 Error: Function definitions are not permitted at the prompt or in scripts.

En cambio Octave puede definir funciones tanto en el intérprete como en un script, algo que lodota de más versatilidad algo más de versatilidad.

Éste es uno de los grandes puntos débiles de Matlab. Ignoro el hecho por el que aún no losoportan.

Lo que no se puede hacer ni en Matlab ni en Octave es acceder directamente a varias funcionesdistintas definidas en un mismo archivo (aunque en Octave puede hacerse indirectamente, a

6Por supuesto, si utilizamos Matlab tenemos que teclear matlab en lugar de octave7En el próximo capítulo estudiaremos las funciones linspace y Octave plot

Page 18: Notas Octave

18 El lenguaje común de Matlab y Octave

-2

-1.5

-1

-0.5

0

0.5

1

1.5

2

-3 -2 -1 0 1 2 3

Comparacion sin vs aprsin

aprsinsin

Figura 3.3: Comparación del desarrollo de Taylor

través de la orden source). No es muy difícil ver por qué. El lenguaje Matlab, cuando llama auna función, busca por los directorios algún archivo que se llame como la función, y luego buscauna sentencia ejecutable en él. Esto implica que cada archivo sólo puede contener una cabecera8.

En octave, podemos acceder a todas las funciones definidas en un fichero a través del coman-do source, que analiza y ejecuta los contenidos de un fichero de órdenes Octave. Por ejemplo,si fichero “biblioteca.m” contiene lo siguiente:

1 function y=cuadrado(x)2 y=x^2;3 end4 function y=raiz(x)5 y=sqrt(x);6 end

podemos acceder a las dos funciones, como se puede ver en el siguiente código:

1 >> source(’biblioteca.m’)2 >> cuadrado(raiz(2))3 ans = 2.0000

3.4. Argumento

El concepto preciso de argumento o valor es complejo pero a nosotros nos bastará con sa-ber que es cualquier elemento manipulable en un código. Los argumentos de un programa desimulación numérica son los números, los índices, las matrices, las secuencias...

8Puede contener más funciones pero sólo se puede llamar una. Esta es la función que tenga la cabecera en la primeralinea cuyo nombre coincida con el nombre del archivo. Esta función puede llamar a otras funciones que se puedenencontrar en el mismo archivo, pero nunca podremos acceder desde fuera a las subfunciones puesto que Matlab no tieneinformación para saber donde se encuentran

Page 19: Notas Octave

3.4 Argumento 19

Tenemos que hacer el esfuerzo conceptual de separar el concepto de argumento del de varia-ble. Una variable es su contenedor, es lo que les da nombre y sirve para manipularlos. Sucede lomismo en cualquier fórmula matemática; siempre se expresa mediante variables y toma sentidocuando éstas contienen algún argumento.

Matlab tiene varios tipos de valores y variables; en consecuencia será valida cualquier combi-nación entre ellos. A continuación se detallan los tipos de argumentos soportados.

3.4.1. Matrices

Matlab no distingue entre escalares y matrices. Si se dice que Matlab es un lenguaje de cálculomatricial es porque todos los números son en el fondo matrices. El número 1 puede ser escalar,vector y matriz a la vez sin ningún problema:

1 >> a=12 a = 13 >> a(1)4 ans = 15 >> a(1,1)6 ans = 17 >> a(1,1,1)8 ans = 1

Tampoco distingue si sus elementos son enteros o reales, todos los números tienen la mismaprecisión en coma flotante, que es doble precisión siempre que no le indiquemos lo contrario. Lasentradas

1 >> a=1052 a = 1053 >> a=1.05e+24 a = 1055 >> a=1050e-16 a = 1057 >> a=105.8 a = 105

son equivalentes. Estas son las dos características más importantes del lenguaje.Las matrices se estiran y encogen sin ninguna limitación ni en el tamaño ni en las dimensiones.

Si intentamos llenar el décimo elemento de un vector inexistente con un 1.

1 >> foo(10)=1

el programa lo va a hacer sin ningún problema

1 foo =2 0 0 0 0 0 0 0 0 0 1

y si ahora le pido

1 >> foo(11,4)=2

obtengo

1 foo =2 0 0 0 0 0 0 0 0 0 1

Page 20: Notas Octave

20 El lenguaje común de Matlab y Octave

3 0 0 0 0 0 0 0 0 0 04 0 0 0 0 0 0 0 0 0 05 0 0 0 0 0 0 0 0 0 06 0 0 0 0 0 0 0 0 0 07 0 0 0 0 0 0 0 0 0 08 0 0 0 0 0 0 0 0 0 09 0 0 0 0 0 0 0 0 0 0

10 0 0 0 0 0 0 0 0 0 011 0 0 0 0 0 0 0 0 0 012 0 0 0 2 0 0 0 0 0 0

Vemos que el comportamiento es un poco extraño. Si nosotros utilizamos únicamente un índiceobtenemos un vector fila, mientras que en una matriz la notación es la usual, el primer elementoes el número de fila y el segundo el número de columna. Esto nos obligará a trasponer vectoresmás de una vez, sobretodo para resolver sistemas lineales de ecuaciones9.

Esta característica facilita la tarea de escribir los algoritmos por primera vez pero tiene grandespeligros 10 e inconvenientes.

Importante: Cualquier número es en realidad una matriz sin fronteras fijas.

Las matrices se ordenan en Matlab del mismo modo que en la realidad, por filas y columnas. Lanotación para diferenciar si una serie de números se encuentran en la misma fila o en la mismacolumna es el siguiente:

el espacio y la coma (,) separan elementos de una misma fila

el retorno de carro y el punto y coma (;) separan elementos de una misma columna

Por ejemplo, si queremos escribir el vector fila ~e = (1 2 3) lo haremos con:

1 >> e=[1,2,3]2 e =3 1 2 34 >> e=[1 2 3]5 e =6 1 2 3

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

1 >> f=[1;2;3]2 f =3 14 25 36 >> f=[17 > 28 > 3]9 f =

10 1

9En Octave existe la variable prefer_column_vectors. Activando esta variable con prefer_column_vectors=1el vector por defecto será columna en vez de fila emulando el comportamiento de Fortran. Sirva esto para mostrar queOctave es totalmente configurable.

10El principal peligro de la asignación dinámica de memoria es que nosotros no sabemos cuándo usamos demasiada.Es muy importante en códigos no usar más memoria en ningún momento que la RAM disponible, porque en el casoque ’pisemos’ fuera de la RAM, el proceso empezará a escribir sobre el disco duro y el rendimiento puede bajar hasta endos órdenes de magnitud. El problema es que en éste caso lo hacemos sin querer y además el programa no nos avisa. Esbueno entonces tener algún monitor del sistema que nos diga cuánta memoria estamos usando en tiempo de ejecución ysi estamos pisando fuera, es decir, escribimos en el espacio ’swap’.

Page 21: Notas Octave

3.4 Argumento 21

11 212 3

Esta es exactamente la misma notación que se sigue para introducir una matriz entera. Lo inten-tamos con: 1 2 3

4 5 67 8 9

1 >> m=[1,2,3;4,5,6;7,8,9]2 m =3 1 2 34 4 5 65 7 8 9

Aunque cualquier combinación de las anteriores sería perfectamente válida, por ejemplo:

1 >> m=[1 2 32 > 4 5 63 > 7 8 9]4 m =5 1 2 36 4 5 67 7 8 9

La llamada simple a un elemento cualquiera de una matriz se hace indicando su fila y su columnapor ese orden. En el caso de la matriz m:

1 >> m(2,1)2 ans = 4

Aprenderemos a crear matrices de más dimensiones en la sección ??.

Tipos de argumentos matriciales

Cuando se habla del tipo de un argumento no estamos hablando sólo de si es una matriz,una cadena de caracteres, un número complejo. El concepto en el ámbito del cálculo numéricova mucho más allá. Se llama tipo a la representación que tiene un argumento en la memoriadel ordenador. Cuando almacenamos un número podemos hacerlo en varias representaciones;coma flotante de simple precisión, entero de 32 bits... Antes hemos hablado de la configuraciónpor defecto de Matlab que almacena todos los elementos de una matriz como reales de dobleprecisión (64 bits o 8 bytes).

Todo lo dicho anteriormente para la representación interna de números es válida sólo pordefecto. En ningún momento afirmamos que el único tipo de escalar posible es el real de dobleprecisión. Podemos definir explícitamente números ,es decir, matrices; con tipos distintos al realde doble precisión (DOUBLE).

Los tipos soportados por matlab son los mismos que C excepto por el tipo long double (real de128 bits). Esta representación tiene una limitación evidente; como la formulación de los argumen-tos en Matlab es matricial sólo podremos tener matrices de un único tipo. No podremos construirmatrices con elementos enteros y elementos reales a la vez. Esta es una limitación común a todoslos lenguajes de programación y viene dado por la manera en la que cualquier programa reserva(alocatea) memoria. Por ejemplo, si deseamos operar con matrices de números enteros de 8 bitsutilizaremos la función int8 del modo siguiente:

Page 22: Notas Octave

22 El lenguaje común de Matlab y Octave

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

Llama la atención el hecho de que el número 109237401823056187365 se ha convertido en el 127.Esto es debido a que el mayor entero de 8 bits que podemos almacenar es precisamente 127. Sinecesitamos una aritmética de mayor precisión entera siempre podemos hacer lo siguiente:

1 x=int64([1,2;109237401823056187365,83.0938])2 x =3 1 24 9223372036854775807 83

Ni siquiera el mayor entero disponible es capaz de almacenar el número anterior.Podemos tener la necesidad de manipular la cantidad de memoria dedicada a cada elemento

de una matriz por dos motivos

1. Estamos definiendo matrices de gran tamaño y tenemos la necesidad de reducir la precisiónde los argumentos reales; ya sea por la necesidad de reservar memoria o por requerimientosde velocidad de cálculo

2. Necesitamos operar con tipos de enteros, ya sean con signo o sin signo para realizar conellos operaciones lógicas por bits o utilizar lógica entera.

En Octave sólo es posible lo segundo porque el tipo de real es siempre el de doble precisión.Hablaremos un poco más de los tipos de argumentos escalares en la sección dedicada a rutinasde creación de matrices.

3.4.2. Secuencias

Son parecidas a los vectores pero no lo son. Aparecen por todos los elementos del lenguaje, enlas submatrices, en los contadores en el funcionamiento interno de muchas funciones... Siempreque necesitemos contar algo aparecerán las secuencias porque es el método propio Matlab paracontar. Si queremos una lista de números que nos cuente del 1 al 10 hacerlo es tan fácil como:

1 >> secuencia=1:102 secuencia =3 1 2 3 4 5 6 7 8 9 10

Si queremos manipular el contador para que no sea de 1 en 1 podemos introducir el salto entredos números sucesivos:

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

Contadores no enteros.

Las secuencias soportan intervalos distintos a los números enteros. Podemos introducir lasecuencia:

Page 23: Notas Octave

3.4 Argumento 23

1 >> 0:0.5:42 ans =3 Columns 1 through 8:4 0.00000 0.50000 1.00000 1.50000 2.00000 2.50000 3.00000 3.500005 Column 9:6 4.00000

Si el intervalo que introducimos no ajusta exactamente al límite superior parará de contar sinpasarse.

1 >> 0:0.52:42 ans =3 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 porquegenera números no enteros. Su utilidad se encuentra en la discretización de intervalos necesaria,por ejemplo, en los ejes de coordenadas.

3.4.3. Submatrices

Para asignar partes de matrices a variables o operar dentro de una matriz con una parte dela misma es necesario asignarles una secuencia de índices. Se puede decir que la submatriz segenera contando los índices de la primera Para entender mejor cómo funciona este tipo de asigna-ciones mejor hacerlo mediante ejemplos. Iniciaremos una sesión en Matlab creando una matrizde números aleatorios:

1 >> foo=rand(5,5)2 foo =3 0.808048 0.804808 0.871166 0.606412 0.8677164 0.114965 0.524531 0.210789 0.163542 0.6390945 0.476355 0.544236 0.254009 0.818164 0.0919346 0.736103 0.231876 0.115706 0.336303 0.4780427 0.807002 0.244172 0.507355 0.814160 0.792253

Ahora crearemos una submatriz llamada bar que contendrá las filas de la segunda a la quinta ycolumnas de la tercera a la quinta.

1 >> bar=foo(2:5,3:5)2 bar =3 0.210789 0.163542 0.6390944 0.254009 0.818164 0.0919345 0.115706 0.336303 0.4780426 0.507355 0.814160 0.792253

Pero las secuencias tienen la capacidad de contar de modos distintos, en el caso siguiente conta-remos las filas de 2 en 2 como muestra el siguiente ejemplo. En él crearemos una submatriz qweque sean, de la matriz foo las filas de la primera a la quinta de 2 en 2 (la primera, la tercera y laquinta) y las columnas de la primera a la tercera.

1 >> qwe=foo(1:2:5,1:3)2 qwe =3 0.80805 0.80481 0.871174 0.47635 0.54424 0.254015 0.80700 0.24417 0.50735

Page 24: Notas Octave

24 El lenguaje común de Matlab y Octave

Si omitimos los elementos de la secuencia y dejamos sólo el símbolo :, el resultado será quetomaremos todos los elementos de la fila o de la columna.

Además de una secuencia los índices pueden introducirse mediante vectores:

1 >> qwe=foo([1,2],[1,2])

3.4.4. Números Complejos

En realidad deberían llamarse matrices cuyos elementos son números complejos, pero se haabreviado. Las reglas matriciales son exactamente las mismas, lo único que cambia es el carácterindividual de cada elemento. La manera de introducir un número complejo como argumento enuna variable es el uso del número i que multiplica a la parte imaginaria.

1 >> numcom=2+3i

También podemos usar otros signos para expresar i como j, I o J. Evidentemente tambiénpodemos crear vectores, matrices y tensores de números complejos, y al buscar un índice en ellostendremos el número complejo completo.

La biblioteca de funciones contiene las funciones habituales para trabajar con este tipo de nú-meros, como real e imag para calcular la parte real e imaginaria y abs para calcular el módulode un número complejo.

3.4.5. Cadenas de texto

Podemos asignar a una variable una cadena de texto introduciéndola entre comillas simpleso dobles:

1 >> saludo=’hola que tal’;

y si pedimos qué hay en la variable:

1 >> saludo2 saludo = hola que tal

En Octave también son válidas las comillas dobles:

1 >> saludo=’’hola que tal’’2 saludo = hola que tal

Matlab almacena las cadenas de texto como un vector de caracteres. Esto significa que aceptatodas las posibilidades de composición de vectores, la diferencia es que operaremos con carac-teres ASCII en vez de con números reales. Para demostrarlo nada mejor que intentar encadenarpalabras en fila

1 >> [’me’,’gusta’,’el’,’furbo’]2 ans = megustaelfurbo

o en columna

1 >> [’me’;’gusta’;’el’;’furbo’]2 ans =3 me

Page 25: Notas Octave

3.5 Operadores 25

4 gusta5 el6 furbo

3.4.6. Variables lógicas

Sólo tenemos dos variables lógicas que son true y false. Estos nombres son sólo interfaces,en realidad Matlab toma 0 como falso y cualquier número distinto de cero como verdadero.

3.5. Operadores

Cuando operamos elementos en Matlab, como cuando lo hacemos en cualquier lenguaje deprogramación, debemos tener en cuenta la dicotomía entre variable y argumento. Es tan impor-tante porque debemos comprender perfectamente la sutileza de que los operadores no operanvariables sino argumentos, en el caso de Matlab, matrices.

La consecuencia directa es que todos los operadores de Matlab son matriciales. En algunoscasos, como la suma o la resta, los operadores matriciales son equivalentes a lo escalares (ele-mentwise11 o elemento a elemento); en cambio la multiplicación y la potencia generan resultadoscompletamente distintos.

Por ejemplo, si tomamos dos matrices cualquiera:

1 >> A=[1 2 3;4 5 6;7 8 9];2 >> B=[9 8 7;6 5 4;3 2 1];

Su multiplicación directa va a dar como resultado precisamente la multiplicación matricial:

1 >> A*B2 ans =3 30 24 184 84 69 545 138 114 90

¿Y si queremos una operación escalar? Todos los operadores de Matlab pasan de matriciales aescalares añadiendo un punto justo antes del símbolo del operador. En el caso de las matricesanteriores:

1 >> A.*B2 ans =3 9 16 214 24 25 245 21 16 9

La potencia es la operación que más errores provoca cuando se es principiante con el Matlab.Cuando uno piensa en la operación de la potencia nunca piensa en ella como una operaciónmatricial; es muy poco intuitivo. No pensamos que la operación:

1 >> A^2

Sea equivalente a:

11Elementwise significa literalmente en inglés elemento a elemento.

Page 26: Notas Octave

26 El lenguaje común de Matlab y Octave

1 >> A*A;

Operación que es matricialmente del todo lógica. Este comportamiento provoca dos errorestípicos.

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 ningunalógica

Un ejemplo claro es lo que nos encontramos cuando elevamos la anterior matriz a una burdaaproximación del número π:

1 >> A^3.142 ans =3 691.22 - 0.43i 850.20 - 0.12i 1009.17 + 0.20i4 1567.33 - 0.05i 1925.90 - 0.01i 2284.47 + 0.02i5 2443.44 + 0.34i 3001.60 + 0.09i 3559.76 - 0.15i

¿Números complejos?El problema es que en Matlab cualquier argumento puede ser una matriz; olvidarnos el punto

antes de utilizar la potencia...

1 >> A.^3.142 ans =3 1.0000 8.8152 31.48914 77.7085 156.5906 277.58435 450.4098 685.0189 991.5657

es uno de los errores más comunes. Por suerte los errores suelen ser tan evidentes que la sangreraramente llega al río. El problema llega cuando elevamos al cuadrado matrices cuadradas. Losresultados obtenidos con el operador matricial y escalar son parecidos y del mismo orden demagnitud con lo que pueden ser un gran escollo en el proceso de depuración.

3.5.1. Operadores aritméticos

x+y Suma. Si ambos operandos son matrices el número de filas 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

x-y Resta. Las consideraciones sobre matrices son las mismas que con el operador suma.

x*y Multiplicación matricial. Si ambos elementos son matrices el número de filas y de columnasdebe ser el mismo. Si uno de los dos operandos es un escalar su valor es multiplicado atodos los elementos del otro.

x.*y Multiplicación elemento a elemento. Si ambos operandos son matrices el número de filasy de columnas debe coincidir.

x/y “División de izquierda a derecha”. Esta operación es equivalente a:((y>)−1x>

)>con la diferencia que en este caso no se calcula la inversa. En el caso que la matriz y no seacuadrada se da una solución con la condición de mínimo error12.

12Esto se hace calculando la pseudo inversa

Page 27: Notas Octave

3.5 Operadores 27

x./y División de izquierda a derecha elementwise. Se divide cada elemento de la matriz x porcada elemento de la matriz y.

x\y División de derecha a izquierda. Esta operación es equivalente a:

x−1y

y sirve para resolver sistemas de ecuaciones lineales. Como en la división anterior no secalcula efectivamente la inversa de la matriz, de modo que en el caso que no sea cuadradaseguirá dando un resultado. Analizaremos este operador con mucha más profundidad enel apartado dedicado a álgebra lineal.

x.\y División de derecha a izquierda elementwise.

x^y

x**y Potencia. Si ambos operadores son escalares el resultado es x elevado a la potencia de y. Six es un escalar y y es una matriz cuadrada el resultado se calcula a partir de un desarrollo deautovalores. Si x es una matriz cuadrada e y es un entero el resultado es la multiplicaciónde x por ella misma y veces y si y es un real se calcula el resultado por un desarrollo deautovalores. Cuando tanto x como y son matrices el resultado es error. La notación ** sólose puede usar en Octave.

x.^y

x.**y Potencia elementwise. Si los dos operandos son matrices deben ser del mismo tamaño. Lanotación .** sólo se puede usar en Octave

-x Negación

x’ Traspuesta compleja conjugada. Si la matriz x está compuesta por números reales el resul-tado es exactamente el mismo que para la traspuesta. Si hay algún argumento complejo eloperador es equivalente a hacer conj(x.’).

x.’ Traspuesta. Nótese que el uso de la notación usual elementwise no tiene el mismo sentido.

3.5.2. Operadores de comparación

x<y Verdadero si x es menor que y.

x<=y Verdadero si x es menor o igual que y.

x==y Verdadero si x es igual que y.

x>=y Verdadero si x es mayor o igual que y.

x>y Verdadero si x es mayor que y.

x!=y

x~=y Verdadero si x es distinto que y. En Octave son válidos ambos signos mientras que Matlabsólo soporta el segundo.

Page 28: Notas Octave

28 El lenguaje común de Matlab y Octave

3.5.3. Operadores lógicos

Hay dos tipos de operaciones lógicos, los que interactúan con matrices y los que lo hacencon expresiones lógicas como las que nos encontramos en las estructuras if y while. Los delprimer tipo son & para “y”, | para “o” y ! para “no”. Si decimos que operan con matrices esporque aplicados a matrices de condiciones lógicas devuelven una matriz del mismo tamaño,por ejemplo:

1 >> [1,2;0,1]&[0,1;0,1]2 ans =3 0 14 0 15 >> ![0,1;2,0]6 ans =7 1 08 0 1

La expresión entera para condiciones lógicas es 0 para “falso” y distinto de 0 para “verdadero”,es decir, lógica binaria usual.

Para componer expresiones lógicas se usan los símbolos && para “y” y || para “o”. La dife-rencia entre estos y los anteriores es que el resultado siempre será booleano. Si se aplica a unamatriz colapsará sus elementos con la función all para llegar a una expresión única. Como yahemos dicho antes su aplicación principal se encuentra en las estructuras de control de ejecucióncomo if y while.

En los capítulos posteriores veremos varias aplicaciones de estos operadores.

3.5.4. Operadores de comparación por bits en enteros

Matlab es también capaz de comparar y manipular los bits en enteros. Para eso dispone delas funciones siguientes:

1 >> bit<TAB>2 bitand bitmax bitset bitxor3 bitcmp bitget bitor bitshift4 >> a=5; %Un numero entero5 >> dec2bin(a) %Que tiene esta representacion decimal6 ans = 1017 >> a=bitset(a,1,0) %Reset del primer bit8 a = 49 >> a=bitset(a,6,1) %Set del sexto bit

10 a = 3611 >> dec2bin(a)12 ans = 10010013 >> b=bitset(1,6) % Una forma alternativa de set14 b = 3315 >> dec2bin(b)16 ans = 10000117 >> bitand(a,b) % y logico18 ans = 3219 >> dec2bin(bitand(a,b)) % En bits...20 ans = 10000021 >> bitor(a,b) % o logico22 ans = 3723 >> dec2bin(bitor(a,b)) % En bits...24 ans = 10010125 >> bitxor(a,b) % o exclusivo logico

Page 29: Notas Octave

3.6 Variables 29

26 ans = 527 >> dec2bin(bitxor(a,b)) % En bits...28 ans = 101

3.6. Variables

Debemos pensar en ellas como cajas que ocupan memoria, independientemente de lo quelleven dentro. Debe abstraerse la variable del argumento que contenga, en el fondo no es másque un nombre.

Por el hecho de ser un lenguaje de scripting las variables no deben declararse. Esto hace queprogramar sea mucho más sencillo, se haga con menos errores y en menos tiempo a costa de unmayor tiempo de ejecución. Esto también significa que la cantidad de memoria asignada a unavariable es dinámica, podemos ampliar una matriz 13 sin ningún problema con el simple hechode llenar un elemento que no exista.

Aquello que nosotros asignamos a una variable se llamará argumento14. A cada variable leasignaremos uno o varios argumentos, de modo que la variable no es más que un nombre por elque llamamos su contenido.

Las variables pueden ser cualquier secuencia de letras, no hay limitación en su número, sóloque deben empezar con un carácter tipo letra o con _ . Se distingue entre mayúsculas y minúscu-las. Los nombres siguientes serían válidos:

1 x2 x153 __hola_que_tal__4 fjalsbdgaoqiwbodj

El nombre de una variable es una función en sí misma, llamada sin argumentos sacará por panta-lla el valor de la variable. Algunas variables tienen un valor por defecto como pi o ans. Algunasde estas variables son parte de la configuración interna del programa así que es importante co-nocerlas para no tener sorpresas desagradables.

3.6.1. Acceso a las variables:

Si nos dicen que una variable es local por defecto probablemente no entendamos nada. Sabersi una variable es accesible o no por una función no es una tarea sencilla y depende de cómo sehayan declarado las variables. El esquema normal es el de la figura 3.4. Supongamos que somosuna variable en el programa principal y en un instante de la ejecución somos el argumento deuna función. No nos sucede absolutamente nada. Otra variable va a tomar nuestro valor en lacabecera de la función y su resultado se va a volcar en el programa principal. A no ser que elresultado se nos asigne, cambiando nuestro valor, seguirá sin sucedernos nada. En cambio lasvariables locales para la función son eliminadas de la memoria cuando termina su ejecución.

Si le damos a una variable el atributo de global con la palabra clave global entonces estavariable podrá ser vista por cualquier unidad de código sin necesidad de llamarla en su cabecera.A estas variables no les importa si están en el programa principal o en una función, su contextoes toda la ejecución; pueden saltar a cualquier hilo como en el esquema de la figura 3.5:

Al estar definida como una variable global no sólo puede ser vista por la función; si ademásla función cambia su valor también cambiará en el programa principal. Un ejemplo de ello es elcódigo siguiente:

13Ampliar una matriz es exactamente equivalente que asignar más memoria a una variable. En Fortran sería dealocatearuna variable, ampliarla y alocatearla otra vez.

14El concepto de argumento en programación es mucho más extenso, pero creo que es conveniente usarlo de este modo.

Page 30: Notas Octave

30 El lenguaje común de Matlab y Octave

Figura 3.4: Comportamiento normal de una variable llamada por una función

Figura 3.5: Comportamiento de una variable global definida en el programa principal

1 >> global x=22 >> x3 x = 24 >> function f()5 global x6 x=37 end8 >> f()9 x = 3

Como se ve debemos tener cuidado con los nombres de las variables globales, no es difícil estro-pear el código llamando una variable global en una función sin querer15.

15El uso de las variables globales es una de las pocas discusiones de estilo abiertas. En otros lenguajes de programación,sobre todo los que permiten la programación orientada a objetos, no es necesario utilizar este tipo de variables. Es unadiscusión entre dos escuelas. Los que estamos más acostumbrados a una programación modular (Fortran) nos sentimosmás cómodos controlando el hilo de ejecución con variables globales. En cambio, la escuela procedente de C++ y de Javaprefieren crear métodos mucho más ricos en los que las funciones son en realidad métodos de un objeto que puede habersido inicializado previamente.

Creo que para un principiante el uso de variables globales es un buen ejercicio mental para aprender que hay distin-tos niveles de ejecución en la programación modular sin entrar en conceptos que muchos usan pero sólo unos pocos

Page 31: Notas Octave

3.6 Variables 31

Un tercer atributo es el de persistent. Cuando dentro de una función indicamos que unavariable es persistent estamos imponiendo que esta variable se guarde en memoria para lasiguiente vez que se llame la función en vez de hacerla desaparecer, como es normal. El diagramaconceptual es el de la figura 3.6.

Figura 3.6: Propiedades de una variable persistente.

No tiene ningún sentido definir una variable como persistent en el programa principalporque las variables locales para el hilo principal no se destruyen hasta que termina la ejecución.

3.6.2. Funciones dedicadas a variables

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

is_global que devuelve un 1 en el caso que la variable efectivamente lo sea

clear que borra el contenido de una o varias variables, funciones o variables globalesdependiendo del parámetro que le pasemos

who que da una lista de las variables que en aquél mismo momento estén ocupadas poralgún argumento. También acepta parámetros para variar su comportamiento.

whos , lo mismo que who pero nos da más información.

Importante: Es necesario entender el concepto de variable local y global para comunicar funcio-nes y scripts de una manera eficiente

3.6.3. Contenedores

La limitación las matrices es que sólo pueden contener elementos de un mismo tipo. Una ma-triz no puede contener una cadena de caracteres y un número a la vez. Si sumamos mentalmentedos matrices entenderemos facilmente por qué.

Necesitemos entonces definir un tipo más complejo que un caracter o un escalar. Un tipo deri-vado es una extensión del concepto de argumento en el que se permite que una variable contengaun argumento múltiple con elementos de distinta naturaleza. Un tipo derivado es lo que permiteasignar a una variable un número y una cadena de caracteres a la vez.

entienden.

Page 32: Notas Octave

32 El lenguaje común de Matlab y Octave

La estructura típica de los tipos derivados es la que tiene forma de árbol. Son llamadas estruc-turas de datos. En ellas, una variable primitiva contiene más variables adicionales que a su vezpueden contener más ramificaciones. Otro tipo es emular el comportamiento de una matriz o unvector y permitir que sus elementos sean de tipos distintos. Obviamente esta ganancia de poten-cia se pierde en los operadores. Una matriz puede ser sumada a otra matriz, en cambio un tipoderivado no puede ser sumado a otro tipo derivado ya que Matlab no tiene ninguna informaciónde qué contiene cada uno.

Esto hace que la línea 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 delmismo tipo y los tipos derivados como estructuras de variables. Entrar en sutilezas teóricas noes muy conveniente, simplemente debemos centrarnos en la gran utilidad de las estructuras dedatos o las celdas de variables ya que permiten agrupar en forma de única variable estructurasmás complejas de lo habitual.

Estructuras de datos

Octave, al igual que la mayoría de los lenguajes de programación modernos, nos permiteagrupar variables en estructuras tipo árbol. Podemos entonces agrupar distintos tipos de argu-mentos dentro de una variable. Para probar esta posibilidad vamos a escribir un script de pruebaque se va a llamar estructura.m.

1 % estructura.m2

3 % Este es el script de prueba para las variables de tipo estructura4 foo.num=1.234;5 foo.string=’hola mundo’;6 foo.options.option1=true;7 foo.options.option2=false;

Lo guardamos en el directorio correspondiente y si nos vamos a la consola y tecleamos estructuraqué obtenemos? Pues nada en absoluto porque le hemos pedido con los puntos y coma que nonos sacara ninguna información por pantalla. Si queremos que nos diga qué hay dentro de lavariable foo debemos teclear foo en la consola y nos aparecerá lo siguiente:

1 >> estructura2 >> foo3 foo =4 {5 num = 1.23406 options =7 {8 option1 = 19 option2 = 0

10 }11 string = hola mundo12 }

que es exactamente la estructura de argumentos que hemos introducido 16. Vemos la manera deintroducir comentarios en un script de Matlab, con el signo%. Todo lo que escribamos a partir deéste símbolo será ignorado por el intérprete.

16Si queremos que Octave nos saque cualquier argumento por pantalla podemos usar la función disp(). En este casoal final de nuestro script podríamos añadir:disp(’nuestra estructura es’)disp(foo)

Page 33: Notas Octave

3.6 Variables 33

Además de muchas otras, la mayor utilidad de las variables de tipo estructura es que nospermiten acortar las cabeceras de las funciones. Pongamos como ejemplo un programa que seconfigura con unos veinte parámetros. Si una función necesita quince de ellos significa que cadavez que llamemos a la función en nuestro código aparecerá una cabecera con quince variables.Esto haría el código más pesado de escribir y mucho más difícil de leer y mantener. Podemosponer todos nuestros parámetros dentro de una variable que se llame parms, de tal maneraque siempre que necesitemos un parámetro, por ejemplo Longitud, en cabecera simplementellamamos a parms y dentro del programa nos referimos a parms.Longitud.

Cell Arrays.

Las celdas son matrices o hiper-matrices de variables. No debemos confundirlas con las ma-trices usuales que son estructuras de argumentos del mismo tipo. Una celda puede contenermatrices, cadenas de texto y argumentos lógicos a la vez siempre que estén en celdas separadas.A diferencia de las estructuras de datos no tendremos que asignar un nombre a cada una de lasceldas porque ya se les asignará un grupo de índices.

Podemos construir celdas de dos modos, el primero es declarar una variable como cell ydarle una dimensiones. Por ejemplo construiremos una celda de 2 por 2 cuyos elementos pareci-dos a los contenidos en la estructura de datos foo:

1 >> foo = cell(2,2)2 foo =3 {4 [1,1] = []5 [2,1] = []6 [1,2] = []7 [2,2] = []8 }9 >> foo{1,1}=1.2340;

10 >> foo{1,2}=[1,2;3,4];11 >> foo{2,1}=’hola mundo’;12 >> foo{2,2}=true;13 >> foo14 foo =15 {16 [1,1] = 1.234017 [2,1] = hola mundo18 [1,2] =19 1 220 3 421 [2,2] = 122 }

Como en el caso de las matrices convencionales podremos ampliar las celdas con sólo llenar unaque no tenga ningún argumento asignado; las celdas “sobrantes” quedan vacías:

1 >> foo{3,1}=false2 foo =3 {4 [1,1] = 1.23405 [2,1] = hola mundo6 [3,1] = 07 [1,2] =8 1 29 3 4

10 [2,2] = 1

Page 34: Notas Octave

34 El lenguaje común de Matlab y Octave

11 [3,2] = []12 }

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

1 >> foo={1.2340,[1,2;3,4];’hola mundo’,true}2 foo =3 {4 [1,1] = 1.23405 [2,1] = hola mundo6 [1,2] =7 1 28 3 49 [2,2] = 1

10 }

Importante: Las celdas pueden almacenar cualquier tipo de argumento, incluso funciones. Esmás fácil y rápido escribirlos utilizando llaves.

La necesidad de los cell arrays y los tipos derivados

No todo en un lenguaje de programación son aplicaciones sencillas donde escalares, vectoresy matrices bastan. Tampoco es cierto que el dato más complejo suelen ser los argumentos quepasamos a las funciones. Un programa puede requerir variables que contengan tipos de grancomplejidad, normalmente obligados por el propio algoritmo.

Supongamos que intentamos una población de datos especialmente compleja, algo usual enuna base de datos. Pongamos como ejemplo una descripción de todos los trabajadores de unaempresa. Esto es un ejemplo, seguramente no utilizaremos un lenguaje de programación orien-tado a cálculo numérico para resolver un problema como este pero otras aplicaciones como losalgoritmos genéticos pueden requerir tipos derivados especialemnte complejos.

Sigamos con el ejemplo definiendo nuestro tipo Empleado. Cada empleado de la empresaproporciona los siguientes datos:

Nombre completo

Nacionalidad

Documento de identidad

• Tipo

• Número

• Fecha de expedición

• Fecha de caducidad

Dirección de contacto

Números de teléfono

• Número de la dirección de contacto

• Teléfono movil de empresa

• Teléfono movil personal

Page 35: Notas Octave

3.7 Sentencias 35

Cuando nuestros datos son muy complejos solemos pensar durante largo tiempo el métodomás adecuado de almacenar todos los datos. Crear una variable para cada trabajador no es muyrecomendable porque es probable que tengamos que iterar sobre el total de ellos. Tampoco parecemuy inteligente partir todos los datos en varias matrices y relacionarlas según los índices.

La abstracción llevada a los lenguajes de programación modernos tiene una consecuenciamuy importante: debemos ser capaces de seguir uilizando las mismas herramientas de programación seacual sea el dato con el que estemos trabajando. Si un lenguaje se ha diseñado con el paradigma dela abstracción como prioridad podremos seguir escalando la complejidad de las estructuras dedatos tanto como queramos sin perder las herramientas de cálculo. Matlab no es un prodigio eneste sentido pero se defiende bien.

El elemento que mantiene la escalabilidad en las estructuras complejas de datos son los cellarrays. Al seguir una estructura matricial pueden encapsularse tantos cell arrays como queramos.Pueden contener tanto los tipos básicos (números y cadenas de texto) como estructuras de datoso otras celdas. De este modo podemos definir la estructura empleado del siguiente modo:

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

7 {8 [1,1] = Paquito Palotes Parrondo9 [2,1] = Deaqui

10 [3,1] =11

12 {13 [1,1] = DNI14 [1,2] = 64684321615 [1,3] = 1212200016 [1,4] = 1212200017 }18

19 [4,1] = C Buenaesperanza 12 1,220 [5,1] =21

22 666251487 55569854123

24 }

Lo novedoso es que mantenemos la escalabilidad de la estructura indefinidamente. Podemossin ninguna restricción encapsular todos los empleados en la variable Empresa como si fueranelementos de una fila en una celda:

1 >> Empresa={Empleado1,Empleado2,Empleado3}

3.7. Sentencias

Como se ha dicho antes, las estructuras esenciales del lenguaje son los contadores y los condi-cionales. Más comúnmente conocidas como las sentencias do y las sentencias if. Estas estructu-ras son comunes con el resto de lenguajes de programación y de scripting existentes. La primeraes un bucle contador que permite ejecutar varias tareas idénticas secuencialmente con la varia-ción de diversos índices; se pueden encapsular con otros contadores y con otras sentencias. La

Page 36: Notas Octave

36 El lenguaje común de Matlab y Octave

segunda permite incluir variaciones en la ejecución del código según el cumplimiento de ciertascondiciones lógicas.

Estos no son las únicas estructuras de programación, son las más básicas. A partir de ellas sederivan sentencias más útiles y más específicas como veremos a continuación.

Al igual que las funciones, las sentencias tienen un principio y un final definido iniciadopor una palabra clave. Matlab utiliza la notación clave-cuerpo-end al igual que Fortran; C, porejemplo delimita estas estructuras mediante llaves y Python utiliza el sangrado.

En este caso Matlab y Fortran presentan una diferencia esencial. Mientras Fortran tiene uncierre para cada una las estructuras; do debe cerrarse con un end do, Matlab cierra todas ellascon un end. El uso sistemático de end puede llevar a confusiones nefastas, es por ello que Octavetambién soporta el uso de endfor, endif...

3.7.1. La sentencia if

Tenemos tres formas de condicional. La más simple es:

1 if (condicion)2 cuerpo3 endif

Por ejemplo:

1 >> esto=1;2 >> if esto3 ... disp(’es esto’);4 ... end5 es esto6 >> esto=0;7 >> if esto8 ... disp(’es esto’);9 ... end

Si queremos que la sentencia no se ignore, y que si la condición no se cumple impongamosun cuerpo distinto podemos usar la estructura:

1 if (condicion)2 cuerpo 13 else4 cuerpo 25 endif

Ejemplo:

1 >> esto=1;2 >> if esto3 ... disp(’es esto’);4 ... else5 ... disp(’es lo otro’);6 ... end7 es esto

En la que se ve perfectamente que si no se cumple la condición 1 inmediatamente se ejecutael cuerpo2. Si tenemos más de una condición lógica sobre una misma variable podemos usar unacondicional múltiple de la siguiente forma:

Page 37: Notas Octave

3.7 Sentencias 37

1 if (condicion 1)2 cuerpo 13 elseif (condicion 2)4 cuerpo 25 ...6 elseif (condicion n)7 cuerpo n8 else9 cuerpo N

10 endif

17 Debe recalcarse que la condición debe ser sobre la misma variable para cerrar la lógica delcondicional. En el caso que tengamos condiciones lógicas sobre más de una variable podemosencapsular los if sin ningún problema:

1 if (condicion a)2 if (condicion b)3 cuerpo a+b4 else5 cuerpo a+bN6 endif7 else8 cuerpo aN9 endif

Es importante que evitemos estructuras lógicas muy complejas, porque son difíciles de entendery de depurar; aún cuando las ha escrito uno mismo. Se verán ejemplos de estas estructuras en lasección de ejercicios.

3.7.2. La sentencia switch.

Lo forma general del comando es:

1 switch (variable_switch)2 case (posible_valor_variable_switch)3 comandos4 case (posible_valor_variable_switch)5 ...6 otherwise7 comandos adicionales8 endswitch

Esta sentencia es la misma que case en Fortran y switch en C. Un ejemplo de su uso sería:

1 >> a = ’dos’2 >> switch (a)3 case (’uno’)4 disp(’has escogido el numero 1’)5 case (’dos’)6 disp(’has escogido el numero 2’)7 otherwise

17Mucho cuidado los programadores acostumbrados a Fortran, sea cual sea la variante. Si nosotros usamos else ifen vez de elseif, Matlab va a pensar que tenemos dos sentencias separadas, es decir, primero un else y luego un ifdentro del else. Esto significa que tenemos una ejecución anómala en vez de un error. Es uno de estos casos en los que elprograma nos ejecuta, nos da un resultado erróneo y nosotros no vemos de ninguna manera el error de programación

Page 38: Notas Octave

38 El lenguaje común de Matlab y Octave

8 disp(’no se que numero has escogido’)9 endswitch

10 has escogido el numero 2

3.7.3. Las sentencias for y while

Así es como se denomina el contador o sentencia do en Matlab. Su estructura es:

1 for [variable contador]=[secuencia del contador]2 cuerpo [dependiente o no de la variable contador]3 endfor

Es decir, para una determinada variable, que avanza de 1 en 1 desde el límite inferior hasta ellímite superior ejecutamos el cuerpo. El cuerpo puede depender o no de la variable contador, éstapuede ser un contador a parte, que simplemente nos imponga que una determinada sentencia seejecute un número fijo de veces. La mayoría de las veces nuestro cuerpo dependerá de la variableque 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 lasecuencia. Por ejemplo, si pedimos que una variable haga un bucle de ese tipo:

1 for i=1:2:10

dentro del bucle la variable i tomará los valores que salen por pantalla en el caso que llamemosla secuencia:

1 >> 1:2:102 ans = 1 3 5 7 9

Por ejemplo:

1 >> for i=5:5:252 ... disp(i),disp(’es multiple de 5’)3 ... end4 55 es multiple de 56 107 es multiple de 58 159 es multiple de 5

10 2011 es multiple de 512 2513 es multiple de 5

Los bucles con contador también se pueden encapsular, y éste encapsulado es esencial cuan-do trabajemos con matrices de dimensión mayor que 1. Por ejemplo, si queremos asignar unaoperación compleja a una matriz de dimensión 3 debemos encapsular 3 contadores:

1 for i=1:IMAX2 for j=1:JMAX3 for k=1:KMAX4 cuerpo5 endfor

Page 39: Notas Octave

3.7 Sentencias 39

6 endfor7 endfor

En vez de controlar el bucle mediante un contador es muy útil controlarlo mediante unacondición lógica. Para eso podemos usar una estructura while.

1 while (condicion)2 cuerpo3 endwhile

Ejemplo:

1 >> a=0;2 >> while a<53 ... disp(a)4 ... a=a+1;5 ... end6 07 18 29 3

10 4

Sólo debemos tener en cuenta cuando programamos que el uso de un while es mucho máscrítico que el uso de un for. Esto es porque la condición lógica que controla el bucle debe aplicarsesobre una variable interna en el bucle. Entonces es probable que si programamos mal, la varia-ble que usamos como control nunca llegue a cumplir la condición que nos para la ejecución. EnMatlab o Octave no suele ser un gran problema, puesto que el sistema puede reaccionar y cortarel proceso de otro modo, pero en otros lenguajes puede tener consecuencias bastante desagra-dables. También debemos tener en cuenta que los bucles controlados por una condición lógicano permiten la paralelización en el caso que tengamos una versión para varios procesadores deMatlab o Octave.

Mal uso de while

Uno de los argumentos posibles para el uso de while en sustitución de for es que el contadorse reasigna en cada iteración, es decir, el bucle no es consciente de las operaciones que se realicencon el índice.

En otros lenguajes de programación como C o Fortran sucede todo lo contrario: todas las ope-raciones con el índice son válidas porque el bucle no se encarga de reasignarle el valor siguiente.Se limita a darle un valor inicial, incrementarlo el entero dado y pararlo según una condicionlógica.

El bucle for en Matlab no es un bucle en el sentido clásico sino que es un iterador18 sobreun vector. En la programación moderna los bucles han desaparecido en favor de los iteradoresporque los segundos son mucho más polivalentes y seguros. Para demostrar qué significa estode iterador sobre un vector nos sirve este simple ejemplo. Generaremos una serie de Fibonaccien un vector y luego iteraremos sobre el mismo.

1 >> fib=[1,1,2,3,5,8]2 fib =3

4 1 1 2 3 5 8

18En informática se define iterador como un objeto que permite a un programa recorrer todos los elementos de un tipoiterable independientemente del tipo de los elements.

Page 40: Notas Octave

40 El lenguaje común de Matlab y Octave

5

6 >> for i=fib7 > disp(i)8 > end9 1

10 111 212 313 514 8

Son más seguros porque permiten iterar sobre una secuencia tan compleja como sea necesariasin arriesgarse a definir una condición sin fin. Esta propiedad deja con poco uso la sentenciawhile mucho menos potentes y más arriesgadas desde el punto de vista de la programaciónpura.

3.7.4. La sentencia do-until

Esta sentencia es equivalente a while con la condición lógica complementaria.

3.7.5. Las sentencias break y continue

Tanto para el for como para los otros tipos de bucles tenemos variables de control de laejecución que pueden ser de utilidad. La sentencia break dentro de un bucle nos quita el hilo19

del bucle para seguir ejecutando el programa o un bucle externo. Un ejemplo sería:

1 num=103;2 div=2;3 while (div*div <= num)4 if (rem (num, div) == 0)5 break;6 endif7 div++;8 endwhile9 if (rem (num, div) == 0)

10 printf (’El divisor menor de %d es %d \n’, num, div);11 else12 printf (’%d es primo \n’, num);13 endif

En cambio la sentencia continue, en vez de sacarnos del bucle, hace que saltemos uno de lospasos del mismo para ir al siguiente estado del contador.

3.7.6. La sentencia try

Los bloques de estructura try son de la forma:

1 try2 cuerpo3 catch4 alternativa5 end

19Se llama hilo precisamente a la línea de ejecución. Nos la podemos imaginar como la línea de código que siguen losprocesos. Este concepto va ligado íntimamente a la gestión de procesos y tiende a complicarse en lenguajes como C oFortran.

Page 41: Notas Octave

3.8 Funciones (II) 41

Por ejemplo:

1 >> a=rand(5,5);b=rand(4,4);2 >> try3 ... a*b4 ... catch5 ... disp(’Dimensiones incompatibles’)6 ... end7 Dimensiones incompatibles

Esta estructura es muy parecida a if-else pero con la particularidad que la condición lógicaes si se produce o no un error. Se usará cuando no sepamos si algo puede ejecutarse bien o no yno queramos que el error afecte al resto de la ejecución del programa. Primero intentará ejecutarla sentencia que hayamos puesto en cuerpo y si devuelve un error ejecutará alternativaignorando el error producido por la primera sentencia.

3.8. Funciones (II)

Tratar la función en Matlab sólo desde el punto de vista de un archivo auxiliar es un tremendoerror. La escritura y manipulación de funciones es la mayor potencia (probablemente la única)del lenguaje. Este planteamiento choca con la formulación básica de la función y se acerca mása los lenguajes orientados a objetos donde podemos asignar un método a una variable, algoimpensable en Fortran. Siendo poco rigurosos podemos decir que si C++ es un lenguaje orientadoa objetos Matlab es orientado a funciones.

3.8.1. Funciones matemáticas básicas

Matlab cuenta con una enorme biblioteca de funciones matemáticas. Su utilidad dependedirectamente del conocimiento que tengamos de ellas. Mientras intuitivamente ya hemos usadolas funciones trigonométricas sin y cos, muchas de las presentes en la colección ni nos sonarán.Cumple el objetivo principal de ahorrarnos tener que escribir cualquier función mínimamenteconocida. El nombre que reciben estas funciones suele ser bastante descriptivo; la función Γ sellamará gamma y las funciones de Airy se llamarán airy.

Estas funciones no son archivos .m, se escriben en un lenguaje compilado como C++ o Fortranpara que su velocidad sea mayor. No debemos tener miedo a usarlas tanto como sea posible.

3.8.2. La Ayuda(II)

Ya hemos hablado del comando help y cómo debe utilizarse. Nosotros también podemosdotar nuestras funciones de una ayuda parecida de una manera muy fácil. Todas las líneas co-mentadas entre la sentencia function y la primera sentencia ejecutable nos saldrán por pantallasi llamamos a la función mediante el comando help. Por ejemplo:

1 function out=derivada_numerica(in)2 %3 % funcion derivada_numerica Calcula las diferencias centradas de4 % primer orden de un vector entrada: in (vector) salida : out (vector)5 %6

7 ...8 end

Cuando hagamos help derivada_numerica obtendremos por pantalla:

Page 42: Notas Octave

42 El lenguaje común de Matlab y Octave

1 funcion derivada_numerica2 Calcula las diferencias centradas de primer orden de un vector3 entrada: in (vector)4 salida : out (vector)

Disponemos también de dos funciones para manejar los errores de ejecución, usage y error.En la sección 3.8.3 tenemos un ejemplo de cómo se usan. Son de gran utilidad sobre todo cuandohagamos debugging de un programa grande. Si se produce un error en la lectura de los argumen-tos o en el cálculo interno se imprime en pantalla toda la cadena de errores que han provocadoel fallo, estos mensajes son a menudo demasiado crípticos. Si intuimos que la ejecución puedefallar en algún sitio debemos preverlo, es una buena táctica pensar el hilo de ejecución tanto sifunciona correctamente como si no.

20

3.8.3. Argumentos de entrada y salida.

En el apartado anterior dedicado a funciones (3.3.1) hemos sido intencionadamente rigurososcon la sintaxis. Si una función retorna sólo una variable pueden omitirse los corchetes:

1 function salida = entrada (arg)2 salida = ...3 end

La función nargin retorna el número de argumentos de entrada necesarios en una función, si loaplicamos a la función entrada que acabamos de definir21:

1 >> nargin(’entrada’)2 ans = 1

Mientras que dentro de la función es una constante cuyo valor es el número de argumentos deentrada:

1 function retval = avg (v)2 % retval = avg(v) v :: vector3 %4 % Calcula la media de los elementos de un vector5 retval = 0;6 if (nargin != 1)7 usage (’avg (vector)’);8 endif9 if (isvector(v))

10 retval = sum(v) / length(v);11 else12 error (’avg: expecting vector argument’);13 endif14 end

Este ejemplo además nos sirve para ver el control de errores de una función. Las palabras claveusage y error son los mensajes que saldrán por pantalla si se comete un mal uso o existe unerror de ejecución respectivamente. Para que entendamos más en profundidad se propone estasesión de consola:

20En Octave también podemos escribir la ayuda en formato texinfo para incluir caracteres matemáticos y fraccionespero es un tema muy avanzado.

21En breve aprenderemos que la mejor manera de llamar este tipo de funciones es mediante un Function handle

Page 43: Notas Octave

3.8 Funciones (II) 43

1 >> help avg2 avg is the user-defined function from the file3 /home/guillem/CursoScripting/ejercicios/avg.m4 retval = avg(v)5 v :: vector6 Calcula la media de los elementos de un vector7 >> v=[1,2,3,4];8 >> avg(v)9 ans = 2.5000

10 >> u=[4,3,2,1];11 >> avg(u,v)12 usage: avg (vector)13 error: evaluating if command near line 8, column 314 error: called from ‘avg’ in file ‘/home/guillem/C...15 >> w=[1,2;3,4];16 >> avg(w)17 error: avg: expecting vector argument18 error: evaluating if command near line 11, column 319 error: called from ‘avg’ in file ‘/home/guillem/C...20 >>

Los corchetes son necesarios sólo cuando queramos retornar más de una variable:

1 function [salida1,salida2] = entrada (args)2 salida1 = ...3 salida2 = ...4 end

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

1 >> function [x,y,z] = f()2 x=1;3 y=2;4 end5 >> [a,b,c]=f()6 warning: in f near line 7, column 8:7 warning: f: some elements in list of return values are undefined8 a = 19 b = 2

10 c = []11 >>

Si queremos saber cuantas variables de salida tiene una función debemos usar nargout. Unavariable de control muy interesante es la palabra clave return, Cuando el hilo de ejecución deuna función pasa por la palabra return inmediatamente retorna la ejecución a la consola o alprograma principal:

1 function out = any_zero(v)2 % out = any_zero (v) v :: vector3 %4 % devuelve un mensaje si algun elemento de v es 05 out = 0;6 for i = 1:length(v)7 if (v (i) == 0)8 out = 1;9 return

Page 44: Notas Octave

44 El lenguaje común de Matlab y Octave

10 endif11 endfor12 printf (’No se ha encontrado ningun cero \n’)13 >> u=[1,2,3,0];14 >> v=[1,2,3,4];15 >> any_zero(u)16 ans = 117 >> any_zero(v)18 No se ha encontrado ningun cero19 ans = 0

3.8.4. inline

El uso que se le da a la función inline en esta sección queda perfectamente cubierto por las funcionesanónimas. El uso de inline queda restringido a la evaluación de una cadena de texto como función, no parala declaración de funciones. Este apartado debe reescribirse

Si Matlab no puede definir funciones completas dentro de un script significa que para escribircualquier expresión matemática no básica debemos crear un archivo. Esto no es del todo ciertopor la sentencia inline. Lo que hace es interpretar una cadena de texto en la que escribimosuna función y la conecta a una variable, como si de un puntero a una función se tratara. Su usoes muy sencillo, pero requiere cierta práctica.

Si queremos introducir una función escribiremos:

1 >> foo=inline(’sin(x)*cos(x)’,’x’);

En la que obviamente introducimos los elementos como cadenas de texto. Para evaluar la funciónlo haremos del modo usual:

1 >> c=foo(6)

que nos pondrá en la variable c el valor de la función en 6, -0.26829.En el caso que nuestra función tenga más de una variable de entrada podemos explicitarlas

como:

1 >> foo2=inline(’sin(x)*cos(y)’,’x’,’y’);

Entonces los parámetros de entrada para la evaluación van a ser dos y van a mantener el ordenasignado en la sentencia inline. De hecho, este intrinsic funciona perfectamente con sólo lafunción como argumento, pero es casi un imperativo para saber cómo se introducen las variablesen la evaluación.

También podemos utilizar la sentencia inline cuando se nos pida evaluar una función. Vi-mos un ejemplo de ello en el primer capítulo cuando se introdujo el lenguaje:

1 >> quad(inline(’besselj(2.5,x)’),0,4.5)2 ans = 1.1178

Para integrar necesitamos una función de una sola variable de modo que hemos creado unanueva función con la sentencia inline para modificar la función besselj. La nueva función(sin nombre) acepta sólo un argumento. Esta práctica es muy frecuente y útil, pensemos que porcada vez que utilicemos un inline nos ahorramos un archivo.

Page 45: Notas Octave

3.8 Funciones (II) 45

3.8.5. Function handles

Hemos enfatizado en la necesidad de diferenciar los conceptos de variable y de argumento.Ahora introduciremos un concepto aún más complejo, el de la manipulación de funciones. EnMatlab la función no es un elemento inerte como en Fortran, se parece bastante más a las fun-ciones de C. Un ejemplo de esta diferencia es que en C podemos crear matrices cuyos elementossean funciones gracias al uso de punteros.

Fuera de estas consideraciones teóricas diremos que Matlab tiene una herramienta para asig-nar funciones (aunque sería más correcto llamarlos métodos) a variables. Esta herramienta sellama Function handle por comparación con una herramienta real, sería conveniente llamarla“asa” o “mango”. Pensemos en un martillo; la herramienta en sí es sólo la cabeza y lo que nosayuda a manejarlo es el mango cuya función, aunque secundaria, es imprescindible. Lo mismosucede con las asas de una paellera. Las funciones en un archivo son como paelleras sin asas,cumplen su función pero no las podemos manejar. Si utilizamos los Function handles para asig-nar una función a una variable podemos utilizar la función sin hacerlo directamente al igual queoperamos los argumentos mediante variables.

Un Function handle se denota con la letra @. Por ejemplo, si queremos asignar a la variablevarsin la función sin lo haremos del siguiente modo:

1 >> varsin = @sin

A partir de ahora la variable sirve de interfaz a la función. Da igual que la función sea parte dela biblioteca estándar o que la acabemos de escribir nosotros mismos. Por si hay alguna duda deque varsin es ahora la función seno:

1 >> varsin(pi/2)2

3 ans = 1

Un uso muy interesante de los Function handles es la creación de estructuras de datos con fun-ciones. Como ejemplo crearemos unas celdas donde los elementos sean las funciones trigonomé-tricas básicas:

1 >> trifun={@sin,@cos,@tan}2 trifun =3 {4 [1,1] =5 sin6 [1,2] =7 cos8 [1,3] =9 tan

10 }11 >> trifun{3}(pi/4)12 ans = 1.0000

Esto hace que tengan un papel protagonista en las cabeceras de las funciones. Cuando una fun-ción necesita a otra como argumento podemos asignarla también por nombre o por una sentenciainline pero lo recomendable es utilizar un Function handle. Por ejemplo, para hacer la siguienteintegral mediante la función quad:

I =∫ π

0

sin(x) dx

1 >> I=quad(’sin’,0,pi)

Page 46: Notas Octave

46 El lenguaje común de Matlab y Octave

2 I = 23 >> I=quad(inline(’sin(x)’),0,pi)4 I = 25 >> I=quad(@sin,0,pi) # Forma recomendada6 I = 2

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

1 >> fhandle=@sin2 fhandle =3 sin4 >> I=quad(fhandle,0,pi)5 I = 2

Y así con todas las rutinas que requieran una función como argumento.

Funciones anónimas

La sentencia inline se considera obsoleta (aunque no oficialmente). El recurso que la haapartado es utilizar un Function handle para declarar una función con la siguiente sintaxis:

1 @(argumentos) sentencia_ejecutable

Por ejemplo, la función foo2 que en la sección anterior se ha declarado mediante un inline seescribiría como sigue:

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

Con la llamada usual:

1 >> foo2(6,2)2 ans = 0.11628

Obviamente también podemos utilizarlo en la cabecera de las funciones:

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

Alguien puede pensar que el nombre de “función anónima” está mal porque si la asignamos auna variable pasará a tener el nombre de la variable. Esta idea, aunque razonable, es completa-mente errónea. Una y otra vez hemos enfatizado que una variable no es un argumento ni unafunción, es algo completamente distinto. La función es anónima porque no tiene ningún nombrefijo, seguirá siendo la misma función independientemente del nombre de la variable.

Las funciones anónimas también pueden encapsularse como muestra el ejemplo anterior22:

1 >> intbessel=@(y) quad(@(x) besselj(2.5,x),0,y);2 >> intbessel(1.3)3 ans = 0.035244

22Este código provoca un error de segmentación en Matlab 7.0.0.19901 (R14) y Octave en versiones inferiores a 2.9.12

Page 47: Notas Octave

3.8 Funciones (II) 47

Funciones como argumentos de funciones.

Si gracias a los Function handles podemos asignar funciones a variables esto nos servirá parapasar funciones como argumentos. Una de las prácticas más beneficiosas en programación es lade la introspección. Es la capacidad de un algoritmo de no depender de los argumentos que utili-cemos. La introspección más común es la aplicada a los números y las matrices; es lo que sucedecuando escribimos cualquier fórmula matemática o función en Matlab, pero aplicar la introspec-ción a las funciones no es tan sencillo. Es muy fácil integrar una función cuando la conocemos,lo que no es integrar una función cualquiera. Debemos encontrar automáticamente los puntossingulares para concentrar los puntos en ellos, controlar automáticamente la precisión y pasarun argumento a la función. La introspección es intentar hacer un algoritmo lo más genérico po-sible y para ello necesitamos llamar funciones como argumentos como sucede con las rutinas deintegración.

Si lo pensamos un poco nos daremos cuenta que no es nada fácil llamar a una función cuyonombre no conocemos y sin saber en qué directorio se encuentra. La solución a este problemason los Function handles, por eso se recomienda encarecidamente su uso. Supongamos que que-remos una rutina que calcule el valor de cualquier función en el punto x = 1 siendo x su únicoargumento:

1 function [out]=fhtest(arg)2 %3 % function OUT=fhtest(@arg)4 %5 % Calcula el valor de la funcion @arg en 1 @arg debe ser un Function6 % Handle7 %8 out=arg(1);

Es muy importante crear una cabecera de ayuda cuando los argumentos de una función no son escalarescomunes. Si no será imposible saber que el argumento de fhtest es un Function handle. Lo correcto seríacrear también un mensaje de error en el caso que el argumento no fuera del tipo adecuado. Cuando unafunción no devuelve ningún resultado lo primero que haremos será utilizar la ayuda:

1 >> help fhtest2 fhtest is the user-defined function from the file3 /home/guillem/sync/CursoScripting/ejercicios/fhtest.m4 function OUT=fhtest(@arg)5 Calcula el valor de la funcion _arg_ en 16 _arg_ debe ser un Function Handle

será un alivio comprobar que existe. Para utilizar la función podemos llamarla directamente conun Function handle:

1 >> fhtest(@sin)2 ans = 0.84147

o como siempre mediante una variable que lo contenga:

1 >> fhsin=@sin2 fhsin =3 sin4 >> fhtest(fhsin)5 ans = 0.84147

Esta estructura permite hacer

Page 48: Notas Octave

48 El lenguaje común de Matlab y Octave

Acceso a las variables desde las funciones anónimas.

Esta sección ha quedado desactualizada para Octave versión superior a 2.9.0 en la que las funcionesanónimas se comportan igual que las de Matlab.

Otra pequeña diferencia entre Matlab y Octave es cómo las funciones anónimas entienden lasvariables dadas en la cabecera. En Octave, una función anónima es estrictamente una función aparte. Las variables internas no tienen ninguna relación con las variables del resto del entorno deejecución. Por ejemplo, si queremos definir la siguiente función de dos variables:

func = e−(x2+y2)

a partir de una función anónima debemos hacerlo como

1 >> func=@(x,y) exp(-(x. ^2+y. ^2))2 func =3 @(x, y) exp (-(x.^ 2 + y.^ 2))

Y llamamos la nueva función del modo usual:

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

Todas estas variables son locales para la función. Todas las variables de la función deben estarpresentes en el interface. Se nos puede ocurrir reducir el número de variables de una funcióndefiniendo algunas de ellas externamente:

1 >> a=2;2 >> func=@(x) exp(-(x.^2+a.^2))3 func =4 @(x) exp (-(x.^2 + a.^2))

De este modo estamos pidiendo que la función tome una variable que en realidad es externacomo propia. En Octave esto da un error en el momento de la llamada:

1 >> func(2)2 error: ‘a’ undefined near line 9 column 223 error: evaluating binary operator ‘. ^’ near line 9, column 234 error: evaluating binary operator ‘+’ near line 9, column 215 error: evaluating prefix operator ‘-’ near line 9, column 156 error: evaluating argument list element number 17 error: called from ‘?unknown?’

Pero si hacemos exactamente lo mismo en Matlab...

1 >> a=2;2 >> func=@(x) exp(-(x.^2+a.^2))3 func =4 @(x) exp(-(x.^2+a.^2))5 >> func(2)6 ans =7 3.3546e-048 >>

El programa el intérprete no nos devuelve ningún error. Esto es debido a que mientras Octaveprefiere la definición de variables globales

Page 49: Notas Octave

3.8 Funciones (II) 49

como apuesta por la seguridad, Matlab es más laxo con el acceso a las variables en el caso delos function handles. De hecho, este es el modo recomendado por los desarrolladores de Matlabpara acortar algunas cabeceras mediante variables externas o para pasar parámetros a funcionesdentro de funciones.

3.8.6. Funciones recursivas

Matlab soporta funciones que durante su ejecución se llaman a ellas mismas porque las lla-madas a las funciones se hacen por valor y no por variable. Es muy difícil encontrar un ejemplodonde la manera más efectiva de resolver un problema sea acudir a la recursión. Es una técnicapeligrosa además de ser muy agresiva con la memoria y debemos evitarla. Un ejemplo de funciónrecursiva sería esta manera tan poco eficiente de calcular un factorial23.

1 function out = fact ()2 if (n > 0)3 out = n* fact (n-1);4 else5 out = 1;6 endif

3.8.7. Encapsulado de funciones

El encapsulado de funciones o nested functions tiene dos utilidades principales:

1. Encapsular partes del cálculo en una función principal dentro de una función secundaria

2. Posibilitar que argumentos de salida sean funciones mediante function handles.

El primer uso es trivial. Podemos definir subfunciones siempre que no tengan ninguna repercusiónen la cabecera. No es más que agrupar una tarea repetitiva para no tener que escribirla variasveces.

El segundo uso es una de las sutilezas proporcionadas por los function handles. Como pode-mos definir subfunciones siempre que no influyan en la cabecera nada nos impide asignarlas a unfunction handle que se pasará en la salida como argumento. Es exactamente el mismo conceptoque el de utilizar funciones como argumentos de funciones pero a la inversa.

Por ejemplo, supongamos que estamos diseñando un filtro para una señal, un filtro pasa-bajos según una determinada frecuencia ω. Lo más sencillo sería hacer una función pasa-bajosque recibiera tres argumentos, el espectro en frecuencias, la longitud del espectro y la frecuenciade corte. Una solución mucho más elegante puede ser definir una función de construcción quedevuelve un function handle con un filtro que utilizamos como otra función por separado. Deeste modo conseguiríamos reducir toda una colección de filtros a una única función generadora.Esta práctica se llama introspección y es junto con la abstracción las dos palabras claves de la pro-gramación moderna. La capacidad de Matlab de convertir funciones en argumentos simples esla mayor potencia del lenguaje y a la vez el concepto más complejo. Dominar bien la abstraccióna nivel de métodos es dominar Matlab.

3.8.8. Herramientas útiles para la manipulación de funciones.

addpath Añade 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 función pasada como argumento

type Muestra información rápida sobre la variable o el nombre de la función. Si el argumento esuna función o una subrutina dentro de un archivo .m muestra el contenido del archivo.

23Existen varias maneras de calcular un factorial. Las dos más eficientes probablemente sean prod(1:n) ygamma(n+1)

Page 50: Notas Octave

50 El lenguaje común de Matlab y Octave

3.9. Entrada/Salida

Supongamos que hemos hecho un script para calcular la solución a un problema de control ynecesitamos que en el arranque el usuario nos introduzca los datos de entrada, o pongámonos enla situación de estar utilizando un código de mecánica de fluidos computacional que nos escupeenormes matrices de datos en crudo.

Cualquier interacción de nuestro programa con el exterior necesitará funciones de comunica-ción, ya sea un pequeño diálogo en la consola o la lectura de matrices de gran tamaño. El primercaso es bastante sencillo pero el segundo requiere conocimientos básicos de almacenamiento dedatos que aprenderemos en breve.

3.9.1. E/S básica por pantalla.

disp Es la función de salida más sencilla. Imprime en pantalla el argumento con el que se llamaya sea una cadena de texto o el contenido de una variable.

format Controla el formato numérico de salida por defecto. Es importante que entendamos quesólo cambia la impresión en pantalla o en un archivo, no estamos cambiando la precisiónnumérica real. format se llama con un argumento que determina el tipo de salida:

short Formato con 5 cifras significativas en contenedores de 10 caracteres.Si el punto decimal se sale de las cifras significativas en algún caso todos losnúmeros pasaran a escribirse según la notación científica.long Formato con 15 cifras significativas en contenedores de 20 caracteres.Si el punto decimal se sale de las cifras significativas en algún caso todos losnúmeros pasaran a escribirse según la notación científica

short elong e El mismo formato que short y long pero usando siempre la nota-ción científica y denotando el exponencial con una e.

short Elong E El mismo formato que short y long pero usando siempre la nota-ción científica y denotando el exponencial con una E.

short glong g Escoge entre el formato usual o la notación científica según lo requie-ra cada número. En el caso de la notación científica la exponencial se denotacon una e.

short Glong G Escoge entre el formato usual o la notación científica según lo requie-ra cada número. En el caso de la notación científica la exponencial se denotacon una E.

freenone Formato libre igual al formato libre de Fortran.

input Es el equivalente a disp pero para la introducción de valores por teclado. Imprime porpantalla 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 título y las opciones del argumento, cadauna de las opciones se presenta con un número y espera que se escoja uno de ellos porteclado. El valor retornado es el número de la opción escogida. Cuando se está utilizandola interfaz gráfica de Matlab aparece una ventana y que muestra un botón por cada opciónPor ejemplo:

Page 51: Notas Octave

3.9 Entrada/Salida 51

1 >> choice=menu(’Esto es un menu’,’uno’,’dos’,’tres’)2 Esto es un menu3 [ 1] uno4 [ 2] dos5 [ 3] tres6 pick a number, any number: 37 choice = 3

3.9.2. E/S básica con archivos

Las palabras clave para guardar variables y sesiones son compatibles pero no idénticas. Estoes porque mientras Matlab tiene sus propios formatos de lectura y escritura Octave ha optadopor formatos abiertos.

Matlab tiene tres formatos binarios a los que llama según la versión en la que se introdujeron,la versión 4, la 6 y la 7. La última versión de Octave es capaz de leer y escribir en los tres, yademás puede utilizar utilizar, además de su propio formato, el formato binario abierto hdf5.

Para ello, se utilizan las siguientes funciones:

save opciones v1 v2 ... Guarda las variables solicitadas en el archivo de nombre dado con el for-mato pedido con el argumento opciones. Lo mejor para conocer los formatos disponiblesy sus posibles incompatibilidades es consultar la ayuda.

load opciones archivo v1 v2 Carga las variables del mismo modo en que las guarda save. Larecomendación vuelve a ser que consultemos la ayuda.

Matlab y Octave cuentan, además con la función diary. Sirve para grabar la sesión literal-mente en un archivo cuyo nombre le hemos dado con anterioridad.

diary on,off,archivo Guarda todos los comandos y resultados en un archivo.

Para hacerlo:

1 >> diary(’nombrearchivo’)2 >> diary on3 >> texto=’graba todo lo que ponemos aqui’;4 >> diary off5 >> texto2=’ya ha parado la grabacion’;

En el archivo de nombre nombrearchivo encontraremos la línea:

1 >> texto=’graba todo lo que ponemos aqui’;

Page 52: Notas Octave

52 El lenguaje común de Matlab y Octave

Page 53: Notas Octave

4Capítulo

Más allá del lenguaje: biblioteca de fun-ciones y extensión de Octave

La clave para el éxito de Matlab, más allá de las características del lenguaje común que com-parte este programa con Octave, estriba en los siguientes puntos:

La enorme biblioteca de funciones científicas disponibles para Matlab y Octave, la mayoríade las cuales están disponibles en ambos entornos, utilizando una sintaxis común.

Las posibilidades adicionales que ofrece un amplio abanico de extensiones o toolboxes. EnMatlab, el disponer de estas extensiones implica el abonar el coste adicional (con frecuencia,muchos miles de euros) necesario para su adquisición. En octave, la práctica totalidad desus toolboxes está disponible con licencia libre a través de Octave Forge[3]. Aunque a algunosde ellos, como Octaviz (un envoltorio para el acceso desde Octave a los objetos del paquetede gráficas 3D VTK) se accede de forma externa a Octave Forge.

La posibilidad de crear extensiones dinámicas, utilizado para ello lenguajes compilados co-mo C o C++. Así, este tipo de extensiones pone al alcance de la mano la potencia de cálculoeste tipo de lenguajes, mediante funciones que pueden ser utilizadas desde un entorno másflexible como son Matlab u Octave.

4.1. La biblioteca de funciones

Queda fuera de los objetivos de este manual el describir, ni siquiera con mediano detalle,la amplia cantidad de funciones disponibles para Matlab y Octave. El lector interesado puedeconsultar la documentación de Octave, disponible en su página web [5], así como [2] ó [1]. Las si-guientes líneas deben entenderse como una mera toma de contacto con la biblioteca de funcionesde Octave.

4.1.1. Álgebra Lineal

Enumeraremos aquí varias funciones cuyo propósito es crear y manipular matrices.

Creación de matrices

eye Matriz identidad

linspace(base,limit,n) Devuelve un vector fila con n elementos equiespaciados entre base ylimit

logspace(base,limit,n) Devuelve un vector fila con n elementos espaciados exponencialmenteentre 10base y 10limit.

ones Devuelve una matriz de las dimensiones solicitadas cuyos elementos son todos 1

rand Devuelve una matriz de las dimensiones solicitadas cuyos elementos son números pseu-doaleatorios entre 0 y 1.

rand* donde * pueden ser varias letras. Devuelve una matriz de las dimensiones solicitadascuyos elementos son números pseudoaleatorios que siguen distintas distribuciones

zeros Devuelve una matriz cuyos elementos son todos ceros.

Page 54: Notas Octave

54 Más allá del lenguaje: biblioteca de funciones y extensión de Octave

meshgrid(x,y) Crea una malla equiespaciada en dos dimensiones a partir de los vectores x e y.Retorna dos matrices, una con la coordenada x y el otro con la coordenada y. Muy utilizadapara el dibujo de gráficos 3D (sección 4.1.2).

Manipulación de forma

reshape(A,m,n,...) Reordena la matriz A para ajustarse a las dimensionesm×n×. . .. Esta funciónsólo manipula la forma, en el caso de que queramos ampliar su tamaño en vez de añadirceros dará un error.

transpose Traspuesta. (Ver los operadores aritméticos para su abreviatura)

ctranspose Traspuesta conjugada. (Ver los operadores aritméticos para su abreviatura)

cat(opt,a,b,...) Concatena matrices donde opt es la dimensión en la que se acoplarán las matricesy los argumentos siguientes matrices cuyas dimensiones permiten el ’pegado’ entre ellas.

repmat(A,[n,m,...]) Crea una matriz por bloques de dimensiones [n,m,...] con copias de lamatriz A.

Ecuaciones lineales

Los operadores \ y / se pueden utilizar para resolver sistemas de ecuaciones lineales:

1 >> A=rand(3);2 >> b;3 >> A\b4 ans =5 3.00886 2.83057 -6.2307

La tercera línea del ejemplo anterior se puede entender como A−1 · b. Cuando la matriz no esregular, se devuelve un ajuste de mínimos cuadrados.

Tanto en Octave como en Matlab, los operadores de resolución de ecuaciones diferencialesllaman a las mismas bibliotecas, ATLAS y LAPACK, una autentica maravilla de la tecnología.Ambas tienen una licencia libre de tipo BSD, que no tiene restricciones de tipo copyleft, lo que hapermitido a un programa privativo como Matlab el incluirlas como parte de su código.

4.1.2. Gráficos

Uno de los puntos fuertes de Matlab y Octave son la facilidades para el dibujo de gráficaselementales, en especial de funciones 3D. Para visualización en tres dimensiones será mejor optarpor otra aplicación más especializada1 Sus funciones se pueden clasificar en dibujo de líneas,gráficos estadísticos, gráficas de contornos y superficies. Hay una gran variedad de funciones,aquí sólo enumeraremos las más importantes.

Antes de seguir adelante, contiene señalar que Octave (a diferencia de Matlab) no tiene rutinasgráficas propias y usa para ello una aplicación aparte llamada Gnuplot. En principio, si nuestrainstalación de Octave no va acompañada de Gnuplot, no podremos dibujar absolutamente nada.Aunque Gnuplot es un programa antiguo y limitado, Octave ofrece una capa de compatibilidadbastante decente con las funciones gráficas de Matlab.

Existen varias formas de invocar a plot, las más sencillas son las siguientes:

1Matlab no es un visualizador 3D, es decir, un programa especializado en la exploración de datos en 3 dimensiones,especialmente si pensamos en conjuntos de datos grandes (varios gigabytes). Para esta tarea contamos, en el mundo delsoftware libre, con excelentes aplicaciones como Mayavi, Mayavi2, OpenDX y Paraview.

Page 55: Notas Octave

4.1 La biblioteca de funciones 55

Figura 4.1: Gráfica de la función f(x) = ex/10 sen(x) con x en [0, 20]

plot(y) Representa las componentes del vector y frente a sus índices.

plot(x,y) Representa a los elementos de y frente a los de x (siendo ambos vectores del mismotamaño).

En el siguiente ejemplo, se representa a la función f(x) = ex/10sen(x) con x en [0, 20]:

1 x=linspace(0,20,100);2 plot (exp(x/10).*sin(x));

El resultado se puede apreciar en la figura 4.1.2.Adicionalmente (como se observa en el siguiente ejemplo) se pueden especificar más datos

para representar, así como una serie de instrucciones de formato que cambiaran la aparienciade salida de la gráfica, incluyendo características como el estilo de línea, el color, etc. Puedeobtenerse más información consultando la ayuda de Octave.

Por ejemplo, representamos las gráficas de ex/10 sen(x) y ex/10 cos(x), con x en [0, 20]:

1 x=linspace(0,20,50);2 plot (x,exp(x/10).*sin(x),’:’,x,exp(x/10).*cos(x),’-^’);

Podemos añadirle una leyenda para localizar ambas funciones, de la siguiente forma:

1 legend(’exp(x/10)*sin(x)’,’exp(x/10)*cos(x)’);2 replot;

Así obtendremos la gráfica que se muestra en la figura 4.1.2.Otras funciones para gráficos:

hold on|off Retiene la gráfica actual, no borrando la pantalla al dibujar la siguiente.

xlabel, ylabel Etiquetas para los ejes X e Y.

title Título para la gráfica.

semilogx Crea una gráfica 2D (al estilo de plot) utilizando una escala logarítmica en el eje X.

semilogy Lo mismo, pero con escala logarítmica en el eje Y.

Page 56: Notas Octave

56 Más allá del lenguaje: biblioteca de funciones y extensión de Octave

Figura 4.2: Gráfica de las funciones ex/10 sen(x) y ex/10 cos(x) en [0, 20]

loglog Crea una gráfica utilizando una escala logarítmica en ambos ejes.

polar(t,r Crea una gráfica en coordenadas polares, t y r.

bar Crea un diagrama de barras, a partir de los datos contenidos en un vector y.

stairs Crea un diagrama de barras, a partir de los datos contenidos en un vector y.

hist Crea un histograma.

plot3 Dibuja líneas en 3D

mesh Dibuja superficies en 3D

contour Dibuja gráficos de contornos de superficies.

Cuando deseemos guardar la gráfica en un fichero, podemos utilizar la función print. Porejemplo, las gráficas anteriores se han guardado en disco con un comando similar al siguiente:

1 print ("fichero.png", "-dpng");

El segundo parámetro indica el dispositivo gráfico que utilizaremos (en el caso anterior, el forma-to de gráficos png). Mediante la ayuda y la documentación de Octave podemos acceder a muchamás información sobre esta función y las anteriores.

Por último, en muchas ocasiones, deseamos representar un conjunto de datos que ha sidoalmacenados previamente en ficheros, probablemente a partir de otros programas que los hangenerado. Para ello disponemos, además de load y save (estudiadas en el apartado 3.9.2) defunciones “al estilo C” que nos permiten una gran libertad a la hora de leer y escribir datos

fopen Abre un fichero y devuelve un identificador del mismo.

fclose Cierra un fichero abierto.

fscanf / fprintf Lee/escribe datos en formato texto en un fichero.

fread / fwrite Leen/escriben datos en formato binario en un fichero.

Page 57: Notas Octave

4.2 Toolkits en Octave 57

4.1.3. Otras utilidades de la biblioteca de funciones

Todavía no hemos hecho más que arañar la superficie de la biblioteca de funciones de Oc-tave, que es demasiado amplia como para que pueda ser tratada en el presente manual. Estabiblioteca incluye, además de más funciones relacionadas operaciones matriciales y de dibujo degráficos, funciones en los campos que se enumeran a continuación, y en otras muchas áreas deconocimiento.

Cálculo de autovalores y autovectores

Cálculo de raíces de ecuaciones no lineales

Aproximación numérica de funciones y datos (interpolación, FFT, funciones spline,...)

Cálculo numérico de derivadas e integrales

Resolución numérica de ecuaciones diferenciales

Procesamiento de imágenes

...

El lector interesado en alguno de los campos anteriores (o en otros no listados) puede con-sultar la documentación oficial de Octave. También puede resultar de utilidad el hojear algúnmanual de Matlab, así como recolectar información de Internet. Si nos fallan todas estas fuentes,podemos solicitar información o ayuda de la comunidad de Octave, a través de su lista de correo(accesible desde la página web de Octave).

4.2. Toolkits en Octave

Además de la biblioteca de funciones, de la que se trata en la sección anterior, existe unagran cantidad de paquetes diseñados para extender las funcionalidades que Octave incluye deserie. Estas extensiones (conocidas en el mundo de Matlab como toolkits) añaden una considerableriqueza a Octave y están disponibles con licencia libre, en su práctica totalidad.

El grueso de estas extensiones se desarrollan y recopilan a través del sitio web SourceForge, enel proyecto conocido como Octave-Forge[3]. En esta página podemos encontrar el listado completode paquetes y funciones que constituyen Octave-Forge. Entre los paquetes disponibles existentanto los dedicados al cálculo simbólico como al proceso de audio o de señales, pasando por ladefinición de constantes físicas. por el procesamiento en paralelo en arquitecturas de múltiplesnúcleos, etc. Su listado es demasiado amplio como para ser introducido aquí.

Existen otras extensiones, fuera de Octave-Forge, que también pueden resultar de gran interés.Entre ellas destacaremos aquí a Octaviz, un envoltorio para poder utilizar desde Octave las clasesde VTK, consiguiendo gráficos de gran calidad en 3D. Son también muy interesantes Octplot yYapso2, alternativas a Gnuplot para el dibujo de gráficas 2D y 3D3.

4.3. Creación de extensiones dinámicas en Octave

En el curso hemos comentado la utilidad de Octave cuando es usado como “lenguaje pega-mento”, utilizándolo para programar y controlar interactivamente la mayor parte del programa,pero implementando las funciones críticas en un lenguaje compilado como C++.

Realizar una extensión de Octave es tan sencillo como crear un fichero C++ siguiendo el si-guiente patrón:

2Yet Another Plotting System for Octave3Por ejemplo, en las figuras 4.1.2 y 4.1.2 se ha utilizado Octplot

Page 58: Notas Octave

58 Más allá del lenguaje: biblioteca de funciones y extensión de Octave

1 #include <octave/oct.h>2 DEFUN_DLD(name, args, nargs , ‘‘Documentation string’’)3 {4 // (...)5 // C++ code6 // (...)7 }8 return octave_value()

Por ejemplo, crearemos una extensión muy sencilla en un fichero llamado holamundo.cpp,que simplemente imprima el mensaje “Hola Mundo”. Para ello, escribimos en el fichero el si-guiente código:

1 #include <octave/oct.h>2 DEFUN_DLD(holamundo, args, nargs , ‘‘Documentation string’’)3 {4 std::cout << ‘‘Hola Mundo!’’ << std::endl;5 return octave_value()6 }

Y lo compilamos con el programa mkoctfile. Éste es un simple script que encapsula alcompilador de C++ del sistema junto a los parámetros adecuados para la compilación del códigoy su enlace con la librería de Octave.

1 $ mkoctfile holamundo.cpp

Como resultado, debemos haber generado un fichero llamado holamundo.oct. Se trata deun fichero binario (en realidad, una librería de enlace dinámico) que contiene a la función C++que hemos definido a través de la macro DEFUN_DLD. Esta función puede ser automáticamenteutilizada desde Octave:

1 >> holamundo2 Hola Mundo!

Para pasar argumentos desde Octave al código C++, deberemos utilizar el segundo paráme-tro de la macro DEFUN_DLD (al que hasta ahora he denominado args). Este parámetro es unavariable de tipo octave_value_list, que define a cualquier lista de valores de octave (es decira una lista de variables de tipo octave_value).

En el código de Octave, al que se puede acceder instalándolo en nuestro ordenador o a tra-vés de internet (por ejemplo, en Octave Forge está disponible en formato navegable), la claseoctave_value es la base de toda una jerarquía de clases numéricas (Matrices, Vectores, etc.).

Para devolver valores desde la función hasta Octave, la macro DEFUN_DLD espera un objetode tipo octave_value_list (que será construido de forma transparente si, en vez de un objetode este tipo, devolvemos una octave_value), como en el siguiente ejemplo.

Por ejemplo, definamos la función f(x) = x2:

1 #include <octave/oct.h>2 DEFUN_DLD(xcuadrado, args, , \3 "Calcula el cuadrado de un real, x’’)4 {5 if(args.length() != 1) {6 std::cerr << "ERROR: Se necesita tomar un valor" << std::endl;7 return octave_value()8 }

Page 59: Notas Octave

4.3 Creación de extensiones dinámicas en Octave 59

9 const double x = args(0).double_value();10 octave_value y = x*x;11 y = x*x;12 return y;13 }

Obsérvese como, en el ejemplo, anterior, obtenemos el argumento pasado a la función (unnúmero real en coma flotante) con el método double_value(). En general, podemos obtenerel contenido de un objeto octave_value utilizando un método del tipo XXXXX_value().

Y un ultimo ejemplo, tomado del manual “Da coda al fine” [6], que aunque incompleta es,junto con la documentación oficial de Octave y su propio código fuente, la referencia más útilpara extender Octave en C++.

En este ejemplo, que define una función que calcula la potencia n–ésima de una matriz, sepuede apreciar, entre otras cosas, la utilización de la clase Matrix de Octave. Como se puedeobservar, el operador asterisco, ha sido sobrecargado para el producto de matrices. El código deOctave dispone de muchas otras clases que pueden resultar útiles para utilizar C++ como entornocientífico, entre ellas ColumnVector, RowVector, etc. Una gran ventaja de esta idea es el hechode que, desde C++, tenemos acceso a todas las funciones de Octave (todas aquellas a las queaccedemos desde el intérprete de Octave o desde scripts y que, a bajo nivel, son implementadasen la biblioteca liboctave).

1 #include <octave/oct.h>2 static bool is_even(int n);3 DEFUN_DLD(matpow, args, ,4 "Return b = a^n for square matrix a, and non-negative, integral n.")5 {6 const int n = args(1).int_value();7 if (n == 0)8 return octave_value(9 DiagMatrix(args(0).rows(), args(0).columns(), 1.0)

10 );11 if (n == 1)12 return args(0);13

14 Matrix p(args(0).matrix_value());15 Matrix b(p);16 int np = n - 1;17 while (np >= 1)18 {19 if (is_even(np))20 {21 np = np / 2;22 }23 else24 {25 np = (np - 1) / 2;26 b = b * p;27 }28 p = p * p;29 }30 return octave_value(b);31 }32 bool33 is_even(int n)34 {35 return n % 2 == 0;36 }

Page 60: Notas Octave

60 Más allá del lenguaje: biblioteca de funciones y extensión de Octave

Page 61: Notas Octave

AApéndice

Análisis crítico del lenguaje Matlab

Esta sección es una visión un poco personal de Matlab en comparación con otros lenguajes de progra-mación superiores. Se conserva aquí tal y como fue escrita en la versión original del libro de G. Borrell[2]

Matlab no es un buen lenguaje de programación. Que seamos capaces de entenderlo fácil-mente a pesar de sus defectos no lo hace bueno porque sencillo no significa correcto ni directosignifica consistente. Matlab tiene defectos y algunos de ellos muy graves.

Esta sección proviene de una discusión con los miembros del departamento de Matemáticasde la Escuela Técnica Superior de Ingenieros Navales. En aquella escuela Matlab se utiliza paraimpartir cursos de programación. Mi visión era que Matlab inyecta ciertos malos vicios que lodescartan como plataforma para la enseñanza de la programación. Si uno debe aprender a an-dar no es normal que empiece con zancos; del mismo modo no es normal que quien empieza aprogramar tome como norma peligrosas particularidades.

Algunos inconvenientes han sido solucionados por el intérprete Octave como extensiones alpropio lenguaje.

A.1. Paréntesis y corchetes. Tuples y celdas

Matlab hereda de Fortran una inconsistencia que es pecata minuta. En muchos lenguajes sepueden ordenar las variables como tuples. Un tuple no es más que un conjunto ordenado, (a)sería una variable, (a,b) un doble, (a,b,c) un triple: un tuple es la generalización para n elementos.En breve entenderemos la importancia de este tipo derivado.

Si se desea llevar la consistencia de un lenguaje al límite se pide que la notación para la asig-nación sea igual a la de la llamada. Si para crear una matriz se usan corchetes es preferible que lallamada a los subíndices también se haga con corchetes. Esto es discutible porque uno puede con-siderar que tras crear una matriz se obtiene una función y que los subíndices son los argumentosen la llamada:

1 m(2,3)

Pero los tuples tienen una función, la de agrupar variables. Si nos fijamos en cómo es unallamada a una función entenderemos perfectamente la notación escogida en muchos lenguajespara un tuple:

1 f(a,b)

Podemos imaginar que lo que la función f tiene a la derecha es un tuple y cada argumento dela llamada es un elemento del mismo.

Todo este discurso sirve para entender que la definición de las funciones en Matlab es incon-sistente:

1 function [x,y]=f(a,b)...

Si (a,b) es un doble... ¿Por qué si lo que retorna es exactamente lo mismo, un doble, debemosutilizar la misma notación que las matrices? Esto no sería tan grave si no fuera porque Matlabverdaderamente tiene un tipo para estos casos: las celdas.

Page 62: Notas Octave

62 Análisis crítico del lenguaje Matlab

Ahora podríamos pensar que por lo menos las celdas se comportarán como verdaderos tuplesper no. Si intentamos una doble asignación:

1 >> {a,b}={1,2}2 error: invalid lvalue function called in expression

¿Qué es entonces una celda? ¿Es una verdadera estructura de variables? ¿Es la asignación delvalor de retorno de una función un caso tan especial para tener esa notación tan exótica? No esmás que un tipo derivado que hace lo que le da la gana.

Mi sugerecia sería definir las funciones como sigue:

1 function {x,y}=f(a,b)

para que la asignación

1 {x,y}=f(2,3)

tenga sentido y convierta las celdas en auténticas tuplas. Desgraciadamente este cambio rom-pería todos los códigos existentes por lo que no es posible.

A.2. La notación del punto

El bug más común en códigos Matlab aparece por el dichoso punto que distingue las opera-ciones matriciales y vectoriales. Es un caso en el que el remedio es aún peor que la enfermedad. Siun prefijo es la manera más breve de modificar un operador una omisión puede provocar gravesdolores de cabeza.

Por lo menos en caso de duda siempre podemos utilizar las funciones para el producto, lapotencia y la división en vez del operador. A mi parecer la mejor distinción sería seguir a fortran:todas las operaciones son escalares y las matriciales requieren una función en vez de un operador.

A.3. Versatilidad o por qué prefiero el intérprete Octave.

A medida que uno adquiere experiencia programando empieza a utilizar estructuras mássofisticadas de forma natural. Este paso suele realizarse en Matlab cuando el uso de las funcionesanónimas es frecuente.

También son de uso común las abreviaturas que, además de ahorrarnos alguna que otra líneade código, también lo hacen más leíble. Un ejemplo de ello son los prefijos y sufijos. Si dispo-nemos de una función que retorna una matriz y sólo nos interesa la primera fila de la mismapodríamos escribir el siguiente código

1 dummy=func(x)2 a=dummy(1,:)

Pero si estamos utilizando el intérprete Octave podremos utilizar la llamada de índices comosufíjo de la siguiente manera:

1 dummy=func(x)(1,:)

Código mucho más leíble para los ojos expertos.Otro caso interesante es el de los operadores ==, ++, -, += y -= muy utilizados en C. Matlab

no los soporta, en cambio Octave sí. Sustituyen esas líneas tan feas del estilo de

Page 63: Notas Octave

A.4 La orientación a objetos 63

1 a=a+4

Por un más leíble

1 a+=4

A.4. La orientación a objetos

Aunque se ha discutido ampliamente sobre la ideonidad de la orientacón a objetos nadie pa-rece dudar que un lenguaje de programación moderno debe soportar este paradigma. La maneramás común de definir un objeto es mediante una clase, entonces un objeto es una instancia de unaclase previamente definida.

Las clases no son más que tipos derivados en los que uno puede definir métodos, variablesprivadas y públicas... y la instancia se crea bien por declaración (lenguajes estáticos) o por llama-da (lenguajes dinámicos). Desgraciadamente Matlab optó por un modelo mucho menos comúnen el que se define la instancia como una estructura de funciones ordenada mediante directorios.

Creo que esta es una decisión equivocada y provocará que la orientación a objetos de Matlabnunca llegue a utilizarse activamente.

A.5. Módulos y funciones

¿Por qué una función en cada archivo? ¿Por qué para escribir códigos no triviales nos vemosobligados a movernos entre una docena de archivos que perfectamente podrían juntarse en unmódulo? Es la mayor y más grave estupidez de el intérprete Matlab que por lo menos ha sidosolucionado en Octave a costa de romper la compatibilidad.

Ignoro por qué aún no se ha subsanado el error pero sin duda alguna es el defecto más san-grante de todos.

A.6. Matlab 2 y otros lenguajes de programación

El Matlab Monkey puede definirse como aquél programador tan acostumbrado a Matlab quees ya incapaz de reconocer todo lo anterior como defectos. El otro gran síntoma es el de utilizarMatlab absolutamente para todo.

El languaje Matlab prácticamente no ha cambiado desde su creación, por consguiente no haresuelto sus defectos y ha añadido otros nuevos. Parece claro que el único aliciente de programaren Matlab es la biblioteca de funciones. Hagámonos entonces la pregunta siguiente: si existieraun lenguaje mejor con la misma biblioteca de funciones... ¿Seguiríamos programando en Matlab?Si la respuesta es sí somos Matlab Monkeys.

Octave es un humilde esfuerzo para paliar alguno de estos inconvenientes aunque la políticade conseguir una compatibilidad máxima, por otro lado completamente comprensible, impidemayores cambios. Aunque esta sección deje Octave en un mal lugar por parecer un mero imita-dor su labor es tremendamente importante por dos razones. Hay millones de líneas escritas enMatlab que no serán nunca portadas a otro lenguaje y demuestra a los desarrolladores de Matlabque es importante distinguir entre el lenguaje de programación y la biblioteca de funciones. Sise extiende es incluso posible que Mathworks termine tomándolo en consideración. Siempre hedicho que la existencia de Octave beneficia indirectamente a Matlab porque la existencia de soft-ware libre siempre aumenta la difusión de una aplicación.

Dentro de la competencia comercial la alternativa más razonable es Mathematica pero su usoparece más adecuado a las necesidades de físicos y matemáticos.

Page 64: Notas Octave

64 Análisis crítico del lenguaje Matlab

Mi apuesta personal es numpy y scipy (http://scipy.org). La idea es dotar a un lenguajede programación existente y más conveniente de todas las funciones necesarias. Desde el iniciodel proyecto ha ido ganando usuarios desilusionados o hastiados con Matlab que encuentran enPython un lenguaje directo, consistente y elegante. La maquinaria interna de Python es bastanteparecida a la de Matlab pero el primero es mucho más fácil de extender.

Además las perspectivas de crecimiento de Python son mucho más optimistas. Hay muchasmás manos y ojos sobre el código y numpy no es más que una pequeña pieza dentro de una granmaquinaria.

Page 65: Notas Octave

Bibliografía

[1] F. Salieri A. Quarterioni. Cálculo Científico con Matlab y Octave. Springer-Verlag, 2006.

[2] Guillem Borrell iÑogueras. Introducción informal a matlab y octave. http://iimyo.forja.rediris.es/.

[3] Octave forge, web page. http://octave.sourceforge.net/.

[4] Octave, mailing lists. http://www.gnu.org/software/octave/archive.html.

[5] Octave, web page. http://www.octave.org/.

[6] Christoph L. Spiel. Da coda al fine. pushing octave’s limits. http://octave.sourceforge.net/coda/index.html.