1 \documentclass[11pt,titlepage,
a4paper]{book
}
3 \title{\textbf{\Huge{Primeros pasos en Maxima
}}}
4 \author{\Large{Mario Rodr\'
{\i}guez Riotorto
}\\
6 http://riotorto.users.sourceforge.net\\
11 \usepackage[spanish, activeacute
]{babel
}
14 \usepackage{amsmath,amsthm
}
18 \usepackage[latin1]{inputenc}
22 \hypersetup{colorlinks, citecolor=black, filecolor=black, linkcolor=black, urlcolor=black, pdftex
}
24 \newcommand{\R}{\mathbb{R
}}
25 \newcommand{\Q}{\mathbb{Q
}}
26 \newcommand{\Z}{\mathbb{Z
}}
27 \newcommand{\N}{\mathbb{N
}}
28 \newcommand{\A}{\mathcal{A
}}
29 \newcommand{\B}{\mathcal{B
}}
30 \newcommand{\D}{\mathcal{D
}}
31 \newcommand{\E}{\mathcal{E
}}
32 \newcommand{\M}{\mathcal{M
}}
33 \newcommand{\Pot}{\mathcal{P
}}
34 \newcommand{\Salg}{\mathcal{S
}}
35 \newcommand{\normal}{\mathcal{N
}}
36 \newcommand{\region}{\mathcal{R
}}
42 \hyphenation{co-rres-pon-dien-te
}
45 % Para generar el documento pdf con el índice alfabético:
51 % Para generar el documento html:
52 % $ latex2html max.tex
65 Copyright
\copyright 2004-
2011 Mario Rodríguez Riotorto
67 Este documento es libre; se puede redistribuir y/o
68 modificar bajo los términos de la GNU General Public License
69 tal como lo publica la Free Software Foundation.
70 Para más detalles véase la GNU General Public License
71 en http://www.gnu.org/copyleft/gpl.html
73 \emph{This
document is free; you can redistribute
74 it and/or modify it under the terms of the
75 GNU General Public License as published by
76 the Free Software Foundation. See the
77 GNU General Public License for more details at \\
78 http://www.gnu.org/copyleft/gpl.html
}
89 \addtocounter{page
}{-
3}
95 \chapter{Introducción
}
97 Este es un manual introductorio al entorno de cálculo simbólico Maxima, directo sucesor del legendario Macsyma.
99 El objetivo del manual es facilitar el acceso a este programa a todas aquellas personas que por vez primera se acercan a él.
101 Maxima es un programa cuyo objeto es la realización de cálculos matemáticos, tanto simbólicos como numéricos; es capaz de manipular expresiones algebraicas y matriciales, derivar e integrar funciones, realizar diversos tipos de gráficos, etc.
103 Su nombre original fue Macsyma (
\emph{MAC's SYmbolic MAnipulation System
}, donde MAC,
\emph{Machine Aided Cognition
}, era el nombre del
\emph{Laboratory for Computer Science
} del MIT durante la fase inicial del proyecto Macsyma). Se desarrolló en estos laboratorios a partir del año
1969 con fondos aportados por varias agencias gubernamentales norteamericanas (
\emph{National Aeronautics and Space Administration
},
\emph{Office of Naval Research
},
\emph{U.S. Department of Energy
} y
\emph{U.S. Air Force
}).
105 El concepto y la organización interna del programa están basados en la tesis doctoral que Joel Moses elaboró en el MIT sobre integración simbólica. Según Marvin Minsky, director de esta tesis, Macsyma pretendía automatizar las manipulaciones simbólicas que realizaban los matemáticos, a fin de entender la capacidad de los ordenadores para actuar de forma inteligente.
107 El año
1982 es clave. El MIT transfiere una copia de Macsyma a la empresa Symbolics Inc. para su explotación económica, haciendo el código propietario, y otra al Departamento de Energía, copia ésta que será conocida con el nombre de DOE-Macsyma. En
1992 la versión comercial de Macsyma sería adquirida por una empresa que se llamaría precisamente Macsyma Inc, y el programa iría perdiendo fuelle progresivamente ante la presencia en el mercado de otros programas similares como Maple o Mathematica, ambos los dos inspirados en sus orígenes en el propio Macsyma.
109 Pero ocurrieron dos historias paralelas. Desde el año
1982, y hasta su fallecimiento en el
2001, William Schelter de la Universidad de Texas mantuvo una versión de este programa adaptada al estándar Common Lisp en base a DOE-Macsyma, la cual ya se conoce con el nombre de Maxima para diferenciarla de la versión comercial. En el año
1998 Schelter había conseguido del DOE permiso para distribuir Maxima bajo la licencia GNU-GPL (www.gnu.org); con este paso, muchas más personas empezaron a dirigir su mirada hacia Maxima, justo en el momento en el que la versión comercial estaba declinando. Actualmente, el proyecto está siendo mantenido por un grupo de desarrolladores originarios de varios países, asistidos y ayudados por otras muchas personas interesadas en Maxima y que mantienen un cauce de comunicación a través de la lista de correo
111 http://maxima.sourceforge.net/maximalist.html
114 Además, desde el año
2006, se ha activado una lista de correos para usuarios de habla hispana en
116 http://lists.sourceforge.net/lists/listinfo/maxima-lang-es
119 Puesto que Maxima se distribuye bajo la licencia GNU-GPL, tanto el código fuente como los manuales son de libre acceso a través de la página web del proyecto,
121 http://maxima.sourceforge.net
124 Uno de los aspectos más relevantes de este programa es su naturaleza libre; la licencia GPL en la que se distribuye brinda al usuario ciertas libertades:
126 \item libertad para utilizarlo,
127 \item libertad para modificarlo y adaptarlo a sus propias necesidades,
128 \item libertad para distribuirlo,
129 \item libertad para estudiarlo y aprender su funcionamiento.
132 La gratuidad del programa, junto con las libertades recién mencionadas, hacen de Maxima una formidable herramienta pedagógica, de investigación y de cálculo técnico, accesible a todos los presupuestos, tanto institucionales como individuales.
134 No quiero terminar esta breve introducción sin antes recordar y agradecer a todo el equipo humano que ha estado y está detrás de este proyecto, desde el comienzo de su andadura allá por los años
70 hasta el momento actual; incluyo también a todas las personas que, aún no siendo desarrolladoras del programa, colaboran haciendo uso de él, presentando y aportando continuamente propuestas e ideas a través de las listas de correos. Un agradecimiento especial a Robert Dodier y James Amundson, quienes me brindaron la oportunidad de formar parte del equipo de desarrollo de Maxima y me abrieron las puertas a una experiencia verdaderamente enriquecedora.
136 Finalmente, un recuerdo a William Schelter. Gracias a él disponemos hoy de un Maxima que, paradójicamente, por ser libre, no pertenece a nadie pero que es de todos.
139 \emph{Ferrol-A Coruña
}
150 \chapter{Despegando con Maxima
}
152 \section{Instalación
}
154 Maxima funciona en Windows, Mac y Linux.
156 En Windows, la instalación consiste en descargar el binario
\verb|exe| desde el enlace correspondiente en la página del proyecto y ejecutarlo.
158 En Mac, es necesario descargar el fichero con extensión
\verb|dmg|, hacer doble clic sobre él y arrastrar los iconos de Maxima, wxMaxima y Gnuplot a la carpeta Aplicaciones. El proceso detallado se explica aquí:
160 http://www.faq-mac.com/
41547/instalacion-maximawxmaxima-mac-javier-arantegui
163 En Linux, la mayoría de las distribuciones tienen ficheros precompilados en sus respectivos repositorios con las extensiones
\verb|rpm| o
\verb|deb|, según el caso. Sin embargo, en algunas distribuciones las versiones oficiales no suelen estar muy actualizadas, por lo que podría ser recomendable proceder con la compilación de las fuentes, tal como se expone a continuación.
165 Las siguientes indicaciones sobre la compilación hacen referencia al sistema operativo Linux.
167 Si se quiere instalar Maxima en su estado actual de desarrollo, será necesario descargar los ficheros fuente completos desde el repositorio de Sourceforge y proceder posteriormente a su compilación. Se deberá tener operativo un entorno Common Lisp en la máquina (
\verb|clisp|,
\verb|cmucl|,
\verb|sbcl| o
\verb|gcl| son todas ellas alternativas válidas), así como todos los programas que permitan ejecutar las instrucciones que se indican a continuación, incluidas las dependencias
\verb|tcl-tk| y
\verb|gnuplot|.
\emph{Grosso modo
}, estos son los pasos a seguir para tener Maxima operativo en el sistema
\footnote{Se supone que se trabaja con clisp, con codificación unicode y que queremos el sistema de ayuda en inglés y español.
}:
169 \item Descargar las fuentes a un directorio local siguiendo las instrucciones que se indican en el enlace al repositorio de la página del proyecto.
170 \item Acceder a la carpeta local de nombre
\verb|maxima| y ejecutar las instrucciones
173 ./configure --enable-clisp --enable-lang-es
179 \item Para ejecutar Maxima desde la línea de comandos (Figura~
\ref{fig:texto
}) se deberá escribir
183 si se quiere trabajar con la interfaz gráfica (Figura~
\ref{fig:xmaxima
}), teclear
189 Otro entorno gráfico es Wxmaxima
\footnote{http://wxmaxima.sourceforge.net
} (Figura~
\ref{fig:wxmaxima
}), que se distribuye conjuntamente con los ejecutables para Windows y Mac. En Linux, una vez instalado Maxima, se podrá instalar este entorno separadamente.
191 Una cuarta alternativa, que resulta muy vistosa por hacer uso de
\TeX, es la de ejecutar Maxima desde el editor Texmacs
\footnote{http://www.texmacs.org
} (Figura~
\ref{fig:texmacs
}).
193 Emacs es un editor clásico en sistemas Unix. Aunque hay varias formas de ejecutar Maxima desde Emacs, con el modo Imaxima
\footnote{http://members3.jcom.home.ne.jp/imaxima
} (Figura~
\ref{fig:imaxima
}) se consigue que los resultados estén formateados en
\TeX.
195 También se han desarrollado en los últimos años entornos web para Maxima
\footnote{http://maxima.sourceforge.net/relatedprojects.html
}.
199 \includegraphics[scale=
0.73]{texto.pdf
}
200 \caption{Maxima desde la línea de comandos.
}
207 \includegraphics[scale=
0.73]{xmaxima.pdf
}
208 \caption{Xmaxima, el entorno gráfico basado en tcl-tk.
}
215 \includegraphics[scale=
0.73]{wxmaxima.pdf
}
216 \caption{Wxmaxima, el entorno gráfico basado en wxwidgets.
}
223 \includegraphics[scale=
0.73]{texmacs.pdf
}
224 \caption{Maxima desde Texmacs.
}
231 \includegraphics[scale=
0.6]{imaxima.pdf
}
232 \caption{Maxima en Emacs.
}
242 \section{Una primera sesión
}
244 En esta sesión se intenta realizar un primer acercamiento al programa a fin de familiarizarse con el estilo operativo de Maxima, dejando sus habilidades matemáticas para más adelante.
246 Una vez accedemos a Maxima, lo primero que vamos a ver será la siguiente información:
249 Maxima
5.25.0 http://maxima.sourceforge.net
250 using Lisp CLISP
2.48 (
2009-
07-
28)
251 Distributed under the GNU Public License. See the file COPYING.
252 Dedicated to the memory of William Schelter.
253 The function bug_report() provides bug reporting information.
257 En primer lugar nos informa sobre la versión de Maxima que se está ejecutando y la URL del proyecto, a continuación indica qué entorno Lisp está dándole soporte al programa y la nota legal sobre la licencia, por supuesto GNU-GPL. Finaliza con un recordatorio a Schelter y cómo debemos proceder si encontramos un fallo en el programa, ayudando así a su mejora. Tras esta cabecera, muy importante, aparece el indicador
\verb|(
%i1)| esperando nuestra primera pregunta (\verb|i| de \emph{input}). Si queremos calcular una simple suma tecleamos la operación deseada seguida de un punto y coma (\verb|;|)\index{1@; (punto y coma)} y una pulsación de la tecla retorno
269 Vemos que el resultado de la suma está etiquetado con el símbolo
\verb|(
%o1)| indicando que es la salida correspondiente a la primera entrada (\verb|o| de \emph{output}). A continuación \verb|(%i2)| indica que Maxima espera nuestra segunda instrucción.
271 El punto y coma actúa también como un separador cuando escribimos varias instrucciones en un mismo renglón. Nuestra siguiente operación consistirá en asignar el valor
34578 a la variable
\verb|x| y el
984003 a la
\verb|y|, solicitando luego su producto,
273 (
%i2) x:34578; y:984003; x*y;
276 34578\leqno{\tt (\%o2)
}
279 984003\leqno{\tt (\%o3)
}
282 34024855734\leqno{\tt (\%o4)
}
284 conviene prestar atención al hecho de que la asignación de un valor a una variable se hace con los dos puntos (
\verb|:|)
\index{35@: (operador de asignación)
}, no con el signo de igualdad, que se reserva para las ecuaciones.
286 Es posible que no deseemos los resultados intermedios que Maxima va calculando o, como en este caso, las asignaciones a las variables que va haciendo; en tales situaciones debe hacerse uso del delimitador
\verb|$|
\index{3@\$
}, que no devuelve los resultados que va calculando. Repitiendo el cálculo de la forma
288 (
%i5) x:34578$ y:984003$ x*y;
291 34024855734\leqno{\tt (\%o7)
}
293 podemos conseguir una salida más limpia. Las asignaciones a variables se mantienen activas mientras dure la sesión con Maxima, por lo que podemos restar las variables
\verb|x| e
\verb|y| anteriores
298 -
949425\leqno{\tt (\%o13)
}
301 Esto tiene un riesgo; si queremos resolver la ecuación $x^
2-
3x+
1=
0$,
303 (
%i9) solve(x^2-3*x+1=0,x);
304 A number was found where a variable was expected -`solve'
305 -- an error. Quitting. To debug this try debugmode(true);
307 nos devuelve un mensaje de error, ya que donde se supone que hay una incógnita, lo que realmente encuentra es un número, en este caso
34578. Hay dos formas de resolver esta situación; la primera consiste en utilizar el operador comilla simple (
\verb|'|)
\index{4@'
}, que evita la evaluación de las variables:
309 (
%i9) solve('x^2-3*'x+1=0,'x);
312 \left[ x=-
{{\sqrt{5}-
3}\over{2}} , x=
{{\sqrt{5}+
3}\over{2}}
313 \right] \leqno{\tt (\%o9)
}
319 34578\leqno{\tt (\%o10)
}
321 como se ve,
\verb|x| mantiene su valor original.
323 La segunda forma de evitar este problema consiste en vaciar el contenido de la variable
\verb|x| mediante la función
\verb|kill|
\index{kill
},
326 (
%i12) solve(x^2-3*x+1=0,x);
329 \left[ x=-
{{\sqrt{5}-
3}\over{2}} , x=
{{\sqrt{5}+
3}\over{2}}
330 \right] \leqno{\tt (\%o12)
}
338 en este caso,
\verb|x| ha perdido su valor.
340 Las etiquetas
\verb|(
%in)|\index{7@\%in} y \verb|(%on)|\index{8@\%on}, siendo \verb|n| un número entero, pueden ser utilizadas a lo largo de una sesión a fin de evitar tener que volver a escribir expresiones; así, si queremos calcular el cociente $\frac{x y}{x-y}$, con $x=34578$ y $y=984003$, podemos aprovechar los resultados \verb|(%o7)| y \verb|(%o8)| y hacer
345 -
{{11341618578}\over{316475}}\leqno{\tt (\%o14)
}
348 Las etiquetas que indican las entradas y salidas pueden ser modificadas a voluntad haciendo uso de las variables
\verb|inchar|
\index{inchar
} y
\verb|outchar|
\index{outchar
},
353 {\it \%i
}\leqno{\tt (\%o15)
}
359 {\it \%o
}\leqno{\tt (\%o16)
}
362 (
%i17) inchar: 'menda;
365 \mbox{{}menda
{}}\leqno{\tt (\%o17)
}
368 (menda18) outchar: 'lerenda;
371 \mbox{{}lerenda
{}}\leqno{\tt (lerenda18)
}
377 8\leqno{\tt (lerenda19)
}
380 (menda20) inchar:'
%i$ outchar:'%o$
386 Al final se han restaurado los valores por defecto.
388 En caso de que se pretenda realizar nuevamente un cálculo ya indicado deberán escribirse dos comillas simples (
\verb|''|)
\index{5@''
}, no comilla doble, junto con la etiqueta de la instrucción deseada
393 x-
984003\leqno{\tt (\%o23)
}
396 Obsérvese que al haber dejado a
\verb|x| sin valor numérico, ahora el resultado es otro. Cuando se quiera hacer referencia al último resultado calculado por Maxima puede ser más sencillo hacer uso del símbolo
\verb|
%|\index{6@\%}, de forma que si queremos restarle la \verb|x| a la última expresión podemos hacer
401 -
984003\leqno{\tt (\%o24)
}
404 Ciertas constantes matemáticas de uso frecuente tienen un símbolo especial en Maxima: la base de los logaritmos naturales ($e$), el cociente entre la longitud de una circunferencia y su diámetro ($
\pi$), la unidad imaginaria ($i=
\sqrt{-
1}$), la constante de Euler-Mascheroni ($
\gamma=-
\int_0^
\infty e^
{-x
} \ln x dx$) y la razón aurea ($
\phi=
\frac{1+
\sqrt{5}}{2}$), se representarán por
\verb|
%e|\index{9@\%e}, \verb|%pi|\index{11@\%pi}, \verb|%i|\index{10@\%i}, \verb|%gamma|\index{12@\%gamma} y \verb|%phi|\index{13@\%phi}, respectivamente.
406 Es muy sencillo solicitar a Maxima que nos informe sobre alguna función de su lenguaje; la técnica nos servirá para ampliar información sobre cualquier instrucción a la que se haga referencia en este manual, por ejemplo,
408 (
%i25) describe(sqrt);
410 -- Función: sqrt (<x>)
411 Raíz cuadrada de <x>. Se representa internamente por `<x>^(
1/
2)'.
412 Véase también `rootscontract'.
414 Si la variable `radexpand' vale `true' hará que las raíces
415 `n'-ésimas de los factores de un producto que sean potencias de
416 `n' sean extraídas del radical; por ejemplo, `sqrt(
16*x^
2)' se
417 convertirá en `
4*x' sólo si `radexpand' vale `true'.
420 There are also some inexact matches for `sqrt'.
421 Try `?? sqrt' to see them.
425 nos instruye sobre la utilización de la función
\verb|sqrt|. Alternativamente, se puede utilizar para el mismo fin el operador interrogación (
\verb|?|)
\index{36@? (operador interrogación)
},
429 -- Función: sqrt (<x>)
430 Raíz cuadrada de <x>. Se representa internamente por `<x>^(
1/
2)'.
431 Véase también `rootscontract'.
433 Si la variable `radexpand' vale `true' hará que las raíces
434 `n'-ésimas de los factores de un producto que sean potencias de
435 `n' sean extraídas del radical; por ejemplo, `sqrt(
16*x^
2)' se
436 convertirá en `
4*x' sólo si `radexpand' vale `true'.
439 There are also some inexact matches for `sqrt'.
440 Try `?? sqrt' to see them.
445 Cuando no conocemos el nombre completo de la función sobre la que necesitamos información podremos utilizar el operador de doble interrogación (
\verb|??|)
\index{37@?? (operador doble interrogación)
} que nos hace la búsqueda de funciones que contienen en su nombre cierta subcadena,
449 0: isqrt (Operadores generales)
450 1: sqrt (Operadores generales)
451 2: sqrtdenest (Funciones y variables para simplification)
452 3: sqrtdispflag (Operadores generales)
453 Enter space-separated numbers, `all' or `none':
3
455 -- Variable opcional: sqrtdispflag
456 Valor por defecto: `true'
458 Si `sqrtdispflag' vale `false', hará que `sqrt' se muestre con el
465 Inicialmente muestra un sencillo menú con las funciones que contienen la subcadena
\verb|sqrt| y en el que debemos seleccionar qué información concreta deseamos; en esta ocasión se optó por
\verb|
3| que es el número asociado a la variable opcional
\verb|sqrtdispflag|.
467 A fin de no perder los resultados de una sesión con Maxima, quizás con el objeto de continuar el trabajo en próximas jornadas, podemos guardar en un archivo aquellos valores que nos puedan interesar; supongamos que necesitamos almacenar el contenido de la variable
\verb|y|, tal como lo definimos en la entrada
\verb|(
%i5)|, así como el resultado de la salida
468 \verb|(
%o9)|, junto con la instrucción que la generó, la entrada \verb|(%i9)|,
470 (
%i28) save("mi.sesion",y,resultado=%o9,ecuacion=%i9)$
473 Véase que el primer argumento de
\verb|save|
\index{save
} es el nombre del archivo, junto con su ruta si se considera necesario, que la variable
\verb|y| se escribe tal cual, pero que las referencias de las entradas y salidas deben ir acompañadas de un nombre que las haga posteriormente reconocibles.
475 Por último, la forma correcta de abandonar la sesión de Maxima es mediante
476 \index{quit
}\begin{Verbatim
}
480 Abramos ahora una nueva sesión con Maxima y carguemos en memoria los resultados de la anterior sesión,
481 \index{load
}\begin{Verbatim
}
482 (
%i1) load("mi.sesion")$
486 984003\leqno{\tt (\%o2)
}
492 \mathrm{solve
}\left(x^
2-
3\,x+
1=
0 , x
\right)
\leqno{\tt (\%o3)
}
498 \left[ x=-
{{\sqrt{5}-
3}\over{2}} , x=
{{\sqrt{5}+
3}\over{2}}
499 \right] \leqno{\tt (\%o4)
}
502 Si ahora quisiéramos recalcular las soluciones de la ecuación, modificándola previamente de manera que el coeficiente de primer grado se sustituyese por otro número, simplemente haríamos
503 \index{subst
}\index{ev
}\begin{Verbatim
}
504 (
%i5) subst(5,3,ecuacion);
507 \mathrm{solve
}\left(x^
2-
5\,x+
1=
0 , x
\right)
\leqno{\tt (\%o5)
}
513 \left[ x=-
{{\sqrt{21}-
5}\over{2}} , x=
{{\sqrt{21}+
5}\over{2}}
514 \right] \leqno{\tt (\%o6)
}
517 La función
\verb|save| guarda las expresiones matemáticas en formato Lisp, pero a nivel de usuario quizás sea más claro almacenarlas en el propio lenguaje de Maxima; si tal es el caso, mejor será el uso de
\verb|stringout|
\index{stringout
}, cuyo resultado será un fichero que también se podrá leer mediante
\verb|load|.
519 Continuemos experimentando con esta segunda sesión de Maxima que acabamos de iniciar.
521 Maxima está escrito en Lisp, por lo que ya se puede intuir su potencia a la hora de trabajar con listas; en el siguiente diálogo, el texto escrito entre las marcas
\verb|/*| y
\verb|*/| son comentarios que no afectan a los cálculos,
524 (
%i7) /* Se le asigna a la variable x una lista */
525 x:
[cos(
%pi), 4/16, [a, b], (-1)^3, integrate(u^2,u)];
528 \left[ -
1 ,
{{1}\over{4}} ,
\left[ a , b
\right] , -
1 ,
{{u^
3
529 }\over{3}} \right] \leqno{\tt (\%o7)
}
532 (
%i8) /* Se calcula el número de elementos del último resultado */
539 (
%i9) /* Se transforma una lista en conjunto, */
540 /* eliminando redundancias. Los */
541 /* corchetes se transforman en llaves */
545 \left \
{-
1 ,
{{1}\over{4}} ,
\left[ a , b
\right] ,
{{u^
3}\over{3
546 }} \right \
}\leqno{\tt (\%o9)
}
549 Vemos a continuación cómo se procede a la hora de hacer sustituciones en una expresión,
552 (
%i10) /* Sustituciones a hacer en x */
556 \left[ -
1 ,
{{1}\over{4}} ,
\left[ c , b
\right] , -
1 ,
{{8}\over{3
557 }} \right] \leqno{\tt (\%o10)
}
560 (
%i11) /* Forma alternativa para hacer lo mismo */
564 \left[ -
1 ,
{{1}\over{4}} ,
\left[ c , b
\right] , -
1 ,
{{8}\over{3
565 }} \right] \leqno{\tt (\%o11)
}
568 (
%i12) %o7[5], u=[1,2,3];
571 \left[ {{1}\over{3}} ,
{{8}\over{3}} ,
9 \right] \leqno{\tt (\%o12)
}
574 En esta última entrada,
\verb|
%o7| hace referencia al séptimo resultado devuelto por Maxima, que es la lista guardada en la variable \verb|x|, de modo que \verb|%o7[5]| es el quinto elemento de esta lista, por lo que esta expresión es equivalente a a \verb|x[5]|; después, igualando \verb|u| a la lista \verb|[1,2,3]| este quinto elemento de la lista es sustituído sucesivamente por las tres cantidades. Tal como ya se ha comentado, Maxima utiliza los dos puntos (\verb|:|) para hacer asignaciones a variables, mientras que el símbolo de igualdad se reserva para la construcción de ecuaciones.
576 Un aspecto a tener en cuenta es que el comportamiento de Maxima está controlado por los valores que se le asignen a ciertas variables globales del sistema. Una de ellas es la variable
\verb|numer|
\index{numer
}, que por defecto toma el valor lógico
\verb|false|, lo que indica que Maxima evitará dar resultados en formato decimal, prefiriendo expresiones simbólicas y fraccionarias,
581 \mathrm{false
}\leqno{\tt (\%o13)
}
587 {{2^
{-
{{1}\over{2}} }}\over{3}}\leqno{\tt (\%o14)
}
594 0.2357022603955159\leqno{\tt (\%o16)
}
597 (
%i17) numer:false$ /*se reinstaura valor por defecto */
600 Sin embargo, en general será preferible el uso de la función
\verb|float|
\index{float
},
602 (
%i18) float(sqrt(8)/12);
605 0.2357022603955159\leqno{\tt (\%o18)
}
608 Las matrices también tienen su lugar en Maxima; la manera más inmediata de construirlas es con la instrucción
\verb|matrix|
\index{matrix
},
611 (
%i19) A: matrix([sin(x),2,%pi],[0,y^2,5/8]);
614 \begin{pmatrix
}\sin x&
2&
\pi\cr 0&y^
2&
{{5}\over{8}}\cr \end{pmatrix
}\leqno{\tt (\%o19)
}
618 (
%i20) B: matrix([1,2],[0,2],[-5,integrate(x^2,x,0,1)]);
621 \begin{pmatrix
}1&
2\cr 0&
2\cr -
5&
{{1}\over{3}}\cr \end{pmatrix
}\leqno{\tt (\%o20)
}
625 (
%i21) A.B; /* producto matricial */
628 \begin{pmatrix
}\sin x-
5\,
\pi&
2\,
\sin x+
{{\pi}\over{3}}+
4\cr -
{{25}\over{8
629 }}&
2\,y^
2+
{{5}\over{24}}\cr \end{pmatrix
} \leqno{\tt (\%o21)
}
632 En cuanto a las capacidades gráficas de Maxima, se remite al lector a la sección correspondiente.
634 A fin de preparar publicaciones científicas, si se quiere redactar documentos en formato
\LaTeX, la función
\verb|tex|
\index{tex
} de Maxima será una útil compañera; en el siguiente ejemplo se calcula una integral y a continuación se pide la expresión resultante en formato
\TeX:
637 (
%i22) 'integrate(sqrt(a+x)/x^5,x,1,2) = integrate(sqrt(2+x)/x^5,x,1,2)$
640 $$
\int_{1}^
{2}{{{\sqrt{x+
4}}\over{x^
5}}\;dx
}=
{{5\,
\sqrt{2}\,
\log
641 \left(
5-
2\,
\sqrt{2}\,
\sqrt{3}\right)+
548\,
\sqrt{3}}\over{2048}}-
{{15
642 \,
\sqrt{2}\,
\log \left(
3-
2\,
\sqrt{2}\right)+
244}\over{6144}}$$
645 Al pegar y copiar el código encerrado entre los dobles símbolos de dólar a un documento
\LaTeX, el resultado es el siguiente:
648 \int_{1}^
{2}{{{\sqrt{x+a
}}\over{x^
5}}\;dx
}=
{{5\,
\sqrt{2}\,
\log
649 \left(
5-
2\,
\sqrt{2}\,
\sqrt{3}\right)+
548\,
\sqrt{3}}\over{2048}}-
{{15
650 \,
\sqrt{2}\,
\log \left(
3-
2\,
\sqrt{2}\right)+
244}\over{6144}}
653 Un comentario sobre la entrada
\verb|
%i22|. Se observa en ella que se ha escrito dos veces el mismo código a ambos lados del signo de igualdad. La única diferencia entre ambos es el apóstrofo que antecede al primer \verb|integrate|; éste es el operador de \emph{comilla simple}, ya anteriormente aparecido, que Maxima utiliza para evitar la ejecución de una instrucción, de forma que en el resultado la primera integral no se calcula, pero sí la segunda, dando lugar a la igualdad que se obtiene como resultado final. Las expresiones que en Maxima se marcan con la comilla simple para no ser evaluadas reciben el nombre de \emph{expresiones nominales}, en contraposición a las otras, conocidas como \emph{expresiones verbales}.
655 Ya se ha comentado más arriba cómo solicitar ayuda de Maxima. Algunos usuarios encuentran engorroso que la ayuda se interfiera con los cálculos; esto se puede arreglar con un mínimo de bricolage informático. Al tiempo que se instala Maxima, se almacena también el sistema de ayuda en formato
\verb|html| en una determinada carpeta; el usuario tan sólo tendrá que buscar esta carpeta, en la que se encontrará la página principal
\verb|maxima.html|, y hacer uso de la función
\verb|system|
\index{system
} de Maxima que ejecuta comandos del sistema, la cual admite como argumento una cadena alfanumérica con el nombre del navegador (en el ejemplo,
\verb|mozilla|) seguido de la ruta hacia el documento
\verb|maxima.html|,
659 system("(mozilla /usr/local/share/maxima/
5.25.0/doc/html/es.utf8/maxima.html)&")$
662 Este proceso se puede automatizar si la instrucción anterior se guarda en un fichero de nombre
\verb|maxima-init.mac| y se guarda en la carpeta hacia la que apunta la variable
\verb|maxima_userdir|; por ejemplo, en Linux,
665 (
%i25) maxima_userdir;
667 $$
\mbox{{}/home/xefe/.maxima
{}}\leqno{\tt (\%o25)
}$$
669 El fichero
\verb|maxima-init.mac| se lee cada vez que arranca Maxima y se ejecutan las instrucciones contenidas en él; se puede utilizar para cargar automáticamente módulos adicionales que vayamos a utilizar con frecuencia, funciones especiales definidas por nosotros o, como en este caso, para que se abra el navegador con las páginas del manual.
677 \chapter{Números y sus operaciones
}
684 \section{Enteros y decimales
}
686 Maxima puede trabajar con números enteros tan grandes como sea necesario,
693 7886578673647905035523632139321850622951359776871732632947425332443594\\
694 4996340334292030428401198462390417721213891963883025764279024263710506\\
695 1926624952829931113462857270763317237396988943922445621451664240254033\\
696 2918641312274282948532775242424075739032403212574055795686602260319041\\
697 7032406235170085879617892222278962370389737472000000000000000000000000\\
698 0000000000000000000000000\end{array
} \leqno{\tt (\%o1)
}
702 Los operadores aritméticos más comunes son:
703 \index{14@+
}\index{16@-
}\index{17@*
}\index{18@/
}\index{19@\^\
}\index{20@**
}\begin{center
}
704 \begin{tabular
}{|c|l|
} \hline
707 \verb|*| & producto \\
708 \verb|/| & división \\
709 \verb|^| o
\verb|**| & potencia \\
\hline
713 Maxima devuelve los resultados de forma exacta, sin aproximaciones decimales; así tenemos que para realizar el cálculo de la expresión
716 \left(
\frac{3^
7}{4+
\frac{3}{5}} \right)^
{-
1} +
\frac{7}{9}
723 (
%i2) ((3^7/(4+3/5))^(-1)+7/9)^3;
726 {{620214013952}\over{1307544150375}}\leqno{\tt (\%o2)
}
728 obteniendo el resultado en forma de fracción simplificada.
730 De todos modos podemos solicitar el resultado en forma decimal; por ejemplo, si queremos la expresión decimal del último resultado,
731 \index{float
}\begin{Verbatim
}
735 0.4743350454163436\leqno{\tt (\%o3)
}
738 Maxima puede trabajar con precisión arbitraria. Para calcular el valor del cociente $
\frac{e
}{\pi}$ con
100 cifras decimales, deberemos especificar primero la precisión requerida asignándole a la variable
\verb|fpprec|
\index{fpprec
} el valor
100 y a continuación realizar el cálculo, solicitando la expresión decimal con una llamada a la función
\verb|bfloat|
\index{bfloat
}:
739 \index{fpprec
}\index{bfloat
}\begin{Verbatim
}
740 (
%i4) fpprec:100$ bfloat(%e / %pi);
744 8.65255979432265087217774789646089617428744623908515539454330288948045\\
745 0445706770586319246625161845173_B
\times 10^
{-
1}\end{array
} \leqno{\tt (\%o5)
}
748 Nótese que cuando un resultado es devuelto en el formato
\verb|bfloat| se escribe la letra
\verb|B|
\index{B
} en lugar de la clásica
\verb|E|
\index{E
} para indicar el exponente.
750 En la instrucción
\verb|
%i4| se establece la precisión deseada y luego se transforma el valor simbólico \verb|%e / %pi| mediante la función \verb|bfloat|. Recuérdese que el símbolo \verb|$| sirve como delimitador entre instrucciones.
752 Veamos cómo factorizar un números tal como $
200!$ en sus factores primos,
753 \index{factor
}\begin{Verbatim
}
758 2^
{197}\,
3^
{97}\,
5^
{49}\,
7^
{32}\,
11^
{19}\,
13^
{16}\,
17^
{11}\,
19^
{10}
759 \,
23^
8\,
29^
6\,
31^
6\,
37^
5\,
41^
4\,
43^
4\,
47^
4\,
53^
3\,
59^
3\,
61^
3\,
67^
2\,
71^
2\\
760 \,
73^
2\,
79^
2\,
83^
2\,
89^
2\,
97^
2\,
101\,
103\,
107\,
109\,
113\,
127\,
131
761 \,
137\,
139\,
149\,
151\,
157\,
163\,
167\,
173\\
762 \,
179\,
181\,
191\,
193\,
197\,
199\end{array
} \leqno{\tt (\%o6)
}
765 En la siguiente factorización hacemos uso de la variable global
\verb|showtime|
\index{showtime
} para saber el tiempo que le lleva ejecutar el cálculo,
766 \index{33@/*...*/
}\begin{Verbatim
}
768 Evaluation took
0.00 seconds (
0.00 elapsed) using
80 bytes.
769 (
%i8) factor(2^300-1);
770 Evaluation took
0.86 seconds (
0.85 elapsed) using
48.571 MB.
774 3^
2\,
5^
3\,
7\,
11\,
13\,
31\,
41\,
61\,
101\,
151\,
251\,
331\,
601\,
1201\,
1321
775 \,
1801\,
4051\,
8101\,
63901\,
100801\\
776 \,
268501\,
10567201\,
13334701\,
1182468601\,
1133836730401\end{array
} \leqno{\tt (\%o8)
}
779 (
%i9) /* desactivamos la información de los tiempos */
782 El texto que se escribe entre
\verb|/*| y
\verb|*/| son comentarios que Maxima ignora.
784 Además de la variable opcional
\verb|showtime|, otro mecanismo de control de los tiempos de ejecución es la función
\verb|time|
\index{time
},
785 \index{33@/*...*/
}\begin{Verbatim
}
789 \left[ 1.7161081 \right] \leqno{\tt (\%o10)
}
792 En relación con los números primos, para saber si un número lo es o no,
793 \index{primep
}\begin{Verbatim
}
794 (
%i11) primep(3^56-1);
797 \mathrm{false
}\leqno{\tt (\%o11)
}
800 Y para solicitarle a Maxima que compruebe si un número es par o impar necesitamos echar mano de las funciones
\verb|evenp|
\index{evenp
} or
\verb|oddp|
\index{oddp
}, respectivamente,
805 \mathrm{true
}\leqno{\tt (\%o12)
}
811 \mathrm{true
}\leqno{\tt (\%o13)
}
814 Le solicitamos a Maxima que nos haga una lista con todos los divisores de un número,
815 \index{divisors
}\begin{Verbatim
}
816 (
%i14) divisors(100);
819 \left \
{1 ,
2 ,
4 ,
5 ,
10 ,
20 ,
25 ,
50 ,
100 \right \
}\leqno{\tt (\%o14)
}
822 En lo que concierne a la división, puede ser necesario conocer el cociente entero y el resto correspondiente; para ello se dispone de las funciones
\verb|quotient|
\index{quotient
} y
\verb|remainder|
\index{remainder
},
824 (
%i15) quotient(5689,214);
827 26\leqno{\tt (\%o15)
}
830 (
%i16) remainder(5689,214);
833 125\leqno{\tt (\%o16)
}
840 \section{Números complejos
}
842 Como ya se comentó más arriba, la unidad imaginaria $
\sqrt{-
1}$ se representa en Maxima mediante el símbolo
\verb|
%i|\index{i},
850 Se soportan las operaciones básicas con números complejos,
852 (
%i2) z1:3+5*%i$ z2:1/2-4*%i$ /*z1 y z2*/
853 (
%i4) z1 + z2; /*suma*/
856 i+
{{7}\over{2}}\leqno{\tt (\%o4)
}
859 (
%i5) z1 - z2; /*resta*/
862 9\,i+
{{5}\over{2}}\leqno{\tt (\%o5)
}
865 (
%i6) z1 * z2; /*multiplicación*/
868 \left(
{{1}\over{2}}-
4\,i
\right)\,
\left(
5\,i+
3\right)
\leqno{\tt (\%o6)
}
871 (
%i7) z1 / z2; /* división */
874 {{5\,i+
3}\over{{{1}\over{2}}-
4\,i
}}\leqno{\tt (\%o7)
}
877 Es posible que estos dos últimos resultados nos parezcan frustrantes y los deseemos en otro formato; a tal efecto podemos pedir a Maxima que nos devuelva
\verb|(
%o6)| y \verb|(%o7)| en forma cartesiana,
878 \index{rectform
}\begin{Verbatim
}
882 {{43}\over{2}}-
{{19\,i
}\over{2}}\leqno{\tt (\%o8)
}
888 {{58\,i
}\over{65}}-
{{74}\over{65}}\leqno{\tt (\%o9)
}
891 Las funciones
\verb|realpart|
\index{realpart
} e
\verb|imagpart|
\index{imagpart
} extraen del número complejo sus partes real e imaginaria, respectivamente,
893 (
%i10) realpart(%o7);
896 -
{{74}\over{65}}\leqno{\tt (\%o10)
}
899 (
%i11) imagpart(%o7);
902 {{58}\over{65}}\leqno{\tt (\%o11)
}
905 Antes hemos optado por los resultados en formato cartesiano; pero también es posible solicitarlos en su forma polar,
906 \index{polarform
}\begin{Verbatim
}
907 (
%i12) polarform(%o7);
910 {{2\,
\sqrt{34}\,e^
{i\,
\left(
\pi-
\arctan \left(
{{29}\over{37}}
911 \right)
\right)
}}\over{\sqrt{65}}}\leqno{\tt (\%o12)
}
914 (
%i13) rectform(%); /* forma rectangular */
917 {{58\,
\sqrt{34}\,i
}\over{\sqrt{65}\,
\sqrt{2210}}}-
{{74\,
\sqrt{34}
918 }\over{\sqrt{65}\,
\sqrt{2210}}}\leqno{\tt (\%o13)
}
921 (
%i14) float(%); /* formato decimal */
924 0.8923076923076924\,i-
1.138461538461538\leqno{\tt (\%o14)
}
927 El módulo de un número complejo se calcula con la función
\verb|abs|
\index{abs
} y se le puede pasar el número tanto en su forma cartesiana como polar,
932 {{2\,
\sqrt{34}}\over{\sqrt{65}}}\leqno{\tt (\%o15)
}
938 {{2\,
\sqrt{34}}\over{\sqrt{65}}}\leqno{\tt (\%o16)
}
941 El argumento de un número complejo se calcula con la función
\verb|carg|
\index{carg
}, que devuelve un ángulo en el intervalo $(-
\pi,
\pi]$,
945 $$
\pi-
\arctan \left(
{{29}\over{37}}\right)
\leqno{\tt (\%o17)
}$$
947 Por último, el conjugado de un número complejo se calcula con la función
\verb|conjugate|
\index{conjugate
}. Como se ve en este ejemplo, el resultado dependerá del formato del argumento, cartesiano o polar,
949 (
%i18) conjugate(%o9); /*forma cartesiana*/
952 -
{{58\,i
}\over{65}}-
{{74}\over{65}}\leqno{\tt (\%o18)
}
955 (
%i19) conjugate(%o12); /*forma polar*/
958 -
{{2\,
\sqrt{34}\,e^
{i\,
\arctan \left(
{{29}\over{37}}\right)
}}\over{
959 \sqrt{65}}}\leqno{\tt (\%o19)
}
965 \section{Combinatoria
}
967 Ya hemos visto el cálculo del factorial de un número natural, bien con el operador
\verb|!|, bien con la función
\verb|factorial|
\index{factorial
}; así podemos calcular el número de permutacions de $n$ elementos, $P_n = n!$,
970 (
%i1) /* permutaciones de 23 elementos */
973 $$
25852016738884976640000\leqno{\tt (\%o1)
}$$
975 Esto nos da el número de ordenaciones diferentes que se pueden hacer con $n$ objetos; si queremos generarlas podemos hacer uso de la función
\verb|permutations|
\index{permutations
},
978 (
%i2) permutations([1,2,3]);
980 $$
\left \
{\left[ 1 ,
2 ,
3 \right] ,
\left[ 1 ,
3 ,
2 \right] ,
981 \left[ 2 ,
1 ,
3 \right] ,
\left[ 2 ,
3 ,
1 \right] ,
\left[ 3 ,
1
982 ,
2 \right] ,
\left[ 3 ,
2 ,
1 \right] \right \
}\leqno{\tt (\%o2)
}$$
984 Cuando se trabaja con factoriales, la función
\verb|minfactorial|
\index{minfactorial
} puede ayudarnos a simplificar algunas expresiones,
989 $$
{{n!
}\over{\left(n+
2\right)!
}}\leqno{\tt (\%o3)
}$$
991 (
%i4) minfactorial (%);
993 $$
{{1}\over{\left(n+
1\right)\,
\left(n+
2\right)
}}\leqno{\tt (\%o4)
}$$
995 El cálculo del número de variaciones con repetición de $m$ elementos tomados de $n$ en $n$, $VR_m^n = m^n$, no necesita de ninguna función especial,
998 (
%i5) /* VR de 17 tomados de 4 en 4 */
1001 $$
83521\leqno{\tt (\%o5)
}$$
1003 Sin embargo, para calcular el número de variaciones sin repetición de $m$ elementos tomados de $n$ en $n$,
1004 $V_m^n = m!/(m-n)!$, debemos hacer uso de la función
\verb|permutation|
\index{permutation
} definida en el módulo
\verb|functs|, que tendremos que cargar en memoria previamente,
1007 (
%i6) load("functs")$
1008 (
%i7) /* V de 17 tomados de 4 en 4 */
1011 $$
57120\leqno{\tt (\%o7)
}$$
1013 Nótese que podemos calcular $P_
{23}$ con esta misma función, sin llamar al factorial,
1016 (
%i8) /* permutaciones de 23 elementos, otra vez */
1019 $$
25852016738884976640000\leqno{\tt (\%o8)
}$$
1021 El número de combinaciones de $m$ elementos tomados de $n$ en $n$, $C_m^n = V_m^n / P_n$, se puede calcular con la función
\verb|binomial|
\index{binomial
},
1024 (
%i9) /* combinaciones de 30 elementos, tomados de 5 en 5 */
1027 $$
142506\leqno{\tt (\%o9)
}$$
1029 El número de permutaciones de $n$ elementos, con repeticiones $a_1,
\ldots, a_k$,
1031 P_n^
{a_1,
\ldots, a_r
} =
\frac{(a_1+
\ldots + a_r)!
}{a_1!
\cdot \ldots \cdot a_r!
},
1033 siendo $a_1+
\ldots + a_r = n$, se calcula con la función
\verb|multinomial_coeff|
\index{multinomial
\_coeff},
1036 (
%i10) /* permutaciones con repetición de 5 elementos,
1037 con repeticiones
2,
2 y
1 */
1038 multinomial_coeff(
2,
2,
1);
1040 $$
30\leqno{\tt (\%o10)
}$$
1042 La función
\verb|stirling1|
\index{stirling1
} calcula el número de Stirling de primera especie, $s(n,k)$, que se define de la forma
1044 (-
1)^
{n-k
} \cdot s(n,k) =
\mbox{Card
} \
{\sigma |
\sigma \mbox{ es permutación de
} \
{1,
\ldots, n\
} \land \sigma \mbox{ tiene
} k
\mbox{ ciclos
}\
}
1048 (
%i11) stirling1(5,2);
1050 $$-
50\leqno{\tt (\%o11)
}$$
1052 Por otro lado, la función
\verb|stirling2|
\index{stirling2
} calcula el número de Stirling de segunda especie, $S(n,k)$, que se define de la forma
1054 S(n,k) =
\mbox{Card
} \
{\pi |
\pi \mbox{ es partición de
} \
{1,
\ldots, n\
} \land \mbox{Card
}(
\pi) = k \
}
1058 (
%i12) stirling2(3,2);
1060 $$
3\leqno{\tt (\%o12)
}$$
1062 Esto es, hay
3 particiones de $\
{1,
2,
3\
}$ formadas por dos subconjuntos, las cuales podemos obtener invocando la función
1063 \verb|set_partitions|
\index{set
\_partitions},
1066 (
%i13) set_partitions ({1,2,3}, 2);
1068 $$
\left \
{\left \
{\left \
{1 \right \
} ,
\left \
{2 ,
3 \right \
}
1069 \right \
} ,
\left \
{\left \
{1 ,
2 \right \
} ,
\left \
{3 \right \
}
1070 \right \
} ,
\left \
{\left \
{1 ,
3 \right \
} ,
\left \
{2 \right \
}
1071 \right \
} \right \
}\leqno{\tt (\%o13)
}$$
1073 El número de Bell, que calculamos con la función
\verb|belln|
\index{belln
} es el número total de particiones que admite un conjunto finito,
1075 B(n) =
\sum_{k=
1}^
{n
} S(n,k).
1079 (
%i14) /* número de particiones en un conjunto de cardinalidad 3 */
1082 $$
5\leqno{\tt (\%o14)
}$$
1084 En relación con la combinatoria, véanse también las secciones
\ref{conjuntos
} y
\ref{grafos
}, sobre conjuntos y grafos, respectivamente.
1095 \chapter{Estructuras de datos
}
1103 Las listas son objetos muy potentes a la hora de representar estructuras de datos; de hecho, toda expresión de Maxima se representa internamente como una lista, lo que no es de extrañar habida cuenta de que Maxima está programado en Lisp (
\emph{List Processing
}). Veamos cómo podemos ver la representación interna, esto es en Lisp, de una sencilla expresión tal como $
1+
3a$,
1104 \index{31@:lisp
}\begin{Verbatim
}
1105 (
%i1) ?print(1+3*a)$
1106 ((MPLUS SIMP)
1 ((MTIMES SIMP)
3 $A))
1109 Pero al nivel del usuario que no está interesado en las interioridades de Maxima, también se puede trabajar con listas como las definidas a continuación, siempre encerradas entre corchetes,
1110 \index{34@
[...
]}\index{32@``...''
}\begin{Verbatim
}
1111 (
%i2) r:[1,[a,3],sqrt(3)/2,"Don Quijote"];
1114 \left[ 1 ,
\left[ a ,
3 \right] ,
{{\sqrt{3}}\over{2}} ,
1115 \mbox{{}Don Quijote
{}} \right] \leqno{\tt (\%o2)
}
1118 Vemos que los elementos de una lista pueden a su vez ser también listas, expresiones matemáticas o cadenas de caracteres incluidas entre comillas dobles, lo que puede ser aprovechado para la construcción y manipulación de estructuras más o menos complejas. Extraigamos a continuación alguna información de las listas anteriores,
1119 \index{listp
}\index{first
}\index{second
}\index{third
}\index{last
}\index{rest
}\index{part
}\index{length
}\index{reverse
}\index{member
}\index{sort
}\index{delete
}\begin{Verbatim
}
1120 (
%i3) listp(r); /* es r una lista? */
1123 \mathrm{true
}\leqno{\tt (\%o3)
}
1126 (
%i4) first(r); /* primer elemento */
1132 (
%i5) second(r); /* segundo elemento */
1135 \left[ a ,
3 \right] \leqno{\tt (\%o5)
}
1138 (
%i6) third(r); /* ...hasta tenth */
1141 {{\sqrt{3}}\over{2}}\leqno{\tt (\%o6)
}
1144 (
%i7) last(r); /* el último de la lista */
1147 \mbox{{}Don Quijote
{}}\leqno{\tt (\%o7)
}
1150 (
%i8) rest(r); /* todos menos el primero */
1153 \left[ \left[ a ,
3 \right] ,
{{\sqrt{3}}\over{2}} ,
1154 \mbox{{}Don Quijote
{}} \right] \leqno{\tt (\%o8)
}
1157 (
%i9) part(r,3); /* pido el que quiero */
1160 {{\sqrt{3}}\over{2}}\leqno{\tt (\%o9)
}
1163 (
%i10) length(r); /* ¿cuántos hay? */
1166 4\leqno{\tt (\%o10)
}
1169 (
%i11) reverse(r); /* le damos la vuelta */
1172 \left[ \mbox{{}Don Quijote
{}} ,
{{\sqrt{3}}\over{2}} ,
\left[ a ,
3
1173 \right] ,
1 \right] \leqno{\tt (\%o11)
}
1176 (
%i12) member(a,r); /* ¿es a un elemento?*/
1179 \mathrm{false
}\leqno{\tt (\%o12)
}
1182 (
%i13) member([a,3],r); /* ¿lo es [a,3]? */
1185 \mathrm{true
}\leqno{\tt (\%o13)
}
1188 (
%i14) /* asigno valor a q y ordeno */
1189 sort(q:
[7,a,
1,d,
5,
3,b
]);
1192 \left[ 1 ,
3 ,
5 ,
7 , a , b , d
\right] \leqno{\tt (\%o14)
}
1195 (
%i15) delete([a,3],r); /* borro elemento */
1198 \left[ 1 ,
{{\sqrt{3}}\over{2}} ,
\mbox{{}Don Quijote
{}} \right] \leqno{\tt (\%o15)
}
1200 Nótese que en todo este tiempo la lista
\verb|r| no se ha visto alterada,
1205 \left[ 1 ,
\left[ a ,
3 \right] ,
{{\sqrt{3}}\over{2}} ,
1206 \mbox{{}Don Quijote
{}} \right] \leqno{\tt (\%o16)
}
1209 Algunas funciones de Maxima permiten añadir nuevos elementos a una lista, tanto al principio como al final,
1210 \index{cons
}\index{endcons
}\begin{Verbatim
}
1214 \left[ 3 ,
7 , a ,
1 , d ,
5 ,
3 , b
\right] \leqno{\tt (\%o17)
}
1217 (
%i18) endcons(x,q);
1220 \left[ 7 , a ,
1 , d ,
5 ,
3 , b , x
\right] \leqno{\tt (\%o18)
}
1226 \left[ 7 , a ,
1 , d ,
5 ,
3 , b
\right] \leqno{\tt (\%o19)
}
1229 En este ejemplo hemos observado también que la lista
\verb|q| no ha cambiado. Si lo que queremos es actualizar su contenido,
1231 (
%i20) q: endcons(x,cons(1+2,q))$
1235 \left[ 3 ,
7 , a ,
1 , d ,
5 ,
3 , b , x
\right] \leqno{\tt (\%o21)
}
1238 Es posible unir dos listas,
1239 \index{append
}\begin{Verbatim
}
1243 \left[ 1 ,
\left[ a ,
3 \right] ,
{{\sqrt{3}}\over{2}} ,
1244 \mbox{{}Don Quijote
{}} ,
3 ,
7 , a ,
1 , d ,
5 ,
3 , b , x
\right] \leqno{\tt (\%o22)
}
1247 Cuando los elementos de una lista van a obedecer un cierto criterio de construcción, podemos utilizar la función
\verb|makelist|
\index{makelist
} para construirla,
1249 (
%i23) s:makelist(2+k*2,k,0,10);
1252 \left[ 2 ,
4 ,
6 ,
8 ,
10 ,
12 ,
14 ,
16 ,
18 ,
20 ,
22 \right] \leqno{\tt (\%o23)
}
1254 donde le hemos indicado a Maxima que nos construya una lista con elementos de la forma
\verb|
2+
2*k|, de modo que
\verb|k| tome valores enteros de
0 a
10.
1256 La función
\verb|apply|
\index{apply
} permite suministrar a otra función todos los elementos de una lista como argumentos, así podemos sumar o multiplicar todos los elementos de la lista
\verb|s| recién creada,
1257 \index{14@+
}\index{16@*
}\begin{Verbatim
}
1258 (
%i24) apply("+",s);
1261 132\leqno{\tt (\%o24)
}
1264 (
%i25) apply("*",s);
1267 81749606400\leqno{\tt (\%o25)
}
1269 aunque estas dos operaciones hubiese sido quizás más apropiado haberlas realizado con las funciones
\verb|sum|
\index{sum
} y
\verb|product|
\index{product
}.
1271 A veces interesará aplicar una misma función a varios elementos de una lista de forma independiente, para lo que haremos uso de
\verb|map|
\index{map
}. A continuación un ejemplo de cálculo de factoriales y otro trigonométrico; en este último, no es necesario aplicar
\verb|map|, ya que algunas funciones se distribuyen automáticamente sobre los elementos de una lista,
1277 \left[ 2 ,
24 ,
720 ,
40320 ,
3628800 ,
479001600 ,
87178291200 ,
20922789888000 ,
\right.\\
1278 \left.
6402373705728000 ,
2432902008176640000 ,
1124000727777607680000
1279 \right]\end{array
} \leqno{\tt (\%o26)
}
1285 \left[ \sin 2 ,
\sin 4 ,
\sin 6 ,
\sin 8 ,
\sin 10 ,
\sin 12 ,
1286 \sin 14 ,
\sin 16 ,
\sin 18 ,
\sin 20 ,
\sin 22 \right] \leqno{\tt (\%o27)
}
1289 A veces se quiere utilizar en
\verb|map| una función que no está definida y que no va a ser utilizada más que en esta llamada a
\verb|map|. En tales casos se puede hacer uso de las funciones
\emph{lambda
}\index{lambda
}; supóngase que a cada elemento $x$ de una lista se le quiere aplicar la función $f(x)=
\sin(x) +
\frac{1}{2}$, sin necesidad de haberla definido previamente,
1292 (
%i28) map(lambda([x], sin(x) + 1/2),[7,3,4,9]);
1295 \left[ \sin 7+
{{1}\over{2}} ,
\sin 3+
{{1}\over{2}} ,
\sin 4+
{{1
1296 }\over{2}} ,
\sin 9+
{{1}\over{2}} \right] \leqno{\tt (\%o28)
}
1299 Como se ve, la función
\emph{lambda
} admite dos argumentos; el primero es una lista (no se puede evitar la redundancia)
1300 de argumentos, siendo el segundo la expresión que indica qué se hace con los elementos de la lista anterior.
1303 Por último, las listas también pueden ser utilizadas en operaciones aritméticas. Algunas de las operaciones que se aplican a continuación no están definidas matemáticamente, por lo que Maxima se toma la libertad de definirlas por su cuenta, lo que redunda en un ahorro de código por parte del usuario y en un estilo de programación más compacto,
1304 \index{14@+
}\index{15@-
}\index{16@*
}\index{17@/
}\index{18@\^\
}\index{21@.
}\begin{Verbatim
}
1305 (
%i29) [1,2,3]+[a,b,c];
1308 \left[ a+
1 , b+
2 , c+
3 \right] \leqno{\tt (\%o29)
}
1311 (
%i30) [1,2,3]*[a,b,c];
1314 \left[ a ,
2\,b ,
3\,c
\right] \leqno{\tt (\%o30)
}
1317 (
%i31) [1,2,3]/[a,b,c];
1320 \left[ {{1}\over{a
}} ,
{{2}\over{b
}} ,
{{3}\over{c
}} \right] \leqno{\tt (\%o31)
}
1323 (
%i32) [1,2,3]-[a,b,c];
1326 \left[ 1-a ,
2-b ,
3-c
\right] \leqno{\tt (\%o32)
}
1329 (
%i33) [1,2,3].[a,b,c]; /* producto escalar */
1332 3\,c+
2\,b+a
\leqno{\tt (\%o33)
}
1338 \left[ a^
3 , b^
3 , c^
3 \right] \leqno{\tt (\%o34)
}
1344 \left[ 3^
{a
} ,
3^
{b
} ,
3^
{c
} \right] \leqno{\tt (\%o35)
}
1347 En Maxima, las listas se pueden interpretar como vectores; para más información, acúdase a la Sección~
\ref{vectores
}.
1349 Para que estas operaciones puedan realizarse sin problemas, la variable global
\verb|listarith|
\index{listarith
} debe tomar el valor
\verb|true|, en caso contrario el resultado será bien distinto,
1351 (
%i36) listarith:false$
1352 (
%i37) [1,2,3]+[4,5,6];
1355 \left[ 4 ,
5 ,
6 \right] +
\left[ 1 ,
2 ,
3 \right] \leqno{\tt (\%o37)
}
1358 (
%i38) listarith:true$
1361 Como ya se vió al comienzo de esta sección, una lista puede ser elemento de otra lista, si queremos deshacer todas las listas interiores para que sus elementos pasen a formar parte de la exterior,
1362 \index{flatten
}\begin{Verbatim
}
1363 (
%i39) flatten([1,[a,b],2,3,[c,[d,e]]]);
1366 \left[ 1 , a , b ,
2 ,
3 , c , d , e
\right] \leqno{\tt (\%o39)
}
1369 El cálculo del módulo de un vector se puede hacer mediante la definición previa de una función al efecto:
1374 then sqrt(apply("+",v^
2))
1375 else error("Mucho ojito: ", v, " no es un vector !!!!")$
1376 (
%i41) xx:[a,b,c,d,e]$
1377 (
%i42) yy:[3,4,-6,0,4/5]$
1378 (
%i43) modulo(xx-yy);
1381 \sqrt{\left(e-
{{4}\over{5}}\right)^
2+d^
2+
\left(c+
6\right)^
2+
\left(b
1382 -
4\right)^
2+
\left(a-
3\right)^
2}\leqno{\tt (\%o43)
}
1395 Los arrays son estructuras que almacenan datos secuencial o matricialmente. Se diferencian de las listas en que éstas pueden alterar su estructura interna y los arrays no; pero la ventaja frente a las listas estriba en que el acceso a un dato cualquiera es directo, mientras que en las listas, al ser estructuras dinámicas, para acceder al $n$-ésimo dato, un puntero debe recorrer todos los elementos de la lista desde el que ocupa el primer lugar. Así pues, se recomienda el uso de arrays cuando se vaya a utilizar una secuencia larga de expresiones cuya estructura se va a mantener inalterable; en general, se mejorarán los tiempos de procesamiento.
1397 Si queremos construir un array, lo debemos declarar previamente mediante la función
\verb|array|
\index{array
}, indicando su nombre y dimensiones; a continuación le asignaríamos valores a sus elementos,
1399 (
%i1) array(arreglillo,2,2);
1402 {\it arreglillo
}\leqno{\tt (\%o1)
}
1405 (
%i2) arreglillo[0,0]: 34$
1406 (
%i3) arreglillo[1,2]:x+y$
1407 (
%i4) arreglillo[2,2]:float(%pi)$
1408 (
%i5) listarray(arreglillo);
1412 \left[ 34 ,
{\it \#\#\#\#\#
} ,
{\it \#\#\#\#\#
} ,
{\it \#\#\#\#\#
} ,
{\it \#\#\#\#\#
} ,
\right. \\
1413 \left. y+x ,
{\it \#\#\#\#\#
} ,
{\it \#\#\#\#\#
} ,
3.141592653589793 \right] \end{array
} \leqno{\tt (\%o5)
}
1416 En el ejemplo, hemos definido un array de dimensiones
3 por
3, ya que la indexación de los arrays comienza por el cero, no por el uno como en el caso de las listas; a continuación hemos asignado valores a tres elementos del array: un entero, una expresión simbólica y un número decimal en coma flotante. Finalmente, la función
\verb|listarray|
\index{listarray
} nos permite ver el contenido del array, utilizando el símbolo
\verb|#####| para aquellos elementos a los que aún no se les ha asignado valor alguno.
1418 Si ya se sabe de antemano que el array va a contener únicamente números enteros o números decimales, podemos declararlo al definirlo para que Maxima optimice el procesamiento de los datos. A continuación se declara un array de números enteros haciendo uso del símbolo
\verb|fixnum|
\index{fixnum
} (en el caso de números decimales en coma flotante se utilizaría
\verb|flonum|
\index{flonum
}) y a continuación la función
\verb|fillarray|
\index{fillarray
} rellenará el array con los elementos previamente almacenados en una lista,
1420 (
%i6) lis: [6,0,-4,456,56,-99];
1423 \left[ 6 ,
0 , -
4 ,
456 ,
56 , -
99 \right] \leqno{\tt (\%o6)
}
1426 (
%i7) array(arr,fixnum,5);
1429 {\it arr
}\leqno{\tt (\%o7)
}
1432 (
%i8) fillarray(arr,lis);
1435 {\it arr
}\leqno{\tt (\%o8)
}
1441 56\leqno{\tt (\%o9)
}
1444 (
%i10) listarray(arr);
1447 \left[ 6 ,
0 , -
4 ,
456 ,
56 , -
99 \right] \leqno{\tt (\%o10)
}
1450 Hasta ahora hemos hecho uso de los llamados array declarados. Si no hacemos la declaración pertinente mediante la función
\verb|array|, y en su lugar realizamos asignaciones directas a los elementos de la estructura, creamos lo que se conoce como array de claves (
\emph{hash array
}) o, en la terminología de Maxima, array no declarado; estos arrays son mucho más generales que los declarados, puesto que pueden ir creciendo de forma dinámica y los índices no tienen que ser necesariamente números enteros,
1455 76\leqno{\tt (\%o11)
}
1458 (
%i12) tab[-58]:2/9;
1461 {{2}\over{9}}\leqno{\tt (\%o12)
}
1464 (
%i13) tab[juan]:sqrt(8);
1467 2^
{{{3}\over{2}}}\leqno{\tt (\%o13)
}
1470 (
%i14) tab["cadena"]: a-b;
1473 a-b
\leqno{\tt (\%o14)
}
1479 5\leqno{\tt (\%o15)
}
1482 (
%i16) listarray(tab);
1485 \left[ {{2}\over{9}} ,
76 , a-b ,
2^
{{{3}\over{2}}} ,
5 \right] \leqno{\tt (\%o16)
}
1488 (
%i17) tab["cadena"];
1491 a-b
\leqno{\tt (\%o17)
}
1493 Esta generalidad en la estructura de los arrays no declarados tiene la contrapartida de restarle eficiencia en el procesamiento de los datos almacenados, siendo preferible, siempre que sea posible, la utilización de los declarados.
1495 Ya por último, junto con los arrays declarados y no declarados mencionados, es posible trabajar a nivel de Maxima con arrays de Lisp. En este caso su construcción se materializa con la función
\verb|make_array|
\index{make
\_array},
1497 (
%i18) a: make_array(flonum,5);
1500 \left\
{ {\it Array
}: \#
\left(
0.0 \;\;
0.0 \;\;
0.0 \;\;
0.0 \;\;
0.0\right)
\right\
} \leqno{\tt (\%o18)
}
1506 3.4\leqno{\tt (\%o19)
}
1512 6.89\leqno{\tt (\%o20)
}
1518 \left\
{ {\it Array
}: \#
\left(
3.4 \;\;
0.0 \;\;
0.0 \;\;
0.0 \;\;
6.89\right)
\right\
} \leqno{\tt (\%o21)
}
1521 Nótense aquí un par de diferencias respecto de la función
\verb|array|: el número
5 indica el número de elementos (indexados de
0 a
4) y no el índice máximo admisible; por otro lado, la función no devuelve el nombre del objeto array, sino el propio objeto.
1533 Una cadena se construye escribiendo un texto o cualquier otra expresión entre comillas dobles. Vamos a hacer algunos ejemplos básicos,
1538 \mbox{{}Los
{}}\leqno{\tt (\%o1)
}
1541 (
%i2) yy: " cerditos";
1544 \mbox{{} cerditos
{}}\leqno{\tt (\%o2)
}
1547 (
%i3) zz: concat(xx,sqrt(9),yy);
1550 \mbox{{}Los
3 cerditos
{}}\leqno{\tt (\%o3)
}
1552 la función
\verb|concat|
\index{concat
} admite varios parámetros, los cuales evalúa y luego concatena convirtiéndolos en una cadena.
1554 La función
\verb|stringp|
\index{stringp
} nos indica si su argumento es o no una cadena,
1559 \mathrm{true
}\leqno{\tt (\%o4)
}
1562 Para saber el número de caracteres de una cadena haremos uso de
\verb|slength|
\index{slength
}
1567 14\leqno{\tt (\%o5)
}
1570 Una vez transformada en cadena una expresión de Maxima, deja de ser evaluable,
1572 (
%i6) concat(sqrt(25));
1575 \mbox{{}5{}}\leqno{\tt (\%o6)
}
1581 \mbox{{}5{}}+
2\leqno{\tt (\%o7)
}
1587 \mathrm{false
}\leqno{\tt (\%o8)
}
1589 el resultado no se simplifica porque uno de los sumandos es una cadena y no se reconoce como cantidad numérica.
1591 La función
\verb|charat|
\index{charat
} devuelve el carácter que ocupa una posición determinada,
1596 \mbox{{}c
{}}\leqno{\tt (\%o9)
}
1599 También podemos solicitar que Maxima nos devuelva una lista con todos los caracteres o palabras que forman una cadena,
1600 \index{charlist
}\index{tokens
}
1602 (
%i10) charlist(zz);
1605 \left[ \mbox{{}L
{}} ,
\mbox{{}o
{}} ,
\mbox{{}s
{}} ,
\mbox{{} {}} ,
1606 \mbox{{}3{}} ,
\mbox{{} {}} ,
\mbox{{}c
{}} ,
\mbox{{}e
{}} ,
1607 \mbox{{}r
{}} ,
\mbox{{}d
{}} ,
\mbox{{}i
{}} ,
\mbox{{}t
{}} ,
1608 \mbox{{}o
{}} ,
\mbox{{}s
{}} \right] \leqno{\tt (\%o10)
}
1614 \left[ \mbox{{}Los
{}} ,
\mbox{{}3{}} ,
\mbox{{}cerditos
{}} \right] \leqno{\tt (\%o11)
}
1617 O podemos transformar letras minúsculas en mayúsculas y viceversa, todas las letras o sólo un rango de ellas,
1618 \index{supcase
}\index{sdowncase
}
1620 (
%i12) /* todo a mayúsculas */
1624 \mbox{{}LOS
3 CERDITOS
{}}\leqno{\tt (\%o12)
}
1627 (
%i13) /* a minúsculas entre la 9a y 12a */
1631 \mbox{{}LOS
3 CErdiTOS
{}}\leqno{\tt (\%o13)
}
1634 (
%i14) /* a minúsculas de la 13a hasta el final */
1638 \mbox{{}LOS
3 CErdiTos
{}}\leqno{\tt (\%o14)
}
1641 (
%i15) /* todo a minúsculas */
1645 \mbox{{}los
3 cerditos
{}}\leqno{\tt (\%o72)
}
1648 (
%i16) /* a mayúsculas entre la 1a y 2a */
1652 \mbox{{}Los
3 cerditos
{}}\leqno{\tt (\%o74)
}
1655 Para comparar si dos cadenas son iguales disponemos de la función
\verb|sequal|
\index{sequal
},
1660 \mbox{{}Los
3 cerditos
{}}\leqno{\tt (\%o17)
}
1663 (
%i18) sequal(tt,zz);
1666 \mathrm{true
}\leqno{\tt (\%o18)
}
1669 (
%i19) tt: supcase(zz);
1672 \mbox{{}LOS
3 CERDITOS
{}}\leqno{\tt (\%o19)
}
1675 (
%i20) sequal(tt,zz);
1678 \mathrm{false
}\leqno{\tt (\%o20)
}
1681 Podemos buscar subcadenas dentro de otras cadenas mediante la función
\verb|ssearch|
\index{ssearch
}; los siguientes ejemplos pretenden aclarar su uso,
1686 \mbox{{}Los
3 cerditos
{}}\leqno{\tt (\%o21)
}
1689 (
%i22) /* busca la subcadena "cer" */
1693 7\leqno{\tt (\%o22)
}
1696 (
%i23) /* busca la subcadena "Cer" */
1700 \mathrm{false
}\leqno{\tt (\%o23)
}
1703 (
%i24) /* busca "Cer" ignorando tamaño */
1704 ssearch("Cer",zz,'sequalignore);
1707 7\leqno{\tt (\%o24)
}
1710 (
%i25) /* busca sólo entre caracteres 1 y 5 */
1711 ssearch("Cer",zz,'sequalignore,
1,
5);
1714 \mathrm{false
}\leqno{\tt (\%o25)
}
1717 Igual que buscamos subcadenas dentro de otra cadena, también podemos hacer sustituciones; en este caso la función a utilizar es
\verb|ssubst|
\index{ssubst
},
1719 (
%i26) ssubst("mosqueteros","cerditos",zz);
1722 \mbox{{}Los
3 mosqueteros
{}}\leqno{\tt (\%o26)
}
1725 Esta función tiene como mínimo tres argumentos, el primero indica la nueva cadena a introducir, el segundo es la subcadena a ser sustituída y el tercero la cadena en la que hay que realizar la sustitución. Es posible utilizar esta función con más argumentos; como siempre, para más información,
\verb|? ssubst|.
1727 Con la función
\verb|substring|
\index{substring
} podemos obtener una subcadena a partir de otra, para lo cual debemos indicar los extremos de la subcadena,
1729 (
%i27) substring(zz,7);
1732 \mbox{{}cerditos
{}}\leqno{\tt (\%o27)
}
1735 (
%i28) substring(zz,3,8);
1738 \mbox{{}s
3 c
{}}\leqno{\tt (\%o28)
}
1741 Como se ve, el segundo argumento indica la posición a partir de la cual queremos la subcadena y el tercero la última posición; si no se incluye el tercer argumento, se entiende que la subcadena se extiende hasta el final de la de referencia.
1743 En algunos contextos el usuario tiene almacenada una expresión sintácticamente correcta de Maxima en formato de cadena y pretende evaluarla, en cuyo caso la función
\verb|eval_string|
\index{eval
\_string} la analizará y evaluará, en tanto que
\verb|parse_string|
\index{parse
\_string} la analiza pero no la evalúa, limitándose a transformarla a una expresión nominal de Maxima,
1745 (
%i29) /* una cadena con una expresión de Maxima */
1746 expr: "integrate(x^
5,x)";
1749 % \mbox{{}integrate(x^5,x){}} \leqno{\tt (\%o29)}
1750 \mbox{{}integrate(x\^
{}5,x)
{}} \leqno{\tt (\%o29)
}
1753 (
%i30) /* se evalúa la cadena */
1757 {{x^
6}\over{6}}\leqno{\tt (\%o30)
}
1760 (
%i31) /* se transforma en una expresión nominal */
1764 {\it integrate
}\left(x^
5 , x
\right)
\leqno{\tt (\%o31)
}
1770 {{x^
6}\over{6}}\leqno{\tt (\%o32)
}
1773 Véase que el resultado de
\verb|parse_string| ya no es una cadena, sino una expresión correcta de Maxima sin evaluar, cuya evaluación se solicita a continuación con la doble comilla simple.
1775 Para más información sobre el procesamiento de cadenas de texto, se sugiere la lectura del capítulo
\verb|stringproc| del manual de referencia.
1786 Se define a continuación un conjunto mediante la función
\verb|set|
\index{set
},
1788 (
%i1) c1:set(a,[2,k],b,sqrt(2),a,set(a,b),
1789 3,"Sancho",set(),b,sqrt(
2),a);
1792 \left \
{3 ,
\sqrt{2} ,
\left \
{ \right \
} ,
\left[ 2 , k
\right]
1793 ,
\mbox{{}Sancho
{}} , a ,
\left \
{a , b
\right \
} , b
\right \
}\leqno{\tt (\%o1)
}
1796 Como se ve, se admiten objetos de muy diversa naturaleza como elementos de un conjunto: números, expresiones, el conjunto vacío (
\verb|
{}|), listas, otros conjuntos o cadenas de caracteres. Se habrá observado que al construir un conjunto se eliminan las repeticiones de elementos, cual es el caso del símbolo $a$ en la lista anterior.
1798 Cuando se trabaja con listas, puede ser de utilidad considerar sus componentes como elementos de un conjunto, luego se necesita una función que nos transforme una lista en conjunto,
1799 \index{setify
}\begin{Verbatim
}
1800 (
%i2) [[2,k],sqrt(2),set(b,a),[k,2],"Panza"];
1803 \left[ \left[ 2 , k
\right] ,
\sqrt{2} ,
\left \
{a , b
\right \
}
1804 ,
\left[ k ,
2 \right] ,
\mbox{{}Panza
{}} \right] \leqno{\tt (\%o2)
}
1810 \left \
{\sqrt{2} ,
\left[ 2 , k
\right] ,
\mbox{{}Panza
{}} ,
1811 \left \
{a , b
\right \
} ,
\left[ k ,
2 \right] \right \
}\leqno{\tt (\%o3)
}
1813 el cambio en la naturaleza de estas dos colecciones de objetos se aprecia en la presencia de llaves en lugar de corchetes. De igual manera, podemos transformar un conjunto en lista,
1814 \index{listify
}\begin{Verbatim
}
1818 \left[ 3 ,
\sqrt{2} ,
\left \
{ \right \
} ,
\left[ 2 , k
\right] ,
1819 \mbox{{}Sancho
{}} , a ,
\left \
{a , b
\right \
} , b
\right] \leqno{\tt (\%o4)
}
1822 Comprobemos de paso que
\verb|
{}| representa al conjunto vacío,
1823 \index{emptyp
}\begin{Verbatim
}
1827 \mathrm{true
}\leqno{\tt (\%o5)
}
1830 Recuérdese que
\verb|
%| sustituye a la última respuesta dada por Maxima, que en este caso había sido una lista, por lo que \verb|%[3]| hace referencia a su tercera componente.
1832 Para comprobar si un cierto objeto forma parte de un conjunto hacemos uso de la instrucción
\verb|elementp|
\index{elementp
},
1834 (
%i6) elementp(sqrt(2),c1);
1837 \mathrm{true
}\leqno{\tt (\%o6)
}
1840 Es posible extraer un elemento de un conjunto y luego añadirle otro distinto
1841 \index{disjoin
}\index{adjoion
}\begin{Verbatim
}
1842 (
%i7) c1: disjoin(sqrt(2),c1); /* sqrt(2) fuera */
1845 \left \
{3 ,
\left \
{ \right \
} ,
\left[ 2 , k
\right] ,
1846 \mbox{{}Sancho
{}} , a ,
\left \
{a , b
\right \
} , b
\right \
}\leqno{\tt (\%o7)
}
1849 (
%i8) c1: adjoin(sqrt(3),c1); /* sqrt(3) dentro */
1852 \left \
{3 ,
\sqrt{3} ,
\left \
{ \right \
} ,
\left[ 2 , k
\right]
1853 ,
\mbox{{}Sancho
{}} , a ,
\left \
{a , b
\right \
} , b
\right \
}\leqno{\tt (\%o8)
}
1856 La sustitución que se acaba de realizar se pudo haber hecho con la función
\verb|subst|
\index{subst
},
1858 (
%i9) /* nuevamente a poner sqrt(2) */
1859 subst(sqrt(
2),sqrt(
3),c1);
1862 \left \
{3 ,
\sqrt{2} ,
\left \
{ \right \
} ,
\left[ 2 , k
\right]
1863 ,
\mbox{{}Sancho
{}} , a ,
\left \
{a , b
\right \
} , b
\right \
}\leqno{\tt (\%o9)
}
1866 La comprobación de si un conjunto es subconjunto de otro se hace con la fución
\verb|subsetp|
\index{subsetp
},
1868 (
%i10) subsetp(set([k,2],"Panza"),c2);
1871 \mathrm{true
}\leqno{\tt (\%o10)
}
1874 A continuación algunos ejemplos de operaciones con conjuntos,
1875 \index{union
}\index{intersection
}\index{setdifference
}\index{cardinality
}\begin{Verbatim
}
1876 (
%i11) union(c1,c2);
1879 \left \
{3 ,
\sqrt{2} ,
\sqrt{3} ,
\left \
{ \right \
} ,
\left[ 2 , k
1880 \right] ,
\mbox{{}Panza
{}} ,
\mbox{{}Sancho
{}} , a ,
\left \
{a , b
1881 \right \
} , b ,
\left[ k ,
2 \right] \right \
}\leqno{\tt (\%o11)
}
1884 (
%i12) intersection(c1,c2);
1887 \left \
{\left[ 2 , k
\right] ,
\left \
{a , b
\right \
} \right \
}\leqno{\tt (\%o12)
}
1890 (
%i13) setdifference(c1,c2);
1893 \left \
{3 ,
\sqrt{3} ,
\left \
{ \right \
} ,
\mbox{{}Sancho
{}} , a
1894 , b
\right \
}\leqno{\tt (\%o13)
}
1897 (
%i14) cardinality(%);
1900 6\leqno{\tt (\%o14)
}
1903 Vemos aquí también cómo pedir el cardinal de un conjunto.
1905 Igual que se ha visto cómo aplicar una función a todos los elementos de una lista, podemos hacer lo mismo con los de un conjunto,
1906 \index{map
}\begin{Verbatim
}
1907 (
%i15) map(sin,set(1,2,3,4,5));
1910 \left \
{\sin 1 ,
\sin 2 ,
\sin 3 ,
\sin 4 ,
\sin 5 \right \
}\leqno{\tt (\%o15)
}
1913 Por último ya, el producto cartesiano de tres conjuntos,
1914 \index{cartesianproduct@cartesian
\_product}\begin{Verbatim
}
1915 (
%i16) cartesian_product(set(1,2),set(a,b,c),set(x,y));
1919 \left \
{\left[ 1 , a , x
\right] ,
\left[ 1 , a , y
\right] ,
1920 \left[ 1 , b , x
\right] ,
\left[ 1 , b , y
\right] ,
\left[ 1 , c
1921 , x
\right] ,
\left[ 1 , c , y
\right] ,
\right.\\
1922 \left.
\left[ 2 , a , x
\right] ,
\left[ 2 , a , y
\right] ,
\left[ 2 , b , x
\right] ,
1923 \left[ 2 , b , y
\right] ,
\left[ 2 , c , x
\right] ,
\left[ 2 , c
1924 , y
\right] \right \
}\end{array
} \leqno{\tt (\%o16)
}
1927 Ya por último, el conjunto de las partes de un conjunto, o conjunto potencia, lo podemos obtener con la función
\verb|powerset|
\index{powerset
}
1930 (
%i17) powerset({1,a,sqrt(2)});
1932 $$
\left \
{\left \
{ \right \
} ,
\left \
{1 \right \
} ,
\left \
{1 ,
1933 \sqrt{2} \right \
} ,
\left \
{1 ,
\sqrt{2} , a
\right \
} ,
\left \
{1
1934 , a
\right \
} ,
\left \
{\sqrt{2} \right \
} ,
\left \
{\sqrt{2} , a
1935 \right \
} ,
\left \
{a
\right \
} \right \
}\leqno{\tt (\%o17)
}$$
1944 El soporte para el desarrollo de algoritmos en el ámbito de la teoría de grafos se encuentra en el módulo
\verb|graphs|
\index{graphs
}. Se trata de un paquete de funciones que aporta la infraestructura básica para el trabajo con grafos, orientados o no. No se admiten bucles ni aristas múltiples.
1946 \index{create
\_graph}\begin{Verbatim
}
1948 (
%i2) g: create_graph(
1950 [ [1,
2],
[2,
3],
[2,
4],
[3,
4],
1951 [4,
5],
[5,
6],
[4,
6],
[6,
7] ]);
1954 \mbox{GRAPH
}\leqno{\tt (\%o2)
}
1957 Como vemos, la respuesta de la función
\verb|create_graph| no es muy informativa, pero nos podemos hacer una idea de la estructura del grafo haciendo
1959 \index{print
\_graph}\begin{Verbatim
}
1960 (
%i3) print_graph(g)$
1962 Graph on
7 vertices with
8 edges.
1973 Vemos que, por ejemplo, el vértice número
3 comparte aristas (no orientadas) con los vértices
4 y
2.
1975 En caso de que el grafo anterior fuese orientado (digrafo) su definición sería:
1978 (
%i4) dg: create_graph(
1980 [ [1,
2],
[2,
3],
[2,
4],
[3,
4],
1981 [4,
5],
[5,
6],
[4,
6],
[6,
7] ],
1983 (
%i5) print_graph(dg)$
1985 Digraph on
7 vertices with
8 arcs.
1996 En este caso,
\verb|print_graph| nos muestra los nodos hijos a la derecha de los padres. En particular, el nodo
7 no es origen de ningún arco, pero es hijo del nodo
6. Otra manera alternativa de mostrar la estructura de un grafo es mediante la función
\verb|draw_graph|
1998 \index{draw
\_graph}\begin{Verbatim
}
1999 (
%i6) draw_graph(g, show_id=true, terminal=eps)$
2000 (
%i7) draw_graph(dg, show_id=true, head_length=0.05, terminal=eps)$
2003 Cuyos aspectos se pueden observar en los apartados
\emph{a)
} y
\emph{b)
} de la Figura~
\ref{fig:graph
}.
2007 \includegraphics[scale=
0.50]{graph1.pdf
}
2008 \includegraphics[scale=
0.50]{graph2.pdf
} \\
2009 \emph{a)
} \hspace{6.5cm
} \emph{b)
} \\
2010 \includegraphics[scale=
0.50]{graph3.pdf
}
2011 \includegraphics[scale=
0.50]{graph4.pdf
} \\
2012 \emph{c)
} \hspace{6.5cm
} \emph{d)
} \\
2013 \caption{Grafos:
\emph{a)
} no orientado;
\emph{b)
} orientado;
\emph{c)
} complemetario del no orientado;
\emph{d)
} camino más corto.
}
2018 Continuemos con el grafo no orientado
\verb|g| definido más arriba y veamos cómo extraer de él cierta información: el número cromático, matriz de adyacencia, grafo complementario, si es conexo, o planar, su diámetro, etc.
2020 \index{chromatic
\_number}\begin{Verbatim
}
2021 (
%i8) chromatic_number(g);
2027 \index{adjacency
\_matrix}\begin{Verbatim
}
2028 (
%i9) adjacency_matrix(g);
2031 \begin{pmatrix
}0&
1&
0&
0&
0&
0&
0\cr 1&
0&
1&
1&
0&
0&
0\cr 0&
1&
0&
1&
0&
0&
0\cr 0&
1&
1&
0
2032 &
1&
1&
0\cr 0&
0&
0&
1&
0&
1&
0\cr 0&
0&
0&
1&
1&
0&
1\cr 0&
0&
0&
0&
0&
1&
0\cr \end{pmatrix
} \leqno{\tt (\%o9)
}
2035 \index{complement
\_graph}\begin{Verbatim
}
2036 (
%i10) gc:complement_graph(g);
2039 \mbox{GRAPH
}\leqno{\tt (\%o10)
}
2043 (
%i11) print_graph(%)$
2045 Graph on
7 vertices with
13 edges.
2056 Pedimos ahora a Maxima que nos represente gráficamente el complementario de
\verb|g|, cuyo aspecto es el del apartado
\emph{c)
} de la Figura~
\ref{fig:graph
}.
2059 (
%i12) draw_graph(gc, show_id=true, terminal=eps)$
2062 Continuamos con algunas otras propiedades:
2064 \index{is
\_connected}\begin{Verbatim
}
2065 (
%i13) is_connected(g);
2068 \mbox{true
}\leqno{\tt (\%o13)
}
2070 \index{is
\_planar}\begin{Verbatim
}
2071 (
%i14) is_planar(g);
2074 \mbox{true
}\leqno{\tt (\%o14)
}
2076 \index{diameter
}\begin{Verbatim
}
2080 4\leqno{\tt (\%o15)
}
2083 Junto con la definición manual, también es posible generar determinados grafos mediante funciones, como el cíclico, el completo, el dodecaedro, un grafo aleatorio, etc.
2085 \index{cycle
\_graph}\begin{Verbatim
}
2086 (
%i16) print_graph(g1: cycle_graph(5))$
2088 Graph on
5 vertices with
5 edges.
2097 \index{complete
\_graph}\begin{Verbatim
}
2098 (
%i17) print_graph(g2: complete_graph(4))$
2100 Graph on
4 vertices with
6 edges.
2108 \index{dodecahedron
\_graph}\begin{Verbatim
}
2109 (
%i18) print_graph(g3: dodecahedron_graph())$
2111 Graph on
20 vertices with
30 edges.
2135 \index{random
\_graph}\begin{Verbatim
}
2136 (
%i19) /* 0.4 de probabilidad para cada arco */
2137 print_graph(g4: random_graph(
10,
0.4))$
2139 Graph on
10 vertices with
15 edges.
2153 Por último ya, un ejemplo de cálculo de la ruta más corta. Se genera un grafo orientado aleatorio, a continuación se calcula la ruta más corta entre dos vértices dados y finalmente se hace una representación gráfica del cálculo realizado, la cual se puede ver en el apartado
\emph{d)
} de la Figura~
\ref{fig:graph
}.
2155 \index{random
\_digraph}\begin{Verbatim
}
2156 (
%i20) r : random_digraph(20, 0.25)$
2158 \index{vertices
}\begin{Verbatim
}
2159 (
%i21) /* Una lista de los vértices del digrafo */
2163 \left[ 19 ,
18 ,
17 ,
16 ,
15 ,
14 ,
13 ,
12 ,
11 ,
10 ,
9 ,
8 ,
7
2164 ,
6 ,
5 ,
4 ,
3 ,
2 ,
1 ,
0 \right] \leqno{\tt (\%o21)
}
2166 \index{shortest
\_path}\begin{Verbatim
}
2167 (
%i22) sh: shortest_path(0,14,r);
2170 \left[ 0 ,
4 ,
1 ,
17 ,
14 \right] \leqno{\tt (\%o22)
}
2175 show_edges = vertices_to_path(sh),
2181 El paquete
\verb|graphs| también permite el uso de etiquetas en los nodos y ponderaciones en las aristas y arcos. El lector interesado podrá consultar la documentación correspondiente en el manual de referencia.
2192 \section{Transformaciones simbólicas
}
2195 \subsubsection{Expresiones algebraicas
}
2197 Sin duda, una de las capacidades más destacables de Maxima es su habilidad para manipular expresiones algebraicas. Desarrollemos un ejemplo que empieza por asignar a la variable
\verb|q| una expresión literal:
2199 (
%i1) q: (x+3)^5-(x-a)^3+(x+b)^(-1)+(x-1/4)^(-5);
2202 {{1}\over{x+b
}}-
\left(x-a
\right)^
3+
\left(x+
3\right)^
5+
{{1}\over{
2203 \left(x-
{{1}\over{4}}\right)^
5}}\leqno{\tt (\%o1)
}
2206 Se observa que en principio Maxima no realiza ningún cálculo. La función
\verb|expand|
\index{expand
} se encarga de desarrollar las potencias y los productos algebraicos,
2212 {{1}\over{x^
5-
{{5\,x^
4}\over{4}}+
{{5\,x^
3}\over{8}}-
{{5\,x^
2}\over{32
2213 }}+
{{5\,x
}\over{256}}-
{{1}\over{1024}}}}+
{{1}\over{x+b
}}+
2214 x^
5+
15\,x^
4+
89\,x^
3+
3\,a\,x^
2+
270\,x^
2- \\
2215 3\,a^
2\,x+
405\,x+a^
3+
243 \end{array
} \leqno{\tt (\%o2)
}
2218 No obstante es posible que no nos interese desplegar toda la expresión, entre otras cosas para evitar una respuesta farragosa y difícil de interpretar; en tal caso podemos utilizar
\verb|expand|
\index{expand
} añadiéndole dos argumentos y operar de la manera siguiente
2220 (
%i3) expand(q,3,2);
2223 {{1}\over{x+b
}}+
\left(x+
3\right)^
5-x^
3+
3\,a\,x^
2-
3\,a^
2\,x+
{{1
2224 }\over{\left(x-
{{1}\over{4}}\right)^
5}}+a^
3\leqno{\tt (\%o3)
}
2227 Con los argumentos adicionales indicamos que queremos la expansión de todas aquellas potencias con exponente positivo menor o igual a
3 y de las que teniendo el exponente negativo no excedan en valor absoluto de
2.
2229 Dada una expresión con valores literales, podemos desear sustituir alguna letra por otra expresión; por ejemplo, si queremos hacer los cambios $a=
2$, $b=
2c$ en el último resultado obtenido,
2234 {{1}\over{x+
2\,c
}}+
\left(x+
3\right)^
5-x^
3+
6\,x^
2-
12\,x+
{{1}\over{
2235 \left(x-
{{1}\over{4}}\right)^
5}}+
8\leqno{\tt (\%o4)
}
2238 En el ejemplo
\verb|
%i4| se presenta una sentencia en la que hay elementos separados por comas (\verb|,|)\index{2@, (coma)}. Esta es una forma simplificada de utilizar la función \verb|ev|, que evalúa la primera expresión asignando los valores que se le van indicando a continuación; por ejemplo, \verb|(%i4)| se podría haber escrito como \verb|ev(%,a=2,b=2*c)|. El uso de la variante con \verb|ev|\index{ev} está más indicado para ser utilizado dentro de expresiones más amplias. Obsérvese el resultado siguiente
2240 (
%i5) 3*x^2 + ev(x^4,x=5);
2243 3\,x^
2+
625\leqno{\tt (\%o5)
}
2245 donde la sustitución $x=
5$ se ha realizado exclusivamente dentro del contexto delimitado por la función
\verb|ev|.
2247 De forma más general, la función
\verb|subst|
\index{subst
} sustituye subexpresiones enteras. En el siguiente ejemplo, introducimos una expresión algebraica y a continuación sustituimos todos los binomios
\verb|x+y| por la letra
\verb|k|,
2249 (
%i6) 1/(x+y)-(y+x)/z+(x+y)^2;
2252 -
{{y+x
}\over{z
}}+
\left(y+x
\right)^
2+
{{1}\over{y+x
}}\leqno{\tt (\%o6)
}
2255 (
%i7) subst(k,x+y,%);
2258 -
{{k
}\over{z
}}+k^
2+
{{1}\over{k
}}\leqno{\tt (\%o7)
}
2261 No obstante, el siguiente resultado nos sugiere que debemos ser precavidos con el uso de esta función, ya que Maxima no siempre interpretará como subexpresión aquella que para nosotros sí lo es:
2262 \index{subst
}\begin{Verbatim
}
2263 (
%i8) subst(sqrt(k),x+y,(x+y)^2+(x+y));
2266 y+x+k
\leqno{\tt (\%o8)
}
2269 La función
\verb|subst| realiza una simple sustitución sintáctica que, si bien es suficiente en la mayor parte de los casos, a veces se queda corta como en la situación anterior; la función
\verb|ratsubst|
\index{ratsubst
} es capaz de utilizar información semántica y obtene mejores resultados,
2271 \index{subst
}\begin{Verbatim
}
2272 (
%i9) ratsubst(sqrt(k),x+y,(x+y)^2+(x+y));
2274 $$k+
\sqrt{k
}\leqno{\tt (\%o9)
}$$
2276 Como una aplicación práctica de
\verb|subst|, veamos cómo podemos utilizarla para obtener el conjugado de un número complejo,
2278 (
%i10) subst(-%i,%i,a+b*%i);
2281 a-i\,b
\leqno{\tt (\%o10)
}
2284 La operación inversa de la expansión es la factorización. Expandamos y factoricemos sucesivamente un polinomio para comprobar los resultados,
2285 \index{expand
}\index{factor
}\begin{Verbatim
}
2286 (
%i11) expand((a-2)*(b+1)^2*(a+b)^5);
2290 a\,b^
7-
2\,b^
7+
5\,a^
2\,b^
6-
8\,a\,b^
6-
4\,b^
6+
10\,a^
3\,b^
5-
10\,a^
2\,b^
5
2291 -
19\,a\,b^
5-
2\,b^
5+
10\,a^
4\,b^
4- \\
35\,a^
2\,b^
4-
10\,a\,b^
4+
5\,a^
5\,b^
3+
10
2292 \,a^
4\,b^
3-
30\,a^
3\,b^
3-
20\,a^
2\,b^
3+a^
6\,b^
2+
8\,a^
5\,b^
2-
10\,a^
4\,b
2293 ^
2- \\
20\,a^
3\,b^
2+
2\,a^
6\,b+a^
5\,b-
10\,a^
4\,b+a^
6-
2\,a^
5 \end{array
} \leqno{\tt (\%o11)
}
2299 \left(a-
2\right)\,
\left(b+
1\right)^
2\,
\left(b+a
\right)^
5\leqno{\tt (\%o12)
}
2302 El máximo común divisor de un conjunto de polinomios se calcula con la función
\verb|gcd|
\index{gcd
} y el mínimo común múltiplo con
\verb|lcm|
\index{lcm
}
2304 (
%i13) p1: x^7-4*x^6-7*x^5+8*x^4+11*x^3-4*x^2-5*x;
2307 x^
7-
4\,x^
6-
7\,x^
5+
8\,x^
4+
11\,x^
3-
4\,x^
2-
5\,x
\leqno{\tt (\%o13)
}
2310 (
%i14) p2: x^4-2*x^3-4*x^2+2*x+3;
2313 x^
4-
2\,x^
3-
4\,x^
2+
2\,x+
3\leqno{\tt (\%o14)
}
2319 x^
3+x^
2-x-
1\leqno{\tt (\%o15)
}
2322 (
%i16) load(functs)$
2326 \left(x-
5\right)\,
\left(x-
3\right)\,
\left(x-
1\right)^
2\,x\,
\left(x+
1
2327 \right)^
3\leqno{\tt (\%o17)
}
2330 En
\verb|(
%i13)| y \verb|(%i14)| definimos los polinomios \verb|p1| y \verb|p2|, a continuación calculamos su máximo común divisor (mcd) en \verb|(%i15)| y antes de pedir el mínimo común múltiplo en \verb|(%i17)| cargamos el paquete \verb|functs| en el que se encuentra definida la función \verb|lcm|. Es posible que deseemos disponer del mcd factorizado, por lo que hacemos
2331 \index{factor
}\begin{Verbatim
}
2332 (
%i18) factor(%o15);
2335 \left(x-
1\right)\,
\left(x+
1\right)^
2\leqno{\tt (\%o18)
}
2338 Hay varias funciones en Maxima que se pueden utilizar para extraer coeficientes de expresiones algebraicas; una de ellas es
\verb|ratcoef|
\index{ratcoef
}. Dado el polinomio $(x-y)^
4$, podemos querer extraer el coeficiente de $x^
2 y^
2$,
2341 (
%i19) ratcoef((x-y)^4, x^2*y^2);
2343 $$
6\leqno{\tt (\%o19)
}$$
2345 Cuando tenemos expandido un polinomio de varias variables, podemos querer transformarlo en otro univariante con coeficientes literales; aquí puede ser de ayuda la función
\verb|rat|
\index{rat
},
2348 (
%i20) q: m^2*x^2+x^2+2*b*m*x-6*m*x-4*x+b^2-6*b+13;
2350 $$m^
2\,x^
2+x^
2+
2\,b\,m\,x-
6\,m\,x-
4\,x+b^
2-
6\,b+
13\leqno{\tt (\%o20)
}$$
2354 $$
\left(m^
2+
1\right)\,x^
2+
\left(
\left(
2\,b-
6\right)\,m-
4\right)\,x+b^
2355 2-
6\,b+
13\leqno{\tt (\%o21)
}$$
2357 Llamando nuevamente a
\verb|ratcoef| podemos extraer el coeficiente del término de primer grado respecto de $x$,
2360 (
%i22) ratcoef(%,x);
2362 $$
\left(
2\,b-
6\right)\,m-
4\leqno{\tt (\%o22)
}$$
2364 Otro ejemplo ilstrativo de
\verb|rat| en acción,
2367 (
%i23) rat((x^b+a*x^b+x)^2, x^b);
2369 $$
\left(a^
2+
2\,a+
1\right)\,
\left(x^
{b
}\right)^
2+
\left(
2\,a+
2\right)\,
2370 x\,x^
{b
}+x^
2\leqno{\tt (\%o23)
}$$
2372 Si en algún momento queremos inhibir las simplificaciones, podemos hacer uso de la variable global
\verb|simp|
\index{simp
}, cuyo valor por defecto es
\verb|true|,
2376 (
%i25) 2 + 2 + a + a;
2379 2+
2+a+a
\leqno{\tt (\%o25)
}
2386 2\,a+
4\leqno{\tt (\%o27)
}
2389 Veamos ahora algunas transformaciones que se pueden hacer con fracciones algebraicas.
2392 (
%i28) expr:(x^2-x)/(x^2+x-6)-5/(x^2-4);
2395 {{x^
2-x
}\over{x^
2+x-
6}}-
{{5}\over{x^
2-
4}}\leqno{\tt (\%o28)
}
2398 Podemos factorizar esta expresión,
2400 \index{factor
}\begin{Verbatim
}
2401 (
%i29) factor(expr);
2404 {{\left(x-
3\right)\,
\left(x^
2+
4\,x+
5\right)
}\over{\left(x-
2\right)
2405 \,
\left(x+
2\right)\,
\left(x+
3\right)
}}\leqno{\tt (\%o29)
}
2408 La expansión devuelve el siguiente resultado,
2410 \index{expand
}\begin{Verbatim
}
2411 (
%i30) expand(expr);
2414 {{x^
2}\over{x^
2+x-
6}}-
{{x
}\over{x^
2+x-
6}}-
{{5}\over{x^
2-
4}}\leqno{\tt (\%o30)
}
2417 Ahora descomponemos la fracción algebraica
\verb|expr| en fracciones simples,
2419 \index{partfrac
}\begin{Verbatim
}
2420 (
%i31) partfrac(expr,x);
2423 -
{{12}\over{5\,
\left(x+
3\right)
}}+
{{5}\over{4\,
\left(x+
2\right)
}}-
2424 {{17}\over{20\,
\left(x-
2\right)
}}+
1\leqno{\tt (\%o31)
}
2427 Por último, transformamos la misma expresión a su forma canónica CRE (
\emph{Cannonical Rational Expression
}), que es un formato que Maxima utiliza para reducir expresiones algebraicas equivalentes a una forma única,
2429 \index{radcan
}\begin{Verbatim
}
2430 (
%i32) radcan(expr);
2433 {{x^
3+x^
2-
7\,x-
15}\over{x^
3+
3\,x^
2-
4\,x-
12}}\leqno{\tt (\%o32)
}
2436 La función
\verb|ratsimp|
\index{ratsimp
} también simplifica cualquier expresión racional, así como las subexpresiones racionales que son argumentos de funciones cualesquiera. El resultado se devuelve como el cociente de dos polinomios. En ocasiones no es suficiente con una sola ejecución de
\verb|ratsimp|, por lo que será necesario aplicarla más veces, esto es lo que hace precisamente la función
\verb|fullratsimp|
\index{fullratsimp
}; concretemos esto con un ejemplo:
2438 (
%i33) (x^(a/2)-1)^2*(x^(a/2)+1)^2 / (x^a-1);
2441 {{\left(x^
{{{a
}\over{2}}}-
1\right)^
2\,
\left(x^
{{{a
}\over{2}}}+
1
2442 \right)^
2}\over{x^
{a
}-
1}}\leqno{\tt (\%o33)
}
2445 (
%i34) ratsimp(%); /* simplificamos una vez */
2448 {{x^
{2\,a
}-
2\,x^
{a
}+
1}\over{x^
{a
}-
1}}\leqno{\tt (\%o34)
}
2451 (
%i35) ratsimp(%); /* simplificamos otra vez */
2454 x^
{a
}-
1\leqno{\tt (\%o35)
}
2457 (
%i36) fullratsimp(%o32); /* ¡simplificamos todo de una vez! */
2460 x^
{a
}-
1\leqno{\tt (\%o36)
}
2463 Dada una fracción algebraica, podemos obtener separadamente el numerador y el denominador,
2464 \index{num
}\index{denom
}\begin{Verbatim
}
2465 (
%i37) fr: (x^3-4*x^2+4*x-2)/(x^2+x+1);
2468 {{x^
3-
4\,x^
2+
4\,x-
2}\over{x^
2+x+
1}}\leqno{\tt (\%o37)
}
2474 x^
3-
4\,x^
2+
4\,x-
2\leqno{\tt (\%o38)
}
2480 x^
2+x+
1\leqno{\tt (\%o39)
}
2483 Maxima nunca puede adivinar a priori las intenciones del usuario para con las expresiones con las que está trabajando, por ello sigue la política de no tomar ciertas decisiones, por lo que a veces puede parecer que no hace lo suficiente o que no sabe hacerlo. Esta forma
\emph{vaga
} de proceder la suple con una serie de funciones y variables globales que permitirán al usuario darle al motor simbólico ciertas directrices sobre qué debe hacer con las expresiones, cómo reducirlas o transformarlas. Sin ánimo de ser exhaustivos, siguen algunos ejemplos en los que se controlan transformaciones de tipo logarítmico y trigonométrico.
2487 \subsubsection{Expresiones logarítmicas
}
2489 Las expresiones que contienen logaritmos suelen ser ambiguas a la hora de reducirlas. Transformamos a continuación la misma expresión según diferentes criterios,
2492 (
%i1) log(x^r)-log(x*y) + a*log(x/y);
2495 -
\log \left(x\,y
\right)+a\,
\log \left(
{{x
}\over{y
}}\right)+r\,
\log
2499 En principio, ha hecho la transformación $
\log x^r
\rightarrow r
\log x$. Esto se controla con la variable global
\verb|logexpand|
\index{logexpand
}, cuyo valor por defecto es
\verb|true|, lo cual sólo permite la reducción recién indicada. Si también queremos que nos expanda los logaritmos de productos y divisiones, le cambiaremos el valor a esta variable global, tal como se indica a continuación,
2502 (
%i2) logexpand: super$
2503 (
%i3) log(x^r)-log(x*y) + a*log(x/y);
2506 -
\log y+a\,
\left(
\log x-
\log y
\right)+r\,
\log x-
\log x
\leqno{\tt (\%o3)
}
2510 (
%i4) /* pedimos que nos simplifique la expresión anterior */
2514 \left(-a-
1\right)\,
\log y+
\left(r+a-
1\right)\,
\log x
\leqno{\tt (\%o4)
}
2517 En caso de no querer que nos haga transformación alguna sobre la expresión de entrada, simplemente haremos
2520 (
%i5) logexpand: false$
2521 (
%i6) log(x^r)-log(x*y) + a*log(x/y);
2524 -
\log \left(x\,y
\right)+a\,
\log \left(
{{x
}\over{y
}}\right)+
\log x^
{
2525 r
}\leqno{\tt (\%o6)
}
2528 Devolvemos ahora la variable
\verb|logexpand| a su estado por defecto,
2531 (
%i7) logexpand: true$
2534 La función
\verb|logcontract|
\index{logcontract
} es la que nos va a permitir compactar expresiones logarítmicas,
2537 (
%i8) logcontract(2*(a*log(x) + 2*a*log(y)));
2540 a\,
\log \left(x^
2\,y^
4\right)
\leqno{\tt (\%o8)
}
2543 Por defecto, Maxima contrae los coeficientes enteros; para incluir en este caso la variable $a$ dentro del logaritmo le asignaremos la propiedad de ser un número entero,
2546 (
%i9) declare(a, integer)$
2547 (
%i10) ''%i8; /* fuerza reevaluación de expresión nominal */
2550 \log \left(x^
{2\,a
}\,y^
{4\,a
}\right)
\leqno{\tt (\%o10)
}
2553 Esta es una forma de hacerlo, pero Maxima permite un mayor refinamiento sobre este particular haciendo uso de la variable global
\verb|logconcoeffp|
\index{logconcoeffp
}.
2558 \subsubsection{Expresiones trigonométricas
}
2560 Toda esta casuística de diferentes formas de representar una misma expresión aumenta considerablemente con aquéllas en las que intervienen las funciones trigonométricas e hiperbólicas. Empecemos con la función
\verb|trigexpand|
\index{trigexpand
}, cuyo comportamiento se controla con las variables globales
\verb|trigexpand| (que le es homónima),
\verb|trigexpandplus|
\index{trigexpandplus
} y
\verb|trigexpandtimes|
\index{trigexpandtimes
}, cuyos valores por defectos son, respectivamente,
\verb|false|,
\verb|true| y
\verb|true|. Puestos a experimentar, definamos primero una expresión trigonométrica e interpretamos algunos resultados,
2563 (
%i1) expr: x+sin(3*x+y)/sin(x);
2566 {{\sin \left(y+
3\,x
\right)
}\over{\sin x
}}+x
\leqno{\tt (\%o1)
}
2570 (
%i2) trigexpand(expr); /* aquí trigexpand vale false */
2573 {{\cos \left(
3\,x
\right)\,
\sin y+
\sin \left(
3\,x
\right)\,
\cos y
2574 }\over{\sin x
}}+x
\leqno{\tt (\%o2)
}
2577 Vemos que sólo se desarrolló la suma del numerador; ahora cambiamos el valor lógico de
\verb|trigexpand|,
2580 (
%i3) trigexpand(expr), trigexpand=true;
2583 {{\left(
\cos ^
3x-
3\,
\cos x\,
\sin ^
2x
\right)\,
\sin y+
\left(
3\,
\cos ^
2
2584 x\,
\sin x-
\sin ^
3x
\right)\,
\cos y
}\over{\sin x
}}+x
\leqno{\tt (\%o3)
}
2587 Cuando la asignación de la variable global se hace como se acaba de indicar, sólo tiene efecto temporal durante esa ejecución, sin haberse alterado a nivel global. Podemos ordenar a Maxima que simplifique la expresión anterior,
2593 -
{{\left(
3\,
\cos x\,
\sin ^
2x-
\cos ^
3x
\right)\,
\sin y+
\left(
\sin ^
3x
2594 -
3\,
\cos ^
2x\,
\sin x
\right)\,
\cos y-x\,
\sin x
}\over{\sin x
}}\leqno{\tt (\%o4)
}
2597 Podemos inhibir el desarrollo de la suma,
2600 (
%i5) trigexpand(expr), trigexpandplus=false;
2603 {{\sin \left(y+
3\,x
\right)
}\over{\sin x
}}+x
\leqno{\tt (\%o5)
}
2606 Otra variable global de interés, que no tiene nada que ver con la función
\verb|trigexpand|, es
\verb|halfangles|
\index{halfangles
}, con valor
\verb|false| por defecto, que controla si se reducen los argumentos trigonométricos con denominador dos,
2612 \sin \left(
{{x
}\over{2}}\right)
\leqno{\tt (\%o6)
}
2616 (
%i7) sin(x/2), halfangles=true;
2619 {{\sqrt{1-
\cos x
}}\over{\sqrt{2}}}\leqno{\tt (\%o7)
}
2622 La función
\verb|trigsimp|
\index{trigsimp
} fuerza el uso de las identidades fundamentales $
\sin^
2 x +
\cos^
2 x =
1$ y $
\cosh^
2 x -
\sinh^
2 x =
1$ para simplificar expresiones,
2625 (
%i8) 5*sin(x)^2 + 4*cos(x)^2;
2628 5\,
\sin ^
2x+
4\,
\cos ^
2x
\leqno{\tt (\%o8)
}
2635 \sin ^
2x+
4\leqno{\tt (\%o9)
}
2638 Como un último ejemplo, veamos cómo reducir productos y potencias de funciones trigonométricas a combinaciones lineales,
2641 (
%i10) -sin(x)^2+3*cos(x)^2*tan(x);
2644 3\,
\cos ^
2x\,
\tan x-
\sin ^
2x
\leqno{\tt (\%o10)
}
2648 (
%i11) trigreduce(%);
2651 {{3\,
\sin \left(
2\,x
\right)
}\over{2}}+
{{\cos \left(
2\,x
\right)
2652 }\over{2}}-
{{1}\over{2}}\leqno{\tt (\%o11)
}
2655 Y si queremos transformar expresiones trigonométricas en complejas,
2658 (
%i12) exponentialize(%);
2661 {{e^
{2\,i\,x
}+e^
{-
2\,i\,x
}}\over{4}}-
{{3\,i\,
\left(e^
{2\,i\,x
}-e
2662 ^
{-
2\,i\,x
}\right)
}\over{4}}-
{{1}\over{2}}\leqno{\tt (\%o12)
}
2665 Otras funciones útiles en este contexto y que el usuario podrá consultar en la documentación son:
\verb|triginverses|
\index{triginverses
},
\verb|trigsign|
\index{trigsign
} y
\verb|trigrat|
\index{trigrat
}.
2674 \section{Ecuaciones
}
2676 Almacenar una ecuación en una variable es tan simple como hacer
2678 (
%i1) ec: 3 * x = 1 + x;
2681 3\,x=x+
1\leqno{\tt (\%o1)
}
2684 A partir de ahí, aquellas operaciones en las que intervenga la variable serán realizadas a ambos miembros de la igualdad; restamos
\verb|x| en los dos lados y a continuación dividimos lo que queda entre
\verb|
2|,
2689 2\,x=
1\leqno{\tt (\%o2)
}
2695 x=
{{1}\over{2}}\leqno{\tt (\%o3)
}
2697 obteniendo de esta manera la solución de la ecuación como si hubiésemos operado manualmente.
2699 Ni qué decir tiene que la ecuación anterior se pudo haber resuelto de un modo más inmediato,
2700 \index{solve
}\begin{Verbatim
}
2704 \left[ x=
{{1}\over{2}} \right] \leqno{\tt (\%o4)
}
2707 La instrucción
\verb|solve| puede admitir como segundo argumento la incógnita que se pretende calcular, lo que resultará de utilidad cuando en la ecuación aparezcan constantes literales,
2709 (
%i5) solve((2-a)/x-3=b*x+1/x,x);
2712 \left[ x=-
{{\sqrt{\left(
4-
4\,a
\right)\,b+
9}+
3}\over{2\,b
}} , x=
{{
2713 \sqrt{\left(
4-
4\,a
\right)\,b+
9}-
3}\over{2\,b
}} \right] \leqno{\tt (\%o5)
}
2716 Las soluciones de las ecuaciones serán probablemente utilizadas en cálculos posteriores, por lo que nos interesará poder extraerlas de la lista anterior; a continuación tomamos el primer resultado calculado por Maxima mediante la función
\verb|part|
\index{part
} y después asignamos a la variable
\verb|sol| el resultado numérico,
2721 x=-
{{\sqrt{\left(
4-
4\,a
\right)\,b+
9}+
3}\over{2\,b
}}\leqno{\tt (\%o6)
}
2727 -
{{\sqrt{\left(
4-
4\,a
\right)\,b+
9}+
3}\over{2\,b
}}\leqno{\tt (\%o7)
}
2730 La función
\verb|rhs|
\index{rhs
} devuelve el miembro derecho de la igualdad, mientras que
\verb|lhs|
\index{lhs
} haría lo propio con el miembro izquierdo.
2732 Es posible resolver ecuaciones polinómicas de grado $
\leq 4$, pero desgraciadamente, como es de esperar, Maxima no dispone de un método general algebraico que permita resolver ecuaciones polinómicas de grado mayor que cuatro,
2734 (
%i8) solve(x^5 - 3*x^4 + 2*x^3 -2*x^2 - x + 4 = 0);
2737 \left[ 0=x^
5-
3\,x^
4+
2\,x^
3-
2\,x^
2-x+
4 \right] \leqno{\tt (\%o8)
}
2739 por lo que
\verb|solve| devolverá la misma ecuación sin resolver.
2741 También
\verb|solve| se puede utilizar para la resolución de sistemas, en cuyo caso las ecuaciones deben ir agrupadas en una lista, así como las incógnitas; nos planteamos la resolución del siguiente sistema no lineal de incógnitas $x$ e $y$,
2746 3*x^
2-y^
2 & = &
6 \\
2753 (
%i9) solve([3*x^2-y^2=6,x=y+a],[x,y]);
2757 \left[ \left[ x=-
{{\sqrt{3}\,
\sqrt{a^
2+
4}+a
}\over{2}} , y=-
{{\sqrt{3
2758 }\,
\sqrt{a^
2+
4}+
3\,a
}\over{2}} \right] ,
\right.\\
2759 \left.
\left[ x=
{{\sqrt{3}\,
2760 \sqrt{a^
2+
4}-a
}\over{2}} , y=
{{\sqrt{3}\,
\sqrt{a^
2+
4}-
3\,a
}\over{2}}
2761 \right] \right] \end{array
} \leqno{\tt (\%o9)
}
2764 Una alternativa al uso de
\verb|solve| es la función
\verb|algsys|
\index{algsys
}. Veamos cómo
\verb|algsys| trata la resolución de la ecuación polinómica anterior
\verb|
%o8|,
2766 (
%i10) algsys([x^5 - 3*x^4 + 2*x^3 -2*x^2 - x + 4 = 0],[x]);
2770 \left[ \left[ x=
2.478283086356668 \right] ,
\left[ x=
.1150057557117295
2771 -
1.27155810694299\,i
\right] ,
\right.\\
2772 \left.
\left[ x=
1.27155810694299\,i+
.1150057557117295
2773 \right] ,
\left[ x=-
.8598396689940523 \right] ,
\right.\\
2774 \left.
\left[ x=
1.151545166402536
2775 \right] \right] \end{array
} \leqno{\tt (\%o10)
}
2778 Como se ve, al no ser capaz de resolverla algebraicamente, nos brinda la oportunidad de conocer una aproximación numérica de la solución. La función
\verb|algsys| reconoce la variable global
\verb|realonly|
\index{realonly
}, que cuando toma el valor
\verb|true|, hará que se ignoren las soluciones complejas,
2780 (
%i11) realonly:true$
2781 (
%i12) ''%i10; /* recalcula la entrada %i10 */
2784 \left[ \left[ x=
2.478283086356668 \right] ,
\left[ x=
1.151545166402536
2785 \right] ,
\left[ x=-
.8598396689940523 \right] \right] \leqno{\tt (\%o12)
}
2788 (
%i13) realonly:false$ /* le devolvemos el valor por defecto */
2791 Un sistema no lineal con coeficientes paramétricos y complejos
2796 \frac{2 + i
}{u+t
} & = &
3 v + u \\
2803 (
%i14) algsys([3*u-a*v=t,(2+%i)/(u+t)=3*v+u,t/u=1],[u,v,t]);
2807 \left[ \left[ u=
{{\sqrt{{{i\,a
}\over{a+
6}}+
{{2\,a
}\over{a+
6}}}
2808 }\over{\sqrt{2}}} , v=
{{2\,
\sqrt{i+
2}}\over{\sqrt{2}\,
\sqrt{a
}\,
2809 \sqrt{a+
6}}} , t=
{{\sqrt{i+
2}\,
\sqrt{a
}}\over{\sqrt{2}\,
\sqrt{a+
6}}} \right] \right. , \\
2810 \left.
\left[ u=-
{{\sqrt{{{i\,a
}\over{a+
6}}+
{{2\,a
}\over{a+
6}}}
2811 }\over{\sqrt{2}}} , v=-
{{2\,
\sqrt{i+
2}}\over{\sqrt{2}\,
\sqrt{a
}\,
2812 \sqrt{a+
6}}} , t=-
{{\sqrt{i+
2}\,
\sqrt{a
}}\over{\sqrt{2}\,
\sqrt{a+
6}
2813 }} \right] \right] \end{array
} \leqno{\tt (\%o14)
}
2816 Veamos cómo trata
\verb|algsys| las ecuaciones indeterminadas, devolviendo la solución en términos paramétricos,
2818 (
%i15) algsys([3*x^2-5*y=x],[x,y]);
2821 \left[ \left[ x=
{\it \%r_1
} , y=
{{3\,
{\it \%r_1
}^
2-
{\it \%r_1
}
2822 }\over{5}} \right] \right] \leqno{\tt (\%o15)
}
2828 \left[ \left[ x=
1 , y=
{{2}\over{5}} \right] \right] \leqno{\tt (\%o16)
}
2831 Maxima nombra los parámetros siguiendo el esquema
\verb|
%rn|\index{14@\%rn}, siendo \verb|n| un número entero positivo. En la entrada \verb|%i16| pedimos que en \verb|%o15| se sustituya el parámetro por la unidad.
2833 En ocasiones conviene eliminar las variables de los sistemas de forma controlada; en tales casos la función a utilizar será
\verb|eliminate|
\index{eliminate
},
2836 (
%i17) eliminate([3*u-a*v=t,(2+%i)/(u+t)=3*v+u,t/u=1],[u]);
2839 \left[ 2\,t-a\,v , -
\left(a^
2+
9\,a
\right)\,v^
2-
\left(
5\,a+
36\right)
2840 \,t\,v-
4\,t^
2+
9\,i+
18 \right] \leqno{\tt (\%o17)
}
2843 Cuando de lo que se trata es de resolver un sistema de ecuaciones lineales, la mejor opción es
\verb|linsolve|
\index{linsolve
}, cuya sintaxis es similar a la de las funciones anteriores. En el siguiente ejemplo, el objetivo es
2846 \left\
{ \begin{array
}{rcrcrcc
}
2847 2 x & - &
4 y & + &
2 z & = & -
2 \\
2848 \frac{1}{3} x & + &
2 y & + &
9 z & = & x+y \\
2849 -
4 x & + &
\sqrt{2} y & + & z & = &
3 y
2856 [ 2 * x -
4 * y +
2 * z = -
2,
2857 1/
3* x +
2 * y +
9 * z = x + y,
2858 -
4 * x + sqrt(
2) * y + z =
3 * y
],
2862 \left[ x=
{{3021\,
\sqrt{2}-
12405}\over{48457}} , y=
{{1537\,
\sqrt{2}+
16642
2863 }\over{48457}} , z=
{{53\,
\sqrt{2}-
2768}\over{48457}} \right] \leqno{\tt (\%o18)
}
2866 Cuando la matriz de coeficientes del sistema es dispersa, la función
\verb|fast_linsolve|
\index{fast
\_linsolve} será preferible, ya que aprovechará tal circunstancia para encontrar las soluciones de forma más rápida.
2868 Si los coeficientes del sistema se tienen en formato matricial, quizás sea más apropiado el uso de la función
\verb|linsolve_by_lu|
\index{linsolve
\_by\_lu}, tal como se indica en la sección dedicada a las matrices.
2870 No todo es resoluble simbólicamente. Existen en Maxima varios procedimientos cuya naturaleza es estrictamente numérica. Uno de ellos es
\verb|realroots|
\index{realroots
}, especializado en el cálculo de
\emph{aproximaciones racionales
} de las raíces reales de ecuaciones polinómicas; el segundo parámetro, que es opcional, indica la cota de error.
2873 (
%i19) realroots(x^8+x^3+x+1, 5e-6);
2876 \left[ x=-
1 , x=-
{{371267}\over{524288}} \right] \leqno{\tt (\%o19)
}
2879 En cambio,
\verb|allroots|
\index{allroots
} obtiene aproximaciones en formato decimal de coma flotante de todas las raíces de las ecuaciones polinómicas, tanto reales como complejas,
2882 (
%i20) allroots(x^8+x^3+x+1);
2886 \left[ x=
.9098297401801199\,i+
.2989522918873167 ,
\right. , \\
\left. x=
.2989522918873167
2887 -
.9098297401801199\,i
\right. , \\
\left.
2888 x=-
.7081337759784606 , x=
.9807253637807569\,
2889 i-
.4581925662678885 \right. , \\
\left.
2890 x=-
.9807253637807569\,i-
.4581925662678885 ,
\right. , \\
\left. x=
.5359278244124014
2891 \,i+
1.013307162369803 \right. , \\
\left.
2892 x=
1.013307162369803-
.5359278244124014\,i , x=
2893 -
1.000000000000001 \right] \end{array
} \leqno{\tt (\%o20)
}
2896 Más allá de las ecuaciones algebraicas,
\verb|find_root|
\index{find
\_root} utiliza el método de bipartición para resolver ecuaciones en su más amplio sentido,
2899 (
%i21) f(x):=144 * sin(x) + 12*sqrt(3)*%pi - 36*x^2 - 12*%pi*x$
2900 (
%i22) find_root(f(z),z,1,2);
2903 1.899889962840263\leqno{\tt (\%o22)
}
2907 El uso del método de Newton requiere cargar en memoria el módulo correspondiente. Veamos como ejemplo la ecuación
2913 \index{mnewton
}\begin{Verbatim
}
2914 (
%i23) load(mnewton)$ /* carga el paquete */
2915 (
%i24) mnewton([2*u^u-5],[u],[1]);
2916 0 errors,
0 warnings
2919 \left[ \left[ u=
1.70927556786144 \right] \right] \leqno{\tt (\%o14)
}
2926 x+
3 \log(x)-y^
2 & = &
0 \\
2927 2 x^
2-x y-
5 x+
1 & = &
0
2933 (
%i25) mnewton([x+3*log(x)-y^2, 2*x^2-x*y-5*x+1],[x, y], [5, 5]);
2936 \left[ \left[ x=
3.756834008012769 , y=
2.779849592817897 \right]
2937 \right] \leqno{\tt (\%o25)
}
2941 (
%i26) mnewton([x+3*log(x)-y^2, 2*x^2-x*y-5*x+1],[x, y], [1, -2]);
2944 \left[ \left[ x=
1.373478353409809 , y=-
1.524964836379522 \right]
2945 \right] \leqno{\tt (\%o26)
}
2948 En los anteriores ejemplos, el primer argumento es una lista con la ecuación o ecuaciones a resolver, las cuales se suponen igualadas a cero; el segundo argumento es la lista de variables y el último el valor inicial a partir del cual se generará el algoritmo y cuya elección determinará las diferentes soluciones del problema.
2958 \section{Inecuaciones
}
2960 Las rutinas para resolver inecuaciones las guarda Maxima en el paquete de funciones
\verb|fourier_elim|, por lo que primero las debemos cargar en memoria,
2963 (
%i1) load("fourier_elim")$
2966 Ciertos mensajes de avisos que nos devuelve Maxima los podemos olvidar, ya que solo nos indican que algunas macros del sistema han tenido que ser redefinidas.
2968 Vamos a resolver una inecuación de primer grado,
2971 (
%i2) ine : (5*x-16)/6 + (x+8)/12 < (x+1)/3;
2973 $$
{{5\,x-
16}\over{6}}+
{{x+
8}\over{12}}<
{{x+
1}\over{3}}\leqno{\tt (\%o2)
}$$
2975 La función clave a llamar se llama precisamente
\verb|fourier_elim|
\index{realroots
} y la sintaxis es similar a la de
\verb|solve|; el primer argumento a pasarle es la lista de inecuaciones, de momento una sola, y el segundo la lista de incógnitas, también una sola,
2978 (
%i3) fourier_elim([ine], [x]);
2980 $$
\left[ x<
4 \right] \leqno{\tt (\%o3)
}$$
2982 Vamos a ver ahora en qué intervalos de la recta el polinomio $x^
4+
5 x^
3+
5 x^
2-
5 x-
6$ toma valores positivos,
2985 (
%i4) p : x^4+5*x^3+5*x^2-5*x-6 $
2988 (
%i5) fourier_elim([p > 0],[x]);
2990 $$
\left[ 1<x
\right] \lor \left[ -
2<x , x<-
1 \right] \lor \left[ x<-
3
2991 \right] \leqno{\tt (\%o5)
}$$
2993 Tal como se ha visto hasta ahora, la función
\verb|fourier_elim| nos devuelve los resultados como disyunciones de listas, interpretándose cada una de ellas como una conjunción lógica de proposiciones; así, el último resultado habría que interpretarlo como
2995 $$(
1<x)
\lor ( -
2<x
\land x<-
1 )
\lor (x<-
3).$$
2997 El resultado anterior cambia sensiblemente cuando admitimos la igualdad en la inecuación,
3000 (
%i6) fourier_elim([p >= 0],[x]);
3002 $$
\left[ x=-
3 \right] \lor \left[ x=-
2 \right] \lor \left[ x=-
1
3003 \right] \lor \left[ x=
1 \right] \lor \left[ 1<x
\right] \lor
3004 \left[ -
2<x , x<-
1 \right] \lor \left[ x<-
3 \right] \leqno{\tt (\%o6)
}$$
3006 Abordamos ahora la resolución de un sistema de inecuaciones lineales con una incógnita,
3010 [(x+
2)/
4 <= x/
2-
3, (
8-x)/
3 < (
1+x)/
2-
1],
3013 $$
\left[ x=
14 \right] \lor \left[ 14<x
\right] \leqno{\tt (\%o7)
}$$
3027 $$
\left[ {\it max
}\left(
0 ,
{{y
}\over{2}}+
{{x
}\over{2}}-
{{1}\over{2}}
3028 \right)<z , z<-y-x+
4 ,
0<x , x<
{\it min
}\left(
1 ,
3-y
\right) ,
0<y
3029 , y<
3 \right] \leqno{\tt (\%o8)
}$$
3031 Otros ejemplos de inecuaciones no lineales,
3034 (
%i9) fourier_elim([max(x,y) < 1, min(x,y) > -1],[x,y]);
3036 $$
\left[ -
1<x , x<
1 , -
1<y , y<
1 \right] \leqno{\tt (\%o19)
}$$
3039 (
%i10) fourier_elim([abs(x) + abs(x/2) + abs(x/3) # 1],[x]);
3041 $$
\left[ x=
0 \right] \lor \left[ 0<x , x<
{{6}\over{11}} \right] \lor
3042 \left[ -
{{6}\over{11}}<x , x<
0 \right] \lor \left[ x<-
{{6}\over{11}}
3043 \right] \lor \left[ {{6}\over{11}}<x
\right] \leqno{\tt (\%o10)
}$$
3047 (
%i11) fourier_elim([log(x) < log(a)],[x,a]);
3049 $$
\left[ 0<x , x<a ,
0<a
\right] \leqno{\tt (\%o11)
}$$
3062 La definición de una matriz es extremadamente simple en Maxima,
3063 \index{matrix
}\begin{Verbatim
}
3064 (
%i1) m1: matrix([3,4,0],[6,0,-2],[0,6,a]);
3067 \begin{pmatrix
}3&
4&
0\cr 6&
0&-
2\cr 0&
6&a
\cr \end{pmatrix
} \leqno{\tt (\%o1)
}
3070 También es posible definir una matriz de forma interactiva tal y como muestra el siguiente ejemplo,
3071 \index{entermatrix
}\begin{Verbatim
}
3072 (
%i2) entermatrix(2,3);
3089 \begin{pmatrix
}{{4}\over{7}}&
0&
\pi\cr \sqrt{2}&
\log 3&-
9\cr \end{pmatrix
} \leqno{\tt (\%o2)
}
3092 Existe un tercer método para construir matrices que es útil cuando el elemento $(i,j)$-ésimo de la misma es función de su posición dentro de la matriz. A continuación, se fija en primer lugar la regla que permite definir un elemento cualquiera y luego en base a ella se construye una matriz de dimensiones $
2 \times 5$
3093 \index{29@:=
}\index{genmatrix
}\begin{Verbatim
}
3095 (
%i4) genmatrix(a,2,5);
3098 \begin{pmatrix
}2&
3&
4&
5&
6\cr 3&
4&
5&
6&
7\cr \end{pmatrix
} \leqno{\tt (\%o4)
}
3100 Obsérvese que el símbolo de asignación para el elemento genérico es
\verb|:=|.
3103 Podemos acceder a los diferentes elementos de la matriz haciendo referencia a sus subíndices, indicando primero la fila y después la columna:
3111 Se puede extraer una submatriz con la función
\verb|submatrix|
\index{submatrix
}, teniendo en cuenta que los enteros que preceden al nombre de la matriz original son las filas a eliminar y los que se colocan detrás indican las columnas que no interesan; en el siguiente ejemplo, queremos la submatriz que nos queda de
\verb|m1| después de extraer la primera fila y la segunda columna,
3113 (
%i6) submatrix(1,m1,2);
3116 \begin{pmatrix
}6&-
2\cr 0&a
\cr \end{pmatrix
} \leqno{\tt (\%o6)
}
3119 Otro ejemplo es el siguiente,
3121 (
%i7) submatrix(1,2,m1,3);
3124 \begin{pmatrix
}0&
6\cr \end{pmatrix
} \leqno{\tt (\%o7)
}
3126 en el que eliminamos las dos primeras filas y la última columna, ?`se pilla el truco?
3128 Al igual que se extraen submatrices, es posible añadir filas y columnas a una matriz dada; por ejemplo,
3129 \index{addrow
}\index{addcol
}\begin{Verbatim
}
3130 (
%i8) addrow(m1,[1,1,1],[2,2,2]);
3133 \begin{pmatrix
}3&
4&
0\cr 6&
0&-
2\cr 0&
6&a
\cr 1&
1&
1\cr 2&
2&
2\cr \end{pmatrix
} \leqno{\tt (\%o8)
}
3136 (
%i9) addcol(%,[7,7,7,7,7]);
3139 \begin{pmatrix
}3&
4&
0&
7\cr 6&
0&-
2&
7\cr 0&
6&a&
7\cr 1&
1&
1&
7\cr 2&
2&
2&
7\cr \end{pmatrix
} \leqno{\tt (\%o9)
}
3142 La matriz identidad es más fácil construirla mediante la función
\verb|ident|
\index{ident
},
3147 \begin{pmatrix
}1&
0&
0\cr 0&
1&
0\cr 0&
0&
1\cr \end{pmatrix
} \leqno{\tt (\%o10)
}
3149 y la matriz con todos sus elementos iguales a cero,
3150 \index{zeromatrix
}\begin{Verbatim
}
3151 (
%i11) zeromatrix(2,4);
3154 \begin{pmatrix
}0&
0&
0&
0\cr 0&
0&
0&
0\cr \end{pmatrix
} \leqno{\tt (\%o11)
}
3157 También, una matriz diagonal con todos los elementos de la diagonal principal iguales puede construirse con una llamada a la función
\verb|diagmatrix|
\index{diagmatrix
},
3159 (
%i12) diagmatrix(4,%e);
3162 \begin{pmatrix
}e&
0&
0&
0\cr 0&e&
0&
0\cr 0&
0&e&
0\cr 0&
0&
0&e
\cr \end{pmatrix
} \leqno{\tt (\%o12)
}
3165 En todo caso, debe tenerse cuidado en que si la matriz no se construye de forma apropiada, Maxima no la reconoce como tal. Para saber si una expresión es reconocida como una matriz se utiliza la función
\verb|matrixp|
\index{matrixp
}; la siguiente secuencia permite aclarar lo que se pretende decir,
3167 (
%i13) matrix([[1,2,3],[4,5,6]]); /* construcción correcta */
3170 \begin{pmatrix
}\left[ 1 ,
2 ,
3 \right] &
\left[ 4 ,
5 ,
6 \right] \cr \end{pmatrix
} \leqno{\tt (\%o13)
}
3173 (
%i14) matrixp(%); /* es la anterior realmente una matriz? */
3176 \mathrm{true
}\leqno{\tt (\%o14)
}
3179 (
%i15) [[7,8,9],[0,1,2]]; /* otra matriz */
3182 \left[ \left[ 7 ,
8 ,
9 \right] ,
\left[ 0 ,
1 ,
2 \right]
3183 \right] \leqno{\tt (\%o15)
}
3186 (
%i16) matrixp(%); /* será una matriz? */
3189 \mathrm{false
}\leqno{\tt (\%o16)
}
3192 Casos particulares de submatrices son las filas y las columnas; los ejemplos se explican por sí solos:
3193 \index{col
}\index{row
}\begin{Verbatim
}
3197 \begin{pmatrix
}0\cr -
2\cr a
\cr \end{pmatrix
} \leqno{\tt (\%o17)
}
3203 \begin{pmatrix
}6&
0&-
2\cr \end{pmatrix
} \leqno{\tt (\%o18)
}
3206 Con las matrices se pueden realizar múltiples operaciones. Empezamos por el cálculo de la potencia de una matriz:
3207 \index{21@\^\ \^\
}\begin{Verbatim
}
3211 \begin{pmatrix
}33&
12&-
8\cr 18&
12&-
2\,a
\cr 36&
6\,a&a^
2-
12\cr \end{pmatrix
} \leqno{\tt (\%o19)
}
3214 Nótese que se utiliza dos veces el símbolo
\verb|^| antes del exponente; en caso de escribirlo una sola vez se calcularían las potencias de cada uno de los elementos de la matriz independientemente, como se indica en el siguiente ejemplo,
3215 \index{18@\^\
}\begin{Verbatim
}
3219 \begin{pmatrix
}9&
16&
0\cr 36&
0&
4\cr 0&
36&a^
2\cr \end{pmatrix
} \leqno{\tt (\%o38)
}
3222 Para la suma, resta y producto matriciales se utilizan los operadores
\verb|+|,
\verb|-| y
\verb|.|, respectivamente,
3223 \index{14@+
}\index{15@-
}\index{17@/
}\index{17@.
}\begin{Verbatim
}
3227 \begin{pmatrix
}12&
20&
0\cr 42&
0&
2\cr 0&
42&a^
2+a
\cr \end{pmatrix
} \leqno{\tt (\%o21)
}
3233 \begin{pmatrix
}-
6&-
12&
0\cr -
30&
0&-
6\cr 0&-
30&a-a^
2\cr \end{pmatrix
} \leqno{\tt (\%o22)
}
3239 \begin{pmatrix
}171&
48&
16\cr 54&
24&-
2\,a^
2\cr 216&
36\,a&a^
3+
24\cr \end{pmatrix
} \leqno{\tt (\%o23)
}
3242 Sin embargo, tanto el producto elemento a elemento de dos matrices, como la multiplicación por un escalar se realizan mediante el operador
\verb|*|, como indican los siguientes dos ejemplos,
3243 \index{16@*
}\begin{Verbatim
}
3247 \begin{pmatrix
}27&
64&
0\cr 216&
0&-
8\cr 0&
216&a^
3\cr \end{pmatrix
} \leqno{\tt (\%o24)
}
3253 \begin{pmatrix
}12&
16&
0\cr 24&
0&-
8\cr 0&
24&
4\,a
\cr \end{pmatrix
} \leqno{\tt (\%o25)
}
3256 Otros cálculos frecuentes con matrices son la transposición, el determinante, la inversión, el polinomio característico, así como los valores y vectores propios; para todos ellos hay funciones en Maxima:
3257 \index{transpose
}\index{determinant
}\index{invert
}\index{detout
}\index{charpoly
}\begin{Verbatim
}
3258 (
%i26) transpose(m1); /*la transpuesta*/
3261 \begin{pmatrix
}3&
6&
0\cr 4&
0&
6\cr 0&-
2&a
\cr \end{pmatrix
} \leqno{\tt (\%o26)
}
3264 (
%i27) determinant(m1); /*el determinante*/
3267 36-
24\,a
\leqno{\tt (\%o27)
}
3270 (
%i28) invert(m1); /*la inversa*/
3273 \begin{pmatrix
}{{12}\over{36-
24\,a
}}&-
{{4\,a
}\over{36-
24\,a
}}&-
{{8}\over{36
3274 -
24\,a
}}\cr -
{{6\,a
}\over{36-
24\,a
}}&
{{3\,a
}\over{36-
24\,a
}}&
{{6
3275 }\over{36-
24\,a
}}\cr {{36}\over{36-
24\,a
}}&-
{{18}\over{36-
24\,a
}}&-
3276 {{24}\over{36-
24\,a
}}\cr \end{pmatrix
} \leqno{\tt (\%o28)
}
3279 (
%i29) invert(m1),detout; /*la inversa, con el determinante fuera*/
3282 {{\begin{pmatrix
}12&-
4\,a&-
8\cr -
6\,a&
3\,a&
6\cr 36&-
18&-
24\cr \end{pmatrix
} }\over{36-
24
3283 \,a
}}\leqno{\tt (\%o29)
}
3286 (
%i30) charpoly(m1,x); /*pol. caract. con variable x*/
3289 \left(
3-x
\right)\,
\left(
12-
\left(a-x
\right)\,x
\right)-
24\,
\left(a-x
3290 \right)
\leqno{\tt (\%o30)
}
3293 (
%i31) expand(%); /*pol. caract. expandido*/
3296 -x^
3+a\,x^
2+
3\,x^
2-
3\,a\,x+
12\,x-
24\,a+
36\leqno{\tt (\%o31)
}
3299 Vamos a suponer ahora que
\verb|a| vale cero y calculemos los valores propios de la matriz,
3300 \index{eigenvalues
}\begin{Verbatim
}
3304 \begin{pmatrix
}3&
4&
0\cr 6&
0&-
2\cr 0&
6&
0\cr \end{pmatrix
} \leqno{\tt (\%o32)
}
3307 (
%i33) eigenvalues(%);
3310 \left[ \left[ -
{{\sqrt{15}\,i+
3}\over{2}} ,
{{\sqrt{15}\,i-
3}\over{2
3311 }} ,
6 \right] ,
\left[ 1 ,
1 ,
1 \right] \right] \leqno{\tt (\%o33)
}
3314 El resultado que se obtiene es una lista formada por dos sublistas, en la primera se encuentran los valores propios, que en este caso son $
\lambda_1=-
\frac{3}{2}-
\frac{\sqrt{15}}{2} i$, $
\lambda_2=-
\frac{3}{2}+
\frac{\sqrt{15}}{2} i$ y $
\lambda_3=
6$, mientras que en la segunda sublista se nos indican las multiplicidades de cada una de las $
\lambda_i$.
3316 Para el cálculo de los vectores propios,
3317 \index{eigenvectors
}\begin{Verbatim
}
3318 (
%i34) eigenvectors(%o32);
3322 \left[ \left[ \left[ -
{{\sqrt{15}\,i+
3}\over{2}} ,
{{\sqrt{15}\,i-
3
3323 }\over{2}} ,
6 \right] ,
\left[ 1 ,
1 ,
1 \right] \right] ,
\right. \\
\left.
3324 \left[ 1 , -
{{\sqrt{15}\,i+
9}\over{8}} , -
{{3\,
\sqrt{3}\,
\sqrt{5}\,i
3325 -
21}\over{8}} \right] ,
\left[ 1 ,
{{\sqrt{15}\,i-
9}\over{8}} ,
{{3
3326 \,
\sqrt{3}\,
\sqrt{5}\,i+
21}\over{8}} \right] ,
\left[ 1 ,
{{3
3327 }\over{4}} ,
{{3}\over{4}} \right] \right] \end{array
} \leqno{\tt (\%o34)
}
3330 Lo que se obtiene es, en primer lugar, los valores propios junto con sus multiplicidades, el mismo resultado que se obtuvo con la función
\verb|eigenvalues|, y a continuación los vectores propios de la matriz asociados a cada uno de los valores propios. A veces interesa que los vectores sean unitarios, de norma
1, para lo que será de utilidad la función
\verb|uniteigenvectors|
\index{uniteigenvectors
}, que se encuentra definida en el paquete
\verb|eigen.lisp|, lo que significa que antes de hacer uso de ella habrá que ejecutar la orden
\verb|load(eigen)|. También podemos solicitar los vectores propios unitarios por medio de la función
\verb|uniteigenvectors|
\index{uniteigenvectors
},
3332 (
%i35) uniteigenvectors(%o32);
3336 \left[ \left[ \left[ -
{{\sqrt{15}\,i+
3}\over{2}} ,
{{\sqrt{15}\,i-
3
3337 }\over{2}} ,
6 \right] ,
\left[ 1 ,
1 ,
1 \right] \right] ,
\right. \\
\left.
3338 \left[ {{\sqrt{2}}\over{\sqrt{23}}} , -
{{\sqrt{2}\,
\sqrt{15}\,i+
9\,
3339 \sqrt{2}}\over{8\,
\sqrt{23}}} , -
{{3\,
\sqrt{2}\,
\sqrt{3}\,
\sqrt{5}\,
3340 i-
21\,
\sqrt{2}}\over{8\,
\sqrt{23}}} \right] ,
\right. \\
\left.
\left[ {{\sqrt{2}
3341 }\over{\sqrt{23}}} ,
{{\sqrt{2}\,
\sqrt{15}\,i-
9\,
\sqrt{2}}\over{8\,
3342 \sqrt{23}}} ,
{{3\,
\sqrt{2}\,
\sqrt{3}\,
\sqrt{5}\,i+
21\,
\sqrt{2}
3343 }\over{8\,
\sqrt{23}}} \right] ,
\left[ {{2\,
\sqrt{2}}\over{\sqrt{17
3344 }}} ,
{{3\,
\sqrt{2}}\over{2\,
\sqrt{17}}} ,
{{3\,
\sqrt{2}}\over{2\,
3345 \sqrt{17}}} \right] \right] \end{array
} \leqno{\tt (\%o35)
}
3348 El rango, el menor de un elemento y una base del espacio nulo de cierta matriz pueden calcularse, respectivamente, con las funciones
\verb|rank|
\index{rank
},
\verb|minor|
\index{minor
} y
\verb|nullspace|
\index{nullspace
},
3351 (
%i36) rank(%o32); /* el rango de la matriz*/
3354 3\leqno{\tt (\%o36)
}
3357 (
%i37) minor(%o32,2,1); /* el menor de un elemento */
3360 \begin{pmatrix
}4&
0\cr 6&
0\cr \end{pmatrix
} \leqno{\tt (\%o37)
}
3363 (
%i38) nullspace(%o32); /* base del núcleo */
3364 0 errors,
0 warnings
3367 {\it span
}\left(
\right)
\leqno{\tt (\%o38)
}
3369 que es la respuesta que se obtiene cuando el espacio nulo está formado por un único elemento.
3371 De forma similar a como la instrucción
\verb|map| aplica una función a todos los elementos de una lista,
\verb|matrixmap|
\index{matrixmap
} hace lo propio con los elementos de una matriz,
3374 (
%i39) matrixmap(sin,%o32);
3377 \begin{pmatrix
}\sin 3&
\sin 4&
0\cr \sin 6&
0&-
\sin 2\cr 0&
\sin 6&
0\cr \end{pmatrix
} \leqno{\tt (\%o39)
}
3380 Avancemos un poco más en otros aspectos del álgebra lineal. Empezamos con el cálculo de la matriz de Jordan $J$ de cierta matriz dada $A$, esto es, la matriz que verifica $A=S J S^
{-
1}$, para cierta $S$. Para ello es necesario cargar previamente el paquete
\verb|diag|
\index{diag
}, se introduce la matriz $A$ y la función
\verb|jordan|
\index{jordan
} se encargará de obtener lo que buscamos en un formato que luego utilizamos para obtener las matrices $J$ y $S$. Finalmente, comprobamos los resultados:
3383 (
%i40) A: matrix([2,4,-6,0],[4,6,-3,-4],[0,0,4,0],[0,4,-6,2]);
3386 \begin{pmatrix
}2&
4&-
6&
0\cr 4&
6&-
3&-
4\cr 0&
0&
4&
0\cr 0&
4&-
6&
2\cr \end{pmatrix
} \leqno{\tt (\%o40)
}
3390 (
%i41) load(diag)$ jl: jordan(A);
3393 \left[ \left[ 6 ,
1 \right] ,
\left[ 2 ,
2 \right] ,
\left[ 4 ,
1
3394 \right] \right] \leqno{\tt (\%o42)
}
3397 \index{dispJordan
}\begin{Verbatim
}
3398 (
%i43) J: dispJordan(jl);
3401 \begin{pmatrix
}6&
0&
0&
0\cr 0&
2&
1&
0\cr 0&
0&
2&
0\cr 0&
0&
0&
4\cr \end{pmatrix
}\leqno{\tt (\%o43)
}
3404 \index{ModeMatrix
}\begin{Verbatim
}
3405 (
%i44) S: ModeMatrix (A,jl);
3408 \begin{pmatrix
}1&
4&
0&
0\cr 1&
0&
1&
1\cr 0&
0&
0&
{{2}\over{3}}\cr 1&
4&
1&
0\cr \end{pmatrix
}\leqno{\tt (\%o44)
}
3412 (
%i45) is(A = S.J.(S^^-1));
3415 \mbox{true
}\leqno{\tt (\%o45)
}
3418 Cuando los coeficientes de un sistema lineal se tengan en forma matricial y los términos independientes en un vector, el sistema se podrá resolver con la función
\verb|linsolve_by_lu|
\index{linsolve
\_by\_lu},
3421 (
%i46) A : matrix([sqrt(2),4],[a,4/5]);
3424 \begin{pmatrix
}\sqrt{2}&
4\cr a&
{{4}\over{5}}\cr \end{pmatrix
} \leqno{\tt (\%o46)
}
3431 \left[ {{1}\over{3}} , a
\right] \leqno{\tt (\%o47)
}
3434 Resolvemos ahora $A X=B$ y luego simplificamos algo el resultado
3437 (
%i48) linsolve_by_lu(A,B);
3440 \left[ \begin{pmatrix
}{{{{1}\over{3}}-
{{4\,
\left(a-
{{a
}\over{3\,
\sqrt{2}
3441 }}\right)
}\over{{{4}\over{5}}-
2\,
\sqrt{2}\,a
}}}\over{\sqrt{2}}}\cr
3442 {{a-
{{a
}\over{3\,
\sqrt{2}}}}\over{{{4}\over{5}}-
2\,
\sqrt{2}\,a
}}\cr
3443 \end{pmatrix
} ,
\mbox{false
} \right] \leqno{\tt (\%o48)
}
3450 \left[ \begin{pmatrix
}{{15\,
\sqrt{2}\,a-
\sqrt{2}}\over{15\,
\sqrt{2}\,a-
6
3451 }}\cr -
{{\left(
15\,
\sqrt{2}-
5\right)\,a
}\over{60\,a-
12\,
\sqrt{2}}}
3452 \cr \end{pmatrix
} ,
\mbox{false
} \right] \leqno{\tt (\%o49)
}
3455 El resultado que se obtiene es una lista que contiene la solución y el símbolo
\verb|false|. Cuando la resolución del sistema sea de índole numérica, esta segunda componente será sustituida por el número de condición, una medida de la bondad del resultado numérico. Veamos de aplicar esto a cierta ecuación matricial del estilo $M X = M M$
3458 (
%i50) M : matrix([sqrt(3),2/5],[3,sin(2)]);
3461 \begin{pmatrix
}\sqrt{3}&
{{2}\over{5}}\cr 3&
\sin 2\cr \end{pmatrix
} \leqno{\tt (\%o50)
}
3465 (
%i51) linsolve_by_lu(M,M.M,'floatfield);
3468 \left[ \begin{pmatrix
}1.732050807568877&
.4000000000000005\cr 3.000000000000001
3469 &
.9092974268256803\cr \end{pmatrix
} ,
49.33731560796254 \right] \leqno{\tt (\%o51)
}
3472 Veamos ahora cómo obtener algunas matrices especiales: la hessiana de una función, la de Hilbert, la de Toeplitz, la de Vandermone y la de Hankel,
3474 \index{hessian
}\begin{Verbatim
}
3475 (
%i52) hessian(exp(x^2*y+a*z),[x,y,z]);
3478 \begin{pmatrix
}4\,x^
2\,y^
2\,e^
{a\,z+x^
2\,y
}+
2\,y\,e^
{a\,z+x^
2\,y
}&
2\,x^
3
3479 \,y\,e^
{a\,z+x^
2\,y
}+
2\,x\,e^
{a\,z+x^
2\,y
}&
2\,a\,x\,y\,e^
{a\,z+x^
2\,
3480 y
}\cr 2\,x^
3\,y\,e^
{a\,z+x^
2\,y
}+
2\,x\,e^
{a\,z+x^
2\,y
}&x^
4\,e^
{a\,z+
3481 x^
2\,y
}&a\,x^
2\,e^
{a\,z+x^
2\,y
}\cr 2\,a\,x\,y\,e^
{a\,z+x^
2\,y
}&a\,x^
2
3482 \,e^
{a\,z+x^
2\,y
}&a^
2\,e^
{a\,z+x^
2\,y
}\cr \end{pmatrix
} \leqno{\tt (\%o52)
}
3485 \index{hilbert
\_matrix}\begin{Verbatim
}
3486 (
%i53) hilbert_matrix(5);
3489 \begin{pmatrix
}1&
{{1}\over{2}}&
{{1}\over{3}}&
{{1}\over{4}}&
{{1}\over{5}}
3490 \cr {{1}\over{2}}&
{{1}\over{3}}&
{{1}\over{4}}&
{{1}\over{5}}&
{{1
3491 }\over{6}}\cr {{1}\over{3}}&
{{1}\over{4}}&
{{1}\over{5}}&
{{1}\over{6
3492 }}&
{{1}\over{7}}\cr {{1}\over{4}}&
{{1}\over{5}}&
{{1}\over{6}}&
{{1
3493 }\over{7}}&
{{1}\over{8}}\cr {{1}\over{5}}&
{{1}\over{6}}&
{{1}\over{7
3494 }}&
{{1}\over{8}}&
{{1}\over{9}}\cr \end{pmatrix
} \leqno{\tt (\%o53)
}
3497 \index{toeplitz
}\begin{Verbatim
}
3498 (
%i54) toeplitz([1,2,3,4],[t,x,y,z]);
3501 \begin{pmatrix
}1&x&y&z
\cr 2&
1&x&y
\cr 3&
2&
1&x
\cr 4&
3&
2&
1\cr \end{pmatrix
} \leqno{\tt (\%o54)
}
3504 \index{vandermonde
\_matrix}\begin{Verbatim
}
3505 (
%i55) vandermonde_matrix([u,v,x,y,z]);
3506 0 errors,
0 warnings
3509 \begin{pmatrix
}1&u&u^
2&u^
3&u^
4\cr 1&v&v^
2&v^
3&v^
4\cr 1&x&x^
2&x^
3&x^
4\cr 1
3510 &y&y^
2&y^
3&y^
4\cr 1&z&z^
2&z^
3&z^
4\cr \end{pmatrix
} \leqno{\tt (\%o55)
}
3513 \index{hankel
}\begin{Verbatim
}
3514 (
%i56) hankel ([v,x,y,z],[p,q,r,s]);
3517 \begin{pmatrix
}v&x&y&z
\cr x&y&z&q
\cr y&z&q&r
\cr z&q&r&s
\cr \end{pmatrix
} \leqno{\tt (\%o56)
}
3520 El lector interesado puede obtener información sobre otras funciones matriciales accediendo a la documentación sobre el paquete
\verb|linearalgebra|
\index{linearalgebra
}.
3522 Veamos ahora cómo trabajar con matrices por bloques. Puesto que los elementos de una matriz pueden ser objetos de cualquier tipo, definamos los elementos como matrices,
3525 (
%i57) m: matrix([matrix([1,0],[0,-1]),matrix([0,1],[1,0])],
3526 [matrix(
[0,
1],
[1,
0]),matrix(
[1,
0],
[0,-
1])
]) ;
3529 \begin{pmatrix
}1&
0\cr 0&-
1\cr \end{pmatrix
} &
\begin{pmatrix
}0&
1\cr 1&
0\cr \end{pmatrix
}\cr
3530 \begin{pmatrix
}0&
1\cr 1&
0\cr \end{pmatrix
}&
\begin{pmatrix
}1&
0\cr 0&-
1\cr \end{pmatrix
}\cr
3531 \end{pmatrix
} \leqno{\tt (\%o57)
}$$
3533 Podemos ahora hacer algunas operaciones básicas con esta matriz,
3539 \begin{pmatrix
}2&
0\cr 0&-
2\cr \end{pmatrix
} &
\begin{pmatrix
}0&
2\cr 2&
0\cr \end{pmatrix
}\cr
3540 \begin{pmatrix
}0&
2\cr 2&
0\cr \end{pmatrix
}&
\begin{pmatrix
}2&
0\cr 0&-
2\cr \end{pmatrix
}\cr
3541 \end{pmatrix
} \leqno{\tt (\%o58)
}$$
3547 \begin{pmatrix
}0&
0\cr 0&
0\cr \end{pmatrix
} &
\begin{pmatrix
}0&
0\cr 0&
0\cr \end{pmatrix
}\cr
3548 \begin{pmatrix
}0&
0\cr 0&
0\cr \end{pmatrix
}&
\begin{pmatrix
}0&
0\cr 0&
0\cr \end{pmatrix
}\cr
3549 \end{pmatrix
} \leqno{\tt (\%o59)
}$$
3555 \begin{pmatrix
}3&
0\cr 0&-
3\cr \end{pmatrix
} &
\begin{pmatrix
}0&
3\cr 3&
0\cr \end{pmatrix
}\cr
3556 \begin{pmatrix
}0&
3\cr 3&
0\cr \end{pmatrix
}&
\begin{pmatrix
}3&
0\cr 0&-
3\cr \end{pmatrix
}\cr
3557 \end{pmatrix
} \leqno{\tt (\%o60)
}$$
3559 Veamos lo que pasa con la multiplicación matricial,
3565 \begin{pmatrix
}1&
1\cr 1&
1\cr \end{pmatrix
} &
\begin{pmatrix
}0&
0\cr 0&
0\cr \end{pmatrix
}\cr
3566 \begin{pmatrix
}0&
0\cr 0&
0\cr \end{pmatrix
}&
\begin{pmatrix
}1&
1\cr 1&
1\cr \end{pmatrix
}\cr
3567 \end{pmatrix
} \leqno{\tt (\%o61)
}$$
3569 Este resultado es incorrecto porque en la multiplicación matricial, los productos entre elementos se hacen con el operador
\verb|*|, que es el correcto cuando los elementos son números; pero cuando los elementos son también matrices, la multiplicación de elementos debe realizarse con el operador del producto matricial. En el ejemplo anterior, los bloques se multiplicaron elemento a elemento. Para indicarle a Maxima la operación correcta, debemos hacer uso de la variable global
\verb|matrix_element_mult|
\index{matrix
\_element\_mult},
3572 (
%i62) matrix_element_mult : "." $
3578 \begin{pmatrix
}2&
0\cr 0&
2\cr \end{pmatrix
} &
\begin{pmatrix
}0&
0\cr 0&
0\cr \end{pmatrix
}\cr
3579 \begin{pmatrix
}0&
0\cr 0&
0\cr \end{pmatrix
}&
\begin{pmatrix
}2&
0\cr 0&
2\cr \end{pmatrix
}\cr
3580 \end{pmatrix
} \leqno{\tt (\%o63)
}$$
3593 \section{Patrones y reglas
}
3595 En un programa de cálculo simbólico, éste no sólo debe tener información sobre una función u operación a partir de su definición, sino que también habrá propiedades y reglas de transformación de expresiones de las que un programa como Maxima debe tener noticia.
3597 Nos planteamos la siguiente situación: necesitamos trabajar con una función $G(x,y)$ que, independientemente de que esté definida o no, sabemos que es igual a la expresión $
\frac{H(x,y)
}{x
}$ en todo su dominio, siendo $H(x,y)$ otra función; queremos que la primera expresión sea sustituída por la segunda y además queremos tener bajo control estas sustituciones. Todo ello se consigue trabajando con patrones y reglas.
3599 Antes de definir la regla de sustitución es necesario saber a qué patrones será aplicable, para lo cual admitiremos que los argumentos de $G(x,y)$ pueden tener cualquier forma:
3601 \index{matchdeclare
}\begin{Verbatim
}
3602 (
%i1) matchdeclare ([x,y], true);
3605 \mathrm{done
}\leqno{\tt (\%o1)
}
3608 En este caso, las variables patrón serán
\verb|x| e
\verb|y|, siendo el segundo argumento una función de predicado
\footnote{Se denominan así todas aquellas funciones que devuelven como resultado de su evaluación
\emph{true
} o
\emph{false
}.
} que devolverá
\verb|true| si el patrón se cumple; en el caso presente, el patrón es universal y admite cualquier formato para estas variables. Si quisiésemos que la regla se aplicase sólo a números enteros, se debería escribir
\verb|matchdeclare (
[x,y
], integerp)|; si quisiésemos que la regla se aplicase siempre que
\verb|x| sea un número, sin imponer restricciones a
\verb|y|, escribiríamos
\verb|matchdeclare (x, numberp, y, true)|. Como se ve, los argumentos impares son variables o listas de variables y los pares las condiciones de los patrones.
3610 Se define ahora la regla de sustitución indicada más arriba, a la que llamaremos
\verb|regla1|,
3612 \index{defrule
}\begin{Verbatim
}
3613 (
%i2) defrule (regla1, G(x,y), H(x,y)/x);
3616 {\it regla_1
}:G
\left(x , y
\right)
\rightarrow {{H
\left(x , y
\right)
3617 }\over{x
}}\leqno{\tt (\%o2)
}
3620 Aplicamos ahora la regla a las expresiones $G(f,
2+k)$ y $G(G(
4,
6),
2+k)$,
3622 \index{apply1
}\begin{Verbatim
}
3623 (
%i3) apply1(G(f,2+k),regla1);
3626 {{H
\left(f , k+
2\right)
}\over{f
}}\leqno{\tt (\%o3)
}
3629 (
%i4) apply1(G(G(4,6),2+k),regla1);
3632 {{4\,H
\left(
{{H
\left(
4 ,
6\right)
}\over{4}} , k+
2\right)
}\over{H
3633 \left(
4 ,
6\right)
}}\leqno{\tt (\%o4)
}
3636 Como se ve en este último ejemplo, la regla se aplica a todas las subexpresiones que contengan a la función $G$. Además,
\verb|apply1| aplica la regla desde fuera hacia adentro. La variable global
\verb|maxapplydepth|
\index{maxapplydepth
} indica a Maxima hasta qué nivel puede bajar en la expresión para aplicar la regla; su valor por defecto es
10000, pero se lo podemos cambiar,
3639 (
%i5) maxapplydepth;
3642 10000\leqno{\tt (\%o5)
}
3645 (
%i6) maxapplydepth:1;
3651 (
%i7) apply1(G(G(4,6),2+k),regla1);
3654 {{H
\left(G
\left(
4 ,
6\right) , k+
2\right)
}\over{G
\left(
4 ,
6\right)
3655 }}\leqno{\tt (\%o7)
}
3658 Quizás sea nuestro deseo realizar la sustitución desde dentro hacia fuera, controlando también a qué niveles se aplica;
\verb|applyb1|
\index{applyb1
} y
\verb|maxapplyheight|
\index{maxapplyheight
} son las claves ahora.
3661 (
%i8) maxapplyheight:1;
3667 (
%i9) applyb1(G(G(4,6),2+k),regla1);
3670 G
\left(
{{H
\left(
4 ,
6\right)
}\over{4}} , k+
2\right)
\leqno{\tt (\%o9)
}
3673 Obsérvese que hemos estado controlando el comportamiento de las funciones $G$ y $H$ sin haberlas definido explícitamente, pero nada nos impide hacerlo,
3676 (
%i10) H(u,v):= u^v+1;
3678 (
%o10) H(u, v) := u + 1
3679 (
%i11) applyb1(G(G(4,6),2+k),regla1);
3682 G
\left(
{{4097}\over{4}} , k+
2\right)
\leqno{\tt (\%o11)
}
3685 Continuemos esta exposición con un ejemplo algo más sofisticado. Supongamos que cierta función $F$ verifica la igualdad
3687 F(x_1+x_2+
\ldots+x_n) = F(x_1) + F(x_2) +
\ldots + F(x_n) + x_1 x_2
\ldots x_n
3689 y que queremos definir una regla que realice esta transformación. Puesto que la regla se aplicará sólo cuando el argumento de $F$ sea un sumando, necesitamos una función de predicado que defina este patrón,
3691 \index{matchdeclare
}\begin{Verbatim
}
3692 (
%i12) esunasuma(expr):= not atom(expr) and op(expr)="+" $
3693 (
%i13) matchdeclare(z,esunasuma)$
3696 En la definición de la nueva regla, le indicamos a Maxima que cada vez que se encuentre con la función $F$ y que ésta tenga como argumento una suma, la transforme según se indica:
\verb|map(F, args(z))| aplica la función a cada uno de los sumandos de
\verb|z|, sumando después estos resultados con la función
\verb|apply|, finalmente a este resultado se le suma el producto de los sumandos de
\verb|z|,
3698 \index{defrule
}\begin{Verbatim
}
3699 (
%i14) defrule(regla2,
3701 apply("+",map(F, args(z))) + apply("*", args(z)));
3704 {\it regla_2
}:F
\left(z
\right)
\rightarrow {\it apply
}\left(
3705 \mbox{{}+
{}} ,
{\it map
}\left(F ,
{\it args
}\left(z
\right)
\right)
3706 \right)+
{\it apply
}\left(
\mbox{{}*
{}} ,
{\it args
}\left(z
\right)
3707 \right)
\leqno{\tt (\%o14)
}
3710 Veamos unos cuantos resultados de la aplicación de esta regla,
3712 \index{apply1
}\begin{Verbatim
}
3713 (
%i15) apply1(F(a+b), regla2);
3716 F
\left(b
\right)+a\,b+F
\left(a
\right)
\leqno{\tt (\%o15)
}
3719 (
%i16) apply1(F(a+b), regla2) - apply1(F(a+c), regla2) ;
3722 -F
\left(c
\right)-a\,c+F
\left(b
\right)+a\,b
\leqno{\tt (\%o16)
}
3725 (
%i17) apply1(F(a+b+c), regla2);
3728 F
\left(c
\right)+a\,b\,c+F
\left(b
\right)+F
\left(a
\right)
\leqno{\tt (\%o17)
}
3731 (
%i18) apply1(F(4), regla2);
3734 F
\left(
4\right)
\leqno{\tt (\%o18)
}
3737 (
%i19) apply1(F(4+5), regla2);
3740 F
\left(
9\right)
\leqno{\tt (\%o19)
}
3742 \index{simp
}\begin{Verbatim
}
3743 (
%i20) simp:false$ /* inhibe la simplificación de Maxima */
3744 (
%i21) apply1(F(4+5), regla2);
3747 4\,
5+
\left(F
\left(
4\right)+F
\left(
5\right)
\right)
\leqno{\tt (\%o21)
}
3750 (
%i22) simp:true$ /* restaura la simplificación de Maxima */
3754 F
\left(
5\right)+F
\left(
4\right)+
20\leqno{\tt (\%o23)
}
3757 En los ejemplos recién vistos, hemos tenido que indicar expresamente a Maxima en qué momento debe aplicar una regla. Otro mecanismo de definición de reglas es el aportado por
\verb|tellsimp|
\index{tellsimp
} y
\verb|tellsimpafter|
\index{tellsimpafter
}; el primero define reglas a aplicar antes de que Maxima aplique las suyas propias, y el segundo para reglas que se aplican después de las habituales de Maxima.
3759 Otra función útil en estos contextos es
\verb|declare|
\index{declare
}, con la que se pueden declarar propiedades algebraicas a nuevos operadores. A continuación se declara una operación de nombre
\verb|o| como
\emph{infija
} (esto es, que sus operandos se colocan a ambos lados del operador); obsérvese que sólo cuando la operación se declara como conmutativa Maxima considera que
\verb|a o b| es lo mismo que
\verb|b o a|, además, no ha sido necesario definir qué es lo que hace la nueva operación con sus argumentos,
3761 \index{infix
}\begin{Verbatim
}
3765 \mbox{{}o
{}}\leqno{\tt (\%o24)
}
3767 \index{is
}\begin{Verbatim
}
3768 (
%i25) is(a o b = b o a);
3771 \mathrm{false
}\leqno{\tt (\%o25)
}
3773 \index{declare
}\begin{Verbatim
}
3774 (
%i26) declare("o", commutative)$
3775 (
%i27) is(a o b = b o a);
3778 \mathrm{true
}\leqno{\tt (\%o27)
}
3792 \section{Funciones matemáticas
}
3794 En Maxima están definidas un gran número de funciones, algunas de las cuales se presentan en la
3795 Figura~
\ref{fig:funciones
}. A continuación se desarrollan algunos ejemplos sobre su uso.
3797 \index{abs
}\index{min
}\index{max
}\index{signum
}\index{binomial
}\index{genfact
}\index{sqrt
}\index{exp
}\index{log
}\index{sin
}\index{cos
}\index{tan
}\index{csc
}\index{sec
}\index{cot
}\index{asin
}\index{acos
}\index{atan
}\index{atan2
}\index{sinh
}\index{cosh
}\index{tanh
}\index{asinh
}\index{acosh
}\index{atanh
}\index{gamma
}\index{beta
}\index{erf
}\begin{figure
}
3799 \begin{tabular
}{|c|c|
} \hline
3800 \verb|abs(x)| & $
\mbox{abs
}(x)$ \\
\hline
3801 \verb|min(x1,x2,...)| & $
\min(x_1,x_2,
\ldots)$ \\
\hline
3802 \verb|max(x1,x2,...)| & $
\max(x_1,x_2,
\ldots)$ \\
\hline
3803 \verb|signum(x)| & $
\mbox{signo
}(x)=
\left\
{
3805 -
1 &
\mbox{si $x<
0$
} \\
3806 0 &
\mbox{si $x=
0$
} \\
3808 \end{array
}\right.$ \\
\hline
3809 \verb|x!| & $x!$ \\
\hline
3810 \verb|x!!| & $x!!$ \\
\hline
3811 \verb|binomial(m,n)| & $
\binom{m
}{n
}=
\frac{m(m-
1)
\ldots[m-(n-
1)
]}{n!
}$ \\
\hline
3812 \verb|genfact(m,n,p)| & $m(m-p)(m-
2p)
\ldots[m-(n-
1)p
]$ \\
\hline
3813 \verb|sqrt(x)| & $
\sqrt{x
}$ \\
\hline
3814 \verb|exp(x)| & $e^x$ \\
\hline
3815 \verb|log(x)| & $
\ln(x)$ \\
\hline
3816 \verb|sin(x)| & $
\sin(x)$ \\
\hline
3817 \verb|cos(x)| & $
\cos(x)$ \\
\hline
3818 \verb|tan(x)| & $
\tan(x)$ \\
\hline
3819 \verb|csc(x)| & $
\csc(x)$ \\
\hline
3820 \verb|sec(x)| & $
\sec(x)$ \\
\hline
3821 \verb|cot(x)| & $
\cot(x)$ \\
\hline
3822 \verb|asin(x)| & $
\arcsin(x)$ \\
\hline
3823 \verb|acos(x)| & $
\arccos(x)$ \\
\hline
3824 \verb|atan(x)| & $
\arctan(x)$ \\
\hline
3825 \verb|atan2(x,y)|& $
\arctan(
\frac{x
}{y
})
\in (-
\pi,
\pi)$ \\
\hline
3826 \verb|sinh(x)| & $
\sinh(x)=
\frac{1}{2}(e^x-e^
{-x
})$ \\
\hline
3827 \verb|cosh(x)| & $
\cosh(x)=
\frac{1}{2}(e^x+e^
{-x
})$ \\
\hline
3828 \verb|tanh(x)| & $
\tanh(x)=
\frac{\sinh(x)
}{\cosh(x)
}$ \\
\hline
3829 \verb|asinh(x)| & $
\mbox{arcsinh
}(x)$ \\
\hline
3830 \verb|acosh(x)| & $
\mbox{arccosh
}(x)$ \\
\hline
3831 \verb|atanh(x)| & $
\mbox{arctanh
}(x)$ \\
\hline
3832 \verb|gamma(x)| & $
\Gamma(x)=
\int_0^
\infty e^
{-u
}u^
{x-
1}du,
\forall x>
0$ \\
\hline
3833 \verb|gamma_incomplete(a,x)| &
3834 $
\Gamma(a,x)=
\int_x^
\infty e^
{-t
}t^
{a-
1}dt$ \\
\hline
3835 \verb|beta(a,b)| & $
\mbox{B
}(a,b)=
\frac{\Gamma(a)
\Gamma(b)
}{\Gamma(a+b)
}$ \\
\hline
3836 \verb|beta_incomplete(a,b,x)| &
3837 $
\mbox{B
}(a,b,x)=
\int_0^x (
1-t)^
{b-
1} t^
{a-
1}dt$ \\
\hline
3838 \verb|erf(x)| & $
\mbox{erf
}(x)=
\int_0^x
\frac{2}{\sqrt{\pi}}e^
{-u^
2}du$ \\
\hline
3841 \caption{Algunas funciones de Maxima.
}
3842 \label{fig:funciones
}
3846 Empecemos por algunos ejemplos,
3857 {{1}\over{3^
{x
}}}\leqno{\tt (\%o2)
}
3860 (
%i3) signum(-3^-x);
3863 -
1\leqno{\tt (\%o3)
}
3866 La función
\verb|genfact(m,n,p)|
\index{genfact
} es el factorial generalizado, de forma que
\verb|genfact(m,m,
1)| coincide con $m!$,
3868 (
%i4) genfact(5,5,1)-5!;
3873 y
\verb|genfact(m,m/
2,
2)| es igual a $m!!$,
3875 (
%i5) genfact(5,5/2,2)-5!!;
3881 Maxima siempre devuelve resultados exactos, que nosotros podemos solicitar en formato decimal,
3882 \index{asin
}\begin{Verbatim
}
3886 {{\pi}\over{2}}\leqno{\tt (\%o6)
}
3892 1.570796326794897\leqno{\tt (\%o7)
}
3895 Pero si damos el argumento en formato decimal, Maxima también devuelve el resultado en este mismo formato, sin necesidad de hacer uso de
\verb|float|,
3900 1.570796326794897\leqno{\tt (\%o8)
}
3903 Recordemos que el formato decimal lo podemos pedir con precisión arbitraria,
3905 (
%i9) fpprec:50$ bfloat(%o8);
3908 1.5707963267948966192313216916397514420985846996876_B
\times 10^
{0}\leqno{\tt (\%o9)
}
3911 La función de error está relacionada con la función de distribución de la variable aleatoria normal $X
\sim \normal(
0,
1)$ de la forma
3913 \Phi(x)=
\Pr(X
\leq x)=
\frac{1}{2}+
\frac{1}{2}\mbox{erf
}\left(
\frac{x
}{\sqrt{2}} \right),
3915 por lo que la probabilidad de que esta variable tome un valor menor que $
1.5$ es
3916 \index{erf
}\begin{Verbatim
}
3917 (
%i10) 0.5+0.5*erf(1.5/sqrt(2)),numer;
3920 0.9331927987311419\leqno{\tt (\%o10)
}
3923 Una forma más elegante de hacer lo anterior es definir nuestra propia función de distribución a partir de la de error, para lo que se hace uso del símbolo
\verb|:=|,
3924 \index{28@:=
}\begin{Verbatim
}
3925 (
%i11) F(x):=1/2+erf(x/sqrt(2))/2 $
3926 (
%i12) F(1.5),numer;
3929 0.9331927987311419\leqno{\tt (\%o12)
}
3932 No terminan aquí las funciones de Maxima; junto a las ya expuestas habría que incluir las funciones de Airy, elípticas y de Bessel, sobre las que se podrá obtener más información ejecutando la instrucción
\verb|??| y utilizando como argumento
\verb|airy|
\index{airy
},
\verb|elliptic|
\index{elliptic
} o
\verb|bessel|
\index{bessel
}, según el caso. Por ejemplo,
3936 0: airy_ai (Funciones y variables para las funciones especiales)
3937 1: airy_bi (Funciones y variables para las funciones especiales)
3938 2: airy_dai (Funciones y variables para las funciones especiales)
3939 3: airy_dbi (Funciones y variables para las funciones especiales)
3940 Enter space-separated numbers, `all' or `none':
0
3942 -- Función: airy_ai (<x>)
3943 Función Ai de Airy, tal como la definen Abramowitz y Stegun,
3944 Handbook of Mathematical Functions, Sección
10.4.
3946 La ecuación de Airy `diff (y(x), x,
2) - x y(x) =
0' tiene dos
3947 soluciones linealmente independientes, `y = Ai(x)' y `y = Bi(x)'.
3948 La derivada `diff (airy_ai(x), x)' es `airy_dai(x)'.
3950 Si el argumento `x' es un número decimal real o complejo, se
3951 devolverá el valor numérico de `airy_ai' siempre que sea posible.
3953 Véanse `airy_bi', `airy_dai' y `airy_dbi'.
3956 Maxima reconoce los dominios en el plano complejo de las funciones; los siguientes ejemplos lo demuestran:
3961 i\,
\sinh 1\leqno{\tt (\%o14)
}
3967 3.141592653589793\,i+
1.09861228866811\leqno{\tt (\%o15)
}
3973 1.570796326794897-
1.316957896924817\,i
\leqno{\tt (\%o16)
}
3984 Sin más preámbulos, veamos algunos ejemplos de cómo calcular límites con la asistencia de Maxima. En primer lugar vemos que es posible hacer que la variable se aproxime al infinito ($x
\rightarrow \infty$) haciendo uso del símbolo
\verb|inf|
\index{inf
}, o que se aproxime al menos infinito ($x
\rightarrow -
\infty$) haciendo uso de
\verb|minf|
\index{minf
},
3985 \index{limit
}\begin{Verbatim
}
3986 (
%i1) limit(1/sqrt(x),x,inf);
3993 (
%i2) limit((exp(x)-exp(-x))/(exp(x)+exp(-x)),x,minf);
3996 -
1\leqno{\tt (\%o2)
}
3998 que nos permite calcular $
\lim_{x
\rightarrow \infty} \frac{1}{\sqrt{x
}}$ y
3999 $
\lim_{x
\rightarrow -
\infty} \frac{e^x-e^
{-x
}}{e^x+e^
{-x
}}$, respectivamente.
4001 Los siguientes ejemplos muestran límites en los que la variable $x$ se aproxima a puntos de discontinuidad,
4003 (
%i3) limit((x^2-x/3-2/3)/(5*x^2-11*x+6),x,1);
4006 -
{{5}\over{3}}\leqno{\tt (\%o3)
}
4009 (
%i4) limit(1/(x-1)^2,x,1);
4012 \infty \leqno{\tt (\%o4)
}
4014 donde hemos obtenido los resultados
4016 \lim_{x
\rightarrow 1} \frac{x^
2-
\frac{x
}{3}-
\frac{2}{3}}{5x^
2-
11x+
6}=-
\frac{5}{3}
4020 \lim_{x
\rightarrow 1} \frac{1}{(x-
1)^
2}=
\infty.
4023 Sin embargo, ciertos límites no se pueden resolver sin aportar información adicional, tal es el caso de
4024 $
\lim_{x
\rightarrow 1} \frac{1}{x-
1}$, para el que podemos hacer
4026 (
%i5) limit(1/(x-1),x,1);
4029 \mbox{infinity
}\leqno{\tt (\%o5)
}
4031 donde Maxima nos responde con el símbolo
\verb|und|
\index{und
} de
\emph{undefined
} o indefinido. En tales situaciones podemos indicarle al asistente que la variable $x$ se aproxima a
1 por la derecha ($x
\rightarrow 1^+$) o por la izquierda ($x
\rightarrow 1^-$),
4032 \index{plus
}\index{minus
}\begin{Verbatim
}
4033 (
%i6) limit(1/(x-1),x,1,plus);
4036 \infty \leqno{\tt (\%o6)
}
4039 (
%i7) limit(1/(x-1),x,1,minus);
4042 -
\infty \leqno{\tt (\%o7)
}
4050 Maxima controla el cálculo de derivadas mediante la instrucción
\verb|diff|
\index{diff
}. A continuación se presentan algunos ejemplos sobre su uso,
4052 (
%i1) diff(x^log(a*x),x); /* primera derivada */
4055 x^
{\log \left(a\,x
\right)
}\,
\left(
{{\log \left(a\,x
\right)
}\over{x
4056 }}+
{{\log x
}\over{x
}}\right)
\leqno{\tt (\%o1)
}
4059 (
%i2) diff(x^log(a*x),x,2); /*derivada segunda*/
4062 x^
{\log \left(a\,x
\right)
}\,
\left(
{{\log \left(a\,x
\right)
}\over{x
4063 }}+
{{\log x
}\over{x
}}\right)^
2+x^
{\log \left(a\,x
\right)
}\,
\left(-
{{
4064 \log \left(a\,x
\right)
}\over{x^
2}}-
{{\log x
}\over{x^
2}}+
{{2}\over{x^
2
4065 }}\right)
\leqno{\tt (\%o2)
}
4068 (
%i3) factor(%); /* ayudamos a Maxima a mejorar el resultado */
4071 x^
{\log \left(a\,x
\right)-
2}\,
\left(
\log ^
2\left(a\,x
\right)+
2\,
4072 \log x\,
\log \left(a\,x
\right)-
\log \left(a\,x
\right)+
\log ^
2x-
\log
4073 x+
2\right)
\leqno{\tt (\%o3)
}
4075 donde se han calculado la primera y segunda derivadas de la función $y=x^
{\ln(ax)
}$. Nótese que en la entrada
\verb|(
%i3)| se le ha pedido al programa que factorizase la salida \verb|(%o2)|.
4077 Pedimos ahora a Maxima que nos calcule el siguiente resultado que implica derivadas parciales,
4079 \frac{\vartheta^
{10}}{\vartheta x^
3 \vartheta y^
5 \vartheta z^
2} \left( e^x
\sin(y)
\tan(z)
\right) =
4080 2 e^x
\cos(y)
\sec^
2(z)
\tan(z).
4084 (
%i4) diff(exp(x)*sin(y)*tan(z),x,3,y,5,z,2);
4087 2\,e^
{x
}\,
\cos y\,
\sec ^
2z\,
\tan z
\leqno{\tt (\%o4)
}
4090 Maxima también nos puede ayudar a la hora de aplicar la regla de la cadena en el cálculo de derivadas de funciones vectoriales con variable también vectorial. Supónganse que cierta variable $z$ depende de otras dos $x$ y $y$, las cuales a su vez dependen de $u$ y $v$. Veamos cómo se aplica la regla de la cadena para obtener
4091 $
\frac{\vartheta z
}{\vartheta v
}$, $
\frac{\vartheta z^
2}{\vartheta y
\vartheta v
}$ o $
\frac{\vartheta z^
2}{\vartheta u
\vartheta v
}$.
4092 \index{depends
}\begin{Verbatim
}
4093 (
%i5) depends(z,[x,y],[x,y],[u,v]);
4096 \left[ z
\left(x , y
\right) , x
\left(u , v
\right) , y
\left(u , v
4097 \right)
\right] \leqno{\tt (\%o5)
}
4103 {{d
}\over{d\,v
}}\,y\,
\left(
{{d
}\over{d\,y
}}\,z
\right)+
{{d
}\over{d\,
4104 v
}}\,x\,
\left(
{{d
}\over{d\,x
}}\,z
\right)
\leqno{\tt (\%o6)
}
4107 (
%i7) diff(z,y,1,v,1);
4110 {{d
}\over{d\,v
}}\,y\,
\left(
{{d^
2}\over{d\,y^
2}}\,z
\right)+
{{d
4111 }\over{d\,v
}}\,x\,
\left(
{{d^
2}\over{d\,x\,d\,y
}}\,z
\right)
\leqno{\tt (\%o7)
}
4114 (
%i8) diff(z,u,1,v,1);
4118 {{d
}\over{d\,u
}}\,y\,
\left(
{{d
}\over{d\,v
}}\,y\,
\left(
{{d^
2}\over{d
4119 \,y^
2}}\,z
\right)+
{{d
}\over{d\,v
}}\,x\,
\left(
{{d^
2}\over{d\,x\,d\,y
4120 }}\,z
\right)
\right)+
{{d^
2}\over{d\,u\,d\,v
}}\,y\,
\left(
{{d
}\over{d\,
4122 {{d
}\over{d\,u
}}\,x\,
\left(
{{d
}\over{d\,v
}}\,x\,
\left(
4123 {{d^
2}\over{d\,x^
2}}\,z
\right)+
{{d
}\over{d\,v
}}\,y\,
\left(
{{d^
2
4124 }\over{d\,x\,d\,y
}}\,z
\right)
\right)+
{{d^
2}\over{d\,u\,d\,v
}}\,x\,
4125 \left(
{{d
}\over{d\,x
}}\,z
\right)
\end{array
} \leqno{\tt (\%o8)
}
4128 La función
\verb|depends| admite un número par de argumentos, los cuales pueden ser variables o listas de variables. Las que ocupan los lugares impares son las variables dependientes y las que están en las posiciones pares las independientes; denominación ésta que tiene aquí un sentido relativo, ya que una misma variable, como la
\verb|x| de la entrada
\verb|
%i5|, puede actuar como independiente respecto de \verb|z| y como dependiente respecto de \verb|u| y \verb|v|.
4130 En cualquier momento podemos solicitarle a Maxima que nos recuerde el cuadro de dependencias,
4131 \index{dependencies
}\begin{Verbatim
}
4135 \left[ z
\left(x , y
\right) , x
\left(u , v
\right) , y
\left(u , v
4136 \right)
\right] \leqno{\tt (\%o9)
}
4139 También podemos eliminar algunas de la dependencias previamente especificadas,
4140 \index{remove
}\begin{Verbatim
}
4141 (
%i10) remove(x,dependency);
4144 \mbox{done
}\leqno{\tt (\%o10)
}
4147 (
%i11) dependencies;
4150 \left[ z
\left(x , y
\right) , y
\left(u , v
\right)
\right] \leqno{\tt (\%o11)
}
4153 (
%i12) diff(z,y,1,v,1);
4156 {{d
}\over{d\,v
}}\,y\,
\left(
{{d^
2}\over{d\,y^
2}}\,z
\right)
\leqno{\tt (\%o12)
}
4159 Veamos cómo deriva Maxima funciones definidas implícitamente. En el siguiente ejemplo, para evitar que
\verb|y| sea considerada una constante, le declararemos una dependencia respecto de
\verb|x|,
4161 (
%i13) depends(y,x)$
4164 (
%i14) diff(x^2+y^3=2*x*y,x);
4167 3\,y^
2\,
\left(
{{d
}\over{d\,x
}}\,y
\right)+
2\,x=
2\,x\,
\left(
{{d
4168 }\over{d\,x
}}\,y
\right)+
2\,y
\leqno{\tt (\%o14)
}
4171 Cuando se solicita el cálculo de una derivada sin especificar la variable respecto de la cual se deriva, Maxima utilizará el símbolo
\verb|del|
\index{del
} para representar las diferenciales,
4176 2\,x\,
{\it del
}\left(x
\right)
\leqno{\tt (\%o15)
}
4178 lo que se interpretará como $
2x dx$. Si en la expresión a derivar hay más de una variable, habrá diferenciales para todas,
4180 (
%i16) diff(x^2+y^3=2*x*y);
4183 \left(
3\,y^
2\,
\left(
{{d
}\over{d\,x
}}\,y
\right)+
2\,x
\right)\,
4184 {\it del
}\left(x
\right)=
\left(
2\,x\,
\left(
{{d
}\over{d\,x
}}\,y
\right)
4185 +
2\,y
\right)\,
{\it del
}\left(x
\right)
\leqno{\tt (\%o16)
}
4188 Recuérdese que durante este cálculo estaba todavía activa la dependencia declarada en la entrada
\verb|(
%i13)|.
4190 Finalmente, para acabar esta sección, hagamos referencia al desarrollo de Taylor de tercer grado de la función
4192 y=
\frac{x
\ln x
}{x^
2-
1}
4194 en el entorno de $x=
1$,
4195 \index{taylor
}\begin{Verbatim
}
4196 (
%i17) taylor((x*log(x))/(x^2-1),x,1,3);
4199 {{1}\over{2}}-
{{\left(x-
1\right)^
2}\over{12}}+
{{\left(x-
1\right)^
3
4200 }\over{12}}+
\cdots \leqno{\tt (\%o17)
}
4206 {{x^
3}\over{12}}-
{{x^
2}\over{3}}+
{{5\,x
}\over{12}}+
{{1}\over{3}}\leqno{\tt (\%o18)
}
4209 A continuación un ejemplo de desarrollo multivariante de la función $y=
\exp(x^
2 \sin(x y))$ alrededor del punto $(
2,
0)$ hasta grado
2 respecto de cada variable,
4211 (
%i19) taylor(exp(x^2*sin(x*y)),[x,2,2],[y,0,2]);
4214 1+
8\,y+
32\,y^
2+
\cdots +
\left(
12\,y+
96\,y^
2+
\cdots \right)\,
\left(x-
2
4215 \right)+
\left(
6\,y+
120\,y^
2+
\cdots \right)\,
\left(x-
2\right)^
2
4216 +
\cdots \leqno{\tt (\%o19)
}
4222 120\,x^
2\,y^
2-
384\,x\,y^
2+
320\,y^
2+
6\,x^
2\,y-
12\,x\,y+
8\,y+
1\leqno{\tt (\%o20)
}
4225 En ocasiones resulta necesario operar con funciones cuyas derivadas son desconocidas, quizás porque la propia función lo es. Esta situación puede llevar a que Maxima devuelva expresiones realmente complicadas de manipular. Un ejemplo es el siguiente, en el que trabajamos con una función $f$ arbitraria
4228 (
%i21) taylor(f(x + x^2),x,1,1);
4231 f
\left(
2\right)+
\left(
\left.
{{d
}\over{d\,x
}}\,f
\left(x^
2+x
\right)
4232 \right|_
{x=
1}\right)\,
\left(x-
1\right)+
\cdots \leqno{\tt (\%o21)
}
4235 Podemos facilitar las cosas si le definimos una función derivada a $f$, a la que llamaremos $df$,
4237 \index{gradef
}\begin{Verbatim
}
4238 (
%i22) gradef(f(x),df(x))$
4239 (
%i23) taylor(f(x+x^2),x,1,1);
4242 f
\left(
2\right)+
3\,
{\it df
}\left(
2\right)\,
\left(x-
1\right)+
\cdots \leqno{\tt (\%o23)
}
4245 El paquete
\verb|pdiff|
\index{pdiff
}, que se encuentra en la carpeta
\verb|share/contrib/|, aporta una solución alternativa a este problema.
4250 \section{Integrales
}
4252 La función de Maxima que controla el cálculo de integrales es
\verb|integrate|
\index{integrate
}, tanto para las definidas como indefinidas; empecemos por estas últimas,
4254 (
%i1) integrate(cos(x)^3/sin(x)^4,x);
4257 {{3\,
\sin ^
2x-
1}\over{3\,
\sin ^
3x
}}\leqno{\tt (\%o1)
}
4260 (
%i2) integrate(a[3]*x^3+a[2]*x^2+a[1]*x+a[0],x);
4263 {{a_
{3}\,x^
4}\over{4}}+
{{a_
{2}\,x^
3}\over{3}}+
{{a_
{1}\,x^
2}\over{2
4264 }}+a_
{0}\,x
\leqno{\tt (\%o2)
}
4266 que nos devuelve, respectivamente, las integrales
4268 \int \frac{\cos^
3 x
}{\sin^
4 x
} dx
4272 \int (a_3 x^
3+a_2 x^
2+a_1 x + a_0) dx.
4275 Además, este último ejemplo nos ofrece la oportunidad de ver cómo escribir coeficientes con subíndices.
4277 Ahora un par de ejemplos sobre la integral definida,
4278 \index{positive
}\index{negative
}\index{zero
}\begin{Verbatim
}
4279 (
%i3) integrate(2*x/((x-1)*(x+2)),x,3,5);
4282 2\,
\left(
{{2\,
\log 7}\over{3}}-
{{2\,
\log 5}\over{3}}+
{{\log 4
4283 }\over{3}}-
{{\log 2}\over{3}}\right)
\leqno{\tt (\%o3)
}
4286 (
%i4) float(%); /*aproximación decimal*/
4289 0.9107277692015807\leqno{\tt (\%o4)
}
4292 (
%i5) integrate(asin(x),x,0,u);
4293 Is u positive, negative, or zero?
4298 u\,
\arcsin u+
\sqrt{1-u^
2}-
1\leqno{\tt (\%o5)
}
4302 \int_3^
5 \frac{2x
}{(x-
1)(x+
2)
} dx
\approx 0.91072776920158
4306 \int_0^u
\arcsin(x) dx = u
\arcsin(u) +
\sqrt{1-u^
2}-
1,
\forall u>
0.
4308 Nótese en este último ejemplo cómo antes de dar el resultado Maxima pregunta si $u$ es positivo, negativo o nulo; tras contestarle escribiendo
\verb|positive;| (punto y coma incluido) obtenemos finalmente el resultado. En previsión de situaciones como esta, podemos darle al sistema toda la información relevante sobre los parámetros utilizados antes de pedirle el cálculo de la integral,
4310 \index{assume
}\begin{Verbatim
}
4314 \left[ u>
0 \right] \leqno{\tt (\%o6)
}
4317 (
%i7) integrate(asin(x),x,0,u);
4320 u\,
\arcsin u+
\sqrt{1-u^
2}-
1\leqno{\tt (\%o7)
}
4323 Cuando Maxima no puede resolver la integral, siempre queda el recurso de los métodos numéricos. El paquete
\verb|quadpack|
\index{quadpack
}, escrito inicialmente en Fortran y portado a Lisp para Maxima, es el encargado de estos menesteres; dispone de varias funciones, pero nos detendremos tan sólo en dos de ellas, siendo la primera la utilizada para integrales definidas en intervalos acotados,
4326 (
%i8) /* El integrador simbólico no puede con esta integral */
4327 integrate(exp(sin(x)),x,
2,
7);
4330 \int_{2}^
{7}{e^
{\sin x
}\;dx
}\leqno{\tt (\%o8)
}
4333 (
%i9) /* Resolvemos numéricamente */
4334 quad_qag(exp(sin(x)),x,
2,
7,
3);
4337 \left[ 4.747336298073747 ,
5.27060206376023 \times 10^
{-
14} ,
31 ,
0
4338 \right] \leqno{\tt (\%o9)
}
4341 La función
\verb|quad_qag|
\index{quad
\_qag} tiene un argumento extra, que debe ser un número entero entre
1 y
6, el cual hace referencia al algoritmo que la función debe utilizar para la cuadratura; la regla heurística a seguir por el usuario es dar un número tanto más alto cuanto más oscile la función en el intervalo de integración. El resultado que obtenemos es una lista con cuatro elementos: el valor aproximado de la integral, la estimación del error, el número de veces que se tuvo que evaluar el integrando y, finalmente, un código de error que será cero si no surgieron problemas.
4343 La otra función de integración numérica a la que hacemos referencia es
\verb|quad_qagi|
\index{quad
\_qagi}, a utilizar en intervalos no acotados. En el siguiente ejemplo se pretende calcular la probabilidad de que una variable aleatoria $
\chi^
2$ de $n=
4$ grados de libertad, sea mayor que la unidad ($
\Pr(
\chi^
2_4 >
1)$),
4347 (
%i11) integrate(x^(n/2-1)*exp(-y/2)/2^(n/2)*gamma(n/2),x,1,inf);
4348 Integral is divergent
4349 -- an error. To debug this try debugmode(true);
4353 (
%i12) quad_qagi(x^(n/2-1)*exp(-x/2)/2^(n/2)*gamma(n/2),x,1,inf);
4356 \left[ .9097959895689501 ,
1.913452127046495 \times 10^
{-
10} ,
165
4357 ,
0 \right] \leqno{\tt (\%o12)
}
4360 El integrador simbólico falla emitiendo un mensaje sobre la divergencia de la integral. La función
\verb|quad_qagi| ha necesitado
165 evaluaciones del integrando para alcanzar una estimación numérica de la integral, la cual se corresponde aceptablemente con la estimación que hacen los algoritmos del paquete de distribuciones de probabilidad (ver Sección~
\ref{probinf
}).
4362 Otras funciones de cuadratura numérica son
\verb|quad_qags|
\index{quad
\_qags},
\verb|quad_qawc|
\index{quad
\_qawc},
\verb|quad_qawf|
\index{quad
\_qawf},
\verb|quad_qawo|
\index{quad
\_qawo} y
\verb|quad_qaws|
\index{quad
\_qaws}, cuyas peculiaridades podrá consultar el lector interesado en el manual de referencia.
4364 La transformada de Laplace de una función $f(x)$ se define como la integral
4366 L(p)=
\int_0^
\infty f(x) e^
{-p x
} dx,
4368 siendo $p$ un número complejo. Así, la transformada de Laplace de $f(x)=k e^
{-k x
}$ es
4369 \index{laplace
}\begin{Verbatim
}
4370 (
%i13) laplace(k*exp(-k*x),x,p);
4373 {{k
}\over{p+k
}}\leqno{\tt (\%o13)
}
4375 y calculando la transformada inversa volvemos al punto de partida,
4376 \index{ilt
}\begin{Verbatim
}
4380 k\,e^
{- k\,x
}\leqno{\tt (\%o14)
}
4383 La transformada de Fourier de una función se reduce a la de Laplace cuando el argumento $p$ toma el valor $-i t$, siendo $i$ la unidad imaginaria y $t
\in \R$,
4385 F(t)=
\int_0^
\infty f(x) e^
{i t x
} dx.
4387 De esta manera, la transformada de Fourier de $f(x)=k e^
{-k x
}$ es
4389 (
%i15) laplace(k*exp(-k*x),x,-%i*t);
4392 {{k
}\over{k-i\,t
}}\leqno{\tt (\%o15)
}
4395 Nótese que si $x>
0$, la $f(x)$ anterior es precisamente la función de densidad de una variable aleatoria exponencial de parámetro $k$, por lo que este último resultado coincide precisamente con la función característica de esta misma distribución.
4397 Puesto que hablamos de la transformada de Fourier, quizás sea este un buen lugar para mencionar la transformada discreta de Fourier. Su cálculo se hace con el algoritmo de la transformada rápida, implementado en la función
\verb|fft|
\index{fft
}, que admite como argumento una lista o array de datos cuya longitud debe ser una potencia de dos. La función inversa está programada en la función
\verb|inverse_fft|
\index{inverse
\_fft}. Para más información, consúltese la documentación correspondiente a estas funciones.
4399 Como comentario final, queda hacer notar que la función
\verb|integrate| admite integrandos matriciales, tal como indica el siguiente ejemplo.
4402 (
%i16) M: matrix([sin(x), x^2+1],[cos(x), exp(x)]);
4404 $$
\begin{pmatrix
}\sin x&x^
2+
1\cr \cos x&e^
{x
}\cr \end{pmatrix
}\leqno{\tt (\%o16)
}$$
4406 (
%i17) 'integrate(M, x) = integrate(M, x);
4408 $$
\int {\begin{pmatrix
}\sin x&x^
2+
1\cr \cos x&e^
{x
}\cr \end{pmatrix
}}{\;dx
}=
\begin{pmatrix
}-
4409 \cos x&
{{x^
3}\over{3}}+x
\cr \sin x&e^
{x
}\cr \end{pmatrix
}\leqno{\tt (\%o17)
}$$
4437 \section{Ecuaciones diferenciales
}
4439 Con Maxima se pueden resolver analíticamente algunas ecuaciones diferenciales ordinarias de primer y segundo orden mediante la instrucción
\verb|ode2|
\index{ode2
}.
4441 Una ecuación diferencial de primer orden tiene la forma general $F(x,y,y')=
0$, donde $y'=
\frac{dy
}{dx
}$. Para expresar una de estas ecuaciones se hace uso de
\verb|diff|
\index{diff
},
4443 (
%i1) /* ecuación de variables separadas */
4444 ec:(x-
1)*y^
3+(y-
1)*x^
3*'diff(y,x)=
0;
4447 x^
3\,
\left(y-
1\right)\,
\left(
{{d
}\over{d\,x
}}\,y
\right)+
\left(x-
1
4448 \right)\,y^
3=
0\leqno{\tt (\%o1)
}
4450 siendo obligatorio el uso de la comilla simple (
\verb|'|) antes de
\verb|diff| al objeto de evitar el cálculo de la derivada, que por otro lado daría cero al no haberse declarado la variable
\verb|y| como dependiente de
\verb|x|. Para la resolución de esta ecuación tan solo habrá que hacer
4455 {{2\,y-
1}\over{2\,y^
2}}=
{\it \%c
}-
{{2\,x-
1}\over{2\,x^
2}}\leqno{\tt (\%o2)
}
4457 donde
\verb|
%c| representa una constante, que se ajustará de acuerdo a la condición inicial que se le imponga a la ecuación. Supóngase que se sabe que cuando $x=2$, debe verificarse que $y=-3$, lo cual haremos saber a Maxima a través de la función \verb|ic1|\index{ic1},
4459 (
%i3) ic1(%o2,x=2,y=-3);
4462 {{2\,y-
1}\over{2\,y^
2}}=-
{{x^
2+
72\,x-
36}\over{72\,x^
2}}\leqno{\tt (\%o3)
}
4465 Veamos ejemplos de otros tipos de ecuaciones diferenciales que puede resolver Maxima,
4467 (
%i4) /* ecuacion homogénea */
4468 ode2(x^
3+y^
3+
3*x*y^
2*'diff(y,x),y,x);
4471 {{4\,x\,y^
3+x^
4}\over{4}}=
{\it \%c
}\leqno{\tt (\%o4)
}
4473 En este caso, cuando no se incluye el símbolo de igualdad, se da por hecho que la expresión es igual a cero.
4476 (
%i5) /* reducible a homogénea */
4477 ode2('diff(y,x)=(x+y-
1)/(x-y-
1),y,x);
4480 {{\log \left(y^
2+x^
2-
2\,x+
1\right)+
2\,
\arctan \left(
{{x-
1}\over{y
}}
4481 \right)
}\over{4}}=
{\it \%c
}\leqno{\tt (\%o5)
}
4485 (
%i6) /* ecuación exacta */
4486 ode2((
4*x^
3+
8*y)+(
8*x-
4*y^
3)*'diff(y,x),y,x);
4489 -y^
4+
8\,x\,y+x^
4=
{\it \%c
}\leqno{\tt (\%o6)
}
4493 (
%i7) /* Bernoulli */
4494 ode2('diff(y,x)-y+sqrt(y),y,x);
4497 2\,
\log \left(
\sqrt{y
}-
1\right)=x+
{\it \%c
}\leqno{\tt (\%o7)
}
4504 \left[ y=e^
{x+
{\it \%c
}}+
2\,e^
{{{x
}\over{2}}+
{{{\it \%c
}}\over{2}}}
4505 +
1 \right] \leqno{\tt (\%o8)
}
4507 En este último caso, optamos por obtener la solución en su forma explícita.
4509 Una ecuación diferencial ordinaria de segundo orden tiene la forma general $F(x,y,y',y'')=
0$, siendo $y''$ la segunda derivada de $y$ respecto de $x$. Como ejemplo,
4511 (
%i9) 'diff(y,x)=x+'diff(y,x,2);
4514 {{d
}\over{d\,x
}}\,y=
{{d^
2}\over{d\,x^
2}}\,y+x
\leqno{\tt (\%o9)
}
4521 y=
{\it \%k_1
}\,e^
{x
}+
{{x^
2+
2\,x+
2}\over{2}}+
{\it \%k_2
}\leqno{\tt (\%o10)
}
4523 Maxima nos devuelve un resultado que depende de dos parámetros,
\verb|
%k1| y \verb|%k2|, que para ajustarlos necesitaremos proporcionar ciertas condiciones iniciales; si sabemos que cuando $x=1$ entonces $y=-1$ y $y'=\left.\frac{dy}{dx}\right|_{x=1}=2$, haremos uso de la instrucción \verb|ic2|\index{ic2},
4525 (
%i11) ic2(%,x=1,y=-1,diff(y,x)=2);
4528 y=
{{x^
2+
2\,x+
2}\over{2}}-
{{7}\over{2}}\leqno{\tt (\%o11)
}
4531 En el caso de las ecuaciones de segundo orden, también es posible ajustar los parámetros de la solución especificando condiciones de contorno, esto es, fijando dos puntos del plano por los que pase la solución; así, si la solución obtenida en
\verb|(
%o10)| debe pasar por los puntos $(-1,3)$ y $(2,\frac{5}{3})$, hacemos
4532 \index{bc2
}\begin{Verbatim
}
4533 (
%i12) bc2(%o10,x=-1,y=3,x=2,y=5/3);
4536 y=-
{{35\,e^
{x+
1}}\over{6\,e^
3-
6}}+
{{x^
2+
2\,x+
2}\over{2}}+
{{15\,e^
3+
20
4537 }\over{6\,e^
3-
6}}\leqno{\tt (\%o12)
}
4539 Nótese que este cálculo se le solicita a Maxima con
\verb|bc2|.
4542 La resolución de sistemas de ecuaciones diferenciales se hace con llamadas a la función
\verb|desolve|
\index{desolve
}. En este contexto es preciso tener en cuenta que se debe utilizar notación funcional dentro de la expresión
\verb|diff|; un ejemplo aclarará este punto, resolviendo el sistema
4546 \frac{df(x)
}{dx
} & = &
3 f(x) -
2 g(x) \\
4547 \frac{dg(x)
}{dx
} & = &
2 f(x) -
2 g(x)
4552 (
%i13) desolve(['diff(f(x),x)=3*f(x)-2*g(x),
4553 'diff(g(x),x)=
2*f(x)-
2*g(x)
],
4558 \left[ f
\left(x
\right)=
{{\left(
2\,g
\left(
0\right)-f
\left(
0\right)
4559 \right)\,e^
{- x
}}\over{3}}-
{{\left(
2\,g
\left(
0\right)-
4\,f
\left(
0
4560 \right)
\right)\,e^
{2\,x
}}\over{3}} ,
\right. \\
\left. g
\left(x
\right)=
{{\left(
4\,g
4561 \left(
0\right)-
2\,f
\left(
0\right)
\right)\,e^
{- x
}}\over{3}}-
{{
4562 \left(g
\left(
0\right)-
2\,f
\left(
0\right)
\right)\,e^
{2\,x
}}\over{3}}
4563 \right] \end{array
} \leqno{\tt (\%o13)
}
4566 Como se ve, las referecias a las funciones deben incluir la variable independiente y las ecuaciones estarán acotadas entre corchetes, así como los nombres de las funciones. Observamos en la respuesta que nos da Maxima la presencia de
\verb|f(
0)| y
\verb|g(
0)|, lo cual es debido a que se desconocen las condiciones de contorno del sistema.
4568 En este último ejemplo, supongamos que queremos resolver el sistema de ecuaciones diferenciales
4572 \frac{df(x)
}{dx
} & = & f(x) + g(x) +
3 h(x) \\
4573 \frac{dg(x)
}{dx
} & = & g(x) -
2 h(x) \\
4574 \frac{dh(x)
}{dx
} & = & f(x) + h(x)
4578 bajo las condiciones $f(
0)=-
1$, $g(
0)=
3$ y $f(
0)=
1$. En primer lugar introduciremos estas condiciones con la función
\verb|atvalue|
\index{atvalue
}, para posteriormente solicitar la resolución del sistema,
4580 (
%i14) atvalue(f(x),x=0,-1)$
4581 (
%i15) atvalue(g(x),x=0,3)$
4582 (
%i16) atvalue(h(x),x=0,1)$
4583 (
%i17) desolve(['diff(f(x),x)=f(x)+g(x)+3*h(x),
4584 'diff(g(x),x)=g(x)-
2*h(x),
4585 'diff(h(x),x)=f(x)+h(x)
],
[f(x),g(x),h(x)
]);
4588 \left[ f
\left(x
\right)=x\,e^
{2\,x
}+e^
{2\,x
}-
2\,e^
{- x
} , g
\left(x
4589 \right)=-
2\,x\,e^
{2\,x
}+
2\,e^
{2\,x
}+e^
{- x
} , h
\left(x
\right)=x\,e
4590 ^
{2\,x
}+e^
{- x
} \right] \leqno{\tt (\%o17)
}
4593 La función
\verb|desolve| también nos va a permitir resolver ecuaciones de orden mayor que dos. En el siguiente ejemplo, abordamos la resolución de la ecuación
4595 \frac{d^
3 y(x)
}{dx^
3} +
\frac{d^
2 y(x)
}{dx^
2} +
\frac{d y(x)
}{dx
} + y(x)=
0
4597 bajo las condiciones que se describen a continuación,
4600 (
%i18) atvalue('diff(y(x),x,2),x=0,v)$
4601 (
%i19) atvalue('diff(y(x),x),x=0,u)$
4602 (
%i20) atvalue(y(x),x=0,w)$
4608 (
%i21) desolve('diff(y(x),x,3)+'diff(y(x),x,2)+'diff(y(x),x)+y(x)=0, y(x));
4611 y
\left(x
\right)=
{{\left(w+v+
2\,u
\right)\,
\sin x
}\over{2}}+
{{\left(w
4612 -v
\right)\,
\cos x
}\over{2}}+
{{\left(w+v
\right)\,e^
{- x
}}\over{2}}\leqno{\tt (\%o21)
}
4616 El paquete
\verb|plotdf|
\index{plotdf
} permite generar campos de direcciones, bien de ecuaciones diferenciales de primer orden
4618 \frac{dy
}{dx
} = F(x,y),
4624 \frac{dx
}{dt
} $ = $ G(x,y) \\
4625 \frac{dy
}{dt
} $ = $ F(x,y)
4630 Los argumentos a pasar a la función
\verb|plotdf| son la función $F$, en el primer caso, y una lista con las funciones $F$ y $G$ en el segundo. Las variables serán siempre $x$ e $y$. Como ejemplo, pidamos a Maxima que genere el campo de direcciones de la ecuación diferencial $
\frac{dy
}{dx
} =
1 + y + y^
2$
4633 (
%i22) load(plotdf)$
4634 (
%i23) plotdf(1 + y + y^2);
4637 El gráfico que resulta es el de la Figura~
\ref{fig:plotdf
}~
\emph{a)
}, en el que además se observan dos trayectorias que se dibujaron de forma interactiva al hacer clic sobre dos puntos del plano.
4639 La función
\verb|plotdf| admite varias opciones, algunas de las cuales aprovechamos en el siguiente ejemplo. Supongamos el modelo predador-presa de Lotka-Volterra, dependiente de dos parámetros $h$ y $k$,
4643 \frac{dx
}{dt
} $ = $
2 x + h x y \\
4644 \frac{dy
}{dt
} $ = $ -x + k x y
4649 El siguiente código permite generar el campo de direcciones correspondiente, dándoles inicialmente a $h$ y $k$ los valores -
1.2 y
0.9, respectivamente; además, aparecerán sobre la ventana gráfica dos barras de deslizamiento para alterar de forma interactiva estos dos parámetros y ver los cambios que se producen en el campo.
4652 (
%i24) plotdf([2*x+k*x*y, -y+h*x*y],
4653 [parameters,"k=-
1.2,h=
0.9"
],
4654 [sliders,"k=-
2:
2,h=-
2:
2"
]);
4657 En la Figura~
\ref{fig:plotdf
}~
\emph{b)
} se observa el gráfico obtenido despúes de pedir trayectorias concretas que pasan por varios puntos del plano (en el archivo gráfico no aparecen las barras de deslizamiento).
4661 \includegraphics[scale=
0.35]{sdfplot1.pdf
}
4662 \includegraphics[scale=
0.35]{sdfplot2.pdf
} \\
4663 \emph{a)
} \hspace{6.5cm
} \emph{b)
} \\
4664 \caption{Campos de direcciones creados con la función 'plotdf':
\emph{a)
} campo de la ecuación $
\frac{dy
}{dx
} =
1 + y + y^
2$;
\emph{b)
} campo correspondiente al modelo predador-presa.
}
4670 Cuando Maxima no es capaz de resolver la ecuación propuesta, se podrá recurrir al método numérico de Runge-Kutta, el cual se encuentra programado en el paquete
\verb|diffeq|
\index{diffeq
}. Como primer ejemplo, nos planteamos la resolución de la ecuación
4672 \frac{dy
}{dt
} = -
2 y^
2 +
\exp(-
3 t),
4674 con la condición $y(
0)=
1$. La función
\verb|ode2| es incapaz de resolverla:
4677 (
%i25) ec: 'diff(y,t)+2*y^2-exp(-3*t)=0;
4680 {{d
}\over{d\,t
}}\,y+
2\,y^
2-e^
{-
3\,t
}=
0\leqno{\tt (\%o25)
}
4683 (
%i26) ode2(ec,y,t);
4686 \mathrm{false
}\leqno{\tt (\%o26)
}
4689 Abordamos ahora el problema con un enfoque numérico, para lo cual definimos la expresión
4691 f(t,y) =
\frac{dy
}{dt
} = -
2 y^
2 +
\exp(-
3 t)
4696 (
%i27) load(diffeq)$
4697 (
%i28) f(t,y):= -2*y^2+exp(-3*t) $
4698 (
%i29) res: runge1(f,0,5,0.5,1);
4702 \left[ \left[ 0.0 ,
0.5 ,
1.0 ,
1.5 ,
2.0 ,
2.5 ,
3.0 ,
3.5 ,
4.0
4703 ,
4.5 ,
5.0 \right] \right. , \\
\left[ 1.0 ,
.5988014211752297 ,
.4011473182183033
4704 ,
.2915932807721147 \right. ,\\
.2260784415237641 ,
0.183860316087325 ,
.1547912058210609
4705 ,
.1336603954558797 ,\\
\left.
.1176289334565761 ,
.1050518038293819 ,
.09491944625388439
4706 \right] , \\
\left[ -
1.0 , -
0.49399612385452 , -
.2720512734596094 , -
.1589442862446483
4707 \right. ,\\ -
.09974417126696171 , -
.06705614729331426 , -
.04779722499498942
4708 , -
.03570266617749457 , \\
\left.
\left. -
.02766698775990988 , -
.02207039201652747
4709 , -
.01801909665196759 \right] \right] \end{array
} \leqno{\tt (\%o29)
}
4713 points_joined = true,
4715 points(res
[1],res
[2]),
4719 La función
\verb|runge1|
\index{runge1
} necesita cinco argumentos: la función derivada $
\frac{dy
}{dt
}$, los valores inicial, $t_0$, y final, $t_1$, de la variable independiente, la amplitud de los subintervalos y el valor que toma $y$ en $t_0$. El resultado es una lista que a su vez contiene tres listas: las abscisas $t$, las ordenadas $y$ y las correspondientes derivadas. Al final del ejemplo anterior, se solicita la representación gráfica de la solución, cuyo aspecto es el mostrado por la Figura~
\ref{fig:diffeq
} \emph{a)
}. (Consúltese la sección
\ref{graficos
} para una descripción de la función
\verb|draw2d|.)
4724 \includegraphics[scale=
0.5]{diffeq1.pdf
}
4725 \includegraphics[scale=
0.5]{diffeq2.pdf
} \\
4726 \emph{a)
} \hspace{6.5cm
} \emph{b)
} \\
4727 \includegraphics[scale=
0.5]{diffeq3.pdf
}
4728 \includegraphics[scale=
0.5]{diffeq4.pdf
} \\
4729 \emph{c)
} \hspace{6.5cm
} \emph{d)
} \\
4730 \caption{Resolución numérica de ecuaciones diferenciales con 'diffeq':
\emph{a)
}, solución de la ecuación de primer orden $
\frac{dy
}{dt
} = -
2 y^
2 +
\exp(-
3 t), y(
0)=
1$;
\emph{b)
}, solución de la ecuación de segundo orden $
\frac{d^
2y
}{dt^
2} =
0.2 (
1-y^
2)
\frac{dy
}{dt
} - y$, con las condiciones $y(
0)=
0.1$ y $y'(
0)=
1$;
\emph{c)
}, diagrama $(y,y')$;
\emph{d)
}, diagrama $(y,y'')$.
}
4735 Nos planteamos ahora la resolución de la ecuación diferencial de segundo orden
4737 \frac{d^
2y
}{dt^
2} =
0.2 (
1-y^
2)
\frac{dy
}{dt
} - y,
4739 con $y(
0)=
0.1$ y $y'(
0)=
1$ para lo cual definimos en Maxima la función
4741 g(t,y,y') =
\frac{d^
2y
}{dt^
2} =
0.2 (
1-y^
2) y' - y,
4745 (
%i31) g(t,y,yp) := 0.2*(1-y^2)*yp - y $
4746 (
%i32) res: runge2(g,0,100,0.1,0.1,1)$
4747 (
%i33) midibujo(i,j):= draw2d(points_joined = true,
4749 points(res
[i
],res
[j
]),
4751 (
%i34) midibujo(1,2)$
4752 (
%i35) midibujo(2,3)$
4753 (
%i36) midibujo(2,4)$
4756 La función
\verb|runge2|
\index{runge2
} necesita seis argumentos: la función derivada $
\frac{d^
2y
}{dt^
2}$, los valores inicial, $t_0$, y final, $t_1$, de la variable independiente, la amplitud de los subintervalos y los valores que toman $y$ y su primera derivada en $t_0$. El resultado es una lista que a su vez contiene cuatro listas: las abscisas $t$, las ordenadas $y$, las correspondientes primeras derivadas y, por último, las segundas derivadas. Al final de este último ejemplo se solicitan algunos gráficos asociados a la solución, los formados con los pares $(t,y)$, $(y,y')$ y $(y,y'')$, que son los correspondientes a los apartados
\emph{b)
},
\emph{c)
} y
\emph{d)
} de la Figura~
\ref{fig:diffeq
}.
4758 El paquete
\verb|dynamics|
\index{dynamics
} dispone de otra rutina para el método de Runge-Kutta,
\verb|rk|
\index{rk
}, que permite la resolución de sistemas de ecuaciones difereciales. Para resolver el sistema
4762 \frac{dx
}{dt
} $ = $
4-x^
2-
4 y^
2 \\
4763 \frac{dy
}{dt
} $ = $ y^
2-x^
2+
1
4767 cargamos el paquete y ejecutamos la sentencia correspondiente, junto con el gráfico asociado que no mostramos.
4770 (
%i37) load(dynamics)$
4771 (
%i38) rk([4-x^2-4*y^2,y^2-x^2+1],[x,y],[-1.25,0.75],[t,0,4,0.02])$
4773 points_joined = true,
4779 Para más información sobre la sintaxis de esta función, ejecútese
\verb|? rk|. El paquete
\verb|dynamics| contiene otras funciones relacionadas con los sistemas dinámicos y los fractales.
4789 \section{Vectores y campos vectoriales
}
4792 En Maxima, los vectores se introducen como simples listas (Sección~
\ref{listas
}), siendo el caso que con ellas se pueden realizar las operaciones de adición, producto por un número y producto escalar de vectores,
4794 \index{14@+
}\index{16@*
}\index{22@.
}\begin{Verbatim
}
4795 (
%i1) [1,2,3]+[a,b,c];
4798 \left[ a+
1 , b+
2 , c+
3 \right] \leqno{\tt (\%o1)
}
4804 \left[ a\,s , b\,s , c\,s
\right] \leqno{\tt (\%o2)
}
4807 (
%i3) [1,2,3].[a,b,c]; /* producto escalar */
4810 3\,c+
2\,b+a
\leqno{\tt (\%o3)
}
4813 El cálculo del módulo de un vector se puede hacer mediante la definición previa de una función al efecto:
4818 then sqrt(apply("+",v^
2))
4819 else error("Mucho ojito: ", v, " no es un vector !!!!")$
4820 (
%i5) xx:[a,b,c,d,e]$
4821 (
%i6) yy:[3,4,-6,0,4/5]$
4822 (
%i7) modulo(xx-yy);
4825 \sqrt{\left(e-
{{4}\over{5}}\right)^
2+d^
2+
\left(c+
6\right)^
2+
\left(b
4826 -
4\right)^
2+
\left(a-
3\right)^
2}\leqno{\tt (\%o7)
}
4829 Los operadores diferenciales que son de uso común en el ámbito de los campos vectoriales están programados en el paquete
\verb|vect|
\index{vect
}, lo que implica que debe ser cargado en memoria antes de ser utilizado. Sigue a continuación una sesión de ejemplo sobre cómo usarlo.
4831 Partamos de los campos escalares $
\phi(x,y,z)=-x+y^
2+z^
2$ y $
\psi(x,y,z)=
4 x +
\log(y^
2+z^
2)$ y demostremos que sus superficies de nivel son ortogonales probando que $
\nabla \phi \cdot \nabla \psi =
0$, siendo $
\nabla$ el operador gradiente,
4833 \index{grad
}\begin{Verbatim
}
4834 (
%i8) /* Se carga el paquete */
4836 (
%i9) /* Se definen los campos escalares */
4837 phi: y^
2+z^
2-x$ psi:log(y^
2+z^
2)+
4*x$
4838 (
%i11) grad(phi) . grad(psi);
4841 {\it grad
}\left(z^
2+y^
2-x
\right)
\cdot {\it grad
}\left(
\log \left(z^
2
4842 +y^
2\right)+
4\,x
\right)
\leqno{\tt (\%o11)
}
4845 Como se ve, Maxima se limita a devolvernos la misma expresión que le introducimos; el estilo de trabajo del paquete
\verb|vect| requiere el uso de dos funciones:
\verb|express|
\index{express
} y
\verb|ev|
\index{ev
}, la primera para obtener la expresión anterior en términos de derivadas y la segunda para forzar el uso de éstas.
4852 {{d
}\over{d\,z
}}\,
\left(z^
2+y^
2-x
\right)\,
\left(
{{d
}\over{d\,z
}}\,
4853 \left(
\log \left(z^
2+y^
2\right)+
4\,x
\right)
\right)+ \\
{{d
}\over{d\,y
}}
4854 \,
\left(z^
2+y^
2-x
\right)\,
\left(
{{d
}\over{d\,y
}}\,
\left(
\log \left(z
4855 ^
2+y^
2\right)+
4\,x
\right)
\right)+ \\
{{d
}\over{d\,x
}}\,
\left(z^
2+y^
2-x
4856 \right)\,
\left(
{{d
}\over{d\,x
}}\,
\left(
\log \left(z^
2+y^
2\right)+
4\,
4857 x
\right)
\right)
\end{array
} \leqno{\tt (\%o12)
}
4863 {{4\,z^
2}\over{z^
2+y^
2}}+
{{4\,y^
2}\over{z^
2+y^
2}}-
4\leqno{\tt (\%o13)
}
4869 0\leqno{\tt (\%o14)
}
4872 Al final, hemos tenido que ayudar un poco a Maxima para que terminase de reducir la última expresión.
4874 Sea ahora el campo vectorial definido por
4875 $
\mathbf{F
}=x y
\mathbf{i
} + x^
2 z
\mathbf{j
} - e^
{x+y
} \mathbf{k
}$
4876 y pidámosle a Maxima que calcule su divergencia, ($
\nabla \cdot \mathbf{F
}$), rotacional ($
\nabla \times \mathbf{F
}$)y laplaciano ($
\nabla^
2 \mathbf{F
}$)
4878 \index{div
}\index{curl
}\index{laplacian
}\begin{Verbatim
}
4879 (
%i15) F: [x*y,x^2*z,exp(x+y)]$
4880 (
%i16) div (F); /* divergencia */
4883 {\it div
}\left(
\left[ x\,y , x^
2\,z , e^
{y+x
} \right] \right)
\leqno{\tt (\%o16)
}
4889 {{d
}\over{d\,y
}}\,
\left(x^
2\,z
\right)+
{{d
}\over{d\,z
}}\,e^
{y+x
}+
{{d
4890 }\over{d\,x
}}\,
\left(x\,y
\right)
\leqno{\tt (\%o17)
}
4893 (
%i18) ev (%, diff);
4896 y
\leqno{\tt (\%o18)
}
4899 (
%i19) curl (F); /* rotacional */
4902 {\it curl
}\left(
\left[ x\,y , x^
2\,z , e^
{y+x
} \right] \right)
\leqno{\tt (\%o19)
}
4908 \left[ {{d
}\over{d\,y
}}\,e^
{y+x
}-
{{d
}\over{d\,z
}}\,
\left(x^
2\,z
4909 \right) ,
{{d
}\over{d\,z
}}\,
\left(x\,y
\right)-
{{d
}\over{d\,x
}}\,e^
{y
4910 +x
} ,
{{d
}\over{d\,x
}}\,
\left(x^
2\,z
\right)-
{{d
}\over{d\,y
}}\,
\left(
4911 x\,y
\right)
\right] \leqno{\tt (\%o20)
}
4914 (
%i21) ev (%, diff);
4917 \left[ e^
{y+x
}-x^
2 , -e^
{y+x
} ,
2\,x\,z-x
\right] \leqno{\tt (\%o21)
}
4920 (
%i22) laplacian (F); /* laplaciano */
4923 {\it laplacian
}\left(
\left[ x\,y , x^
2\,z , e^
{y+x
} \right] \right)
\leqno{\tt (\%o22)
}
4929 {{d^
2}\over{d\,z^
2}}\,
\left[ x\,y , x^
2\,z , e^
{y+x
} \right] +
{{d^
2
4930 }\over{d\,y^
2}}\,
\left[ x\,y , x^
2\,z , e^
{y+x
} \right] +
{{d^
2
4931 }\over{d\,x^
2}}\,
\left[ x\,y , x^
2\,z , e^
{y+x
} \right] \leqno{\tt (\%o23)
}
4934 (
%i24) ev (%, diff);
4937 \left[ 0 ,
2\,z ,
2\,e^
{y+x
} \right] \leqno{\tt (\%o24)
}
4940 Nótese en todos los casos el usos de la secuencia
\verb|express| -
\verb|ev|. Si el usuario encuentra incómoda esta forma de operar, siempre podrá definir una función que automatice el proceso; por ejemplo,
4943 (
%i25) milaplaciano(v):= ev(express(laplacian(v)), diff) $
4944 (
%i26) milaplaciano(F);
4947 \left[ 0 ,
2\,z ,
2\,e^
{y+x
} \right] \leqno{\tt (\%o26)
}
4950 Por último, el paquete
\verb|vect| incluye también la definición del producto vectorial, al cual le asigna el operador
\verb|~|
\index{34@
\symbol{126}},
4953 (
%i27) [a, b, c] ~ [x, y, z];
4956 \left[ a , b , c
\right] \sim \left[ x , y , z
\right] \leqno{\tt (\%o27)
}
4962 \left[ b\,z-c\,y , c\,x-a\,z , a\,y-b\,x
\right] \leqno{\tt (\%o28)
}
4979 Maxima no está habilitado para realizar él mismo gráficos, por lo que necesitará de un programa externo que realice esta tarea. Nosotros nos limitaremos a ordenar qué tipo de gráfico queremos y Maxima se encargará de comunicárselo a la aplicación gráfica que esté activa en ese momento, que por defecto será Gnuplot. La otra herramienta gráfica es Openmath, un programa Tcl-tk que se distribuye conjuntamente con Maxima.
4983 \section{El módulo ''plot''
}
4985 Las funciones
\verb|plot2d|
\index{plot2d
} y
\verb|plot3d|
\index{plot3d
} son las que se utilizan por defecto. Veamos un ejemplo de cada una de ellas.
4988 (
%i1) xy:[[10,.6], [20,.9], [30,1.1], [40,1.3], [50,1.4]]$
4989 (
%i2) plot2d([[discrete,xy], 2*%pi*sqrt(u/980)], [u,0,50],
4990 [style,
[points,
5,
2,
6],
[lines,
1,
1]],
4991 [legend,"Datos experimentais","Predicion da teoria"
],
4992 [xlabel,"Lonxitude do pendulo (cm)"
],
[ylabel,"periodo (s)"
],
4994 "set terminal postscript eps;set out 'plot2d.eps'"
])$
4997 Se ha definido en el ejemplo una lista de puntos empíricos a representar, junto con su función teórica, pidiendo su representación gráfica en el dominio $
[0,
50]$. El resto de código hace referencia a diversas opciones:
\verb|style|,
\verb|legend|,
\verb|xlabel|,
\verb|ylabel| y
\verb|gnuplot_preamble|, esta última permite escribir código de Gnuplot para que éste lo ejecute; aquí se le pide que devuelva el gráfico en formato Postscript. El ejemplo siguiente genera una superficie explícita. Las dos salidas gráficas se representan en la Figura~
\ref{fig:plot
}
5000 (
%i3) plot3d (2^(-u^2 + v^2), [u, -3, 3], [v, -2, 2],
5002 "set terminal postscript eps;set out 'plot3d.eps'"
])$
5007 \includegraphics[scale=
0.55]{plot2d.pdf
}
5008 \includegraphics[scale=
0.55]{plot3d.pdf
} \\
5009 \caption{Gráficos generados por las funciones plot2d y plot3d.
}
5014 El control de las opciones gráficas se consigue manipulando la variable global
\verb|plot_options|
\index{plot
\_options}, cuyo estado por defecto es
5017 (
%o4) [[x, - 1.755559702014e+305, 1.755559702014e+305],
5018 [y, -
1.755559702014e+305,
1.755559702014e+305],
5019 [t, -
3,
3],
[GRID,
30,
30],
[VIEW_DIRECTION,
1,
1,
1],
5020 [COLOUR_Z, FALSE
],
[TRANSFORM_XY, FALSE
],
5021 [RUN_VIEWER, TRUE
],
[PLOT_FORMAT, GNUPLOT
],
5022 [GNUPLOT_TERM, DEFAULT
],
[GNUPLOT_OUT_FILE, FALSE
],
5023 [NTICKS,
10],
[ADAPT_DEPTH,
10],
[GNUPLOT_PM3D, FALSE
],
5024 [GNUPLOT_PREAMBLE,
],
[GNUPLOT_CURVE_TITLES,
[DEFAULT
]],
5025 [GNUPLOT_CURVE_STYLES,
[with lines
3, with lines
1,
5026 with lines
2, with lines
5, with lines
4, with lines
6,
5027 with lines
7]],
[GNUPLOT_DEFAULT_TERM_COMMAND,
],
5028 [GNUPLOT_DUMB_TERM_COMMAND, set term dumb
79 22],
5029 [GNUPLOT_PS_TERM_COMMAND, set size
1.5,
1.5;set term postsc#
5030 ript eps enhanced
color solid
24]]
5033 Para mayor información sobre el significado de cada uno de los elementos de esta lista, así como de las funciones
\verb|plot2d| y
\verb|plot3d|, consúltese la documentación.
5035 Por defecto, Maxima invocará al programa Gnuplot para la generación de gráficos, pero quizás prefiramos el programa Openmath, que forma parte de la distribución de Maxima; en tal caso tendríamos que modificar previamente las opciones guardadas en
\verb|plot_options| y a continuación solicitar el gráfico deseado, como en este caso en el que se representa la función gamma y su inversa.
5037 \index{set
\_plot\_option}\begin{verbatim
}
5038 (
%i5) set_plot_option([plot_format, openmath])$
5039 (
%i6) plot2d([gamma(x),1/gamma(x)],[x,-4.5,5],[y,-10,10])$
5042 El resto de esta sección lo dedicaremos a hacer una somera descripción del paquete
\verb|draw|, un proyecto consistente en el desarrollo de un interfaz que permita aprovechar al máximo las habilidades gráficas de Gnuplot.
5048 \section{El módulo ''draw''
}
5050 Aquí, las funciones a utilizar son
\verb|draw2d|
\index{draw2d
},
\verb|draw3d|
\index{draw3d
} y
\verb|draw|
\index{draw
}, para escenas en
2d,
3d y para gráficos múltiples y animaciones, respectivamente. Puesto que se trata de un módulo adicional, será necesario cargarlo en memoria antes de hacer uso de él. Empecemos por un ejemplo comentado.
5056 explicit(
%pi*x^3+sqrt(2)*x^2+10,x,0,2),
5058 key = "Parametric curve",
5061 parametric(
2*cos(rrr)+
3, rrr, rrr,
0,
6*
%pi),
5063 points_joined = true,
5064 point_type = diamant,
5068 key = "Empiric data",
5069 points(makelist(random(
40.0),k,
1,
5)),
5070 title = "DRAWING CURVES",
5074 Los argumentos de
\verb|draw2d| se dividen en tres grupos:
\emph{objetos gráficos
} (en el ejemplo,
\verb|explicit|
\index{explicit
},
\verb|parametric|
\index{parametric
} y
\verb|points|
\index{points
}),
\emph{opciones locales
} (que afectan directamente a la representación de los objetos gráficos, como
\verb|key|
\index{key
},
\verb|
color|
\index{color},
\verb|line_width|
\index{line
\_width},
\verb|nticks|
\index{nticks
},
\verb|line_type|
\index{line
\_type},
\verb|points_joined|
\index{points
\_joined} y
\verb|line_width|
\index{line
\_width}) y
\emph{opciones globales
} (que hacen referencia a aspectos generales del gráfico, como
\verb|title|
\index{title
} y
\verb|terminal|
\index{terminal
}). Las opciones se indican como igualdades, escribiendo a la izquierda el nombre de la opción y a la derecha el valor que se le quiera asignar, a la vez que los objetos gráficos tienen el formato igual que las llamadas a funciones, esto es, el nombre del objeto a dibujar seguido, entre paréntesis, de los parámetros que definen al objeto.
5076 Todos estos argumentos se interpretan secuencialmente, de forma que al asignar un cierto valor a una opción local, ésta afectará a todos los objetos gráficos que le sigan. En este ejemplo,
\verb|line_width| comienza teniendo valor
1, que es el asignado por defecto, luego se le da el valor
3 para la representación de la curva paramétrica y finalmente se le devuelve el valor original antes de representar los segmentos que unen los puntos aleatoriamente generados. En cambio, las dos opciones globales,
\verb|title| y
\verb|terminal|, aunque se colocaron al final, podrían haberse ubicado en cualquier otro lugar.
5078 Siguiendo con los gráficos en dos dimensiones, el siguiente ejemplo muestra una escena en la que intervienen los objetos
\verb|ellipse|
\index{ellipse
},
\verb|image|
\index{image
},
\verb|label|
\index{label
},
\verb|vector|
\index{vector
} y, ya lo conocemos,
\verb|explicit|. Antes de ejecutar esta instrucción es necesario leer el fichero gráfico
\verb|gatos.xpm|
\footnote{El formato gráfico XPM es el único que puede leer Maxima.
}
5081 (
%i3) cats: read_xpm("gatos.xpm")$
5085 ellipse(
5,
3,
8,
6,
0,
360),
5086 image(cats,
0,
0,
10,
7),
5090 label(
["This is Francisco",-
1,-
0.5]),
5091 vector(
[-
1,
0],
[2,
4]),
5093 vector(
[11,
7],
[-
2,-
1]),
5094 label(
["This is Manolita",
11,
8]),
5095 explicit(sin(x)-
2,x,-
4,
15) )$
5098 Junto con los objetos gráficos introducidos en los ejemplos, cuyos resultados se pueden ver en los apartados
\emph{a)
} y
\emph{b)
} de la Figura~
\ref{fig:draw
}, también existen
\verb|polygon|
\index{polygon
},
\verb|rectangle|
\index{rectangle
},
\verb|polar|
\index{polar
},
\verb|implicit|
\index{implicit
} y
\verb|geomap|
\index{geomap
}, este último para mapas cartográficos.
5100 Mostramos a continuación algunas escenas tridimensionales. En primer lugar, el valor absoluto de la función $
\Gamma$ de Euler, junto con sus líneas de contorno.
5104 block(
[re,im,g:gamma(x+
%i*y)],
5112 surface_hide = true,
5114 contour_levels =
[0,
0.5,
6], /* de
0 a
6 en saltos de
0.5 */
5117 explicit(gamma2(x,y),x,-
4,
4,y,-
2,
2))$
5120 Una superficie paramétrica, que junto con la anterior escena, se pueden ver ambas en la Figura~
\ref{fig:draw
}, apartados
\emph{c)
} y
\emph{d)
}.
5125 title = "Figure
8 - Klein bottle",
5126 rot_horizontal =
360,
5127 xrange =
[-
3.4,
3.4],
5128 yrange =
[-
3.4,
3.4],
5129 zrange =
[-
1.4,
1.4],
5134 surface_hide = true,
5135 parametric_surface((
2+cos(u/
2)*sin(v)-sin(u/
2)*sin(
2*v))*cos(u),
5136 (
2+cos(u/
2)*sin(v)-sin(u/
2)*sin(
2*v))*sin(u),
5137 sin(u/
2)*sin(v) + cos(u/
2)*sin(
2*v),
5138 u, -
%pi, 360*%pi/180-%pi, v, 0, 2*%pi) )$
5141 En el gráfico siguiente se combinan varios objetos: una superficie explícita, dos curvas paramétricas y dos etiquetas, cuyo aspecto es el mostrado en el apartado
\emph{e)
} de la Figura~
\ref{fig:draw
}.
5146 explicit(exp(sin(x)+cos(x^
2)),x,-
3,
3,y,-
3,
3),
5148 parametric(cos(
5*u)^
2,sin(
7*u),u-
2,u,
0,
2),
5151 parametric(t^
2,sin(t),
2+t,t,
0,
2),
5152 surface_hide = true,
5153 title = "Surface & curves",
5155 label(
["UP",-
2,
0,
3]),
5156 label(
["DOWN",
2,
0,-
3]),
5157 rot_horizontal =
10,
5162 En el siguiente ejemplo hacemos una proyección esférica del hemisferio sur, que se ve en el apartado
\emph{f)
} de la Figura~
\ref{fig:draw
}. El paquete
\verb|worldmap|
\index{worldmap
} carga en memoria las coordenadas latitud--longitud de las líneas fronterizas y costeras de todos los países del mundo, así como algunas funciones necesarias para su manipulación y procesamiento,
5165 (
%i9) load(worldmap)$
5167 surface_hide = true,
5168 rot_horizontal =
60,
5172 cos(phi)*cos(theta),
5173 cos(phi)*sin(theta),
5178 geomap(
[South_America,Africa,Australia
],
5179 [spherical_projection,
0,
0,
0,
1]),
5181 geomap(
[South_America,Africa,Australia
],
5182 [cylindrical_projection,
0,
0,
0,
1,
2]),
5190 \includegraphics[scale=
0.5]{draw1.pdf
}
5191 \includegraphics[scale=
0.5]{draw2.pdf
} \\
5192 \emph{a)
} \hspace{6.5cm
} \emph{b)
} \\
5193 \includegraphics[scale=
0.5]{draw3.pdf
}
5194 \includegraphics[scale=
0.5]{draw4.pdf
} \\
5195 \emph{c)
} \hspace{6.5cm
} \emph{d)
} \\
5196 \includegraphics[scale=
0.5]{draw5.pdf
}
5197 \includegraphics[scale=
0.5]{draw6.pdf
} \\
5198 \emph{e)
} \hspace{6.5cm
} \emph{f)
} \\
5199 \includegraphics[scale=
0.5]{draw7.pdf
} \\
5201 \caption{Gráficos generados con el paquete draw:
\emph{a)
} y
\emph{b)
} con draw2d;
\emph{c)
},
\emph{d)
},
\emph{e)
} y
\emph{f)
} con draw3d;
\emph{g)
}, un gráfico múltiple.
}
5206 Además de los objetos gráficos tridimensionales ya vistos, también se hayan definidos
\verb|points|,
\verb|vector| e
\verb|implicit|.
5208 También es posible generar múltiples gráficos en un mismo fichero o hacer animaciones en formato GIF o en la ventana gráfica. Para ver más ejemplos de gráficos generados con el paquete
\verb|draw|, se recomienda acceder a la dirección
5210 http://riotorto.users.sourceforge.net/gnuplot
5212 o consultar el sistema de ayuda de Maxima.
5214 Ya como colofón, un ejemplo de gráfico múltiple en el que se muestra también cómo dar sombreado a las superficies tridimensionales. El resultado en el apartado
\emph{g)
} de la Figura~
\ref{fig:draw
}.
5218 gr3d(surface_hide = true,
5221 explicit(sin(sqrt(x^
2+y^
2)),x,-
5,
5,y,-
5,
5))$
5226 gr3d(surface_hide = true,
5229 user_preamble = "set pm3d map",
5230 explicit(sin(sqrt(x^
2+y^
2)),x,-
5,
5,y,-
5,
5))$
5236 terminal = eps_color,
5242 Se comienza definiendo las dos escenas a representar, la función explícita y el gráfico de densidades, en sendos objetos
\verb|gr3d|, ya que ambos son de naturaleza tridimensional. Estos objetos se pasan luego a la función
\verb|draw| como argumentos, junto con algunas opciones globales. La función
\verb|draw| es realmente la que ha generado también los gráficos anteriores, siendo
\verb|draw2d| y
\verb|draw3d| sinónimos de
\verb|draw(gr2d(...))| y
\verb|draw(gr3d(...))|, respectivamente.
5253 \chapter{Probabilidades y estadística
}
5256 \section{Probabilidad
}
5259 El paquete
\emph{distrib
}\index{distrib
} contiene la definición de las funciones de distribución de probabilidad más comunes, tanto discretas (binomial, de Poisson, de Bernoulli, geométrica, uniforme discreta, hipergeométrica y binomial negativa), como continuas (normal, $t$ de Student, $
\chi^
2$ de Pearson, $F$ de Snedecor, exponencial, lognormal, gamma, beta, uniforme continua, logística, de Pareto, de Weibull, de Rayleigh, de Laplace, de Cauchy y de Gumbel). Para cada una de ellas se puede calcular la probabilidad acumulada, la función de densidad, los cuantiles, medias, varianzas y los coeficientes de asimetría y curtosis:
5262 (
%i1) load(distrib)$
5265 \index{assume
}\begin{Verbatim
}
5269 \index{cdf
\_normal}\begin{Verbatim
}
5270 (
%i3) cdf_normal(x,mu,s);
5273 {{\mathrm{erf
}\left(
{{x-
\mu}\over{\sqrt{2}\,s
}}\right)
}\over{2}}+
{{1
5274 }\over{2}}\leqno{\tt (\%o3)
}
5277 \index{pdf
\_poisson}\begin{Verbatim
}
5278 (
%i4) pdf_poisson(5,1/s);
5281 {{e^
{-
{{1}\over{s
}} }}\over{120\,s^
5}}\leqno{\tt (\%o4)
}
5284 \index{quantile
\_student\_t}\begin{Verbatim
}
5285 (
%i5) quantile_student_t(0.05,25);
5288 -
1.708140543186975\leqno{\tt (\%o5)
}
5291 \index{mean
\_weibull}\begin{Verbatim
}
5292 (
%i6) mean_weibull(3,67);
5295 {{67\,
\Gamma\left(
{{1}\over{3}}\right)
}\over{3}}\leqno{\tt (\%o6)
}
5298 \index{var
\_binomial}\begin{Verbatim
}
5299 (
%i7) var_binomial(34,1/8);
5302 {{119}\over{32}}\leqno{\tt (\%o7)
}
5305 \index{skewness
\_rayleigh}\begin{Verbatim
}
5306 (
%i8) skewness_rayleigh(1/5);
5309 {{{{\pi^
{{{3}\over{2}}}}\over{4}}-
{{3\,
\sqrt{\pi}}\over{4}}}\over{
5310 \left(
1-
{{\pi}\over{4}}\right)^
{{{3}\over{2}}}}}\leqno{\tt (\%o8)
}
5313 \index{kurtosis
\_gumbel}\begin{Verbatim
}
5314 (
%i9) kurtosis_gumbel (2,3);
5317 {{12}\over{5}}\leqno{\tt (\%o9)
}
5320 Si su argumento es un número entero positivo, la función
\verb|random(n)|
\index{random
} genera un número seudoaleatorio con distribución uniforme discreta entre $
0$ y $n-
1$, ambos inclusive; así, una simulación del lanzamiento de un dado sería
5325 3\leqno{\tt (\%o10)
}
5327 y una serie de
100 lanzamientos de una moneda,
5328 \index{makelist
}\begin{Verbatim
}
5329 (
%i11) makelist(random(2),i,1,100);
5333 \left[ 0 ,
0 ,
1 ,
0 ,
1 ,
1 ,
1 ,
0 ,
1 ,
1 ,
1 ,
0 ,
0 ,
1 ,
0 ,
1
5334 ,
0 ,
1 ,
0 ,
1 ,
1 ,
1 ,
1 ,
0 ,
0 ,
0 ,
1 ,
0 ,
1 ,
0 ,
1 ,
1 ,
0 ,
\right. \\
\left.
5335 0 ,
1 ,
1 ,
1 ,
1 ,
0 ,
0 ,
0 ,
1 ,
0 ,
1 ,
0 ,
1 ,
0 ,
1 ,
0 ,
0
5336 ,
1 ,
0 ,
0 ,
0 ,
0 ,
0 ,
1 ,
0 ,
0 ,
1 ,
1 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
\right. \\
\left.
5337 1 ,
1 ,
1 ,
0 ,
1 ,
1 ,
1 ,
0 ,
1 ,
0 ,
0 ,
0 ,
0 ,
1 ,
1 ,
0 ,
0
5338 ,
1 ,
0 ,
1 ,
0 ,
1 ,
1 ,
0 ,
0 ,
1 ,
1 ,
0 ,
0 ,
1 ,
0 ,
0 ,
1
5339 \right] \end{array
} \leqno{\tt (\%o11)
}
5342 Cuando el argumento es un número decimal positivo, la variable aleatoria que se simula es la uniforme continua, dando como resultado un número real perteneciente al intervalo $
[0,r)$,
5347 0.373047098775396\leqno{\tt (\%o12)
}
5350 El algoritmo generador de los números seudoaleatorios es determinista, de manera que partiendo de una misma semilla o valor inicial, se generará la misma secuencia de números. Para controlar el valor de esta semilla disponemos de las funciones
\verb|make_random_state|
\index{make
\_random\_state} y
\verb|set_random_state|
\index{set
\_random\_state}; por ejemplo, para definir una semilla que se genere a partir del estado actual del reloj del sistema haremos
5352 (
%i13) nueva_semilla: make_random_state(true)$
5355 Sin embargo, para que tal semilla se active en el generador, debemos indicarlos expresamente haciendo
5357 (
%i14) set_random_state(nueva_semilla)$
5360 El argumento de la función
\verb|make_random_state| puede ser también un número entero, como se hace en el ejemplo de más abajo.
5362 Veamos un caso de aplicación de todo esto. Supongamos que queremos simular diferentes series estocásticas, pero que todas ellas sean iguales. Si hacemos
5364 (
%i15) makelist(random(6),i,1,10);
5367 \left[ 3 ,
0 ,
0 ,
5 ,
0 ,
5 ,
1 ,
4 ,
4 ,
5 \right] \leqno{\tt (\%o15)
}
5370 (
%i16) makelist(random(6),i,1,10);
5373 \left[ 0 ,
4 ,
0 ,
0 ,
5 ,
4 ,
0 ,
0 ,
1 ,
5 \right] \leqno{\tt (\%o16)
}
5376 (
%i17) makelist(random(6),i,1,10);
5379 \left[ 3 ,
3 ,
3 ,
1 ,
3 ,
2 ,
1 ,
5 ,
2 ,
4 \right] \leqno{\tt (\%o17)
}
5381 lo más probable es que obtengamos tres secuencias distintas, como en el ejemplo. Pero si hacemos
5383 (
%i18) semilla: make_random_state(123456789)$
5384 (
%i19) set_random_state(semilla)$ makelist(random(6),i,1,10);
5387 \left[ 4 ,
4 ,
0 ,
1 ,
0 ,
3 ,
2 ,
5 ,
4 ,
4 \right] \leqno{\tt (\%o19)
}
5390 (
%i20) set_random_state(semilla)$ makelist(random(6),i,1,10);
5393 \left[ 4 ,
4 ,
0 ,
1 ,
0 ,
3 ,
2 ,
5 ,
4 ,
4 \right] \leqno{\tt (\%o20)
}
5396 (
%i21) set_random_state(semilla)$ makelist(random(6),i,1,10);
5399 \left[ 4 ,
4 ,
0 ,
1 ,
0 ,
3 ,
2 ,
5 ,
4 ,
4 \right] \leqno{\tt (\%o21)
}
5401 se verá que las tres secuencias son iguales, ya que antes de generar cada muestra aleatoria reiniciamos el estado del generador. La función
\verb|random| y las otras funciones relacionadas con ella discutidas hasta aquí están disponibles sin necesidad de cargar el paquete
\verb|distrib|.
5403 Sin embargo, el paquete adicional
\verb|distrib|
\index{distrib
} también permite simular muchas otras variables aleatorias, tanto discretas como continuas. A modo de ejemplo, pedimos sendas muestra de tamaño
5 de las variables aleatorias binomial $B(
5,
\frac{1}{3})$, Poisson $P(
7)$, hipergeométrica $HP(
15,
20,
7)$, exponencial $Exp(
12.5)$ y Weibull $Wei(
7,
\frac{23}{3})$; puesto que ya se ha cargado más arriba el paquete, no es necesario ejecutar nuevamente
\verb|load(distrib)|.
5405 \index{random
\_binomial}\index{random
\_poisson}\index{random
\_hypergeometric}\index{random
\_exp}\index{random
\_weibull}
5407 (
%i22) random_binomial(5,1/3,5);
5410 \left[ 3 ,
1 ,
2 ,
3 ,
2 \right] \leqno{\tt (\%o22)
}
5413 (
%i23) random_poisson(7,5);
5416 \left[ 8 ,
3 ,
10 ,
5 ,
6 \right] \leqno{\tt (\%o23)
}
5419 (
%i24) random_hypergeometric(15,20,7,5);
5422 \left[ 4 ,
2 ,
4 ,
3 ,
2 \right] \leqno{\tt (\%o24)
}
5425 (
%i25) random_exp(12.5,5);
5429 \left[ .05865376074017901 ,
.2604319923173137 ,
.07552948674579418 ,
\right. \\
\left.
5430 .02948508382731128 ,
.2117111885482312 \right] \end{array
} \leqno{\tt (\%o25)
}
5433 (
%i26) random_weibull(7,23/3,5);
5437 \left[ 6.35737206358163 ,
7.436207845095266 ,
8.101343432607079 ,
\right. \\
\left.
5438 7.835164678709573 ,
6.350884234996046 \right] \end{array
} \leqno{\tt (\%o26)
}
5441 Para más información sobre estas y otras funciones de simulación estocástica, tecléese
\verb|? distrib|.
5447 \section{Estadística descriptiva
}
5449 Maxima es capaz de realizar ciertos tipos de procesamiento de datos. El paquete
\verb|descriptive|
\index{descriptive
}, junto con otros, es el que nos puede ayudar en este tipo de tareas.
5451 Durante la instalación de Maxima se almacenan junto al fichero
\verb|descriptive.mac| tres muestras de datos:
\verb|pidigits.data|,
\verb|wind.data| y
\verb|biomed.data|, los cuales cargaremos en memoria con las funciones
\verb|read_list|
\index{read
\_list} y
\verb|read_matrix|
\index{read
\_matrix}.
5453 Las muestras univariantes deben guardarse en listas, tal como se muestra a continuación
5455 (
%i1) s1:[3,1,4,1,5,9,2,6,5,3,5];
5458 \left[ 3 ,
1 ,
4 ,
1 ,
5 ,
9 ,
2 ,
6 ,
5 ,
3 ,
5 \right] \leqno{\tt (\%o1)
}
5460 y muestras multivariantes en matrices, como en
5462 (
%i2) s2:matrix([13.17, 9.29],[14.71, 16.88],[18.50, 16.88],
5463 [10.58,
6.63],
[13.33,
13.25],
[13.21,
8.12]);
5466 \begin{pmatrix
}13.17&
9.29\cr 14.71&
16.88\cr 18.5&
16.88\cr 10.58&
6.63\cr 13.33
5467 &
13.25\cr 13.21&
8.12\cr \end{pmatrix
} \leqno{\tt (\%o2)
}
5470 En este caso, el número de columnas es igual a la dimensión de la variable aleatoria y el número de filas al tamaño muestral.
5472 Los datos se pueden introducir manualmente, pero las muestras grandes se suelen guardar en ficheros de texto. Por ejemplo, el fichero
\verb|pidigits.data| contiene los
100 primeros dígitos del n'umero $
\pi$:
5486 Para cargar estos dígitos en Maxima,
5487 \index{file
\_search}\begin{Verbatim
}
5488 (
%i3) s1 : read_list (file_search ("pidigits.data"))$
5492 100\leqno{\tt (\%o4)
}
5495 El fichero
\verb|wind.data| contiene las velocidades medias del viento registradas diariamente en
5 estaciones meteorológicas de Irlanda. Lo que sigue carga los datos,
5497 (
%i5) s2:read_matrix(file_search ("wind.data"))$
5501 100\leqno{\tt (\%o6)
}
5504 (
%i7) s2[%]; /* último registro */
5507 \left[ 3.58 ,
6.0 ,
4.58 ,
7.62 ,
11.25 \right] \leqno{\tt (\%o7)
}
5510 Algunas muestras incluyen datos no numéricos. Como ejemplo, el fichero
\verb|biomed.data| contiene cuatro medidas sanguíneas tomadas en dos grupos de pacientes,
\verb|A| y
\verb|B|, de edades diferentes,
5512 (
%i8) s3:read_matrix(file_search ("biomed.data"))$
5516 100\leqno{\tt (\%o9)
}
5519 (
%i10) s3[1]; /* primer registro */
5522 \left[ A ,
30 ,
167.0 ,
89.0 ,
25.6 ,
364 \right] \leqno{\tt (\%o10)
}
5525 El primer individuo pertenece al grupo
\verb|A|, tiene
30 años de edad y sus cuatro medidas sanguíneas fueron
167.0,
89.0,
25.6 y
364.
5527 El paquete
\verb|descriptive| incluye dos funciones que permiten hacer recuentos de datos:
\verb|continuous_freq|
\index{continuous
\_freq} y
5528 \verb|discrete_freq|
\index{discrete
\_freq}; la primera de ellas agrupa en intervalos los valores de una lista de datos y hace el recuento de cuántos hay dentro de cada una de las clases,
5530 (
%i11) load("descriptive")$
5531 (
%i12) continuous_freq(s1,5);
5534 \left[ \left[ 0 ,
1.8 ,
3.6 ,
5.4 ,
7.2 ,
9.0 \right] ,
\left[ 16
5535 ,
24 ,
18 ,
17 ,
25 \right] \right] \leqno{\tt (\%o12)
}
5538 La primera lista contiene los límites de los intervalos de clase y la segunda los recuentos correspondientes: hay
16 dígitos dentro del intervalo $
[0,
1.8]$, eso es ceros y unos,
24 dígitos en $(
1.8,
3.6]$, es decir, doses y treses, etc. El segundo parámetro indica el número de clases deseadas, que por defecto es
10.
5540 La función
\verb|discrete_freq| hace el recuento de las frecuencias absolutas en muestras discretas, tanto numéricas como categóricas. Su único argumento es una lista,
5542 (
%i13) discrete_freq(s1);
5545 \left[ \left[ 0 ,
1 ,
2 ,
3 ,
4 ,
5 ,
6 ,
7 ,
8 ,
9 \right] ,
5546 \left[ 8 ,
8 ,
12 ,
12 ,
10 ,
8 ,
9 ,
8 ,
12 ,
13 \right] \right] \leqno{\tt (\%o13)
}
5549 (
%i14) discrete_freq(transpose(col(s3,1))[1]);
5552 \left[ \left[ A , B
\right] ,
\left[ 35 ,
65 \right] \right] \leqno{\tt (\%o14)
}
5555 La primera lista contiene los valores muestrales y la segunda sus frecuencias absolutas. Las instrucciones
\verb|? col| y
\verb|? transpose| ayudarán a comprender la última entrada.
5557 En cuanto al cálculo de parámetros muestrales, el paquete
\verb|descriptive| incluye, tanto para muestras univariantes como multivariantes, medias (
\verb|mean|
\index{mean
}), varianzas (
\verb|var|
\index{var
}), desviaciones típicas (
\verb|std|
\index{std
}), momentos centrales (
\verb|central_moment|
\index{central
\_moment}) y no centrales (
\verb|noncentral_moment|
\index{noncentral
\_moment}), coeficientes de variación (
\verb|cv|
\index{cv
}), rangos (
\verb|range|
\index{range
}), medianas (
\verb|median|
\index{median
}), cuantiles (
\verb|quantile|
\index{quantile
}), coeficientes de curtosis (
\verb|kurtosis|
\index{kurtosis
}) y de asimetría (
\verb|skewness|
\index{skewness
}), y otros. En los siguientes ejemplos,
\verb|s1| es una muestra univariante y
\verb|s2| multivariante:
5563 {{471}\over{100}}\leqno{\tt (\%o15)
}
5569 4.71\leqno{\tt (\%o16)
}
5572 (
%i17) mean(s2); /* vector de medias */
5575 \left[ 9.9485 ,
10.1607 ,
10.8685 ,
15.7166 ,
14.8441 \right] \leqno{\tt (\%o17)
}
5578 Cuando la muestra contiene datos en formato decimal, los resultados serán también en este formato, pero si la muestra contiene tan solo datos enteros, los resultados serán devueltos en formato racional. En caso de querer forzar que los resultados sean devueltos siempre en formato decimal, podemos jugar con la variable global
\verb|numer|
\index{numer
}.
5585 8.425899999999999\leqno{\tt (\%o19)
}
5588 (
%i20) var(s2); /* vector de varianzas */
5591 \left[ 17.22190675000001 ,
14.98773651 ,
15.47572875 ,
32.17651044000001
5592 ,
24.42307619000001 \right] \leqno{\tt (\%o20)
}
5595 (
%i21) /* 1er y 3er cuartiles */
5596 [quantile(s1,
1/
4),quantile(s1,
3/
4)
];
5599 \left[ 2.0 ,
7.25 \right] \leqno{\tt (\%o21)
}
5605 9\leqno{\tt (\%o22)
}
5608 (
%i25) range(s2); /* vector de rangos */
5611 \left[ 19.67 ,
20.96 ,
17.37 ,
24.38 ,
22.46 \right] \leqno{\tt (\%o25)
}
5614 (
%i26) kurtosis(s1);
5617 -
1.273247946514421\leqno{\tt (\%o26)
}
5620 (
%i27) kurtosis(s2); /* vector de coef. curtosis */
5624 \left[ -
.2715445622195385 ,
0.119998784429451 , -
.4275233490482866 ,
\right. \\
\left.
5625 -
.6405361979019522 , -
.4952382132352935 \right] \end{array
} \leqno{\tt (\%o27)
}
5628 Un aspecto crucial en el análisis estadístico multivariante es la dependencia estocástica entre variables, para lo cual Maxima permite el cálculo de matrices de covarianzas (
\verb|cov|
\index{cov
}) y correlaciones (
\verb|cor|
\index{cor
}), así como de otras medidas de variabilidad global. La variable global
\verb|fpprintprec|
\index{fpprintprec
} es utilizada para limitar el número de decimales a imprimir; lo cual no afecta a la precisión de los cálculos.
5631 (
%i28) fpprintprec:7$ /* número de dígitos deseados en la salida */
5632 (
%i29) cov(s2); /* matriz de covarianzas */
5635 \begin{pmatrix
}17.22191&
13.61811&
14.37217&
19.39624&
15.42162\cr 13.61811&
14.98774
5636 &
13.30448&
15.15834&
14.9711\cr 14.37217&
13.30448&
15.47573&
17.32544&
16.18171
5637 \cr 19.39624&
15.15834&
17.32544&
32.17651&
20.44685\cr 15.42162&
14.9711
5638 &
16.18171&
20.44685&
24.42308\cr \end{pmatrix
} \leqno{\tt (\%o29)
}
5641 (
%i30) cor(s2); /* matriz de correlaciones */
5644 \begin{pmatrix
}1.0&
.8476339&
.8803515&
.8239624&
.7519506\cr .8476339&
1.0&
.8735834
5645 &
.6902622&
0.782502\cr .8803515&
.8735834&
1.0&
.7764065&
.8323358\cr .8239624
5646 &
.6902622&
.7764065&
1.0&
.7293848\cr .7519506&
0.782502&
.8323358&
.7293848
5647 &
1.0\cr \end{pmatrix
} \leqno{\tt (\%o30)
}
5650 Las funciones
\verb|global_variances|
\index{global
\_variances} y
\verb|list_correlations|
\index{list
\_correlations} calculan, respectivamente, ciertas medidas globales de variación y correlación; para más información, pídase ayuda a Maxima con el comando
\verb|describe| o con
\verb|?|.
5652 Hay varios tipos de diagramas estadísticos programados en el paquete
\verb|descriptive|:
\verb|scatterplot|
\index{scatterplot
} para gráficos de dispersión,
\verb|histogram|
\index{histogram
},
\verb|barsplot|
\index{barsplot
},
\verb|piechart|
\index{piechart
} y
\verb|boxplot|
\index{boxplot
} para el análisis homocedástico. A continuación se presentan un par de ejemplos cuyos salidas se presentan en la Figura~
\ref{fig:multivar
}.
5655 (
%i31) /* Comparando variabilidades */
5659 title = "Velocidades del viento")$
5663 (
%i32) /* Diagramas de dispersión para las
5664 tres últimas estaciones meteorológicas */
5667 point_type = circle,
5673 \includegraphics[scale=
1.0]{viento1.pdf
} \\
5674 \includegraphics[scale=
1.0]{viento2.pdf
}
5675 \caption{Gráficos para muestras multivariantes:
\emph{a)
} diagramas de cajas;
\emph{b)
} diagramas de dispersión para tres variables.
}
5676 \label{fig:multivar
}
5681 \section{Estadística inferencial
}
5683 El paquete
\verb|stats|
\index{stats
} contiene algunos procedimientos clásicos de estadística inferencial. Cada uno de estos procedimientos devuelve un objeto de tipo
\verb|inference_result|
\index{inference
\_result}, el cual guarda todos los resultados obtenidos, aunque sólo muestre una selección de ellos por defecto, los que se consideran de más relevancia; el resto permanecen ocultos y sólo serán visibles a petición del usuario. Los siguientes ejemplos aclararán su uso.
5685 Partamos de una muestra de tamaño
20 y tratemos de contrastar la hipótesis nula de que la media de la población de la cual procede es igual a
32, frente a la alternativa de que la media es diferente a este valor. Para aplicar el test de Student nos interesa saber si podemos considerar la población normal; la función
\verb|test_normality|
\index{test
\_normality} nos puede ser de ayuda,
5689 (
%i2) x: [28.9,35.0,30.6,31.3,31.9,31.7,29.3,37.8,29.9,36.8,
5690 28.0,
25.3,
39.6,
30.4,
23.3,
24.7,
38.6,
31.3,
29.8,
31.9]$
5691 (
%i3) test_normality(x);
5696 \mbox{{}SHAPIRO - WILK TEST
{}} \\
5697 {\it statistic
} =
0.9508091 \\
5698 {\it p
\_value} =
0.3795395
5700 \right.
\leqno{\tt (\%o3)
}
5703 Según este resultado, no hay evidencias suficientes para rechazar la hipótesis de normalidad. Hagamos ahora el contraste sobre la media,
5706 (
%i4) z: test_mean(x,mean=32);
5711 \mbox{{}MEAN TEST
{}} \\
5712 {\it mean
\_estimate} =
31.305 \\
5713 {\it conf
\_level} =
0.95 \\
5714 {\it conf
\_interval} =
\left[ 29.21482 ,
33.39518 \right] \\
5715 {\it method
} =
\mbox{{}Exact t-test. Unknown variance.
{}} \\
5716 {\it hypotheses
} =
\mbox{{}H0: mean =
32 , H1: mean
} \neq \mbox{32{}} \\
5717 {\it statistic
} =
0.6959443 \\
5718 {\it distribution
} =
\left[ {\it student
\_t} ,
19 \right] \\
5719 {\it p
\_value} =
0.4948895
5721 \right.
\leqno{\tt (\%o4)
}
5724 En la llamada a la función
\verb|test_mean|
\index{test
\_mean} se ha indicado mediante la opción
\verb|mean| el valor de la media en la hipótesis nula. El objeto devuelto por la función consta, como se ve, de varios elementos: el título del objeto, la media muestral, el nivel de confianza, el intervalo de confianza, información sobre el método utilizado, hipótesis a contrastar, estadístico de contraste, su distribución y el $p$-valor correspondiente. Si ahora quisiésemos extraer la media muestral para utilizar en otros cálculos,
5726 \index{take
\_inference}\begin{Verbatim
}
5727 (
%i5) take_inference(mean_estimate,z);
5730 31.305\leqno{\tt (\%o5)
}
5733 En caso de querer extraer más de un resultado,
5736 (
%i6) take_inference([p_value,statistic],z);
5739 \left[ 0.4948895 ,
0.6959443 \right] \leqno{\tt (\%o6)
}
5742 Para saber con certeza qué resultados guarda el objeto devuelto haremos uso de la función
\verb|items_inference|
\index{items
\_inference}, con lo que comprobamos que la función
\verb|test_mean| no oculta ninguno de sus resultados,
5745 (
%i7) items_inference(z);
5748 \left[ {\it mean
\_estimate} ,
{\it conf
\_level} ,
5749 {\it conf
\_interval} ,
{\it method
} ,
{\it hypotheses
} ,
5750 {\it statistic
} ,
{\it distribution
} ,
{\it p
\_value} \right] \leqno{\tt (\%o7)
}
5753 En caso de que la muestra no procediese de una población normal, y si el tamaño muestral fuese suficientemente grande, se podría hacer uso de la opción
\verb|asymptotic=true|, si la desviación típica de la población fuese conocida, por ejemplo $
\sigma=
4.5$, podría añadirse la opción
\verb|dev=
4.5|. En fin, las opciones que admite esta función permiten al usuario tener cierto control sobre el procedimiento; para más información consúltese el manual.
5755 Si la población de referencia no es normal y la muestra es pequeña, siempre se puede acudir a un test no paramétrico para realizar un contraste sobre la mediana,
5757 \index{test
\_signed\_rank}\begin{Verbatim
}
5758 (
%i8) signed_rank_test(x,median=32);
5763 \mbox{{}SIGNED RANK TEST
{}} \\
5764 {\it med
\_estimate} =
30.95 \\
5765 {\it method
} =
\mbox{{}Asymptotic test. Ties
{}} \\
5766 {\it hypotheses
} =
\mbox{{}H0: med =
32 , H1: med
} \neq \mbox{32{}} \\
5767 {\it statistic
} =
75 \\
5768 {\it distribution
} =
\left[ {\it normal
} ,
104.5 ,
26.78152 \right] \\
5769 {\it p
\_value} =
0.2706766
5771 \right.
\leqno{\tt (\%o8)
}
5774 Consúltese el manual de referencia de Maxima para ver qué otros tests están programados en el paquete
\verb|stats|, así como las opciones que se pueden utilizar en cada caso.
5785 \chapter{Otros métodos numéricos
}
5786 \label{sec:numericos
}
5790 \section{Interpolación
}
5792 El paquete
\verb|interpol|
\index{interpol
} permite abordar el problema de la interpolación desde tres enfoques: lineal, polinomio de Lagrange y
\emph{splines
} cúbicos.
5794 A lo largo de esta sección vamos a suponer que disponemos de los valores empíricos de la siguiente tabla:
5797 \begin{tabular
}{|c||c|c|c|c|c|
} \hline
5798 x &
7 &
8 &
1 &
3 &
6 \\
\hline
5799 y &
2 &
2 &
5 &
2 &
7 \\
\hline
5803 Nos planteamos en primer lugar el cálculo de la función de interpolación lineal, para lo cual haremos uso de la función
\verb|linearinterpol|,
5806 (
%i1) load(interpol)$
5810 (
%i2) datos: [[7,2],[8,2],[1,5],[3,2],[6,7]]$
5813 \index{linearinterpol
}\begin{Verbatim
}
5814 (
%i3) linearinterpol(datos);
5818 \left(
{{13}\over{2}}-
{{3\,x
}\over{2}}\right)\,
{\it charfun_2
}\left(
5819 x , -
\infty ,
3\right)+
2\,
{\it charfun_2
}\left(x ,
7 ,
\infty
5820 \right)+ \\
\left(
37-
5\,x
\right)\,
{\it charfun_2
}\left(x ,
6 ,
7\right)+
5821 \left(
{{5\,x
}\over{3}}-
3\right)\,
{\it charfun_2
}\left(x ,
3 ,
6
5822 \right)
\end{array
} \leqno{\tt (\%o3)
}
5829 Empezamos cargando el paquete que define las funciones de interpolación y a continuación introducimos los pares de datos en forma de lista. La función
\verb|linearinterpol| devuelve una expresión definida a trozos, en la que
\verb|charfun2(x,a,b)|
\index{charfun2
} devuelve
1 si el primer argumento pertence al intervalo $
[a, b)$ y
0 en caso contrario. Por último, definimos cierta función
\verb|f| previa evaluación (dos comillas simples) de la expresión devuelta por
\verb|linearinterpol|. Esta función la podemos utilizar ahora tanto para interpolar como para extrapolar:
5832 (
%i5) map(f,[7.3,25/7,%pi]);
5835 \left[ 2 ,
{{62}\over{21}} ,
{{5\,
\pi}\over{3}}-
3 \right] \leqno{\tt (\%o5)
}
5842 \left[ 2.0 ,
2.952380952380953 ,
2.235987755982989 \right] \leqno{\tt (\%o6)
}
5845 Unos comentarios antes de continuar. Los datos los hemos introducido como una lista de pares de números, pero también la función admite una matriz de dos columnas o una lista de números, asignándole en este último caso las abscisas secuencialmente a partir de la unidad; además, la lista de pares de la variable
\verb|datos| no ha sido necesario ordenarla respecto de la primera coordenada, asunto del que ya se encarga Maxima por cuenta propia.
5847 El polinomio de interpolación de Lagrange se calcula con la función
\verb|lagrange|; en el siguiente ejemplo le daremos a los datos un formato matricial y le indicaremos a Maxima que nos devuelva el polinomio con variable independiente
\verb|w|,
5850 (
%i7) datos2: matrix([7,2],[8,2],[1,5],[3,2],[6,7]);
5853 \begin{pmatrix
}7&
2\cr 8&
2\cr 1&
5\cr 3&
2\cr 6&
7\cr \end{pmatrix
} \leqno{\tt (\%o7)
}
5856 \index{lagrange
}\begin{Verbatim
}
5857 (
%i8) lagrange(datos2,varname='w);
5860 {{73\,w^
4}\over{420}}-
{{701\,w^
3}\over{210}}+
{{8957\,w^
2}\over{420
5861 }}-
{{5288\,w
}\over{105}}+
{{186}\over{5}}\leqno{\tt (\%o8)
}
5869 (
%i10) map(g,[7.3,25/7,%pi]), numer;
5872 \left[ 1.043464999999799 ,
5.567941928958199 ,
2.89319655125692
5873 \right] \leqno{\tt (\%o10)
}
5876 Disponemos en este punto de dos funciones de interpolación; representémoslas gráficamente junto con los datos empíricos,
5884 key = "Interpolador lineal",
5885 explicit(f(x),x,
0,
10),
5887 key = "Interpolador de Lagrange",
5888 explicit(g(x),x,
0,
10),
5889 key = "Datos empiricos",
5893 cuyo resultado se ve en el apartado
\emph{a)
} de la Figura~
\ref{fig:int
}.
5896 El método de los
\emph{splines
} cúbicos consiste en calcular polinomios interpoladores de tercer grado entre dos puntos de referencia consecutivos, de manera que sus derivadas cumplan ciertas condiciones que aseguren una curva sin cambios bruscos de dirección. La función que ahora necesitamos es
\verb|cspline|,
5898 \index{cspline
}\begin{Verbatim
}
5899 (
%i13) cspline(datos);
5903 \left(
{{1159\,x^
3}\over{3288}}-
{{1159\,x^
2}\over{1096}}-
{{6091\,x
5904 }\over{3288}}+
{{8283}\over{1096}}\right)\,
{\it charfun_2
}\left(x ,
5905 -
\infty ,
3\right)+ \\
\left(-
{{2587\,x^
3}\over{1644}}+
{{5174\,x^
2
5906 }\over{137}}-
{{494117\,x
}\over{1644}}+
{{108928}\over{137}}\right)\,
5907 {\it charfun_2
}\left(x ,
7 ,
\infty \right)+ \\
\left(
{{4715\,x^
3}\over{1644
5908 }}-
{{15209\,x^
2}\over{274}}+
{{579277\,x
}\over{1644}}-
{{199575}\over{274
5909 }}\right)\,
{\it charfun_2
}\left(x ,
6 ,
7\right)+ \\
\left(-
{{3287\,x^
3
5910 }\over{4932}}+
{{2223\,x^
2}\over{274}}-
{{48275\,x
}\over{1644}}+
{{9609
5911 }\over{274}}\right)\,
{\it charfun_2
}\left(x ,
3 ,
6\right)
\end{array
} \leqno{\tt (\%o13)
}
5919 (
%i15) map(s1,[7.3,25/7,%pi]), numer;
5922 \left[ 1.438224452554664 ,
3.320503453379974 ,
2.227405312429507
5923 \right] \leqno{\tt (\%o15)
}
5926 La función
\verb|cspline| admite, además de la opción
\verb|'varname| que ya se vió anteriormente, otras dos a las que se hace referencia con los símbolos
\verb|'d1| y
\verb|'dn|, que indican las primeras derivadas en las abscisas de los extremos; estos valores establecen las condiciones de contorno y con ellas Maxima calculará los valores de las segundas derivadas en estos mismos puntos extremos; en caso de no suministrarse, como en el anterior ejemplo, las segundas derivadas se igualan a cero. En el siguiente ejemplo hacemos uso de estas opciones,
5929 (
%i16) cspline(datos,'varname='z,d1=1,dn=0);
5933 \left(
{{2339\,z^
3}\over{2256}}-
{{14515\,z^
2}\over{2256}}+
{{24269\,z
5934 }\over{2256}}-
{{271}\over{752}}\right)\,
{\it charfun_2
}\left(z ,
5935 -
\infty ,
3\right)+ \\
\left(-
{{1553\,z^
3}\over{564}}+
{{35719\,z^
2
5936 }\over{564}}-
{{68332\,z
}\over{141}}+
{{174218}\over{141}}\right)\,
5937 {\it charfun_2
}\left(z ,
7 ,
\infty \right)+ \\
\left(
{{613\,z^
3}\over{188
5938 }}-
{{35513\,z^
2}\over{564}}+
{{56324\,z
}\over{141}}-
{{38882}\over{47
5939 }}\right)\,
{\it charfun_2
}\left(z ,
6 ,
7\right)+ \\
\left(-
{{4045\,z^
3
5940 }\over{5076}}+
{{1893\,z^
2}\over{188}}-
{{5464\,z
}\over{141}}+
{{2310
5941 }\over{47}}\right)\,
{\it charfun_2
}\left(z ,
3 ,
6\right)
\end{array
} \leqno{\tt (\%o16)
}
5949 (
%i18) map(s2,[7.3,25/7,%pi]), numer;
5952 \left[ 1.595228723404261 ,
2.88141531519733 ,
2.076658794432369
5953 \right] \leqno{\tt (\%o18)
}
5959 \includegraphics[scale=
0.55]{interpol1.pdf
}
5960 \includegraphics[scale=
0.55]{interpol2.pdf
} \\
5961 \emph{a)
} \hspace{6.5cm
} \emph{b)
} \\
5962 \caption{Interpolación:
\emph{a)
} lineal y de Lagrange;
\emph{b)
} \emph{Splines
} cúbicos.
}
5967 Con esto hemos obtenido dos interpoladores distintos por el método de los
\emph{splines
} cúbicos; con el siguiente código pedimos su representación gráfica, cuyo resultado se observa en el apartado
\emph{b)
} de la Figura~
\ref{fig:int
}.
5972 explicit(s1(x),x,
0,
10),
5975 explicit(s2(x),x,
0,
10),
5976 key = "Datos empiricos",
5986 \section{Ajuste por mínimos cuadrados
}
5989 Existe en Maxima la posibilidad de ajustar por mínimos cuadrados a datos empíricos los parámetros de curvas arbitrarias mediante las funciones del paquete
\verb|lsquares|
\index{lsquares
}. Vamos a simular una muestra de tamaño
100 de valores $x$ en el intervalo $
[0,
10]$. Con estas abscisas calculamos después las ordenadas a partir de la suma de una señal determinista ($f$) más un ruido gaussiano. Para hacer la simulación necesitamos cargar en primer lugar al paquete
\verb|distrib|.
5991 \index{random
\_continuous\_uniform}\begin{Verbatim
}
5992 (
%i1) load(distrib)$
5993 (
%i2) abs: makelist(random_continuous_uniform(0,10),k,1,100)$
5994 (
%i3) f(x):=3*(x-5)^2$
5995 (
%i4) data: apply(matrix,makelist([x, f(x)+random_normal(0,1)],x,abs))$
5998 Aunque la señal determinista obedece a una función polinómica de segundo grado, si no lo sabemos a priori intentamos ajustar un polinomio cúbico:
6000 \index{lsquares
\_estimates}\begin{Verbatim
}
6001 (
%i5) load(lsquares)$
6002 (
%i6) param: lsquares_estimates(data,[x,y],
6003 y=a*x^
3+b*x^
2+c*x+d,
[a,b,c,d
]), numer;
6007 \left[ \left[ a=-
0.002705800223881305 , b=
3.018798873646606 \right.
\right.
6008 , \\
\left.
\left. c=-
29.94151342602112 , d=
74.78603431944423 \right] \right] \end{array
} \leqno{\tt (\%o6)
}
6011 Vemos claramente que el término de tercer grado es supérfluo, por lo que reajustamos al de segundo grado,
6014 (
%i7) param: lsquares_estimates(data,[x,y],
6015 y=b*x^
2+c*x+d,
[b,c,d
]), numer;
6018 \left[ \left[ b=
2.979110687882263 , c=-
29.78353057922009 , d=
74.64523259993118
6019 \right] \right] \leqno{\tt (\%o7)
}
6022 Ahora estamos en disposición de estudiar los residuos para valorar el ajuste. En primer lugar calculamos el error cuadrático medio del residuo, definido como
6025 \mbox{MSE
} =
\frac{1}{n
} \sum_{i=
1}^
{n
} \left(
\mbox{rhs
}(e_i) -
\mbox{lhs
}(e_i)
\right)^
2,
6027 siendo $n$ el tamaño de la muestra y $
\mbox{rhs
}(e_i)$ y $
\mbox{lhs
}(e_i)$ los miembros derecho e izquierdo, respectivamente, de la expresión a ajustar. Para el caso que nos ocupa, el valor calculado es
6029 \index{lsquares
\_residual\_mse}\begin{Verbatim
}
6030 (
%i8) lsquares_residual_mse(data, [x,y], y=b*x^2+c*x+d, first(param));
6033 1.144872557335554\leqno{\tt (\%o8)
}
6036 \index{lsquares
\_residuals}También podemos calcular el vector de los residuos, definidos como $
\mbox{lhs
}(e_i) -
\mbox{rhs
}(e_i)$, $
\forall i$, para a continuación representarlos gráficamente junto con los datos y la curva ajustada, tal como se aprecia en la Figura~
\ref{fig:lsquares
}.
6038 \index{draw
}\begin{Verbatim
}
6039 (
%i9) res: lsquares_residuals(data, [x,y],
6040 y=b*x^
2+c*x+d, first(param))$
6041 (
%i10) load(draw)$ /* necesitaremos las rutinas gráficas */
6042 (
%i10) scene1: gr2d(points(data),
6043 explicit(ev(b*x^
2+c*x+d,first(param)),x,
0,
10))$
6044 (
%i12) scene2: gr2d(points_joined = true,
6046 (
%i13) draw(terminal = eps, scene1, scene2)$
6051 \includegraphics[scale=
1.0]{lsquares.pdf
}
6052 \caption{Resultados gráficos del ajuste por mínimos cuadrados.
}
6053 \label{fig:lsquares
}
6057 Nosotros ya sabemos que el ruido del proceso simulado es gaussiano de esperanza nula. En una situación real, este dato lo desconoceremos y nos interesará contrastar la hipótesis de normalidad y la de la nulidad de la media de los residuos. El paquete
\verb|stats| tiene algunos procedimientos inferenciales, entre los cuales están las funciones
\verb|test_normality| y
\verb|test_mean|; primero cargamos el paquete y contrastamos la hipótesis de normalidad,
6059 \index{test
\_normality}\begin{Verbatim
}
6061 (
%i15) test_normality(res);
6066 \mbox{{}SHAPIRO - WILK TEST
{}} \\
6067 {\it statistic
} =
0.986785359052448 \\
6068 {\it p
\_value} =
0.423354600782769
6070 \right.
\leqno{\tt (\%o15)
}
6073 El $p$-valor es lo suficientemente alto como para no rechazar la hipótesis nula de normalidad; ahora contrastamos la nulidad de la esperanza del ruido,
6075 \index{test
\_mean}\begin{Verbatim
}
6076 (
%i16) test_mean(res);
6081 \mbox{{}MEAN TEST
{}} \\
6082 {\it mean
\_estimate} = -
1.002451472320587 \times 10^
{-
7} \\
6083 {\it conf
\_level} =
0.95 \\
6084 {\it conf
\_interval} =
\left[ -
.2133782738324136 ,
.2133780733421191 \right] \\
6085 {\it method
} =
\mbox{{}Exact t-test. Unknown variance.
{}} \\
6086 {\it hypotheses
} =
\mbox{{}H0: mean =
0 , H1: mean
} \neq \mbox{{}0{}} \\
6087 {\it statistic
} =
9.321855844715968 \times 10^
{-
7} \\
6088 {\it distribution
} =
\left[ {\it student
\_t} ,
99 \right] \\
6089 {\it p
\_value} =
.9999992583830712
6091 \right.
\leqno{\tt (\%o16)
}
6094 Sin duda admitiríamos la hipótesis nula como válida.
6103 \section{Optimización con restricciones
}
6105 El paquete
\verb|augmented_lagrangian|
\index{augmented
\_lagrangian} permite minimizar funciones bajo restricciones expresables en forma de igualdades. Concretamente, si queremos obtener el valor mínimo de la función $f(x,y) = x^
2 +
2 y^
2$, entre aquellos puntos que cumplen la condición $x+y=
1$, podemos hacer uso de la función
6106 \verb|augmented_lagrangian_method|
\index{augmented
\_lagrangian\_method}.
6108 En primer lugar debemos cargar en memoria el programa correspondiente,
6111 (
%i1) load ("augmented_lagrangian")$
6114 Introducimos la función objetivo y la restricción, la cual guardamos en una lista, dando por sentado que la expresión que la define está igualada a cero,
6117 (
%i2) f(x,y) := x^2 + 2*y^2 $
6118 (
%i3) c: [x + y - 1] $
6121 A continuación hacemos la llamada a la función correspondiente, en la que introducimos la función, la lista de variables independientes, las restricciones, un vector con una solución inicial aproximada y una opción que controla la salida de resultados intermedios. El valor que nos devuelve la función es una lista con dos elementos, siendo el primero la solución y el segundo el valor de un parámetro del algoritmo.
6124 (
%i4) sol: augmented_lagrangian_method(
6125 f(x,y),
[x, y
], c,
[1,
1], iprint=
[-
1,
0]);
6127 $$
\left[ \left[ x=
.6666598410800233 , y=
.3333402724554476 \right] ,
6128 {\it \%lambda
}=
\left[ -
1.333337940892538 \right] \right] \leqno{\tt (\%o4)
}$$
6130 Podemos asignar la solución a las variables
\verb|x0| y
\verb|y0| y a continuación
\verb|z0|, el valor mínimo alcanzado,
6133 (
%i5) [x0,y0]: map(rhs, first(sol)) $
6136 $$
0.666666818190186\leqno{\tt (\%o6)
}$$
6138 Para facilitar la visualización del problema, podemos plantearnos la realización de un gráfico, Figura~
\ref{fig:lagran
},
6141 (
%i7) load("draw") $
6145 enhanced3d =
[z,x,z
],
6146 explicit(x^
2 +
2*y^
2, x, -
2,
2, y, -
2,
2),
6149 enhanced3d =
[-z,x,z
],
6150 parametric_surface(x, -x+
1, z, x, -
2,
2, z, -
1,
5),
6155 points(
[[x0,y0,z0
]]))$
6160 \includegraphics[scale=
1.6]{lagran.pdf
}
6161 \caption{Minimización con restricciones.
}
6172 \section{Programación lineal
}
6174 El paquete
\verb|simplex|
\index{simplex
} dispone de las funciones
\verb|minimize_lp|
\index{minimize
\_lp} y
\verb|maximize_lp|
\index{maximize
\_lp} para la resolución de problemas de programación lineal. Nos planteamos el siguiente problema:
6177 \mbox{Max.
} & F(x_1, x_2, x_3, x_4) & =
2 x_1 +
4 x_2 + x_3 + x_4 \\
6178 \mbox{sujeto a
} & x_1 +
3 x_2 + x_4 &
\leq 4 \\
6179 &
2 x_1 + x_2 &
\leq 3 \\
6180 & x_2 +
4 x_3 + x_4 &
\leq 3 \\
6181 & x_1, x_2, x_3, x_4 &
\in \R^+
6183 que seguidamente pasamos a resolver cargando previamente en memoria el programa y definiendo la función objetivo y las restricciones asociadas al problema,
6186 (
%i1) load("simplex") $
6187 (
%i2) F : 2*x1 + 4*x2 + x3 + x4 $
6188 (
%i3) r1 : x1 + 3*x2 + x4 <= 4 $
6189 (
%i4) r2 : 2*x1 + x2 <= 3 $
6190 (
%i5) r3 : x2 + 4*x3 + x4 <= 3 $
6191 (
%i6) r4 : x1 >= 0 $
6192 (
%i7) r5 : x2 >= 0 $
6193 (
%i8) r6 : x3 >= 0 $
6194 (
%i9) r7 : x4 >= 0 $
6197 A continuación resolvemos el problema invocando la función
\verb|maximize_lp|,
6200 (
%i10) maximize_lp(F, [r1, r2, r3, r4, r5, r6, r7]);
6202 $$
\left[ {{13}\over{2}} ,
\left[ {\it x_3
}=
{{1}\over{2}} ,
{\it x_4
}=
6203 0 ,
{\it x_2
}=
1 ,
{\it x_1
}=
1 \right] \right] \leqno{\tt (\%o10)
}$$
6205 El primer elemento de la lista es el valor máximo que alcanza la función objetivo y el segundo es la lista que contiene la solución.
6215 \chapter{Programando en Maxima
}
6218 \section{Programación a nivel de Maxima
}
6221 Esencialmente, programar consiste en escribir secuencialmente un grupo de sentencias sintácticamente correctas que el intérprete pueda leer y luego ejecutar; la manera más sencilla de empaquetar varias sentencias es mediante paréntesis, siendo el resultado del programa la salida de la última sentencia:
6224 (
%i1) (a:3, b:6, a+b);
6245 Como se ve en las salidas
\verb|
%o2| y \verb|%o3|, este método conlleva un peligro, que consiste en que podemos alterar desapercibidamente valores de variables que quizás se estén utilizando en otras partes de la sesión actual. La solución pasa por declarar variables localmente, cuya existencia no se extiende más allá de la duración del programa, mediante el uso de bloques; el siguiente ejemplo muestra el mismo cálculo anterior declarando \verb|c| y \verb|d| locales, además se ve cómo es posible asignarles valores a las variables en el momento de crearlas:
6247 \index{block
}\begin{Verbatim
}
6248 (
%i4) block([c,d:6],
6270 A la hora de hacer un programa, lo habitual es empaquetarlo como cuerpo de una función, de forma que sea sencillo utilizar el código escrito tantas veces como sea necesario sin más que escribir el nombre de la función con los argumentos necesarios; la estructura de la definición de una función necesita el uso del operador
\verb|:=|
6273 f(<arg1>,<arg2>,...):=<expr>
6276 donde
\verb|<expr>| es una única sentencia o un bloque con variables locales; véanse los siguientes ejemplos:
6279 (
%i7) loga(x,a):= float(log(x) / log(a)) $
6286 1.403677461028802\leqno{\tt (\%o8)
}
6290 (
%i9) fact(n):=block([prod:1],
6291 for k:
1 thru n do prod:prod*k,
6299 119622220865480194561963161495657715064383733760000000000\leqno{\tt (\%o10)
}
6303 En el primer caso (
\verb|loga|) se definen los logaritmos en base arbitraria (Maxima sólo tiene definidos los naturales); además, previendo que sólo los vamos a necesitar en su forma numérica, solicitamos que nos los evalúe siempre en formato decimal. En el segundo caso (
\verb|fact|) hacemos uso de un bucle para calcular factoriales. Esta última función podría haberse escrito recursivamente mediante un sencillo condicional,
6306 (
%i11) fact2(n):= if n=1 then 1
6314 119622220865480194561963161495657715064383733760000000000\leqno{\tt (\%o12)
}
6317 O más fácil todavía,
6323 119622220865480194561963161495657715064383733760000000000\leqno{\tt (\%o13)
}
6326 Acabamos de ver dos estructuras de control de flujo comunes a todos los lenguajes de programación, las sentencias
\verb|if-then-else| y los bucles
\verb|for|. En cuanto a las primeras, puede ser de utilidad la siguiente tabla de operadores relacionales
6328 \index{22@=
}\index{23@\#
}\index{24@$>$
}\index{25@$<$
}\index{26@$>=$
}\index{27@$=<$
}\begin{center
}
6329 \begin{tabular
}{|c|c|
} \hline
6330 \verb|=| & ...igual que... \\
\hline
6331 \verb|#| & ...diferente de... \\
\hline
6332 \verb|>| & ...mayor que... \\
\hline
6333 \verb|<| & ...menor que... \\
\hline
6334 \verb|>=| & ...mayor o igual que... \\
\hline
6335 \verb|<=| & ...menor o igual que... \\
\hline
6339 He aquí un ejemplo de uso.
6342 (
%i14) makelist(is(log(x)<x-1), x, [0.9,1,1.1]);
6345 \left[ \mbox{true
} ,
\mbox{false
} ,
\mbox{true
} \right] \leqno{\tt (\%o14)
}
6348 Los operadores lógicos que frecuentemente se utilizarán con las relaciones anteriores son
\verb|and|
\index{and
},
\verb|or|
\index{or
} y
\verb|not|
\index{not
}, con sus significados obvios
6351 \begin{tabular
}{|c|c||c|c|c|
} \hline
6352 p & q & p
\verb|and| q & p
\verb|or| q &
\verb|not| p \\
\hline
6353 \verb|false| &
\verb|false| &
\verb|false| &
\verb|false| &
\verb|true| \\
6354 \verb|false| &
\verb|true| &
\verb|false| &
\verb|true| &
\verb|true| \\
6355 \verb|true| &
\verb|false| &
\verb|false| &
\verb|true| &
\verb|false| \\
6356 \verb|true| &
\verb|true| &
\verb|true| &
\verb|true| &
\verb|false| \\
\hline
6361 (
%i15) if sin(4)< 9/10 and 2^2 = 4 then 1 else -1 ;
6364 1\leqno{\tt (\%o15)
}
6368 (
%i16) if sin(4)< -9/10 and 2^2 = 4 then 1 else -1 ;
6371 -
1\leqno{\tt (\%o16)
}
6374 Se ilustra en el ejemplo anterior (
\verb|
%i14|) cómo se evalúa con la función \verb|is|\index{is} el valor de verdad de una expresión relacional ante la ausencia de un condicional o de un operador lógico; la siguiente secuencia aclara algo más las cosas:
6377 (
%i17) sin(4)< 9/10 ;
6380 \sin 4<
{{9}\over{10}}\leqno{\tt (\%o17)
}
6384 (
%i18) is(sin(4)< 9/10);
6387 \mbox{true
}\leqno{\tt (\%o18)
}
6390 Pero ante la presencia de un operador lógico o una sentencia condicional,
\verb|is| ya no es necesario:
6393 (
%i19) sin(4)< 9/10 and 2^2 = 4;
6396 \mbox{true
}\leqno{\tt (\%o19)
}
6399 \index{if
}\begin{Verbatim
}
6400 (
%i20) if sin(4)< 9/10 then 1;
6403 1\leqno{\tt (\%o20)
}
6406 En cuanto a los bucles,
\verb|for|
\index{for
} es muy versátil; tiene las siguientes variantes:
6409 for <var>:<val1> step <val2> thru <val3> do <expr>
6410 for <var>:<val1> step <val2> while <cond> do <expr>
6411 for <var>:<val1> step <val2> unless <cond> do <expr>
6414 Cuando el incremento de la variable es la unidad, se puede obviar la parte de la sentencia relativa a
\verb|step|
\index{step
}, dando lugar a los esquemas
6416 \index{thru
}\index{while
}\index{unless
}\begin{Verbatim
}
6417 for <var>:<val1> thru <val3> do <expr>
6418 for <var>:<val1> while <cond> do <expr>
6419 for <var>:<val1> unless <cond> do <expr>
6422 Cuando no sea necesaria la presencia de una variable de recuento de iteraciones, también se podrá prescindir de los
\verb|for|, como en
6425 while <cond> do <expr>
6426 unless <cond> do <expr>
6429 Algunos ejemplos que se explican por sí solos:
6432 (
%i21) for z:-5 while z+2<0 do print(z) ;
6438 \mbox{done
}\leqno{\tt (\%o21)
}
6442 (
%i22) for z:-5 unless z+2>0 do print(z) ;
6449 \mbox{done
}\leqno{\tt (\%o22)
}
6453 (
%i23) for cont:1 thru 3 step 0.5 do (var: cont^3, print(var)) ;
6461 \mbox{done
}\leqno{\tt (\%o23)
}
6465 (
%i24) [z, cont, var];
6468 \left[ z ,
{\it cont
} ,
27.0 \right] \leqno{\tt (\%o24)
}
6472 (
%i25) while random(20) < 15 do print("qqq") ;
6478 \mbox{done
}\leqno{\tt (\%o25)
}
6481 Véase en el resultado
\verb|
%o24| cómo las variables \verb|z| y \verb|cont| no quedan con valor asignado, mientras que \verb|var| sí; la razón es que tanto \verb|z| como \verb|cont| son locales en sus respectivos bucles, expirando cuando éste termina; esto significa, por ejemplo, que no sería necesario declararlas locales dentro de un bloque.
6483 Otra variante de
\verb|for|, sin duda inspirada en la propia sintaxis de Lisp, es cuando el contador recorre los valores de una lista; su forma es
6486 for <var> in <lista> do <expr>
6491 \index{in
}\begin{Verbatim
}
6492 (
%i26) for z in [sin(x), exp(x), x^(3/4)] do print(diff(z,x)) $
6505 Cuando una función debe admitir un número indeterminado de argumentos, se colocarán primero los que tengan carácter obligatorio, encerrando el último entre corchetes para indicar que a partir de ahí el número de argumentos puede ser arbitrario. La siguiente función suma y resta alternativamente las potencias $n$-ésimas de sus argumentos, siendo el exponente su primer argumento,
6508 (
%i27) sumdif(n,[x]):= x^n . makelist((-1)^(k+1), k, 1, length(x)) $
6512 (
%i28) sumdif(7,a,b,c,d,e,f,g);
6515 g^
7-f^
7+e^
7-d^
7+c^
7-b^
7+a^
7\leqno{\tt (\%o28)
}
6519 (
%i29) sumdif(%pi,u+v);
6522 \left(v+u
\right)^
{\pi}\leqno{\tt (\%o29)
}
6525 En la entrada
\verb|
%i27|, dentro del cuerpo de la función, la variable \verb|x| es la lista de los argumentos que podríamos llamar \emph{restantes}; como tal lista, la función \verb|length| devuelve el número de elementos que contiene. Recuérdese también que una lista elevada a un exponente devuelve otra lista con los elementos de la anterior elevados a ese mismo exponente. Por último, el operador \verb|.| calcula el producto escalar.
6527 En otras ocasiones, puede ser de interés pasar como argumento una función, en lugar de un valor numérico o una expresión. Esto no tiene problema para Maxima, pero debe hacerse con cierto cuidado. A continuación se define una función de Maxima que toma como argumento una función y la aplica a los cinco primeros números enteros positivos,
6530 (
%i30) fun_a(G):= map(G, [1,2,3,4,5]) $
6533 Pretendemos ahora aplicar a estos cinco elementos la función seno, lo cual no da ningún problema,
6539 \left[ \sin 1 ,
\sin 2 ,
\sin 3 ,
\sin 4 ,
\sin 5 \right] \leqno{\tt (\%o31)
}
6542 Pero el problema lo vamos a tener cuando queramos aplicar una función algo más compleja,
6545 (
%i32) fun_a(sin(x)+cos(x));
6546 Improper name or value in functional position:
6548 #0: fun_a(g=sin(x)+cos(x))
6549 -- an error. To debug this try debugmode(true);
6551 lo cual se debe al hecho de que la función
\verb|map| no reconoce el argumento como función. En tal caso lo apropiado es definir la función objetivo separadamente, lo cual podemos hacer como función ordinaria o como función lambda:
6554 (
%i33) sc(z):= sin(z) + cos(z) $
6561 \left[ \sin 1+
\cos 1 ,
\sin 2+
\cos 2 ,
\sin 3+
\cos 3 ,
\sin 4+
\cos 4
6562 ,
\sin 5+
\cos 5 \right] \leqno{\tt (\%o34)
}
6566 (
%i35) fun_a( lambda([z], sin(z)+cos(z)) );
6569 \left[ \sin 1+
\cos 1 ,
\sin 2+
\cos 2 ,
\sin 3+
\cos 3 ,
\sin 4+
\cos 4
6570 ,
\sin 5+
\cos 5 \right] \leqno{\tt (\%o35)
}
6573 Cuando se hace un programa, lo habitual es escribir el código con un editor de texto y almacenarlo en un archivo con extensión
\verb|mac|. Una vez dentro de Maxima, la instrucción
6576 load("ruta/fichero.mac")$
6578 leerá las funciones escritas en él y las cargará en la memoria, listas para ser utilizadas.
6580 Si alguna de las funciones definidas en el fichero
\verb|fichero.mac| contiene algún error, devolviéndonos un resultado incorrecto, Maxima dispone del modo de ejecución de depurado (
\verb|debugmode|
\index{debugmode
}), que ejecuta el código paso a paso, pudiendo el programador chequear interactivamente el estado de las variables o asignarles valores arbitrariamente. Supongamos el siguiente contenido de cierto fichero
\verb|prueba.mac|
6582 \begin{Verbatim
}[frame=single
]
6590 Ahora, la siguiente sesión nos permite analizar los valores de las variables en cierto punto de la ejecución de la función:
6593 (
%i26) load("prueba.mac"); /* cargamos fichero */
6596 \mbox{{}prueba.mac
{}}\leqno{\tt (\%o26)
}
6600 (
%i27) :break foo 3 /* declaro punto de ruptura al final de línea 3*/
6601 Turning on debugging debugmode(true)
6602 Bkpt
0 for foo (in prueba.mac line
4)
6606 (
%i27) foo(2); /* llamada a función */
6607 Bkpt
0:(prueba.mac
4)
6608 prueba.mac:
4:: /* se detiene al comienzo de la línea
4 */
6609 (dbm:
1) u; /* ¿valor de u? */
6611 (dbm:
1) y; /* ¿valor de y? */
6613 (dbm:
1) u:
1000; /* cambio valor de u */
6615 (dbm:
1) :continue /* continúa ejecución */
6618 1000000\leqno{\tt (\%o27)
}
6624 \section{Programación a nivel de Lisp
}
6627 A veces se presentan circunstancias en las que es mejor hacer programas para Maxima directamente en Lisp
\index{lisp
}; tal es el caso de las funciones que no requieran de mucho procesamiento simbólico, como funciones de cálculo numérico o la creación de nuevas estructuras de datos.
6629 Sin dar por hecho que el lector conoce el lenguaje de programación Lisp, nos limitaremos a dar unos breves esbozos. Empecemos por ver cómo almacena Maxima internamente algunas expresiones:
6635 {{3}\over{4}}\leqno{\tt (\%o1)
}
6644 (
%i2) :lisp ($num $%o1)
6648 La expresión $
\frac{3}{4}$ se almacena internamente como la lista
\verb|((RAT SIMP)
3 4)|. Una vez se ha entrado en modo Lisp mediante
\verb|:lisp|, le hemos pedido a Maxima que nos devuelva la expresión
\verb|
%o1|; la razón por la que se antepone el símbolo de dólar es que desde Lisp, los objetos de Maxima, tanto variables como nombres de funciones, llevan este prefijo. En la segunda instrucción que introducimos a nivel Lisp, le indicamos que aplique a la fracción la función de Maxima \verb|num|, que devuelve el numerador de una fracción.
6650 Del mismo modo que desde el nivel de Lisp ejecutamos una instrucción de Maxima, al nivel de Maxima también se pueden ejecutar funciones de Lisp. Como ejemplo, veamos el comportamiento de las dos funciones de redondeo, la definida para Maxima y la propia del lenguaje Lisp:
6661 Maxima encountered a Lisp error:
6664 ROUND: $
%PI is not a real number
6666 Automatically continuing.
6667 To reenable the Lisp debugger set *debugger-hook* to nil.
6670 En el primer caso llamamos a la función de redondeo de Maxima y nos devuelve un resultado que reconocemos como correcto. En el segundo caso, al utilizar el prefijo
\verb|?|, estamos haciendo una llamada a la función
\verb|round| de Lisp y obtenemos un error; la razón es que esta función de Lisp sólo reconoce números como argumentos. En otras palabras, a nivel de Maxima se ha redefinido
\verb|round| para que reconozca expresiones simbólicas.
6672 A efectos de saciar nuestra curiosidad, veamos cómo se almacenan internamente otras expresiones:
6678 2\,y+x
\leqno{\tt (\%o5)
}
6685 \left[ 1 ,
2 \right] \leqno{\tt (\%o6)
}
6690 ((MPLUS SIMP) $X ((MTIMES SIMP)
2 $Y))
6698 Otra forma de mostrar la representación interna de expresiones de Maxima es invocando la función
\verb|print| de Lisp. El siguiente ejemplo nos muestra que Maxima almacena internamente una expresión negativa como un producto por -
1.
6703 ((MTIMES SIMP) -
1 $A)
6706 Para terminar, un ejemplo de cómo definir a nivel de Lisp una función que cambia de signo una expresión cualquiera que le pasemos como argumento:
6709 (
%i8) :lisp (defun $opuesto (x) (list '(mtimes) -1 x))
6717 -b-a
\leqno{\tt (\%o9)
}
6720 Se ha hecho un gran esfuerzo para que Maxima sea lo más universal posible en cuanto a entornos
\emph{Common Lisp
}, de tal manera que en la actualidad Maxima funciona perfectamente con los entornos libres
\verb|clisp|,
\verb|gcl|,
\verb|cmucl| o
\verb|sbcl|.
6722 También es posible llamar desde el nivel de Lisp funciones que previamente hayan sido definidas en Maxima, para lo cual será necesario utilizar la función Lisp
\verb|mfuncall|.
6725 (
%i10) cubo(x):= x^3$
6726 (
%i11) :lisp (mfuncall '$cubo 3)
6730 Con
\verb|:lisp| sólo podemos ejecutar una única sentencia Lisp; pero si lo que queremos es abrir una sesión Lisp completa, haremos uso de la función
\verb|to_lisp|
\index{to
\_lisp}, terminada la cual volveremos a Maxima ejecutando
\verb|(to-maxima)|.
6734 Type (to-maxima) to restart, ($quit) to quit Maxima.
6736 MAXIMA> (+ #c(
3 4) #c(
5 6/
8)) ; suma complejos
6740 "
2 no es negativo") ; ejemplo de condicional