This is maxima.info, produced by makeinfo version 5.1 from maxima.texi.


File: maxima.info,  Node: Conjuntos,  Next: Definición de Funciones,  Prev: Reglas y patrones,  Up: Top

35 Conjuntos
************

* Menu:

* Introducción a los conjuntos::       
* Funciones y variables para los conjuntos::       


File: maxima.info,  Node: Introducción a los conjuntos,  Next: Funciones y variables para los conjuntos,  Prev: Conjuntos,  Up: Conjuntos

35.1 Introducción a los conjuntos
=================================

Maxima dispone de funciones para realizar operaciones con conjuntos,
como la intersección o la unión.  Los conjuntos deben ser finitos y
definidos por enumeración.  Maxima trata a los conjuntos y a las listas
como objectos de distinta naturaleza, lo que permite trabajar con
conjuntos cuyos elementos puedan ser también conjuntos o listas.

Además de funciones para operar con conjuntos finitos, Maxima dispone
también de algunas funciones sobre combinatoria, como los números de
Stirling de primera y segunda especie, números de Bell, coeficientes
multinomiales, particiones de enteros no negativos y algunos otros.
Maxima también define la función delta de Kronecker.

35.1.1 Utilización
------------------

Para construir un conjunto cuyos elementos sean 'a_1, ..., a_n', se
utiliza la instrucción 'set(a_1, ..., a_n)' o '{a_1, ..., a_n}'; para
formar un conjunto vacío, basta con hacer 'set()' o '{}'.  Para
introducir conjuntos en Maxima, 'set (...)' y '{ ... }' son
equivalentes.  Los conjuntos se muestran siempre con llave.

Si un elemento se indica más de una vez, el proceso de simplificación
elimina los elementos redundantes.

     (%i1) set();
     (%o1)                          {}
     (%i2) set(a, b, a);
     (%o2)                        {a, b}
     (%i3) set(a, set(b));
     (%o3)                       {a, {b}}
     (%i4) set(a, [b]);
     (%o4)                       {a, [b]}
     (%i5) {};
     (%o5)                          {}
     (%i6) {a, b, a};
     (%o6)                        {a, b}
     (%i7) {a, {b}};
     (%o7)                       {a, {b}}
     (%i8) {a, [b]};
     (%o8)                       {a, [b]}

Dos elementos candidatos a formar parte de un conjunto, <x> e <y>, son
redundantes, esto es, se consideran el mismo elemento a efectos de
consruir el conjunto, si y sólo si 'is (<x> = <y>)' devuelve el valor
'true'.  Nótese que 'is (equal (<x>, <y>))' puede devolver 'true' y 'is
(<x> = <y>)' retornar 'false'; en cuyo caso los elementos <x> e <y> se
considerarían distintos.

     (%i1) x: a/c + b/c;
                                   b   a
     (%o1)                         - + -
                                   c   c
     (%i2) y: a/c + b/c;
                                   b   a
     (%o2)                         - + -
                                   c   c
     (%i3) z: (a + b)/c;
                                   b + a
     (%o3)                         -----
                                     c
     (%i4) is (x = y);
     (%o4)                         true
     (%i5) is (y = z);
     (%o5)                         false
     (%i6) is (equal (y, z));
     (%o6)                         true
     (%i7) y - z;
                                b + a   b   a
     (%o7)                    - ----- + - + -
                                  c     c   c
     (%i8) ratsimp (%);
     (%o8)                           0
     (%i9) {x, y, z};
                               b + a  b   a
     (%o9)                    {-----, - + -}
                                 c    c   c

Para formar un conjunto a partir de los miembros de una lista úsese
'setify'.

     (%i1) setify([b, a]);
     (%o1)                        {a, b}

Los elementos 'x' e 'y' de un conjunto se consideran iguales si 'is(x =
y)' devuelve el valor 'true'.  Así, 'rat(x)' y 'x' se consideran el
mismo elemento de un conjunto; consecuentemente,

     (%i1) {x, rat(x)};
     (%o1)                          {x}

Además, puesto que 'is((x-1)*(x+1) = x^2 - 1)' devuelve 'false',
'(x-1)*(x+1)' y 'x^2-1' se consideran elementos diferentes; así

     (%i1) {(x - 1)*(x + 1), x^2 - 1};
                                            2
     (%o1)               {(x - 1) (x + 1), x  - 1}

Para reducir este conjunto a otro unitario, aplicar 'rat' a cada
elemento del conjunto:

     (%i1) {(x - 1)*(x + 1), x^2 - 1};
                                            2
     (%o1)               {(x - 1) (x + 1), x  - 1}
     (%i2) map (rat, %);
                                   2
     (%o2)/R/                    {x  - 1}

Para eliminar redundancias con otros conjuntos, será necesario utilizar
otras funciones de simplificación.  He aquí un ejemplo que utiliza
'trigsimp':

     (%i1) {1, cos(x)^2 + sin(x)^2};
                                 2         2
     (%o1)                {1, sin (x) + cos (x)}
     (%i2) map (trigsimp, %);
     (%o2)                          {1}

Se entiende que un conjunto está simplificado cuando entre sus elementos
no hay redundancias y se hayan ordenados.  La versión actual de las
funciones para conjuntos utiliza la función 'orderlessp' de Maxima para
ordenar sus elementos; sin embargo, futuras versiones de las funciones
para operar con conjuntos podrán utilizar otras funciones de ordenación.

Algunas operaciones con conjuntos, tales como la sustitución, fuerzan
automáticamente una re-simplificación; por ejemplo,

     (%i1) s: {a, b, c}$
     (%i2) subst (c=a, s);
     (%o2)                        {a, b}
     (%i3) subst ([a=x, b=x, c=x], s);
     (%o3)                          {x}
     (%i4) map (lambda ([x], x^2), set (-1, 0, 1));
     (%o4)                        {0, 1}

Maxima considera a las listas y conjuntos como objetos diferentes;
funciones tales como 'union' y 'intersection' emitirán un error si
alguno de sus argumentos no es un conjunto.  Si se necesita aplicar una
función de conjunto a una lista, se deberá utilizar la función 'setify'
para convertirla previamente en conjunto.  Así,

     (%i1) union ([1, 2], {a, b});
     Function union expects a set, instead found [1,2]
      -- an error.  Quitting.  To debug this try debugmode(true);
     (%i2) union (setify ([1, 2]), {a, b});
     (%o2)                     {1, 2, a, b}

Para extraer todos los elementos de un conjunto 's' que satisfagan un
predicado 'f', úsese 'subset(s,f)'.  (Un predicado es una función
booleana.)  Por ejemplo, para encontrar las ecuaciones en un conjunto
dado que no dependan de la variable 'z', se hará

     (%i1) subset ({x + y + z, x - y + 4, x + y - 5},
                   lambda ([e], freeof (z, e)));
     (%o1)               {- y + x + 4, y + x - 5}

La sección 'Funciones y variables para los conjuntos' incluye una lista
completa de funciones para operar con conjuntos en Maxima.

35.1.2 Iteraciones con elementos
--------------------------------

Hay dos formas para operar iterativamente sobre los elementos de un
conjunto.  Una es utilizar 'map'; por ejemplo:

     (%i1) map (f, {a, b, c});
     (%o1)                  {f(a), f(b), f(c)}

La otra forma consiste en hacer uso de la construcción 'for <x> in <s>
do'

     (%i1) s: {a, b, c};
     (%o1)                       {a, b, c}
     (%i2) for si in s do print (concat (si, 1));
     a1
     b1
     c1
     (%o2)                         done

Las funciones de Maxima 'first' y 'rest' funcionan también con
conjuntos.  En este caso, 'first' devuelve el primer elemento que se
muestra del conjunto, el cual puede depender de la implementación del
sistema.  Si 's' es un conjunto, entonces 'rest(s)' equivale a 'disjoin
(first(s), s)'.  Hay otras funciones que trabajan correctamente con
conjuntos.  En próximas versiones de las funciones para operar con
conjuntos es posible que 'first' y 'rest' trabajen de modo diferente o
que ya no lo hagan en absoluto.

35.1.3 Fallos
-------------

Las funciones para operar con conjuntos utilizan la función 'orderlessp'
de Maxima para ordenar los elementos de los conjuntos, así como la
función 'like' de Lisp para decidir sobre la igualdad de dichos
elementos.  Ambas funciones tienen fallos que son conocidos y que pueden
aflorar si se trabaja con conjuntos que tengan elementos en formato de
listas o matrices y que contengan expresiones racionales canónicas
(CRE). Un ejemplo es

     (%i1) {[x], [rat (x)]};
     Maxima encountered a Lisp error:

       The value #:X1440 is not of type LIST.

     Automatically continuing.
     To reenable the Lisp debugger set *debugger-hook* to nil.

Esta expresión provoca una parada de Maxima junto con la emisión de un
mensaje de error, el cual dependerá de la versión de Lisp que utilice
Maxima.  Otro ejemplo es

     (%i1) setify ([[rat(a)], [rat(b)]]);
     Maxima encountered a Lisp error:

       The value #:A1440 is not of type LIST.

     Automatically continuing.
     To reenable the Lisp debugger set *debugger-hook* to nil.

Estos fallos son causados por fallos en 'orderlessp' y 'like', no por
fallos cuyo origen se encuentre en las funciones para conjuntos.  Para
ilustrarlo, se pueden ejecutar las siguientes expresiones

     (%i1) orderlessp ([rat(a)], [rat(b)]);
     Maxima encountered a Lisp error:

       The value #:B1441 is not of type LIST.

     Automatically continuing.
     To reenable the Lisp debugger set *debugger-hook* to nil.
     (%i2) is ([rat(a)] = [rat(a)]);
     (%o2)                         false

Hasta que estos errores no se corrijan, no es aconsejable construir
conjuntos que tengan por elementos listas o matrices que contengan
expresiones en forma CRE; sin embargo, un conjunto con elementos de la
forma CRE no deberían dar problemas:

     (%i1) {x, rat (x)};
     (%o1)                          {x}

La función 'orderlessp' de Maxima tiene otro fallo que puede causar
problemas con las funciones para conjuntos, en concreto, que el
predicado de ordenación 'orderlessp' no es transitivo.  El ejemplo más
simple que ilustra este punto es

     (%i1) q: x^2$
     (%i2) r: (x + 1)^2$
     (%i3) s: x*(x + 2)$
     (%i4) orderlessp (q, r);
     (%o4)                         true
     (%i5) orderlessp (r, s);
     (%o5)                         true
     (%i6) orderlessp (q, s);
     (%o6)                         false

El fallo puede causar problemas con todas las funciones para conjuntos,
así como también con otras funciones de Maxima.  Es probable, pero no
seguro, que este fallo se puede evitar si todos los elementos del
conjunto están en la forma de expresión racional canónica (CRE) o han
sido simplificados con 'ratsimp'.

Los mecanismos 'orderless' y 'ordergreat' de Maxima son incompatibles
con las funciones para conjuntos.  Si se necesitan utilizar 'orderless'
o 'ordergreat', hágase antes de construir los conjuntos y no se utilice
la instrucción 'unorder'.

Se ruega a todo usuario que crea haber encontrado un fallo en las
funciones para conjuntos que lo comunique en la base de datos de Maxima.
Véase 'bug_report'.

35.1.4 Autores
--------------

Stavros Macrakis de Cambridge, Massachusetts y Barton Willis de la
University of Nebraska at Kearney (UNK).


File: maxima.info,  Node: Funciones y variables para los conjuntos,  Prev: Introducción a los conjuntos,  Up: Conjuntos

35.2 Funciones y variables para los conjuntos
=============================================

 -- Función: adjoin (<x>, <a>)

     Calcula la unión del conjunto <a> y '{<x>}'.

     La función 'adjoin' emite un mensaje de error si <a> no es un
     conjunto literal.

     Las sentencias 'adjoin(<x>, <a>)' y 'union(set(<x>), <a>)' son
     equivalentes, aunque 'adjoin' puede ser algo más rápida que
     'union'.

     Véase también 'disjoin'.

     Ejemplos:

          (%i1) adjoin (c, {a, b});
          (%o1)                       {a, b, c}
          (%i2) adjoin (a, {a, b});
          (%o2)                        {a, b}

 -- Función: belln (<n>)

     Representa el n-ésimo número de Bell, de modo que 'belln(n)' es el
     número de particiones de un conjunto de <n> elementos.

     El argumento <n> debe ser un entero no negativo.

     La función 'belln' se distribuye sobre ecuaciones, listas, matrices
     y conjuntos.

     Ejemplos:

     'belln' se aplica a enteros no negativos,

          (%i1) makelist (belln (i), i, 0, 6);
          (%o1)               [1, 1, 2, 5, 15, 52, 203]
          (%i2) is (cardinality (set_partitions ({})) = belln (0));
          (%o2)                         true
          (%i3) is (cardinality (set_partitions ({1, 2, 3, 4, 5, 6}))
                                      = belln (6));
          (%o3)                         true

     Si <n> no es un entero no negativo, la función 'belln(n)' no hace
     cálculo alguno.

          (%i1) [belln (x), belln (sqrt(3)), belln (-9)];
          (%o1)        [belln(x), belln(sqrt(3)), belln(- 9)]

 -- Función: cardinality (<a>)

     Devuelve el número de elementos del conjunto <a>.

     La función 'cardinality' ignora los elementos redundantes, incluso
     cuando la simplificación está desabilitada.

     Ejemplos:

          (%i1) cardinality ({});
          (%o1)                           0
          (%i2) cardinality ({a, a, b, c});
          (%o2)                           3
          (%i3) simp : false;
          (%o3)                         false
          (%i4) cardinality ({a, a, b, c});
          (%o4)                           3

 -- Función: cartesian_product (<b_1>, ... , <b_n>)

     Devuelve un conjunto formado por listas de la forma '[<x_1>, ...,
     <x_n>]', siendo <x_1>, ..., <x_n> elementos de los conjuntos <b_1>,
     ...  , <b_n>, respectivamente.

     La función 'cartesian_product' emite un mensaje de error si alguno
     de sus argumentos no es un conjunto literal.

     Ejemplos:

          (%i1) cartesian_product ({0, 1});
          (%o1)                      {[0], [1]}
          (%i2) cartesian_product ({0, 1}, {0, 1});
          (%o2)           {[0, 0], [0, 1], [1, 0], [1, 1]}
          (%i3) cartesian_product ({x}, {y}, {z});
          (%o3)                      {[x, y, z]}
          (%i4) cartesian_product ({x}, {-1, 0, 1});
          (%o4)              {[x, - 1], [x, 0], [x, 1]}

 -- Función: disjoin (<x>, <a>)

     Devuelve el conjunto <a> sin el elemento <x>.  Si <x> no es
     elemento de <a>, entonces el resultado es el propio <a>.

     La función 'disjoin' emite un mensaje de error si <a> no es un
     conjunto literal.

     Las sentencias 'disjoin(<x>, <a>)', 'delete(<x>, <a>)' y
     'setdifference(<a>, set(<x>))' son todas ellas equivalentes; pero
     en general, 'disjoin' será más rápida que las otras.

     Ejemplos:

          (%i1) disjoin (a, {a, b, c, d});
          (%o1)                       {b, c, d}
          (%i2) disjoin (a + b, {5, z, a + b, %pi});
          (%o2)                      {5, %pi, z}
          (%i3) disjoin (a - b, {5, z, a + b, %pi});
          (%o3)                  {5, %pi, b + a, z}

 -- Función: disjointp (<a>, <b>)

     Devuelve 'true' si y sólo si los conjuntos <a> y <b> son disjuntos.

     La función 'disjointp' emite un mensaje de error si <a> o <b> no
     son conjuntos literales.

     Ejemplos:

          (%i1) disjointp ({a, b, c}, {1, 2, 3});
          (%o1)                         true
          (%i2) disjointp ({a, b, 3}, {1, 2, 3});
          (%o2)                         false

 -- Función: divisors (<n>)

     Calcula el conjunto de divisores de <n>.

     La sentencia 'divisors(<n>)' devuelve un conjunto de enteros si <n>
     es un entero no nulo.  El conjunto de divisores incluye los
     elementos 1 y <n>.  Los divisores de un entero negativo son los
     divisores de su valor absoluto.

     La función 'divisors' se distribuye sobre las ecuaciones, listas,
     matrices y conjuntos.

     Ejemplos:

     Se puede comprobar que 28 es un número perfecto: la suma de sus
     divisores (excepto él mismo) es 28.

          (%i1) s: divisors(28);
          (%o1)                 {1, 2, 4, 7, 14, 28}
          (%i2) lreduce ("+", args(s)) - 28;
          (%o2)                          28

     La función 'divisors' es simplificadora.  Haciendo la sustitución
     de 'a' por 8 en 'divisors(a)' devuelve los divisores sin tener que
     reevaluar 'divisors(8)',

          (%i1) divisors (a);
          (%o1)                      divisors(a)
          (%i2) subst (8, a, %);
          (%o2)                     {1, 2, 4, 8}

     La función 'divisors' se distribuye sobre ecuaciones, listas,
     matrices y conjuntos.

          (%i1) divisors (a = b);
          (%o1)               divisors(a) = divisors(b)
          (%i2) divisors ([a, b, c]);
          (%o2)        [divisors(a), divisors(b), divisors(c)]
          (%i3) divisors (matrix ([a, b], [c, d]));
                            [ divisors(a)  divisors(b) ]
          (%o3)             [                          ]
                            [ divisors(c)  divisors(d) ]
          (%i4) divisors ({a, b, c});
          (%o4)        {divisors(a), divisors(b), divisors(c)}

 -- Función: elementp (<x>, <a>)

     Devuelve 'true' si y sólo si <x> es miembro del conjunto <a>.

     La función 'elementp' emite un mensaje de error si <a> no es un
     conjunto literal.

     Ejemplos:

          (%i1) elementp (sin(1), {sin(1), sin(2), sin(3)});
          (%o1)                         true
          (%i2) elementp (sin(1), {cos(1), cos(2), cos(3)});
          (%o2)                         false

 -- Función: emptyp (<a>)
     Devuelve 'true' si y sólo si <a> es el conjunto vacío o la lista
     vacía.

     Ejemplos:

          (%i1) map (emptyp, [{}, []]);
          (%o1)                     [true, true]
          (%i2) map (emptyp, [a + b, {{}}, %pi]);
          (%o2)                 [false, false, false]

 -- Función: equiv_classes (<s>, <F>)

     Devuelve el conjunto de las clases de equivalencia del conjunto <s>
     respecto de la relación de equivalencia <F>.

     El argumento <F> es una función de dos variables definida sobre el
     producto cartesiano <s> por <s>.  El valor devuelto por <F> debe
     ser 'true' o 'false', o bien una expresión <expr> tal que
     'is(<expr>)' tome el valor 'true' o 'false'.

     Si <F> no es una relación de equivalencia, 'equiv_classes' la
     acepta sin emitir ningún mensaje de error, pero el resultado será
     incorrecto en general.

     Ejemplos:

     La relación de equivalencia es una expresión lambda que devuelve
     'true' o 'false',

          (%i1) equiv_classes ({1, 1.0, 2, 2.0, 3, 3.0},
                                lambda ([x, y], is (equal (x, y))));
          (%o1)            {{1, 1.0}, {2, 2.0}, {3, 3.0}}

     La relación de equivalencia es el nombre de una función relacional
     en la que 'is' evalúa a 'true' o 'false',

          (%i1) equiv_classes ({1, 1.0, 2, 2.0, 3, 3.0}, equal);
          (%o1)            {{1, 1.0}, {2, 2.0}, {3, 3.0}}

     Las clases de equivalencia son números que difieren en un múltiplo
     de 3.

          (%i1) equiv_classes ({1, 2, 3, 4, 5, 6, 7},
                        lambda ([x, y], remainder (x - y, 3) = 0));
          (%o1)              {{1, 4, 7}, {2, 5}, {3, 6}}

 -- Función: every (<f>, <s>)
 -- Función: every (<f>, <L_1>, ..., <L_n>)

     Devuelve 'true' si el predicado <f> vale 'true' para todos los
     argumentos dados.

     Dado un conjunto como segundo argumento, 'every(<f>, <s>)' devuelve
     'true' si 'is(<f>(<a_i>))' devuelve 'true' para todos los <a_i>
     pertenecientes <s>.  La función 'every' puede evaluar o no <f> para
     todos los <a_i> pertenecientes <s>.  Puesto que los conjuntos no
     están ordenados, 'every' puede evaluar '<f>(<a_i>)' en cualquier
     orden.

     Dada una o más listas como argumentos, 'every(<f>, <L_1>, ...,
     <L_n>)' devuelve 'true' si 'is(<f>(<x_1>, ..., <x_n>))' devuelve
     'true' para todo <x_1>, ..., <x_n> en <L_1>, ..., <L_n>,
     respectivamente.  La función 'every' puede evaluar o no <f> para
     cualquier combinación de <x_1>, ..., <x_n>; además, 'every' evalúa
     las listas en el orden creciente del índice.

     Dado un conjunto vacío '{}' o lista vacía '[]' como argumentos,
     'every' devuelve 'false'.

     Si la variable global 'maperror' vale 'true', todas las listas
     <L_1>, ..., <L_n> deben ser de igual longitud.  Si 'maperror' vale
     'false', los argumentos en forma de listas se truncan para igualar
     sus longitudes a la de la lista más corta.

     Los valores que devuelve el predicado <f> cuando toman (mediante
     'is') un valor diferente a 'true' y 'false' se controlan con la
     variable global 'prederror'.  Si 'prederror' vale 'true', tales
     valores se consideran como 'false' y la respuesta de 'every' es
     'false'.  Si 'prederror' vale 'false', tales valores se consideran
     como desconocidos ('unknown') y la respuesta de 'every' es
     'unknown'.

     Ejemplos:

     Se aplica 'every' a un único conjunto.  El predicado es una función
     de un argumento.

          (%i1) every (integerp, {1, 2, 3, 4, 5, 6});
          (%o1)                         true
          (%i2) every (atom, {1, 2, sin(3), 4, 5 + y, 6});
          (%o2)                         false

     Se aplica 'every' a dos listas.  El predicado es una función de dos
     argumentos.

          (%i1) every ("=", [a, b, c], [a, b, c]);
          (%o1)                         true
          (%i2) every ("#", [a, b, c], [a, b, c]);
          (%o2)                         false

     Las respuestas del predicado <f> que se evalúan a cualquier cosa
     diferente de 'true' y 'false' están controlados por la variable
     global 'prederror'.

          (%i1) prederror : false;
          (%o1)                         false
          (%i2) map (lambda ([a, b], is (a < b)), [x, y, z],
                             [x^2, y^2, z^2]);
          (%o2)              [unknown, unknown, unknown]
          (%i3) every ("<", [x, y, z], [x^2, y^2, z^2]);
          (%o3)                        unknown
          (%i4) prederror : true;
          (%o4)                         true
          (%i5) every ("<", [x, y, z], [x^2, y^2, z^2]);
          (%o5)                         false

 -- Función: extremal_subset (<s>, <f>, max)
 -- Función: extremal_subset (<s>, <f>, min)

     Calcula el subconjunto de <s> para el cual la función <f> toma sus
     valores mayor y menor.

     La sentencia 'extremal_subset(<s>, <f>, max)' devuelve el
     subconjunto del conjunto o lista <s> para el cual la función real
     <f> toma su valor máximo.

     La sentencia 'extremal_subset(<s>, <f>, min)' devuelve el
     subconjunto del conjunto o lista <s> para el cual la función real
     <f> toma su valor mínimo.

     Ejemplos

          (%i1) extremal_subset ({-2, -1, 0, 1, 2}, abs, max);
          (%o1)                       {- 2, 2}
          (%i2) extremal_subset ({sqrt(2), 1.57, %pi/2}, sin, min);
          (%o2)                       {sqrt(2)}

 -- Función: flatten (<expr>)

     Recoge los argumentos de subexpresiones con el mismo operador que
     <expr> y construye con ellas otra expresión a partir de estos
     argumentos.

     Aquellas subexpresiones en las que el operador es diferente del
     operador principal de 'expr' se copian sin modificarse, incluso
     cuando ellas mismas contengan subexpresiones en las que el operador
     sea el mismo que el de 'expr'.

     Es posible que 'flatten' construya expresiones en las que el número
     de argumentos difiera del número admitido por el operador, lo cual
     hará que se emita un mensaje de error.  La función 'flatten' no
     intentará detectar estas situaciones.

     Las expresiones que tengan representaciones especiales, por ejemplo
     las racionales canónicas (CRE), no admiten que se aplique sobre
     ellas la función 'flatten'; en tales casos se devuelve el argumento
     sin modificación.

     Ejemplos:

     Aplicada a una lista, 'flatten' reune todos los elementos que son a
     su vez listas.

          (%i1) flatten ([a, b, [c, [d, e], f], [[g, h]], i, j]);
          (%o1)            [a, b, c, d, e, f, g, h, i, j]

     Aplicado a un conjunto, 'flatten' reune todos los elementos que son
     a su vez conjuntos.

          (%i1) flatten ({a, {b}, {{c}}});
          (%o1)                       {a, b, c}
          (%i2) flatten ({a, {[a], {a}}});
          (%o2)                       {a, [a]}

     La función 'flatten' es similar a la declaración del operador
     principal como n-ario.  Sin embargo, 'flatten' no tiene efecto
     alguno sobre subexpresiones que tengan un operador diferente del
     principal, mientras que sí lo tiene una declaración n-aria.

          (%i1) expr: flatten (f (g (f (f (x)))));
          (%o1)                     f(g(f(f(x))))
          (%i2) declare (f, nary);
          (%o2)                         done
          (%i3) ev (expr);
          (%o3)                      f(g(f(x)))

     La función 'flatten' trata las funciones subindicadas como a
     cualquier otro operador.

          (%i1) flatten (f[5] (f[5] (x, y), z));
          (%o1)                      f (x, y, z)
                                      5

     Es posible que 'flatten' construya expresiones en las que el número
     de argumentos difiera del número admitido por el operador.

          (%i1) 'mod (5, 'mod (7, 4));
          (%o1)                   mod(5, mod(7, 4))
          (%i2) flatten (%);
          (%o2)                     mod(5, 7, 4)
          (%i3) ''%, nouns;
          Wrong number of arguments to mod
           -- an error.  Quitting.  To debug this try debugmode(true);

 -- Función: full_listify (<a>)

     Sustituye los operadores de conjunto presentes en <a> por
     operadores de listas, devolviendo el resultado.  La función
     'full_listify' sustituye operadores de conjuntos en subexpresiones
     anidadas, incluso cuando el operador principal no es 'set'.

     La función 'listify' sustituye únicamente el operador principal.

     Ejemplos:

          (%i1) full_listify ({a, b, {c, {d, e, f}, g}});
          (%o1)               [a, b, [c, [d, e, f], g]]
          (%i2) full_listify (F (G ({a, b, H({c, d, e})})));
          (%o2)              F(G([a, b, H([c, d, e])]))

 -- Función: fullsetify (<a>)

     Si <a> es una lista, sustituye el operador de lista por el de
     conjunto, aplicando posteriormente 'fullsetify' a todos los
     elementos que son a su vez conjuntos.  Si <a> no es una lista, se
     devuelve sin cambio alguno.

     La función 'setify' sustituye solamente el operador principal.

     Ejemplos:

     En la salida '(%o2)' el argumento de 'f' no se convierte en
     conjunto porque el operador principal de 'f([b])' no es una lista.

          (%i1) fullsetify ([a, [a]]);
          (%o1)                       {a, {a}}
          (%i2) fullsetify ([a, f([b])]);
          (%o2)                      {a, f([b])}

 -- Función: identity (<x>)

     La función 'identity' devuelve su argumento cualquiera que sea
     éste.

     Ejemplos:

     La función 'identity' puede utilizarse como predicado cuando los
     argumentos ya son valores booleanos.

          (%i1) every (identity, [true, true]);
          (%o1)                         true

 -- Función: integer_partitions (<n>)
 -- Función: integer_partitions (<n>, <len>)

     Devuelve particiones enteras de <n>, esto es, listas de enteros
     cuyas sumas son <n>.

     La sentencia 'integer_partitions(<n>)' devuelve el conjunto de
     todas las particiones del entero <n>.  Cada partición es una lista
     ordenada de mayor a menor.

     La sentencia 'integer_partitions(<n>, <len>)' devuelve todas las
     particiones de longitud <len> o menor; en este caso, se añaden
     ceros a cada partición con menos de <len> términos para que todas
     ellas sean de longitud <len>.  Las particiones son listas ordenadas
     de mayor a menor.

     Una lista [a_1, ..., a_m] es una partición de un entero no negativo
     n si (1) cada a_i es entero no nulo y (2) a_1 + ... + a_m = n. Así,
     0 no tiene particiones.

     Ejemplos:

          (%i1) integer_partitions (3);
          (%o1)               {[1, 1, 1], [2, 1], [3]}
          (%i2) s: integer_partitions (25)$
          (%i3) cardinality (s);
          (%o3)                         1958
          (%i4) map (lambda ([x], apply ("+", x)), s);
          (%o4)                         {25}
          (%i5) integer_partitions (5, 3);
          (%o5) {[2, 2, 1], [3, 1, 1], [3, 2, 0], [4, 1, 0], [5, 0, 0]}
          (%i6) integer_partitions (5, 2);
          (%o6)               {[3, 2], [4, 1], [5, 0]}

     Para encontrar todas las particiones que satisfagan cierta
     condición, utilícese la función 'subset'; he aquí un ejemplo que
     encuentra todas las particiones de 10 formadas por números primos.

          (%i1) s: integer_partitions (10)$
          (%i2) cardinality (s);
          (%o2)                          42
          (%i3) xprimep(x) := integerp(x) and (x > 1) and primep(x)$
          (%i4) subset (s, lambda ([x], every (xprimep, x)));
          (%o4) {[2, 2, 2, 2, 2], [3, 3, 2, 2], [5, 3, 2], [5, 5], [7, 3]}

 -- Función: intersect (<a_1>, ..., <a_n>)
     Es una forma abreviada de la función 'intersection'.

 -- Función: intersection (<a_1>, ..., <a_n>)

     Devuelve el conjunto de todos los elementos que son comunes a los
     conjuntos <a_1> a <a_n>.

     Emite un mensaje de error en caso de que cualquiera de los <a_i> no
     sea un conjunto.

     Ejemplos:

          (%i1) S_1 : {a, b, c, d};
          (%o1)                     {a, b, c, d}
          (%i2) S_2 : {d, e, f, g};
          (%o2)                     {d, e, f, g}
          (%i3) S_3 : {c, d, e, f};
          (%o3)                     {c, d, e, f}
          (%i4) S_4 : {u, v, w};
          (%o4)                       {u, v, w}
          (%i5) intersection (S_1, S_2);
          (%o5)                          {d}
          (%i6) intersection (S_2, S_3);
          (%o6)                       {d, e, f}
          (%i7) intersection (S_1, S_2, S_3);
          (%o7)                          {d}
          (%i8) intersection (S_1, S_2, S_3, S_4);
          (%o8)                          {}

 -- Función: kron_delta (<x1>, <y1>, ..., <xp>, <yp>)

     Es la función delta de Kronecker.

     La función 'kron_delta' devuelve 1 cuando <xi> y <yi> son iguales
     para todos los pares, devolviendo 0 si existe un par en el que <xi>
     y <yi> no sean iguales.  La igualdad se determina utilizando
     'is(equal(xi,xj))' y la desigualdad con 'is(notequal(xi,xj))'.  En
     caso de un solo argumento, 'kron_delta' devuelve un mensaje de
     error.

     Ejemplos:

          (%i1) kron_delta(a,a);
          (%o1)                                  1
          (%i2) kron_delta(a,b,a,b);
          (%o2)                          kron_delta(a, b)
          (%i3) kron_delta(a,a,b,a+1);
          (%o3)                                  0
          (%i4) assume(equal(x,y));
          (%o4)                            [equal(x, y)]
          (%i5) kron_delta(x,y);
          (%o5)                                  1

 -- Función: listify (<a>)

     Si <a> es un conjunto, devuelve una lista con los elementos de <a>;
     si <a> no es un conjunto, devuelve <a>.

     La función 'full_listify' sustituye todos los operadores de
     conjunto en <a> por operadores de lista.

     Ejemplos:

          (%i1) listify ({a, b, c, d});
          (%o1)                     [a, b, c, d]
          (%i2) listify (F ({a, b, c, d}));
          (%o2)                    F({a, b, c, d})

 -- Función: lreduce (<f>, <s>)
 -- Función: lreduce (<f>, <s>, <init>)

     Amplía la función binaria <F> a n-aria mediante composición, siendo
     <s> una lista.

     La sentencia 'lreduce(<F>, <s>)' devuelve 'F(... F(F(s_1, s_2),
     s_3), ... s_n)'.  Si se incluye el argumento opcional <s_0>, el
     resultado equivale a 'lreduce(<F>, cons(<s_0>, <s>))'.

     La función <F> se aplica primero a los elementos del extremo
     izquierdo de la lista, de ahí el nombre 'lreduce', (left reduce).

     Véanse también 'rreduce', 'xreduce' y 'tree_reduce'.

     Ejemplos:

     La función 'lreduce' sin el argumento opcional,

          (%i1) lreduce (f, [1, 2, 3]);
          (%o1)                     f(f(1, 2), 3)
          (%i2) lreduce (f, [1, 2, 3, 4]);
          (%o2)                  f(f(f(1, 2), 3), 4)

     La función 'lreduce' con el argumento opcional,

          (%i1) lreduce (f, [1, 2, 3], 4);
          (%o1)                  f(f(f(4, 1), 2), 3)

     La función 'lreduce' aplicada a operadores binarios de Maxima.  El
     símbolo '/' es el operador división.

          (%i1) lreduce ("^", args ({a, b, c, d}));
                                         b c d
          (%o1)                       ((a ) )
          (%i2) lreduce ("/", args ({a, b, c, d}));
                                          a
          (%o2)                         -----
                                        b c d

 -- Función: makeset (<expr>, <x>, <s>)

     Genera un conjunto cuyos miembros se generan a partir de la
     expresión <expr>, siendo <x> una lista de variables de <expr> y <s>
     un conjunto o lista de listas.  Para generar los elementos del
     conjunto, se evalúa <expr> asignando a las variables de <x> los
     elementos de <s> en paralelo.

     Los elementos de <s> deben tener la misma longitud que <x>.  La
     lista de variables <x> debe ser una lista de símbolos sin
     subíndices.  Cuando se trate de un único símbolo, <x> debe
     expresarse como una lista de un elemento y cada elemento de <s>
     debe ser una lista de un sólo elemento.

     Véase también 'makelist'.

     Ejemplos:

          (%i1) makeset (i/j, [i, j], [[1, a], [2, b], [3, c], [4, d]]);
                                     1  2  3  4
          (%o1)                     {-, -, -, -}
                                     a  b  c  d
          (%i2) S : {x, y, z}$
          (%i3) S3 : cartesian_product (S, S, S);
          (%o3) {[x, x, x], [x, x, y], [x, x, z], [x, y, x], [x, y, y],
          [x, y, z], [x, z, x], [x, z, y], [x, z, z], [y, x, x],
          [y, x, y], [y, x, z], [y, y, x], [y, y, y], [y, y, z],
          [y, z, x], [y, z, y], [y, z, z], [z, x, x], [z, x, y],
          [z, x, z], [z, y, x], [z, y, y], [z, y, z], [z, z, x],
          [z, z, y], [z, z, z]}
          (%i4) makeset (i + j + k, [i, j, k], S3);
          (%o4) {3 x, 3 y, y + 2 x, 2 y + x, 3 z, z + 2 x, z + y + x,
                                                 z + 2 y, 2 z + x, 2 z + y}
          (%i5) makeset (sin(x), [x], {[1], [2], [3]});
          (%o5)               {sin(1), sin(2), sin(3)}

 -- Función: moebius (<n>)

     Representa la función de Moebius.

     Si <n> es el producto de k números primos diferentes,
     'moebius(<n>)' devuelve (-1)^k, retornando 1 si <n> = 1 y 0 para
     cualesquiera otros enteros positivos.

     La función de Moebius se distribuye respecto de ecuaciones, listas,
     matrices y conjuntos.

     Ejemplos:

          (%i1) moebius (1);
          (%o1)                           1
          (%i2) moebius (2 * 3 * 5);
          (%o2)                          - 1
          (%i3) moebius (11 * 17 * 29 * 31);
          (%o3)                           1
          (%i4) moebius (2^32);
          (%o4)                           0
          (%i5) moebius (n);
          (%o5)                      moebius(n)
          (%i6) moebius (n = 12);
          (%o6)                    moebius(n) = 0
          (%i7) moebius ([11, 11 * 13, 11 * 13 * 15]);
          (%o7)                      [- 1, 1, 1]
          (%i8) moebius (matrix ([11, 12], [13, 14]));
                                     [ - 1  0 ]
          (%o8)                      [        ]
                                     [ - 1  1 ]
          (%i9) moebius ({21, 22, 23, 24});
          (%o9)                      {- 1, 0, 1}

 -- Función: multinomial_coeff (<a_1>, ..., <a_n>)
 -- Función: multinomial_coeff ()

     Calcula el coeficiente multinomial.

     Si todos los <a_k> son enteros no negativos, el coeficiente
     multinomial es el número de formas de colocar '<a_1> + ... + <a_n>'
     objetos diferentes en n cajas con <a_k> elementos en la k-ésima
     caja.  En general, 'multinomial_coeff (<a_1>, ..., <a_n>)' calcula
     '(<a_1> + ... + <a_n>)!/(<a_1>! ... <a_n>!)'.

     Si no se dan argumentos, 'multinomial_coeff()' devuelve 1.

     Se puede usar 'minfactorial' para simplificar el valor devuelto por
     'multinomial_coeff'.

     Ejemplos:

          (%i1) multinomial_coeff (1, 2, x);
                                      (x + 3)!
          (%o1)                       --------
                                        2 x!
          (%i2) minfactorial (%);
                               (x + 1) (x + 2) (x + 3)
          (%o2)                -----------------------
                                          2
          (%i3) multinomial_coeff (-6, 2);
                                       (- 4)!
          (%o3)                       --------
                                      2 (- 6)!
          (%i4) minfactorial (%);
          (%o4)                          10

 -- Función: num_distinct_partitions (<n>)
 -- Función: num_distinct_partitions (<n>, <list>)

     Si <n> es un entero no negativo, devuelve el número de particiones
     enteras distintas de <n>, en caso contrario
     'num_distinct_partitions' devuelve una forma nominal.

     La sentencia 'num_distinct_partitions(<n>, list)' devuelve una
     lista con el número de particiones distintas de 1, 2, 3, ..., <n>.

     Una partición distinta de <n> es una lista de números enteros
     positivos distintos k_1, ..., k_m tales que <n> = k_1 + ... + k_m.

     Ejemplos:

          (%i1) num_distinct_partitions (12);
          (%o1)                          15
          (%i2) num_distinct_partitions (12, list);
          (%o2)      [1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 15]
          (%i3) num_distinct_partitions (n);
          (%o3)              num_distinct_partitions(n)

 -- Función: num_partitions (<n>)
 -- Función: num_partitions (<n>, <list>)

     Si <n> es un entero no negativo, devuelve el número de particiones
     enteras de <n>, en caso contrario 'num_partitions' devuelve una
     expresión nominal.

     La sentencia 'num_partitions(<n>, list)' devuelve una lista con los
     números de particiones enteras de 1, 2, 3, ..., <n>.

     Siendo <n> un entero no negativo, 'num_partitions(<n>)' es igual a
     'cardinality(integer_partitions(<n>))'; sin embargo,
     'num_partitions' no construye el conjunto de particiones, por lo
     que es más rápido.

     Ejemplos:

          (%i1) num_partitions (5) = cardinality (integer_partitions (5));
          (%o1)                         7 = 7
          (%i2) num_partitions (8, list);
          (%o2)            [1, 1, 2, 3, 5, 7, 11, 15, 22]
          (%i3) num_partitions (n);
          (%o3)                   num_partitions(n)

 -- Función: partition_set (<a>, <f>)

     Particiona el conjunto <a> respecto del predicado <f>.

     La función 'partition_set' devuelve una lista con dos conjuntos; el
     primer conjunto es el subconjunto de <a> para el cual el predicado
     <f> devuelve 'false' y el segundo contiene al resto de elementos de
     <a>.

     La función 'partition_set' no aplica 'is' al valor devuelto por
     <f>.

     La función 'partition_set' emite un mensaje de error si <a> no es
     un conjunto literal.

     Véase también 'subset'.

     Ejemplos:

          (%i1) partition_set ({2, 7, 1, 8, 2, 8}, evenp);
          (%o1)                   [{1, 7}, {2, 8}]
          (%i2) partition_set ({x, rat(y), rat(y) + z, 1},
                            lambda ([x], ratp(x)));
          (%o2)/R/              [{1, x}, {y, y + z}]

 -- Función: permutations (<a>)

     Devuelve un conjunto con todas las permutaciones distintas de los
     miembros de la lista o conjunto <a>.  Cada permutación es una
     lista, no un conjunto.

     Si <a> es una lista, sus miembros duplicados no son eliminados
     antes de buscar sus permutaciones.

     Si <a> no es una lista o conjunto, 'permutations' emite un mensaje
     de error.

     Véase también 'random_permutation'.

     Ejemplos:

          (%i1) permutations ([a, a]);
          (%o1)                       {[a, a]}
          (%i2) permutations ([a, a, b]);
          (%o2)           {[a, a, b], [a, b, a], [b, a, a]}

 -- Función: powerset (<a>)
 -- Función: powerset (<a>, <n>)

     Devuelve el conjunto de todos los subconjuntos del conjunto <a> o
     un sunconjunto de ellos.

     La sentencia 'powerset(<a>)' devuelve el conjunto de todos los
     subconjuntos de <a>, que contendrá '2^cardinality(<a>)' elementos.

     La sentencia 'powerset(<a>, <n>)' devuelve el conjunto de todos los
     subconjuntos de <a> de cardinalidad <n>.

     La función 'powerset' emite un mensaje de error si <a> no es un
     conjunto literal o si <n> no es un entero no negativo.

     Ejemplos:

          (%i1) powerset ({a, b, c});
          (%o1) {{}, {a}, {a, b}, {a, b, c}, {a, c}, {b}, {b, c}, {c}}
          (%i2) powerset ({w, x, y, z}, 4);
          (%o2)                    {{w, x, y, z}}
          (%i3) powerset ({w, x, y, z}, 3);
          (%o3)     {{w, x, y}, {w, x, z}, {w, y, z}, {x, y, z}}
          (%i4) powerset ({w, x, y, z}, 2);
          (%o4)   {{w, x}, {w, y}, {w, z}, {x, y}, {x, z}, {y, z}}
          (%i5) powerset ({w, x, y, z}, 1);
          (%o5)                 {{w}, {x}, {y}, {z}}
          (%i6) powerset ({w, x, y, z}, 0);
          (%o6)                         {{}}

 -- Función: random_permutation (<a>)

     Devuelve una permutación aleatoria del conjunto o lista <a>,
     siguiendo el algoritmo de Knuth.

     El valor devuelto es una lista nueva distinta del argumento,
     incluso cuando todos los elementos son iguales.  Sin embargo, los
     elementos del argumento no se copian.

     Ejemplos:

          (%i1) random_permutation ([a, b, c, 1, 2, 3]);
          (%o1)                  [c, 1, 2, 3, a, b]
          (%i2) random_permutation ([a, b, c, 1, 2, 3]);
          (%o2)                  [b, 3, 1, c, a, 2]
          (%i3) random_permutation ({x + 1, y + 2, z + 3});
          (%o3)                 [y + 2, z + 3, x + 1]
          (%i4) random_permutation ({x + 1, y + 2, z + 3});
          (%o4)                 [x + 1, y + 2, z + 3]

 -- Función: rreduce (<f>, <s>)
 -- Función: rreduce (<f>, <s>, <init>)

     Amplía la función binaria <F> a n-aria mediante composición, siendo
     <s> una lista.

     La sentencia 'rreduce(<F>, <s>)' devuelve 'F(s_1, ... F(s_{n - 2},
     F(s_{n - 1}, s_n)))'.  Si se incluye el argumento opcional <s_{n +
     1}>, el resultado equivale a 'rreduce(<F>, endcons(<s_{n + 1}>,
     <s>))'.

     La función <F> se aplica primero a los elementos del extremo
     derecho de la lista, de ahí el nombre 'rreduce', (right reduce).

     Véanse también 'lreduce', 'xreduce' y 'tree_reduce'.

     Ejemplos:

     La función 'rreduce' sin el argumento opcional,

          (%i1) rreduce (f, [1, 2, 3]);
          (%o1)                     f(1, f(2, 3))
          (%i2) rreduce (f, [1, 2, 3, 4]);
          (%o2)                  f(1, f(2, f(3, 4)))

     La función 'rreduce' con el argumento opcional,

          (%i1) rreduce (f, [1, 2, 3], 4);
          (%o1)                  f(1, f(2, f(3, 4)))

     La función 'rreduce' aplicada a operadores binarios de Maxima.  El
     símbolo '/' es el operador división.

          (%i1) rreduce ("^", args ({a, b, c, d}));
                                           d
                                          c
                                         b
          (%o1)                         a
          (%i2) rreduce ("/", args ({a, b, c, d}));
                                         a c
          (%o2)                          ---
                                         b d

 -- Función: setdifference (<a>, <b>)

     Devuelve el conjunto con los elementos del conjunto <a> que no
     pertenecen al conjunto <b>.

     La función 'setdifference' emite un mensaje de error si <a> o <b>
     no son conjuntos.

     Ejemplos:

          (%i1) S_1 : {a, b, c, x, y, z};
          (%o1)                  {a, b, c, x, y, z}
          (%i2) S_2 : {aa, bb, c, x, y, zz};
          (%o2)                 {aa, bb, c, x, y, zz}
          (%i3) setdifference (S_1, S_2);
          (%o3)                       {a, b, z}
          (%i4) setdifference (S_2, S_1);
          (%o4)                     {aa, bb, zz}
          (%i5) setdifference (S_1, S_1);
          (%o5)                          {}
          (%i6) setdifference (S_1, {});
          (%o6)                  {a, b, c, x, y, z}
          (%i7) setdifference ({}, S_1);
          (%o7)                          {}

 -- Función: setequalp (<a>, <b>)

     Devuelve 'true' si los conjuntos <a> y <b> tienen el mismo número
     de elementos y 'is (<x> = <y>)' vale 'true' para 'x' perteneciente
     a <a> e 'y' perteneciente a <b>, considerados en el orden que
     determina la función 'listify'.  En caso contrario, 'setequalp'
     devuelve 'false'.

     Ejemplos:

          (%i1) setequalp ({1, 2, 3}, {1, 2, 3});
          (%o1)                         true
          (%i2) setequalp ({a, b, c}, {1, 2, 3});
          (%o2)                         false
          (%i3) setequalp ({x^2 - y^2}, {(x + y) * (x - y)});
          (%o3)                         false

 -- Función: setify (<a>)

     Construye un conjunto con los miembros de la lista <a>.  Los
     elementos duplicados de la lista <a> son borrados y ordenados de
     acuerdo con el predicado 'orderlessp'.

     La función 'setify' emite un mensaje de error si <a> no es un
     conjunto literal.

     Ejemplos:

          (%i1) setify ([1, 2, 3, a, b, c]);
          (%o1)                  {1, 2, 3, a, b, c}
          (%i2) setify ([a, b, c, a, b, c]);
          (%o2)                       {a, b, c}
          (%i3) setify ([7, 13, 11, 1, 3, 9, 5]);
          (%o3)                {1, 3, 5, 7, 9, 11, 13}

 -- Función: setp (<a>)

     Devuelve 'true' si y sólo si <a> es un conjunto de Maxima.

     La función 'setp' devuelve 'true' tanto cuando el conjunto tiene
     como cuando no tiene elementos repetidos.

     La función 'setp' is equivalent to the Maxima function 'setp(a) :=
     not atom(a) and op(a) = 'set'.

     Ejemplos:

          (%i1) simp : false;
          (%o1)                         false
          (%i2) {a, a, a};
          (%o2)                       {a, a, a}
          (%i3) setp (%);
          (%o3)                         true

 -- Función: set_partitions (<a>)
 -- Función: set_partitions (<a>, <n>)

     Devuelve el conjunto de todas las particiones de <a> o un
     subconjunto de ellas.

     La sentencia 'set_partitions(<a>, <n>)' devuelve un conjunto con
     todas las descomposiciones de <a> en <n> conjuntos no vacíos
     disjuntos.

     La sentencia 'set_partitions(<a>)' devuelve el conjunto de todas
     las particiones.

     La función 'stirling2' devuelve la cardinalidad del conjunto de las
     particiones de un conjunto.

     Se dice que un conjunto P es una partición del conjunto S si
     verifica

       1. cada elemento de P es un conjunto no vacío,
       2. los elementos de P son disjuntos,
       3. la unión de los elementos de P es igual a S.

     Ejemplos:

     El conjunto vacío forma una partición de sí mismo,

          (%i1) set_partitions ({});
          (%o1)                         {{}}

     La cardinalidad del conjunto de particiones de un conjunto puede
     calcularse con 'stirling2',

          (%i1) s: {0, 1, 2, 3, 4, 5}$
          (%i2) p: set_partitions (s, 3)$
          (%i3) cardinality(p) = stirling2 (6, 3);
          (%o3)                        90 = 90

     Cada elemento de 'p' debería tener <n> = 3 miembros,

          (%i1) s: {0, 1, 2, 3, 4, 5}$
          (%i2) p: set_partitions (s, 3)$
          (%i3) map (cardinality, p);
          (%o3)                          {3}

     Por último, para cada miembro de 'p', la unión de sus elementos
     debe ser igual a 's',

          (%i1) s: {0, 1, 2, 3, 4, 5}$
          (%i2) p: set_partitions (s, 3)$
          (%i3) map (lambda ([x], apply (union, listify (x))), p);
          (%o3)                 {{0, 1, 2, 3, 4, 5}}

 -- Función: some (<f>, <a>)
 -- Función: some (<f>, <L_1>, ..., <L_n>)

     Devuelve 'true' si el predicado <f> devuelve 'true' para al menos
     uno de sus argumentos.  Si el segundo argumento es un conjunto,
     'some (<f>, <a>)' devuelve 'true' si '<f>(<a_i>)' devuelve también
     'true' para alguno de los <a_i> en <a>; puede ser que 'some' no
     evalúe <f> para todos los <a_i> de <s>.  Puesto que los conjuntos
     no están ordenados, 'some' puede evaluar '<f>(<a_i>)' en cualquier
     orden.

     Dada una o más listas como argumentos, 'some (<f>, <L_1>, ...,
     <L_n>)' devuelve 'true' si '<f>(<x_1>, ..., <x_n>)' devuelve
     también 'true' para al menos un <x_1>, ..., <x_n> de <L_1>, ...,
     <L_n>, respectivamente; puede ser que 'some' no evalúe <f> para
     todos las combinaciones <x_1>, ..., <x_n>.  La función 'some'
     evalúa las listas en el orden creciente de su índice

     Dado un conjunto vacío '{}' o una lista vacía como argumentos,
     'some' devuelve 'false'.

     Si la variable global 'maperror' vale 'true', todas las listas
     <L_1>, ..., <L_n> deben tener igual número de elementos.  Si
     'maperror' vale 'false', los argumentos se truncan para tener todos
     el número de elementos de la lista más corta.

     Los valores que devuelve el predicado <f> cuando toman (mediante
     'is') un valor diferente a 'true' y 'false' se controlan con la
     variable global 'prederror'.  Si 'prederror' vale 'true', tales
     valores se consideran como 'false'.  Si 'prederror' vale 'false',
     tales valores se consideran como desconocidos ('unknown').

     Ejemplos:

     La función 'some' aplicada a un único conjunto.  El predicado es
     una función de un argumento,

          (%i1) some (integerp, {1, 2, 3, 4, 5, 6});
          (%o1)                         true
          (%i2) some (atom, {1, 2, sin(3), 4, 5 + y, 6});
          (%o2)                         true

     La función 'some' aplicada a dos listas.  El predicado es una
     función de dos argumentos,

          (%i1) some ("=", [a, b, c], [a, b, c]);
          (%o1)                         true
          (%i2) some ("#", [a, b, c], [a, b, c]);
          (%o2)                         false

     Las respuestas del predicado <f> que se evalúan a cualquier cosa
     diferente de 'true' y 'false' están controlados por la variable
     global 'prederror'.

          (%i1) prederror : false;
          (%o1)                         false
          (%i2) map (lambda ([a, b], is (a < b)), [x, y, z],
                               [x^2, y^2, z^2]);
          (%o2)              [unknown, unknown, unknown]
          (%i3) some ("<", [x, y, z], [x^2, y^2, z^2]);
          (%o3)                        unknown
          (%i4) some ("<", [x, y, z], [x^2, y^2, z + 1]);
          (%o4)                         true
          (%i5) prederror : true;
          (%o5)                         true
          (%i6) some ("<", [x, y, z], [x^2, y^2, z^2]);
          (%o6)                         false
          (%i7) some ("<", [x, y, z], [x^2, y^2, z + 1]);
          (%o7)                         true

 -- Función: stirling1 (<n>, <m>)

     Es el número de Stirling de primera especie.

     Si tanto <n> como <m> son enteros no negativos, el valor que toma
     'stirling1 (<n>, <m>)' es el número de permutaciones de un conjunto
     de <n> elementos con <m> ciclos.  Para más detalles, véase Graham,
     Knuth and Patashnik Concrete Mathematics.  Maxima utiliza una
     relación recursiva para definir 'stirling1 (<n>, <m>)' para <m>
     menor que 0; no está definida para <n> menor que 0 ni para
     argumentos no enteros.

     La función 'stirling1' es simplificadora.  Maxima reconoce las
     siguientes identidades:

       1. stirling1(0, n) = kron_delta(0, n) (Ref.  [1])
       2. stirling1(n, n) = 1 (Ref.  [1])
       3. stirling1(n, n - 1) = binomial(n, 2) (Ref.  [1])
       4. stirling1(n + 1, 0) = 0 (Ref.  [1])
       5. stirling1(n + 1, 1) = n! (Ref.  [1])
       6. stirling1(n + 1, 2) = 2^n - 1 (Ref.  [1])

     Estas identidades se aplican cuando los argumentos son enteros
     literales o símbolos declarados como enteros y el primer argumento
     es no negativo.  La función 'stirling1' no simplifica para
     argumentos no enteros.

     Referencias:

     [1] Donald Knuth, The Art of Computer Programming, Tercera Edición,
     Volumen 1, Sección 1.2.6, Ecuaciones 48, 49 y 50.

     Ejemplos:

          (%i1) declare (n, integer)$
          (%i2) assume (n >= 0)$
          (%i3) stirling1 (n, n);
          (%o3)                           1

     La función 'stirling1' no simplifica en caso de argumentos no
     enteros,

          (%i1) stirling1 (sqrt(2), sqrt(2));
          (%o1)              stirling1(sqrt(2), sqrt(2))

     Maxima aplicas algunas identidades a 'stirling1',

          (%i1) declare (n, integer)$
          (%i2) assume (n >= 0)$
          (%i3) stirling1 (n + 1, n);
                                      n (n + 1)
          (%o3)                       ---------
                                          2
          (%i4) stirling1 (n + 1, 1);
          (%o4)                          n!

 -- Función: stirling2 (<n>, <m>)

     Es el número de Stirling de segunda especie.

     Si <n> y <m> son enteros no negativos, 'stirling2 (<n>, <m>)' es el
     número de formas en las que se puede particionar un conjunto de
     cardinal <n> en <m> subconjuntos disjuntos.  Maxima utiliza una
     relación recursiva para definir 'stirling2 (<n>, <m>)' con <m>
     menor que 0; la función no está definida para <n> menor que 0 ni
     para argumentos no enteros.

     La función 'stirling2' es simplificadora.  Maxima reconoce las
     siguientes identidades:

       1. stirling2(0, n) = kron_delta(0, n) (Ref.  [1])
       2. stirling2(n, n) = 1 (Ref.  [1])
       3. stirling2(n, n - 1) = binomial(n, 2) (Ref.  [1])
       4. stirling2(n + 1, 1) = 1 (Ref.  [1])
       5. stirling2(n + 1, 2) = 2^n - 1 (Ref.  [1])
       6. stirling2(n, 0) = kron_delta(n, 0) (Ref.  [2])
       7. stirling2(n, m) = 0 when m > n (Ref.  [2])
       8. stirling2(n, m) = sum((-1)^(m - k) binomial(m k) k^n,i,1,m) /
          m! si m y n son enteros y n no negativo.  (Ref.  [3])

     Estas identidades se aplican cuando los argumentos son enteros
     literales o símbolos declarados como enteros y el primer argumento
     es no negativo.  La función 'stirling2' no simplifica para
     argumentos no enteros.

     Referencias:

     [1] Donald Knuth.  The Art of Computer Programming, Tercera
     Edición, Volumen 1, Sección 1.2.6, Ecuaciones 48, 49 y 50.

     [2] Graham, Knuth y Patashnik.  Concrete Mathematics, Tabla 264.

     [3] Abramowitz y Stegun.  Handbook of Mathematical Functions,
     Sección 24.1.4.

     Ejemplos:

          (%i1) declare (n, integer)$
          (%i2) assume (n >= 0)$
          (%i3) stirling2 (n, n);
          (%o3)                           1

     La función 'stirling2' no simplifica en caso de argumentos no
     enteros,

          (%i1) stirling2 (%pi, %pi);
          (%o1)                  stirling2(%pi, %pi)

     Maxima aplicas algunas identidades a 'stirling2',

          (%i1) declare (n, integer)$
          (%i2) assume (n >= 0)$
          (%i3) stirling2 (n + 9, n + 8);
                                   (n + 8) (n + 9)
          (%o3)                    ---------------
                                          2
          (%i4) stirling2 (n + 1, 2);
                                        n
          (%o4)                        2  - 1

 -- Función: subset (<a>, <f>)

     Devuelve el subconjunto del conjunto <a> que satisface el predicado
     <f>.

     La función 'subset' devuelve el conjunto que contiene a los
     elementos de <a> para los cuales <f> devuelve un resultado
     diferente de 'false'.  La función 'subset' no aplica 'is' al valor
     retornado por <f>.

     La función 'subset' emite un mensaje de error si <a> no es un
     conjunto literal.

     Véase también 'partition_set'.

     Ejemplos:

          (%i1) subset ({1, 2, x, x + y, z, x + y + z}, atom);
          (%o1)                     {1, 2, x, z}
          (%i2) subset ({1, 2, 7, 8, 9, 14}, evenp);
          (%o2)                      {2, 8, 14}

 -- Función: subsetp (<a>, <b>)

     Devuelve 'true' si y sólo si el conjunto <a> es un subconjunto de
     <b>.

     La función 'subsetp' emite un mensaje de error si cualesquiera <a>
     o <b> no es un conjunto literal.

     Ejemplos:

          (%i1) subsetp ({1, 2, 3}, {a, 1, b, 2, c, 3});
          (%o1)                         true
          (%i2) subsetp ({a, 1, b, 2, c, 3}, {1, 2, 3});
          (%o2)                         false

 -- Función: symmdifference (<a_1>, ..., <a_n>)

     Devuelve la diferencia simétrica de los conjuntos ' <a_1>, ...,
     <a_n>'.

     Dados dos argumentos, 'symmdifference (<a>, <b>)' equivale a 'union
     (setdifference (<a>, <b>), setdifference (<b>, <a>))'.

     La función 'symmdifference' emite un mensaje de error si alguno de
     su argumentos no es un conjunto literal.

     Ejemplos:

          (%i1) S_1 : {a, b, c};
          (%o1)                       {a, b, c}
          (%i2) S_2 : {1, b, c};
          (%o2)                       {1, b, c}
          (%i3) S_3 : {a, b, z};
          (%o3)                       {a, b, z}
          (%i4) symmdifference ();
          (%o4)                          {}
          (%i5) symmdifference (S_1);
          (%o5)                       {a, b, c}
          (%i6) symmdifference (S_1, S_2);
          (%o6)                        {1, a}
          (%i7) symmdifference (S_1, S_2, S_3);
          (%o7)                       {1, b, z}
          (%i8) symmdifference ({}, S_1, S_2, S_3);
          (%o8)                       {1,b, z}

 -- Función: tree_reduce (<F>, <s>)
 -- Función: tree_reduce (<F>, <s>, <s_0>)

     Amplía la función binaria <F> a n-aria, siendo <s> una lista.

     La función 'tree_reduce' equivale a lo suguiente: Aplicar <F> a
     pares sucesivos de elementos para formar una nueva lista
     '[<F>(<s_1>, <s_2>), <F>(<s_3>, <s_4>), ...]', llevando el elemento
     final sin cambiar si el número de elementos es impar; después
     repetir hasta que la lista se reduzca a un único elemento, que es
     el valor de retorno.

     Cuando está presente el argumento opcional <s_0>, el resultado
     equivale a 'tree_reduce(<F>, cons(<s_0>, <s>)'.

     Para la suma de números decimales en coma flotante, 'tree_reduce'
     puede devolver una suma que tenga un error de redondeo menor que el
     conseguido por 'rreduce' o 'lreduce'.

     Los elementos de <s> y los resultados parciales pueden colocarse en
     un árbol binario de mínima profundidad, de ahí el nombre de
     tree_reduce.

     Ejemplos:

     La función 'tree_reduce' aplicada a una lista con un número par de
     elementos,

          (%i1) tree_reduce (f, [a, b, c, d]);
          (%o1)                  f(f(a, b), f(c, d))

     La función 'tree_reduce' aplicada a una lista con un número impar
     de elementos,

          (%i1) tree_reduce (f, [a, b, c, d, e]);
          (%o1)               f(f(f(a, b), f(c, d)), e)

 -- Function: union (<a_1>, ..., <a_n>)

     Devuelve la unión de los conjuntos <a_1> hasta <a_n>.

     La sentencia 'union()' (sin argumentos) devuelve el conjunto vacío.

     La función 'union' emite un mensaje de error si alguno de sus
     argumentos no es un conjunto literal.

     Ejemplos:

          (%i1) S_1 : {a, b, c + d, %e};
          (%o1)                   {%e, a, b, d + c}
          (%i2) S_2 : {%pi, %i, %e, c + d};
          (%o2)                 {%e, %i, %pi, d + c}
          (%i3) S_3 : {17, 29, 1729, %pi, %i};
          (%o3)                {17, 29, 1729, %i, %pi}
          (%i4) union ();
          (%o4)                          {}
          (%i5) union (S_1);
          (%o5)                   {%e, a, b, d + c}
          (%i6) union (S_1, S_2);
          (%o6)              {%e, %i, %pi, a, b, d + c}
          (%i7) union (S_1, S_2, S_3);
          (%o7)       {17, 29, 1729, %e, %i, %pi, a, b, d + c}
          (%i8) union ({}, S_1, S_2, S_3);
          (%o8)       {17, 29, 1729, %e, %i, %pi, a, b, d + c}

 -- Función: xreduce (<F>, <s>)
 -- Función: xreduce (<F>, <s>, <s_0>)

     Amplía la función <F> a n-aria mediante composición; si <F> ya es
     n-aria, aplica <F> a <s>.  Si <F> no es n-aria, 'xreduce' equivale
     a 'lreduce'.  El argumento <s> debe ser una lista.

     Funciones n-arias reconocidas por Maxima son la suma '+', la
     multiplicación '*', 'and', 'or', 'max', 'min' y 'append'.  Las
     funciones también se pueden declarar n-arias mediante 'declare(<F>,
     nary)'; para estas funciones, 'xreduce' será más rápida que
     'rreduce' o 'lreduce'.

     Cuando está presente el argumento opcional <s_0>, el resultado
     equivale a 'xreduce(<s>, cons(<s_0>, <s>))'.

     La suma de números decimales en coma flotante no es exactamente
     asociativa; aún así, 'xreduce' aplica la suma n-aria cuando <s>
     contiene números en coma flotante.

     Ejemplos:

     La función 'xreduce' aplicada a una función n-aria; 'F' es invocada
     una sóla vez, con todos sus argumentos,

          (%i1) declare (F, nary);
          (%o1)                         done
          (%i2) F ([L]) := L;
          (%o2)                      F([L]) := L
          (%i3) xreduce (F, [a, b, c, d, e]);
          (%o3)         [[[[[("[", simp), a], b], c], d], e]

     La función 'xreduce' aplicada a una función que se desconoce si es
     n-aria; 'G' es invocada varias veces, con dos argumentos de cada
     vez,

          (%i1) G ([L]) := L;
          (%o1)                      G([L]) := L
          (%i2) xreduce (G, [a, b, c, d, e]);
          (%o2)         [[[[[("[", simp), a], b], c], d], e]
          (%i3) lreduce (G, [a, b, c, d, e]);
          (%o3)                 [[[[a, b], c], d], e]


File: maxima.info,  Node: Definición de Funciones,  Next: Programación,  Prev: Conjuntos,  Up: Top

36 Definición de Funciones
**************************

* Menu:

* Introducción a la definición de funciones::  
* Funciones::                    
* Macros::                       
* Funciones y variables para la definición de funciones::  


File: maxima.info,  Node: Introducción a la definición de funciones,  Next: Funciones,  Prev: Definición de Funciones,  Up: Definición de Funciones

36.1 Introducción a la definición de funciones
==============================================


File: maxima.info,  Node: Funciones,  Next: Macros,  Prev: Introducción a la definición de funciones,  Up: Definición de Funciones

36.2 Funciones
==============

36.2.1 Funciones ordinarias
---------------------------

Para definir una función en Maxima es necesario utilizar el operador
':='.

Por ejemplo,

     f(x) := sin(x)

define una función 'f'.  También se pueden definir funciones anónimas
utilizando 'lambda'; por ejemplo,

     lambda ([i, j], ...)

puede utilizarse en lugar de 'f' donde

     f(i,j) := block ([], ...);
     map (lambda ([i], i+1), l)

devolvería una lista con todos sus elementos aumentados en una unidad.

También se puede definir una función con un número variable de
argumentos, sin más que añadir un argumento final al que se le asigna
una lista con todos los argumentos adicionales.:

     (%i1) f ([u]) := u;
     (%o1)                      f([u]) := u
     (%i2) f (1, 2, 3, 4);
     (%o2)                     [1, 2, 3, 4]
     (%i3) f (a, b, [u]) := [a, b, u];
     (%o3)               f(a, b, [u]) := [a, b, u]
     (%i4) f (1, 2, 3, 4, 5, 6);
     (%o4)                 [1, 2, [3, 4, 5, 6]]

El miembro derecho de una función debe ser una expresión.  Así, si se
quiere una secuencia de expresiones, se debe hacer

     f(x) := (expr1, expr2, ...., exprn);

siendo el valor que alcance exprn el devuelto por la función.

Si se quiere hacer un 'return' desde alguna de las expresiones de la
función, se debe utilizar la estructura 'block' junto con 'return'.  Por
ejemplo,

     block ([], expr1, ..., if (a > 10) then return(a), ..., exprn)

es una expresión de pleno derecho, por lo que puede ocupar el lado
derecho de la definición de una función.  Aquí puede ocurrir que el
retorno se produzca antes que se alcance la última expresión.

Los primeros corchetes del bloque ('[]') pueden contener una lista de
variables junto con posibles asignaciones, tal como '[a: 3, b, c: []]',
lo que provocará que las tres variables 'a','b' y 'c' se consideren
locales y sean independientes de otras globales con el mismo nombre; las
variables locales sólo estarán activas mientras se ejecute el código que
está dentro de la estructura 'block', o dentro de funciones que son
llamadas desde dentro de 'block'.  A esto se le llama asignación
dinámica, pues las variables sobreviven desde el inicio del bloque hasta
que éste deje de estar operativo.  Una vez se salga del bloque los
valores originales de las variables, si es que los había, quedan
restaurados.  Es recomendable proteger las variables de esta forma.  Se
tendrá en cuenta que las asignaciones a las variables del bloque se
hacen en paralelo, lo que significa que si como en el ejemplo anterior
se hace 'c: a' en el momento de entrar en el bloque, el valor de 'c'
será el que tenía 'a' antes de entrar en el bloque, es decir, antes de
la asignación 'a: 3'.  Así, haciendo lo siguiente

     block ([a: a], expr1, ... a: a+3, ..., exprn)

se prevendría de que el valor externo de 'a' fuese alterado, pero
permitiría acceder a él desde dentro del bloque.  La parte derecha de
las asignaciones se evalúa dentro de su contexto antes de hacer efectiva
la asignación.  Utilizando únicamente 'block([x],..' haría que 'x' se
tuviese a sí misma como valor, justo como si se acabase de iniciar una
nueva sesión de Maxima.

Los valores de los argumentos de una funcón se tratan exactamente de la
misma forma que las variables de un bloque.  Así, con

     f(x) := (expr1, ..., exprn);

y

     f(1);

se estaría en un contexto similar para la evaluación de las expresiones
como si se hubiera hecho

     block ([x: 1], expr1, ..., exprn)

Dentro de las funciones, cuando el lado derecho de la definición deba
ser evaluado será útil hacer uso de 'define' y posiblemente de 'buildq'.

36.2.2 Funciones array
----------------------

Una función array almacena el valor de la función la primera vez que es
invocada con un argumento dado, devolviendo el valor almacenado sin
recalcularlo cuando es llamada con ese mismo argumento.  Estas funciones
reciben también el nombre de funciones memorizadoras.

Los nombres de las funciones array son añadidos a la lista global
'arrays', no a la lista global 'functions'.  La función 'arrayinfo'
devuelve la lista de argumentos para los que hay valores almacenados y
'listarray' devuelve precisamente estos valores almacenados.  Las
funciones 'dispfun' y 'fundef' devuelven la definición de la función
array.

La función 'arraymake' construye una llamada a una función array, de
forma similar a como lo hace 'funmake' para las funciones ordinarias.
Por otro lado, 'arrayapply' aplica una función array a sus argumentos,
tal como lo hace 'apply' con las funciones ordinarias.  No existe para
las funciones array nada similar a 'map', aunque 'map(lambda([<x>],
<a>[<x>]), <L>)' o 'makelist(<a>[<x>], <x>, <L>)', siendo <L> una lista,
podrían suplantar esta carencia.

La función 'remarray' borra la definición de una función array, así como
cualesquiera valores almacenados que tenga asociados, tal como
'remfunction' lo hace con las funciones ordinarias.

La llamada 'kill(<a>[<x>])' borra el valor de la función array <a>
almacenado para el argumento <x>; la próxima vez que se llame a <a> con
el argumento <x>, se recalculará el valor correspondiente.  Sin embargo,
no hay forma de borrar todos los valores almacenados de una sola vez,
excepto mediante 'kill(<a>)' o 'remarray(<a>)', con lo que se borra
también la definición de la propia función.


File: maxima.info,  Node: Macros,  Next: Funciones y variables para la definición de funciones,  Prev: Funciones,  Up: Definición de Funciones

36.3 Macros
===========

 -- Función: buildq (<L>, <expr>)
     Sustituye en paralelo las variables nombradas en la lista <L> en la
     expresión <expr>, sin evaluar ésta.  La expresión resultante se
     simplifica pero no se evalúa hasta que 'buildq' termine de hacer
     las sustituciones.

     Los elementos de <L> son símbolos o expresiones de asignación del
     tipo '<symbol>: <value>', evaluadas en paralelo.  Esto es, el valor
     de una variable en la parte derecha de una asignación es el valor
     que toma dicha variable en el contexto desde el que se invoca a
     'buildq'.  En caso de que a una variable de <L> no se le haga una
     signación explícita, su valor en 'buildq' es el mismo que tiene en
     el contexto desde el que se llama a 'buildq'.

     Las variables referenciadas en <L> se sustituyen en <expr> en
     paralelo.  Esto es, la sustitución para cada variable se determina
     antes de que se hagan las sustituciones, de forma que la
     sustitución de una variable no tiene efecto alguno sobre las otras.

     Si alguna variable <x> aparece como 'splice (<x>)' en <expr>,
     entonces a <x> se le debe asignar una lista, la cual será
     interpolada en <expr> en lugar de hacer una simple sustitución; ver
     ejemplo más abajo.

     Cualesquiera otras variables de <expr> que no aparezcan en <L> se
     traspasan al resultado tal cual, incluso cuando tienen asignados
     valores en el contexto desde el que se llama a 'buildq'.

     Ejemplos:

     'a' queda asociada explícitamente a 'x', mientras que 'b' tiene la
     misma asociación (29) que en el contexto de llamada y 'c' es
     traspasado al resultado sin ser sustituido.  La expresión
     resultante no se evalúa hasta que no se le obligue a ello mediante
     la evaluación explícita '''%'.

          (%i1) (a: 17, b: 29, c: 1729)$
          (%i2) buildq ([a: x, b], a + b + c);
          (%o2)                      x + c + 29
          (%i3) ''%;
          (%o3)                       x + 1758

     En este ejemplo, 'e' se asocia a una lista, la cual aparece como
     tal en los argumentos de 'foo' e interpolada en los argumentos de
     'bar'.

          (%i1) buildq ([e: [a, b, c]], foo (x, e, y));
          (%o1)                 foo(x, [a, b, c], y)
          (%i2) buildq ([e: [a, b, c]], bar (x, splice (e), y));
          (%o2)                  bar(x, a, b, c, y)

     Como se ve a continuación, el resultado se simplifica tras las
     sustituciones.  Si la simplificación se realizase antes que las
     sustituciones, ambos resultados serían iguales.

          (%i1) buildq ([e: [a, b, c]], splice (e) + splice (e));
          (%o1)                    2 c + 2 b + 2 a
          (%i2) buildq ([e: [a, b, c]], 2 * splice (e));
          (%o2)                        2 a b c

     Las variables de <L> se asocian en paralelo; si se hiciese
     secuencialmente, el primer resultado sería 'foo (b, b)'.  Las
     sustituciones se llevan a cabo en paralelo.  Compárese el segundo
     resultado con el resultado de 'subst', que hace las sustituciones
     de forma secuencial.

          (%i1) buildq ([a: b, b: a], foo (a, b));
          (%o1)                       foo(b, a)
          (%i2) buildq ([u: v, v: w, w: x, x: y, y: z, z: u],
                        bar (u, v, w, x, y, z));
          (%o2)                 bar(v, w, x, y, z, u)
          (%i3) subst ([u=v, v=w, w=x, x=y, y=z, z=u],
                       bar (u, v, w, x, y, z));
          (%o3)                 bar(u, u, u, u, u, u)

     Se construye a continuación un sistema de ecuaciones con algunas
     variables o expresiones en el lado izquierdo y sus valores en el
     derecho; 'macroexpand' muestra la expresión devuelta por
     'show_values'.

          (%i1) show_values ([L]) ::= buildq ([L], map ("=", 'L, L));
          (%o1)   show_values([L]) ::= buildq([L], map("=", 'L, L))
          (%i2) (a: 17, b: 29, c: 1729)$
          (%i3) show_values (a, b, c - a - b);
          (%o3)          [a = 17, b = 29, c - b - a = 1683]
          (%i4) macroexpand (show_values (a, b, c - a - b));
          (%o4)    map(=, '([a, b, c - b - a]), [a, b, c - b - a])

     Dada una función con varios argumentos, se crea otra función en la
     cual algunos argumentos son fijos.

          (%i1) curry (f, [a]) :=
                  buildq ([f, a], lambda ([[x]], apply (f, append (a, x))))$
          (%i2) by3 : curry ("*", 3);
          (%o2)        lambda([[x]], apply(*, append([3], x)))
          (%i3) by3 (a + b);
          (%o3)                       3 (b + a)

 -- Función: macroexpand (<expr>)
     Devuelve la macroexpansión de <expr>, sin evaluarla, cuando 'expr'
     es una llamada a una función macro; en caso contrario,
     'macroexpand' devuelve <expr>.

     Si la expansión de <expr> devuelve otra llamada a una función
     macro, esta llamada también se expande.

     La función 'macroexpand' no evalúa su argumento.  Sin embargo, si
     la expansión de una llamada a función macro tiene efectos
     laterales, éstos se ejecutan.

     Véanse también '::=', 'macros' y 'macroexpand1'.

     Ejemplos:

          (%i1) g (x) ::= x / 99;
                                              x
          (%o1)                      g(x) ::= --
                                              99
          (%i2) h (x) ::= buildq ([x], g (x - a));
          (%o2)            h(x) ::= buildq([x], g(x - a))
          (%i3) a: 1234;
          (%o3)                         1234
          (%i4) macroexpand (h (y));
                                        y - a
          (%o4)                         -----
                                         99
          (%i5) h (y);
                                      y - 1234
          (%o5)                       --------
                                         99

 -- Función: macroexpand1 (<expr>)
     Devuelve la macroexpansión de <expr>, sin evaluarla, cuando 'expr'
     es una llamada a una función macro; en caso contrario,
     'macroexpand1' devuelve <expr>.

     La función 'macroexpand1' no evalúa su argumento.  Sin embargo, si
     la expansión de una llamada a función macro tiene efectos
     laterales, éstos se ejecutan.

     Si la expansión de <expr> devuelve otra llamada a una función
     macro, esta llamada no se expande.

     Véanse también '::=', 'macros' y 'macroexpand'.

     Ejemplos:

          (%i1) g (x) ::= x / 99;
                                              x
          (%o1)                      g(x) ::= --
                                              99
          (%i2) h (x) ::= buildq ([x], g (x - a));
          (%o2)            h(x) ::= buildq([x], g(x - a))
          (%i3) a: 1234;
          (%o3)                         1234
          (%i4) macroexpand1 (h (y));
          (%o4)                       g(y - a)
          (%i5) h (y);
                                      y - 1234
          (%o5)                       --------
                                         99

 -- Variable global: macros
     Valor por defecto: '[]'

     La variable 'macros' es la lista de las funciones macro definidas
     por el usuario.  El operador de definición de funciones macro '::='
     coloca la nueva función macro en esta lista, mientras que 'kill',
     'remove' y 'remfunction' eliminan las funciones macro de la lista.

     Véase también 'infolists'.

 -- Función: splice (<a>)

     Interpola la lista nombrada por el átomo <a> dentro de una
     expresión, pero sólo si 'splice' aparece dentro de 'buildq'; en
     otro caso, 'splice' se considera una función no definida.  Si <a>
     aparece dentro de 'buildq' sin 'splice', entonces queda sustituida
     por una lista dentro del resultado.  El argumento de 'splice' debe
     ser un átomo, no pudiendo ser una lista literal ni una expresión
     que devuelva una lista.

     Normalmente 'splice' suministra los argumentos para una función u
     operador.  Para una función 'f', la expresión 'f (splice (<a>))'
     dentro de 'buildq' se convierte en 'f (<a>[1], <a>[2], <a>[3],
     ...)'.  Dado un operador 'o', la expresión '"o" (splice (<a>)'
     dentro de 'buildq' se convierte en '"o" (<a>[1], <a>[2], <a>[3],
     ...)', donde 'o' puede ser cualquier tipo de operador, normalmente
     uno que admita varios argumentos.  Nótese que el operador debe ir
     encerrado entre comillas dobles '"'.

     Ejemplos:

          (%i1) buildq ([x: [1, %pi, z - y]], foo (splice (x)) / length (x));
                                 foo(1, %pi, z - y)
          (%o1)                -----------------------
                               length([1, %pi, z - y])
          (%i2) buildq ([x: [1, %pi]], "/" (splice (x)));
                                          1
          (%o2)                          ---
                                         %pi
          (%i3) matchfix ("<>", "<>");
          (%o3)                          <>
          (%i4) buildq ([x: [1, %pi, z - y]], "<>" (splice (x)));
          (%o4)                   <>1, %pi, z - y<>


File: maxima.info,  Node: Funciones y variables para la definición de funciones,  Prev: Macros,  Up: Definición de Funciones

36.4 Funciones y variables para la definición de funciones
==========================================================

 -- Función: apply (<F>, [<x_1>, ..., <x_n>])
     Construye y evalúa la expresión '<F>(<arg_1>, ..., <arg_n>)'.

     La función 'apply' no hace distinciones entre funciones array y
     funciones ordinarias; cuando <F> es el nombre de una función array,
     'apply' evalúa '<F>(...)', esto es, hace una llamada con paréntesis
     en lugar de corchetes.  La función 'arrayapply' evalúa una llamada
     a función con corchetes para estos casos.

     Ejemplos:

     La función 'apply' evalúa sus argumentos.  En este ejemplo, 'min'
     se aplica al valor de 'L'.

          (%i1) L : [1, 5, -10.2, 4, 3];
          (%o1)                 [1, 5, - 10.2, 4, 3]
          (%i2) apply (min, L);
          (%o2)                        - 10.2

     La función 'apply' evalúa sus argumentos, incluso cuando la función
     <F> no lo hace.

          (%i1) F (x) := x / 1729;
                                             x
          (%o1)                     F(x) := ----
                                            1729
          (%i2) fname : F;
          (%o2)                           F
          (%i3) dispfun (F);
                                             x
          (%t3)                     F(x) := ----
                                            1729

          (%o3)                         [%t3]
          (%i4) dispfun (fname);
          fname is not the name of a user function.
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i5) apply (dispfun, [fname]);
                                             x
          (%t5)                     F(x) := ----
                                            1729

          (%o5)                         [%t5]

     La función 'apply' evalúa el nombre de función <F>.  La comilla
     simple ''' evita la evaluación.  El nombre 'demoivre' corresponde a
     una variable global y también a una función.

          (%i1) demoivre;
          (%o1)                         false
          (%i2) demoivre (exp (%i * x));
          (%o2)                  %i sin(x) + cos(x)
          (%i3) apply (demoivre, [exp (%i * x)]);
          demoivre evaluates to false
          Improper name or value in functional position.
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i4) apply ('demoivre, [exp (%i * x)]);
          (%o4)                  %i sin(x) + cos(x)

 -- Función: block ([<v_1>, ..., <v_m>], <expr_1>, ..., <expr_n>)
 -- Función: block (<expr_1>, ..., <expr_n>)

     La función 'block' evalúa <expr_1>, ..., <expr_n> secuencialmente y
     devuelve el valor de la última expresión evaluada.  La secuencia
     puede alterarse con las funciones 'go', 'throw' y 'return'.  La
     última expresión es <expr_n> a menos que 'return' o una expresión
     que contenga un 'throw' sea evaluada.  Las variables <v_1>, ...,
     <v_m> son locales en el bloque; éstas se distiguen de las globales
     que tengan el mismo nombre.  Si no se declaran variables locales
     entonces se puede omitir la lista.  Dentro del bloque, cualquier
     otra variable distinta de <v_1>, ..., <v_m> se considera global.

     La función 'block' guarda los valores actuales de las variables
     <v_1>, ..., <v_m>, si los tienen, a la entrada del bloque y luego
     las evalúa a sí mismas, es decir les saca el valor temporalmente.
     A las variables locales se les puede asignar cualquier valor dentro
     del bloque, pero al salir de éste, los valores inicialmente
     almacenados quedan restaurados, al tiempo que los asignados dentro
     del bloque se pierden.

     La declaración 'local(<v_1>, ..., <v_m>)' dentro de un bloque
     almacena las propiedades asociadas a los símbolos <v_1>, ...,
     <v_m>, borra cualesquiera otras propiedades antes de evaluar las
     expresiones y restaura las propiedades guardadas antes de abandonar
     el bloque.  Algunas declaraciones, como ':=', 'array',
     'dependencies', 'atvalue', 'matchdeclare', 'atomgrad', 'constant',
     'nonscalar', 'assume' y otras se implementan como propiedades de
     símbolos.  El efecto producido por 'local' consiste en hacer que
     tales declaraciones tengan efecto sólo dentro del bloque, en otro
     caso las declaraciones dentro del bloque tendrían un efecto global
     que afectarían al exterior de 'block'.

     Un 'block' puede aparecer dentro de otro 'block'.  Las variables
     locales se inicializan cada vez que se entra dentro de un nuevo
     bloque.  Las variables locales de un bloque se consideran globales
     dentro de otro anidado dentro del primero.  Si una variable es no
     local dentro de un bloque, su valor es el que le corresponde en el
     bloque superior.  Este criterio se conoce con el nombre de "alcance
     dinámico".

     El valor del bloque es el de la última sentencia o el argumento de
     la función 'return', que puede utilizarse para salir del bloque.
     La función 'go' puede usarse para transferir el control a la
     sentencia del bloque que esté etiquetada con el argumento de 'go'.
     Para etiquetar una sentencia basta que vaya precedida de un
     argumento atómico como cualquier otra sentencia dentro del bloque.
     Por ejemplo, 'block ([x], x:1, tururu, x: x+1, ..., go(tururu),
     ...)'.  El argumento de 'go' debe ser el nombre de una etiqueta
     colocada dentro del bloque.  No se puede utilzar 'go' para
     trasladarse a una etiqueta de un bloque que no sea el que contenga
     a 'go'.

     Normalmente los bloques aparecerán al lado derecho de las
     definiciones de funciones, pero también pueden utilizarse en otros
     contextos.

 -- Función: break (<expr_1>, ..., <expr_n>)

     Calcula e imprime <expr_1>, ..., <expr_n> para luego provocar la
     detención de Maxima, de modo que el usuario pueda examinar y
     cambiar el entorno de ejecución.  Pulsando posteriormente 'exit;'
     el cálculo se reanuda.

 -- Función: catch (<expr_1>, ..., <expr_n>)

     Evalúa <expr_1>, ..., <expr_n> una a una; si alguna de ellas
     conlleva la evaluación de una expresión de la forma 'throw (arg)',
     entonces el valor de 'catch' es el de 'throw (arg)' y ya no se
     evalúan más expresiones.  Esta respuesta pasa todos los niveles de
     anidamiento hasta el 'catch' más próximo.  Si no hay ningún 'catch'
     que contenga un 'throw' se emite un mensaje de error.

     Si la evaluación de los argumentos no conlleva la evaluación de
     ningún 'throw', entonces el valor de 'catch' es el devuelto por
     <expr_n>.

          (%i1) lambda ([x], if x < 0 then throw(x) else f(x))$
          (%i2) g(l) := catch (map (''%, l))$
          (%i3) g ([1, 2, 3, 7]);
          (%o3)               [f(1), f(2), f(3), f(7)]
          (%i4) g ([1, 2, -3, 7]);
          (%o4)                          - 3

     La función 'g' devuelve las imágenes por 'f' de todos los elementos
     de la lista 'l' si ésta contiene únicamente números no negativos;
     si no es este el caso, entonces 'g' captura el primer negativo que
     encuentra y lo devuelve por medio del 'throw'.

 -- Function: compfile (<filename>, <f_1>, ..., <f_n>)
 -- Function: compfile (<filename>, functions)
 -- Function: compfile (<filename>, all)

     Traduce funciones de Maxima a código Lisp, guardándolo luego en el
     fichero <filename>.

     Con la llamada 'compfile(<filename>, <f_1>, ..., <f_n>)' se
     traducen las funciones especificadas, mientras que
     'compfile(<filename>, functions)' y 'compfile(<filename>, all)'
     traducen las funciones definidas por el usuario.

     El código Lisp traducido no se evalúa, ni el fichero de salida es
     procesado por el compilador de Lisp.  La función 'translate' crea y
     evalúa las traducciones Lisp, mientras que 'compile_file' traduce
     primero de Maxima a Lisp y luego ejecuta el compilador Lisp.

     Véanse también 'translate', 'translate_file' y 'compile_file'.

 -- Función: compile (<f_1>, ..., <f_n>)
 -- Función: compile (functions)
 -- Función: compile (all)

     Traduce las funciones de Maxima <f_1>, ..., <f_n> a Lisp, evaluando
     el código resultante, y llama a la función Lisp 'COMPILE' para cada
     función traducida.  La función 'compile' devuelve una lista con los
     nombres de las funciones compiladas.

     Las llamadas 'compile (all)' o 'compile (functions)' compilan todas
     las funciones definidas por el usuario.

     La función 'compile' no evalúa sus argumentos, pero con el operador
     comilla-comilla ('''') sí lo hace.

 -- Función: define (<f>(<x_1>, ..., <x_n>), <expr>)
 -- Función: define (<f>[<x_1>, ..., <x_n>], <expr>)
 -- Función: define (funmake (<f>, [<x_1>, ..., <x_n>]), <expr>)
 -- Función: define (arraymake (<f>, [<x_1>, ..., <x_n>]), <expr>)
 -- Función: define (ev (<expr_1>), <expr_2>)

     Define una función de nombre <f> con argumentos <x_1>, ..., <x_n> y
     cuerpo <expr>.  'define' evalúa siempre su segundo argumento, a
     menos que se indique lo contrario con el operador de comilla
     simple.  La función así definida puede ser una función ordinaria de
     Maxima (con sus argumentos encerrados entre paréntesis) o una
     función array (con sus argumentos encerrados entre corchetes).

     Cuando el último o único argumento <x_n> es una lista de un solo
     elemento, la función definida por 'define' acepta un número
     variable de argumentos.  Los valores de los argumentos se van
     asignando uno a uno a <x_1>, ..., <x_(n - 1)>, y los que queden, si
     los hay, se asignan a <x_n> en forma de lista.

     Cuando el primer argumento de 'define' es una expresión de la forma
     '<f>(<x_1>, ..., <x_n>)' o '<f>[<x_1>, ..., <x_n>]', se evalúan los
     argumentos de la función, pero no <f>, incluso cuando se trate de
     una función o variable ya existente con ese nombre.

     Cuando el primer argumento es una expresión con operador 'funmake',
     'arraymake' o 'ev', se evalúa este primer argumento, lo que permite
     calcular la función.

     Todas las definiciones de funciones aparecen en el mismo espacio de
     nombres; definiendo una función 'f' dentro de otra función 'g' no
     limita automáticamente el alcance de 'f' a 'g'.  Sin embargo,
     'local(f)' hace que la definición de la función 'f' sea efectiva
     sólo dentro del bloque o expresión compuesta en el que aparece
     'local'.

     Si un argumento formal <x_k> es un símbolo afectado por el operador
     comilla simple (expresión nominal), la función definida por
     'define' no evalúa el correspondiente valor de argumento.  En
     cualquier otro caso, los argumentos que se pasan son evaluados.

     Véanse también ':=' y '::='.

     Ejemplos:

     'define' evalúa siempre su segundo argumento, a menos que se
     indique lo contrario con el operador de comilla simple.

          (%i1) expr : cos(y) - sin(x);
          (%o1)                    cos(y) - sin(x)
          (%i2) define (F1 (x, y), expr);
          (%o2)              F1(x, y) := cos(y) - sin(x)
          (%i3) F1 (a, b);
          (%o3)                    cos(b) - sin(a)
          (%i4) F2 (x, y) := expr;
          (%o4)                   F2(x, y) := expr
          (%i5) F2 (a, b);
          (%o5)                    cos(y) - sin(x)

     La función así definida puede ser una función ordinaria de Maxima o
     una función array.

          (%i1) define (G1 (x, y), x.y - y.x);
          (%o1)               G1(x, y) := x . y - y . x
          (%i2) define (G2 [x, y], x.y - y.x);
          (%o2)                G2     := x . y - y . x
                                 x, y

     Cuando el último o único argumento <x_n> es una lista de un solo
     elemento, la función definida por 'define' acepta un número
     variable de argumentos.

          (%i1) define (H ([L]), '(apply ("+", L)));
          (%o1)                H([L]) := apply("+", L)
          (%i2) H (a, b, c);
          (%o2)                       c + b + a

     Cuando el primer argumento es una expresión con operador 'funmake',
     'arraymake' o 'ev', se evalúa este primer argumento.

          (%i1) [F : I, u : x];
          (%o1)                        [I, x]
          (%i2) funmake (F, [u]);
          (%o2)                         I(x)
          (%i3) define (funmake (F, [u]), cos(u) + 1);
          (%o3)                  I(x) := cos(x) + 1
          (%i4) define (arraymake (F, [u]), cos(u) + 1);
          (%o4)                   I  := cos(x) + 1
                                   x
          (%i5) define (foo (x, y), bar (y, x));
          (%o5)                foo(x, y) := bar(y, x)
          (%i6) define (ev (foo (x, y)), sin(x) - cos(y));
          (%o6)             bar(y, x) := sin(x) - cos(y)

 -- Función: define_variable (<name>, <default_value>, <mode>)

     Introduce una variable global en el entorno de Maxima.  La función
     'define_variable' puede ser útil en los paquetes escritos por los
     usuarios que vayan a ser compilados o traducidos con frecuencia.

     La función 'define_variable' ejecuta los siguientes pasos:

       1. 'mode_declare (<name>, <mode>)' declara el modo de <name> al
          traductor.  Véase 'mode_declare' para ver la lista de modos
          aceptables.

       2. Si aún no tiene asignación, se le da a la variable
          <default_value> el valor <name>.

       3. 'declare (<name>, special)' la declara como especial.

       4. Asocia <name> a una función de comprobación para asegurar que
          a <name> sólo se le asignan valores del modo declarado.

     La propiedad 'value_check' se puede asociar a cualquier variable
     que haya sido definida mediante 'define_variable' en cualquiera de
     los modos diferentes a 'any'.  La propiedad 'value_check' puede ser
     una expresión lambda o una función de una variable, que será
     invocada al intentar asignar un valor a la variable; el argumento
     pasado a la función 'value_check' es el valor que se le quiere
     asignar a la variable.

     La función 'define_variable' evalúa 'default_value' pero no 'name'
     ni 'mode'; el valor que devuelve es el valor actual de 'name', el
     cual es 'default_value' si a 'name' no se le ha aplicado ninguna
     asignación, o el valor de dicha asignación en caso contrario.

     Ejemplos:

     'foo' es una variable booleana con valor inicial 'true'.
          (%i1) define_variable (foo, true, boolean);
          (%o1)                         true
          (%i2) foo;
          (%o2)                         true
          (%i3) foo: false;
          (%o3)                         false
          (%i4) foo: %pi;
          Error: foo was declared mode boolean, has value: %pi
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i5) foo;
          (%o5)                         false

     'bar' es una variable entera, cuyo valor habrá de ser primo.
          (%i1) define_variable (bar, 2, integer);
          (%o1)                           2
          (%i2) qput (bar, prime_test, value_check);
          (%o2)                      prime_test
          (%i3) prime_test (y) := if not primep(y) then
                                     error (y, "is not prime.");
          (%o3) prime_test(y) :=
                   if not primep(y) then error(y, "is not prime.")
          (%i4) bar: 1439;
          (%o4)                         1439
          (%i5) bar: 1440;
          1440 is not prime.
          #0: prime_test(y=1440)
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i6) bar;
          (%o6)                         1439

     'baz_quux' es una variable a la que no se le podrá asignar valor
     alguno.  El modo 'any_check' es como 'any', pero 'any_check' activa
     el mecanismo 'value_check', cosa que 'any' no hace.
          (%i1) define_variable (baz_quux, 'baz_quux, any_check);
          (%o1)                       baz_quux
          (%i2) F: lambda ([y], if y # 'baz_quux then
                           error ("Cannot assign to `baz_quux'."));
          (%o2) lambda([y], if y # 'baz_quux
                             then error(Cannot assign to `baz_quux'.))
          (%i3) qput (baz_quux, ''F, value_check);
          (%o3) lambda([y], if y # 'baz_quux
                             then error(Cannot assign to `baz_quux'.))
          (%i4) baz_quux: 'baz_quux;
          (%o4)                       baz_quux
          (%i5) baz_quux: sqrt(2);
          Cannot assign to `baz_quux'.
          #0: lambda([y],if y # 'baz_quux then
                       error("Cannot assign to `baz_quux'."))(y=sqrt(2))
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i6) baz_quux;
          (%o6)                       baz_quux

 -- Función: dispfun (<f_1>, ..., <f_n>)
 -- Función: dispfun (all)

     Muestra la deficnión de las funciones de usuario <f_1>, ..., <f_n>.
     Cada argumento puede ser el nombre de una macro (definida mediante
     '::='), una función ordinaria (definida mediante ':=' o 'define'),
     una función arreglo (definida mediante ':=' o 'define', pero
     encerrando los argumentos dentro de corchetes '[ ]'), una función
     de subíndice (definida mediante ':=' o 'define', pero encerrando
     algunos argumentos entre corchetes y otros entre paréntesis '( )'),
     una función de subíndice seleccionada por un subíndice variable, o
     una función de subíndice definida con un subíndice constante.

     La llamada 'dispfun (all)' muestra todas las funciones de usuario
     tal como las dan las listas 'functions', 'arrays' y 'macros',
     omitiendo las funciones con subíndices definidas con subíndices
     constantes.

     La función 'dispfun' crea una etiqueta ('%t1', '%t2', etc.)  para
     cada función mostrada, y asigna la definición de la función a la
     etiqueta.  En contraste, 'fundef' devuelve las definiciones de las
     funciones.

     La función 'dispfun' no evalúa sus argumentos; el operador de
     comilla-comilla '''' permite la evaluación.

     La función 'dispfun' devuelve la lista de etiquetas de expresiones
     intermedias correspondientes a las funciones mostradas.

     Ejemplos:

          (%i1) m(x, y) ::= x^(-y);
                                               - y
          (%o1)                   m(x, y) ::= x
          (%i2) f(x, y) :=  x^(-y);
                                               - y
          (%o2)                    f(x, y) := x
          (%i3) g[x, y] :=  x^(-y);
                                              - y
          (%o3)                     g     := x
                                     x, y
          (%i4) h[x](y) :=  x^(-y);
                                              - y
          (%o4)                     h (y) := x
                                     x
          (%i5) i[8](y) :=  8^(-y);
                                              - y
          (%o5)                     i (y) := 8
                                     8
          (%i6) dispfun (m, f, g, h, h[5], h[10], i[8]);
                                               - y
          (%t6)                   m(x, y) ::= x

                                               - y
          (%t7)                    f(x, y) := x

                                              - y
          (%t8)                     g     := x
                                     x, y

                                              - y
          (%t9)                     h (y) := x
                                     x

                                              1
          (%t10)                     h (y) := --
                                      5        y
                                              5

                                               1
          (%t11)                    h  (y) := ---
                                     10         y
                                              10

                                              - y
          (%t12)                    i (y) := 8
                                     8

          (%o12)       [%t6, %t7, %t8, %t9, %t10, %t11, %t12]
          (%i12) ''%;
                               - y              - y            - y
          (%o12) [m(x, y) ::= x   , f(x, y) := x   , g     := x   ,
                                                      x, y
                            - y           1              1             - y
                  h (y) := x   , h (y) := --, h  (y) := ---, i (y) := 8   ]
                   x              5        y   10         y   8
                                          5             10

 -- Función: fullmap (<f>, <expr_1>, ...)
     Similar a 'map', pero conservará el mapeado descendente de todas
     las subexpresiones hasta que los operadores principales ya no sean
     los mismos.

     La función 'fullmap' es utilizada por el simplificador de Maxima en
     algunas transformaciones matriciales, por lo que Maxima generará en
     algunas ocasiones mensajes de error relacionados con 'fullmap'
     aunque el usuario no haya invocado explícitamente esta función.

          (%i1) a + b * c;
          (%o1)                        b c + a
          (%i2) fullmap (g, %);
          (%o2)                   g(b) g(c) + g(a)
          (%i3) map (g, %th(2));
          (%o3)                     g(b c) + g(a)

 -- Función: fullmapl (<f>, <list_1>, ...)
     Similar a 'fullmap', pero 'fullmapl' sólo hace mapeo sobre listas y
     matrices.

          (%i1) fullmapl ("+", [3, [4, 5]], [[a, 1], [0, -1.5]]);
          (%o1)                [[a + 3, 4], [4, 3.5]]

 -- Variable del sistema: functions
     Valor por defecto: '[]'

     La variable 'functions' es una lista que contiene los nombres de
     las funciones ordinarias de Maxima.  Una función ordinaria es
     aquella que ha sido construida mediante cualquiera de los métodos
     'define' o ':=' y que es invocada utilizando paréntesis.  Una
     función puede definirse durante una sesión de Maxima o en un
     fichero que posteriormente será cargado en memoria por 'load' o
     'batch'.

     Las funciones array, que son invocadas con corchetes ('F[x]'), y
     las funciones subindicadas, que son las invocadas con corchetes y
     paréntesis ('F[x](y)') se registran en la variable global 'arrays',
     no en 'functions'.

     Las funciones Lisp no se registran en ninguna lista.

     Ejemplos:

          (%i1) F_1 (x) := x - 100;
          (%o1)                   F_1(x) := x - 100
          (%i2) F_2 (x, y) := x / y;
                                                x
          (%o2)                    F_2(x, y) := -
                                                y
          (%i3) define (F_3 (x), sqrt (x));
          (%o3)                   F_3(x) := sqrt(x)
          (%i4) G_1 [x] := x - 100;
          (%o4)                    G_1  := x - 100
                                      x
          (%i5) G_2 [x, y] := x / y;
                                               x
          (%o5)                     G_2     := -
                                       x, y    y
          (%i6) define (G_3 [x], sqrt (x));
          (%o6)                    G_3  := sqrt(x)
                                      x
          (%i7) H_1 [x] (y) := x^y;
                                                y
          (%o7)                     H_1 (y) := x
                                       x
          (%i8) functions;
          (%o8)              [F_1(x), F_2(x, y), F_3(x)]
          (%i9) arrays;
          (%o9)                 [G_1, G_2, G_3, H_1]

 -- Función: fundef (<f>)

     Devuelve la definición de la función <f>.

     Cada argumento puede ser el nombre de una macro (definida mediante
     '::='), una función ordinaria (definida mediante ':=' o 'define'),
     una función arreglo (definida mediante ':=' o 'define', pero
     encerrando los argumentos dentro de corchetes '[ ]'), una función
     de subíndice (definida mediante ':=' o 'define', pero encerrando
     algunos argumentos entre corchetes y otros entre paréntesis '( )'),
     una función de subíndice seleccionada por un subíndice variable, o
     una función de subíndice definida con un subíndice constante.

     La función 'fundef' no evalúa sus argumentos; el operador
     comilla-comilla '''' permite la evaluación.

     La llamada de función 'fundef (<f>)' devuelve la definición de <f>.
     Por el contrario, 'dispfun (<f>)' crea una etiqueta intermedia y le
     asigna la definición a la etiqueta.

 -- Función: funmake (<F>, [<arg_1>, ..., <arg_n>])

     Devuelve una expresión '<F>(<arg_1>, ..., <arg_n>)'.  El valor así
     retornado es simplificado pero no evaluado, de forma que la función
     <F> no es invocada, incluso cuando exista.

     La función 'funmake' no hace distinciones entre funciones array y
     funciones ordinarias; cuando <F> es el nombre de una función array,
     'funmake' devuelve '<F>(...)', esto es, una llamada a función con
     paréntesis en lugar de corchetes.  La función 'arraymake' devuelve
     una llamada a función con corchetes para estos casos.

     La función 'funmake' evalúa sus argumentos.

     Ejemplos:

     La función 'funmake' aplicada a una función ordinaria de Maxima.

          (%i1) F (x, y) := y^2 - x^2;
                                             2    2
          (%o1)                  F(x, y) := y  - x
          (%i2) funmake (F, [a + 1, b + 1]);
          (%o2)                    F(a + 1, b + 1)
          (%i3) ''%;
                                        2          2
          (%o3)                  (b + 1)  - (a + 1)

     La función 'funmake' aplicada a una macro.

          (%i1) G (x) ::= (x - 1)/2;
                                            x - 1
          (%o1)                    G(x) ::= -----
                                              2
          (%i2) funmake (G, [u]);
          (%o2)                         G(u)
          (%i3) ''%;
                                        u - 1
          (%o3)                         -----
                                          2

     La función 'funmake' aplicada a una función subindicada.

          (%i1) H [a] (x) := (x - 1)^a;
                                                  a
          (%o1)                   H (x) := (x - 1)
                                   a
          (%i2) funmake (H [n], [%e]);
                                                 n
          (%o2)               lambda([x], (x - 1) )(%e)
          (%i3) ''%;
                                              n
          (%o3)                       (%e - 1)
          (%i4) funmake ('(H [n]), [%e]);
          (%o4)                        H (%e)
                                        n
          (%i5) ''%;
                                              n
          (%o5)                       (%e - 1)

     La función 'funmake' aplicada a un símbolo que no está asociado a
     función alguna.

          (%i1) funmake (A, [u]);
          (%o1)                         A(u)
          (%i2) ''%;
          (%o2)                         A(u)

     La función 'funmake' evalúa sus argumentos, pero no el valor
     retornado.

          (%i1) det(a,b,c) := b^2 -4*a*c;
                                              2
          (%o1)              det(a, b, c) := b  - 4 a c
          (%i2) (x : 8, y : 10, z : 12);
          (%o2)                          12
          (%i3) f : det;
          (%o3)                          det
          (%i4) funmake (f, [x, y, z]);
          (%o4)                    det(8, 10, 12)
          (%i5) ''%;
          (%o5)                         - 284

     Maxima simplifica el valor retornado de 'funmake'.

          (%i1) funmake (sin, [%pi / 2]);
          (%o1)                           1

 -- Función: lambda ([<x_1>, ..., <x_m>], <expr_1>, ..., <expr_n>)
 -- Function: lambda ([[<L>]], <expr_1>, ..., <expr_n>)
 -- Function: lambda ([<x_1>, ..., <x_m>, [<L>]], <expr_1>, ...,
          <expr_n>)
     Define y devuelve una expresión lambda (es decir, una función
     anónima).  La función puede tener argumentos <x_1>, ..., <x_m> y/o
     argumentos opcionales <L>, que aparecerán dentro del cuerpo de la
     función como una lista.  El valor que devuelve la función es
     <expr_n>.  Una expresión lambda puede asignarse a una variable y
     ser evaluada como si fuese una función ordinaria.  Además, puede
     aparecer en algunos contextos en los que sea necesario un nombre de
     función.

     Cuando se evalúa la función, se crean las variables <x_1>, ...,
     <x_m> sin asignación de valores.  Una función 'lambda' puede
     aparecer dentro de un 'block' o de otra 'lambda'.  Las variables
     locales se inicializan cada vez que se entra dentro de un nuevo
     bloque o de otra función 'lambda'.  Las variables locales se
     consideran globales dentro de un bloque o función 'lambda' anidado
     dentro del primero.  Si una variable es no local dentro de un
     bloque o función 'lambda', su valor es el que le corresponde en el
     bloque o función 'lambda' superior.  Este criterio se conoce con el
     nombre de "alcance dinámico".

     Una vez establecidas las variables locales <expr_1> a <expr_n> son
     secuencialmente evaluadas.  La variable especial '%%' representa el
     valor de la expresión inmediata anterior.  Las sentencias 'throw' y
     'catch' pueden aparecer también en la lista de expresiones.

     La función 'return' no puede aparecer en una expresión 'lambda' a
     menos que se encuentre acotada dentro de un bloque ('block'), en
     cuyo caso 'return' establece el valor de retorno del bloque, pero
     no de la expresión 'lambda', a menos que el bloque resulte ser
     precisamente <expr_n>.  De igual manera, 'go' no puede aparecer en
     una expresión 'lambda' si no es dentro de un 'block'.

     Las funciones 'lambda' no evalúan sus argumentos; el operador
     comilla-comilla '''' permite su evaluación.

     Ejemplo:

        * Una función lambda puede asignarse a una variable y ser
          evaluada como si fuese una función ordinaria.
          (%i1) f: lambda ([x], x^2);
                                                2
          (%o1)                    lambda([x], x )
          (%i2) f(a);
                                          2
          (%o2)                          a
        * Una expresión lambda puede aparecer en algunos contextos en
          los que sea necesario un nombre de función.
          (%i3) lambda ([x], x^2) (a);
                                          2
          (%o3)                          a
          (%i4) apply (lambda ([x], x^2), [a]);
                                          2
          (%o4)                          a
          (%i5) map (lambda ([x], x^2), [a, b, c, d, e]);
                                  2   2   2   2   2
          (%o5)                 [a , b , c , d , e ]
        * Los argumentos son variables locales.  Otras variables se
          consideran globales.  Las variables globales son evaluadas en
          el momento que lo es la expresión, a menos que la evaluación
          de las mismas sea forzada, como cuando se hace uso de ''''.
          (%i6) a: %pi$
          (%i7) b: %e$
          (%i8) g: lambda ([a], a*b);
          (%o8)                   lambda([a], a b)
          (%i9) b: %gamma$
          (%i10) g(1/2);
                                       %gamma
          (%o10)                       ------
                                         2
          (%i11) g2: lambda ([a], a*''b);
          (%o11)                lambda([a], a %gamma)
          (%i12) b: %e$
          (%i13) g2(1/2);
                                       %gamma
          (%o13)                       ------
                                         2
        * Las expresiones lambda pueden anidarse.  Las variables locales
          de expresiones lambda exteriores se consideran globales en
          expresiones internas, a menos que se enmascaren con variables
          locales de igual nombre.
          (%i14) h: lambda ([a, b], h2: lambda ([a], a*b), h2(1/2));
                                                             1
          (%o14)    lambda([a, b], h2 : lambda([a], a b), h2(-))
                                                             2
          (%i15) h(%pi, %gamma);
                                       %gamma
          (%o15)                       ------
                                         2
        * Puesto que 'lambda' no evalúa sus argumentos, la expresión
          lambda 'i' de más abajo no define una función del tipo
          "multiplicar por 'a'".  Tal tipo de función se puede definir a
          través de 'buildq', como en la expresión lambda 'i2' de más
          abajo.
          (%i16) i: lambda ([a], lambda ([x], a*x));
          (%o16)            lambda([a], lambda([x], a x))
          (%i17) i(1/2);
          (%o17)                  lambda([x], a x)
          (%i18) i2: lambda([a], buildq([a: a], lambda([x], a*x)));
          (%o18)    lambda([a], buildq([a : a], lambda([x], a x)))
          (%i19) i2(1/2);
                                               x
          (%o19)                   lambda([x], -)
                                               2
          (%i20) i2(1/2)(%pi);
                                         %pi
          (%o20)                         ---
                                          2
        * Una expresión lambda puede tener un número variable de
          argumentos, los cuales se indican mediante '[<L>]', bien sea
          solo o como un último argumento.  Estos argumentos aparecerán
          dentro del cuerpo de la función en forma de lista.
          (%i1) f : lambda ([aa, bb, [cc]], aa * cc + bb);
          (%o1)          lambda([aa, bb, [cc]], aa cc + bb)
          (%i2) f (foo, %i, 17, 29, 256);
          (%o2)       [17 foo + %i, 29 foo + %i, 256 foo + %i]
          (%i3) g : lambda ([[aa]], apply ("+", aa));
          (%o3)             lambda([[aa]], apply(+, aa))
          (%i4) g (17, 29, x, y, z, %e);
          (%o4)                  z + y + x + %e + 46

 -- Función: local (<v_1>, ..., <v_n>)

     La declaración 'local(<v_1>, ..., <v_m>)' dentro de un bloque
     almacena las propiedades asociadas a los símbolos <v_1>, ...,
     <v_m>, borra cualesquiera otras propiedades antes de evaluar las
     expresiones y restaura las propiedades guardadas antes de abandonar
     el bloque.

     Algunas declaraciones, como ':=', 'array', 'dependencies',
     'atvalue', 'matchdeclare', 'atomgrad', 'constant', 'nonscalar',
     'assume' y otras se implementan como propiedades de símbolos.  El
     efecto producido por 'local' consiste en hacer que tales
     declaraciones tengan efecto sólo dentro del bloque, en otro caso
     las declaraciones dentro del bloque tendrían un efecto global que
     afectarían al exterior de 'block'.

     La función 'local' sólo puede usarse dentro de un 'block', en el
     cuerpo de definición de funciones o de expresiones 'lambda' o en la
     función 'ev', siéndole permitido aparecer una sóla vez en cada una
     de ellas.

     La función 'local' no evalúa sus argumentos y devuelve 'done'.

     Ejemplo:

     Definición local de una función.

          (%i1) foo (x) := 1 - x;
          (%o1)                    foo(x) := 1 - x
          (%i2) foo (100);
          (%o2)                         - 99
          (%i3) block (local (foo), foo (x) := 2 * x, foo (100));
          (%o3)                          200
          (%i4) foo (100);
          (%o4)                         - 99

 -- Variable opcional: macroexpansion
     Valor por defecto: 'false'

     La variable 'macroexpansion' controla si la expansión (esto es, el
     valor de retorno) de una función macro se sustituye por la llamada
     a la función macro.  Una sustitución puede acelerar futuras
     evaluaciones de la expresión, bajo el coste que implica tener que
     almacenar la expansión.

     'false'
          La expansión de una función macro no se sustituye por la
          llamada a la función macro.
     'expand'
          La primera vez que se evalúa una llamada a función macro se
          almacena la expansión.  De esta manera la expansión no se
          recalcula en llamadas posteriores; cualesquiera efectos
          laterales (como 'print' o asignaciones a variables globales)
          tan solo tienen lugar la primera vez que la función macro es
          evaluada.  La expansión en una expresión no afecta a otras
          expresiones que llamen a la misma función macro.
     'displace'
          La primera vez que se evalúa una llamada a una función macro,
          la expansión se sustituye por la llamada, modificando así la
          expresión desde la que se hizo la llamada a la función macro.
          La expansión no se recalcula en llamadas posteriores;
          cualesquiera efectos laterales tan solo tienen lugar la
          primera vez que la función macro es evaluada.  La expansión en
          una expresión no afecta a otras expresiones que llamen a la
          misma función macro.

     Ejemplos:

     Si 'macroexpansion' vale 'false', una función macro es llamada cada
     vez que la expresión de llamada es evaluada.

          (%i1) f (x) := h (x) / g (x);
                                            h(x)
          (%o1)                     f(x) := ----
                                            g(x)
          (%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                                 return (x + 99));
          (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                               return(x + 99))
          (%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                                 return (x - 99));
          (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                               return(x - 99))
          (%i4) macroexpansion: false;
          (%o4)                         false
          (%i5) f (a * b);
          x - 99 is equal to x
          x + 99 is equal to x
                                      a b - 99
          (%o5)                       --------
                                      a b + 99
          (%i6) dispfun (f);
                                            h(x)
          (%t6)                     f(x) := ----
                                            g(x)

          (%o6)                         done
          (%i7) f (a * b);
          x - 99 is equal to x
          x + 99 is equal to x
                                      a b - 99
          (%o7)                       --------
                                      a b + 99

     Si 'macroexpansion' vale 'expand', una función macro tan solo es
     llamada una vez.

          (%i1) f (x) := h (x) / g (x);
                                            h(x)
          (%o1)                     f(x) := ----
                                            g(x)
          (%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                                 return (x + 99));
          (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                               return(x + 99))
          (%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                                 return (x - 99));
          (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                               return(x - 99))
          (%i4) macroexpansion: expand;
          (%o4)                        expand
          (%i5) f (a * b);
          x - 99 is equal to x
          x + 99 is equal to x
                                      a b - 99
          (%o5)                       --------
                                      a b + 99
          (%i6) dispfun (f);
                                            h(x)
          (%t6)                     f(x) := ----
                                            g(x)

          (%o6)                         done
          (%i7) f (a * b);
                                      a b - 99
          (%o7)                       --------
                                      a b + 99

     Si 'macroexpansion' vale 'expand', una función macro es llamada una
     vez y la expresión de llamada se modifica.

          (%i1) f (x) := h (x) / g (x);
                                            h(x)
          (%o1)                     f(x) := ----
                                            g(x)
          (%i2) g (x) ::= block (print ("x + 99 is equal to", x), return (x + 99));
          (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                                                            return(x + 99))
          (%i3) h (x) ::= block (print ("x - 99 is equal to", x), return (x - 99));
          (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                                                            return(x - 99))
          (%i4) macroexpansion: displace;
          (%o4)                       displace
          (%i5) f (a * b);
          x - 99 is equal to x
          x + 99 is equal to x
                                      a b - 99
          (%o5)                       --------
                                      a b + 99
          (%i6) dispfun (f);
                                           x - 99
          (%t6)                    f(x) := ------
                                           x + 99

          (%o6)                         done
          (%i7) f (a * b);
                                      a b - 99
          (%o7)                       --------
                                      a b + 99

 -- Variable opcional: mode_checkp
     Valor por defecto: 'true'

     Cuando 'mode_checkp' vale 'true', 'mode_declare' chequea los modos
     de las variables con valores asignados.

 -- Variable opcional: mode_check_errorp
     Valor por defecto: 'false'

     Cuando 'mode_check_errorp' vale 'true', 'mode_declare' llama a
     error.

 -- Variable opcional: mode_check_warnp
     Valor por defecto: 'true'

     Cuando 'mode_check_warnp' vale 'true', se detallan los errores de
     modo.

 -- Función: mode_declare (<y_1>, <modo_1>, ..., <y_n>, <modo_n>)

     La función 'mode_declare' se utiliza para declarar los modos de
     variables y funciones para la ulterior traducción a Lisp o
     compilación de funciones.  Se coloca habitualmente al comienzo de
     la definición de una función, de un script en Maxima o se ejecuta
     en tiempo real.

     Los argumentos de 'mode_declare' son pares formados por una
     variable y un modo, el cual debe ser 'boolean', 'fixnum', 'number',
     'rational' o 'float'.  Cada variable puede ser sustituida por una
     lista de variables, en cuyo caso todas ellas tendrán el mismo modo.

     Código numérico que utilice arreglos puede ejecutarse más rápido
     declarando el tamaño que va a ocupar el arreglo, como en:

          mode_declare (array (a [10, 10]), float)

     para un arreglo de números en coma flotante de dimensiones 10 x 10.

     Se puede declarar el modo del resultado de una función poniendo
     'function (f_1, f_2, ...)' como argumento; aquí 'f_1', 'f_2', ...
     son los nombres de las funciones.  Por ejemplo, la expresión

          mode_declare ([function (f_1, f_2, ...)], fixnum)

     declara que el valor a devolver por 'f_1', 'f_2', ...  son enteros
     de modo "single-word".

     El nombre 'modedeclare' es sinónimo de 'mode_declare'.

 -- Función: mode_identity (<arg_1>, <arg_2>)
     Es una forma especial usada con 'mode_declare' y 'macros' para
     declarar, por ejemplo, una lista de listas de números.

 -- Función: remfunction (<f_1>, ..., <f_n>)
 -- Función: remfunction (all)
     Desliga las definiciones de función de sus símbolos <f_1>, ...,
     <f_n>.  Los argumentos pueden ser nombres de funciones ordinarias
     (creadas con ':=' o 'define') o de funciones macro (creadas con
     '::=').

     La instrucción 'remfunction (all)' desliga todas las definiciones
     de funciones.

     La función 'remfunction' no evalúa sus argumentos.

     La función 'remfunction' devuelve una lista con los símbolos para
     los que la definición de función fue desligada.  Devuelve 'false'
     en el lugar de cualquier símbolo para el que no hay función
     definida.

     La función 'remfunction' no se puede aplicar a arrays de funciones
     ni a funciones subindicadas.  Sí es aplicable en tales casos la
     función 'remarray'.

 -- Variable opcional: savedef
     Valor por defecto: 'true'

     Si 'savedef' vale 'true', se mantiene la versión Maxima de una
     función definida por el usuario cuando ésta se traduce, lo que
     permite mostrar su código con 'dispfun' y que la función pueda ser
     editada.

     Si 'savedef' vale 'false', los nombres de las funciones traducidas
     se eliminan de la lista 'functions'.

 -- Variable opcional: transcompile
     Valor por defecto: 'true'

     Si 'transcompile' vale 'true', 'translate' y 'translate_file'
     generan declaraciones para hacer el código traducido más apto para
     la compilación.

     La función 'compfile' hace la asignación 'transcompile: true'.

 -- Función: translate (<f_1>, ..., <f_n>)
 -- Función: translate (functions)
 -- Función: translate (all)

     Traduce las funciones definidas por el usuario <f_1>, ..., <f_n>
     del lenguaje de Maxima a Lisp y evalúa las traducciones Lisp.
     Normalmente las funciones traducidas se ejecutan más rapidamente
     que las originales.

     Las llamadas 'translate (all)' o 'translate (functions)' traducen
     todas las funciones de usuario.

     Las funciones a ser traducidas deberían incluir una llamada a
     'mode_declare' al comienzo siempre que sea posible, a fin de
     producir código más eficiente.  Por ejemplo:

          f (x_1, x_2, ...) := block ([v_1, v_2, ...],
              mode_declare (v_1, modo_1, v_2, modo_2, ...), ...)

     donde <x_1>, <x_2>, ...  son los parámetros que se pasan a la
     función y <v_1>, <v_2>, ...  son las variables locales.

     Los nombres de las funciones traducidas son eliminados de la lista
     'functions' si 'savedef' vale 'false' (ver más abajo) y son
     añadidos a las listas 'props'.

     Las funciones no deberían ser traducidas hasta no estar
     completamente depuradas.

     Se supone que las expresiones están simplificadas; en caso de no
     estarlo, se generará código correcto pero ineficiente.  Así, el
     usuario no debería asignar a 'simp' el valor 'false', el cual
     inhibe la simplificación de la expresión a ser traducida.

     Cuando la variable 'translate' vale 'true', se traducen
     automáticamente las funciones de usuario a Lisp.

     Nótese que las funciones traducidas puede que no se ejecuten
     exactamente igual a como lo hacían antes de la traducción, debido a
     posibles incompatibilidades entre las versiones de Maxima y Lisp.
     En general, la función 'rat' con más de un argumento y la función
     'ratvars' no deberían utilizarse si algunas de las variables son
     declaradas como expresiones racionales canónicas (CRE) mediante
     'mode_declare'.  Además, la asignación 'prederror: false' no
     traducirá.

     Si 'savedef' vale 'true', entonces la versión de Maxima de una
     función de usuario permanecerá cuando la función sea traducida por
     'translate'.  Con esto se hace posible que se muestre la definición
     llamando a 'dispfun' y que la función sea editada.

     Si 'transrun' vale 'false' entonces las versiones interpretadas de
     todas las funciones serán ejecutadas en lugar de las versiones
     traducidas.

     El resultado devuelto por 'translate' es una lista con los nombres
     de las funciones traducidas.

 -- Función: translate_file (<nombre_fichero_maxima>)
 -- Función: translate_file (<nombre_fichero_maxima>,
          <nombre_fichero_lisp>)

     Traduce un fichero en código Maxima a un fichero en código Lisp.
     La función 'translate_file' devuelve una lista con los nombres de
     tres ficheros: el nombre del ficheero en Maxima, el nombre del
     fichero en Lisp y el nombre del fichero que contiene información
     adicional sobre la traducción.  La función 'translate_file' evalúa
     sus argumentos.

     La llamada 'translate_file ("foo.mac"); load("foo.LISP")' es lo
     mismo que 'batch ("foo.mac")', excepto por la presencia de ciertas
     restricciones, como el uso de '''' y '%', por ejemplo.

     La llamada 'translate_file (<nombre_fichero_maxima>)' traduce un
     fichero en Maxima, <nombre_fichero_maxima>, a otro en Lisp de
     nombre similar.  Por ejemplo, 'foo.mac' se traduce en 'foo.LISP'.
     El nombre del fichero en Maxima puede incluir el nombre de un
     directorio, en cuyo caso el fichero de salida Lisp se guardará en
     el mismo directorio desde el que se leyó la fuente Maxima.

     La llamada 'translate_file (<nombre_fichero_maxima>,
     <nombre_fichero_lisp>)' traduce el fichero Maxima
     <nombre_fichero_maxima> en el fichero Lisp <nombre_fichero_lisp>.
     La función 'translate_file' ignora la extensión del fichero, en
     caso de que exista, de 'nombre_fichero_lisp'; la extensión del
     fichero de salida Lisp será invariablemente 'LISP'.  El nombre del
     fichero Lisp puede incluir la ruta del directorio, en cuyo caso se
     almacenará en el directorio especificado.

     La función 'translate_file' también escribe un fichero de mensajes
     de avisos del traductor con diversos niveles de gravedad.  La
     extensión de este fichero es 'UNLISP'.  Este fichero puede contener
     información valiosa, aunque de difícil interpretación, para
     detectar fallos en el código traducido.  El fichero 'UNLISP' se
     guarda siempre en el mismo directorio desde el que se leyó la
     fuente de Maxima.

     La función 'translate_file' emite código Lisp que incluye algunas
     declaraciones y definiciones que entran en efecto tan pronto como
     el código Lisp es compilado.  Véase 'compile_file' para más
     información sobre este particular.

     Véanse también 'tr_array_as_ref', 'tr_bound_function_applyp',
     'tr_exponent', 'tr_file_tty_messagesp',
     'tr_float_can_branch_complex', 'tr_function_call_default',
     'tr_numer', 'tr_optimize_max_loop', 'tr_semicompile',
     'tr_state_vars', 'tr_warnings_get', 'tr_warn_bad_function_calls',
     'tr_warn_fexpr', 'tr_warn_meval', 'tr_warn_mode',
     'tr_warn_undeclared', y 'tr_warn_undefined_variable'.

 -- Variable opcional: transrun
     Valor por defecto: 'true'

     Si 'transrun' vale 'false' entonces se ejecutarán las versiones
     interpretadas de todas las funciones, en lugar de las versiones
     traducidas.

 -- Variable opcional: tr_array_as_ref
     Valor por defecto: 'true'

     Si 'translate_fast_arrays' vale 'false', referencias de arreglos en
     el código Lisp creadas por 'translate_file' se ven afectadas por
     'tr_array_as_ref'.

     El valor de la variable 'tr_array_as_ref' no tiene ningún efecto
     cuando 'translate_fast_arrays' vale 'true'.

 -- Variable opcional: tr_bound_function_applyp
     Valor por defecto: 'true'

     Si 'tr_bound_function_applyp' vale 'true', Maxima envía un aviso si
     encuentra una variable con valor asignado que está siendo utilizada
     como una función.  'tr_bound_function_applyp' no influye en el
     código generado bajo estas circunstancias.

     Por ejemplo, una expresión como 'g (f, x) := f (x+1)' provocará un
     mensaje de esta naturaleza.

 -- Variable opcional: tr_file_tty_messagesp
     Valor por defecto: 'false'

     Si 'tr_file_tty_messagesp' vale 'true', los mensajes generados por
     'translate_file' durante la traducción de un fichero se muestran en
     la consola y se insertan en el fichero UNLISP. Si vale 'false', los
     mensajes sobre la traducción del fichero sólo se incorporan al
     fichero UNLISP.

 -- Variable opcional: tr_float_can_branch_complex
     Valor por defecto: 'true'

     Le dice al traductor de Maxima a Lisp que las funciones 'acos',
     'asin', 'asec' y 'acsc' pueden devolver valores complejos.

 -- Variable opcional: tr_function_call_default
     Valor por defecto: 'general'

     El valor 'false' significa llama a 'meval', 'expr' significa que
     Lisp asignó los argumentos de la función, 'general', el valor por
     defecto, devuelve código apropiado para 'mexprs' y 'mlexprs' pero
     no para 'macros'.  La opción 'general' asegura que las asignaciones
     de las variables son correctas en el código compilado.  En modo
     'general', cuando se traduce F(X), si F es una variable con valor,
     entonces se entiende que se quiere calcular 'apply (f, [x])', y
     como tal se traduce, con el apropiado aviso.  No es necesario
     desactivar esto.  Con los valores por defecto la falta de mensajes
     de aviso implica compatibilidad completa entre el código traducido
     y compilado con el interpretado por Maxima.

 -- Variable opcional: tr_numer
     Valor por defecto: 'false'

     Si 'tr_numer' vale 'true' se utilizan las propiedades numéricas en
     aquellos átomos que las posean, como en '%pi'.

 -- Variable opcional: tr_optimize_max_loop
     Valor por defecto: 100

     El valor de 'tr_optimize_max_loop' es el número máximo de veces que
     el traductor repetirá la macro-expansión y la optimización en el
     tratamiento de una expresión.

 -- Variable opcional: tr_semicompile
     Valor por defecto: 'false'

     Si 'tr_semicompile' vale 'true', las salidas de 'translate_file' y
     'compfile' serán macro-expandidas pero no compiladas a código
     máquina por el compilador de Lisp.

 -- Variable del sistema: tr_state_vars
     Valor por defecto:

          [transcompile, tr_semicompile, tr_warn_undeclared, tr_warn_meval,
          tr_warn_fexpr, tr_warn_mode, tr_warn_undefined_variable,
          tr_function_call_default, tr_array_as_ref,tr_numer]

     Es la lista de variables que afectan la forma en que se obtiene la
     salida del código traducido.  Esta información es útil para
     desarrolladores que pretendan corregir posibles fallos del
     traductor.  Comparando el código traducido con el que se debería
     obtener bajo unas ciertas condiciones, es posible hacer el
     seguimiento de los fallos.

 -- Función: tr_warnings_get ()

     Devuelve una lista con los avisos dados por el traductor.

 -- Variable opcional: tr_warn_bad_function_calls
     Valor por defecto: 'true'

     Devuelve un aviso cuando se hacen llamadas a funciones que quizás
     no sean correctas debido a declaraciones inapropiadas realizadas
     durante la traducción.

 -- Variable opcional: tr_warn_fexpr
     Valor por defecto: 'compfile'

     Devuelve un aviso si se encuentra con alguna FEXPR. Las FEXPR no
     deberían aparecer en el código traducido.

 -- Variable opcional: tr_warn_meval
     Valor por defecto: 'compfile'

     Devuelve un aviso si la función 'meval' es llamada.  Si 'meval' es
     invocada, es señal de la presencia de problemas en la traducción.

 -- Variable opcional: tr_warn_mode
     Valor por defecto: 'all'

     Devuelve un aviso cuando a las variables se les asignan valores
     incompatibles con su modo.

 -- Variable opcional: tr_warn_undeclared
     Valor por defecto: 'compile'

     Determina cuando enviar mensajes sobre variables no declaradas.

 -- Variable opcional: tr_warn_undefined_variable
     Valor por defecto: 'all'

     Devuelve un aviso cuando se detectan variables globales no
     definidas.

 -- Función: compile_file (<nombre_fich>)
 -- Función: compile_file (<nombre_fich>, <nombre_fich_compilado>)
 -- Función: compile_file (<nombre_fich>, <nombre_fich_compilado>,
          <nombre_fich_lisp>)

     Traduce el fichero Maxima <nombre_fich> a Lisp, ejecuta el
     compilador de Lisp y, en caso de ser exitosa la compilación, carga
     el código compilado en Maxima.

     La función 'compile_file' devuelve una lista con los nombres de
     tres ficheros: el fichero original en Maxima, la traducción Lisp,
     notas sobre la traducción y el código compilado.  Si la compilación
     falla, el cuarto elemento es 'false'.

     Algunas declaraciones y definiciones entran en efecto tan pronto
     como el código Lisp es compilado (sin cargar el código compilado).
     Éstas incluyen funciones definidas con el operador ':=', macros
     definidas con el operador '::=', 'alias', 'declare',
     'define_variable', 'mode_declare' y 'infix', 'matchfix', 'nofix',
     'postfix', 'prefix' y 'compfile'.

     Asignaciones y llamadas a funciones no se evalúan hasta que el
     código compilado es cargado.  En particular, dentro del fichero
     Maxima, asignaciones a los controles ("flags") de traducción
     ('tr_numer', etc.)  no tienen efecto durante la traducción.

     El <nombre_fich> no puede contener sentencias del tipo ':lisp'.

     La función 'compile_file' evalúa sus argumentos.

 -- Función: declare_translated (<f_1>, <f_2>, ...)

     Cuando se traduce un fichero de código Maxima a Lisp, es importante
     para el traductor saber qué funciones de las que están en el
     fichero van a ser llamadas como traducidas o compiladas, y cuáles
     son simplemente funciones Maxima o que no están definidas.  Se
     genera el código '(MFUNCTION-CALL fn arg1 arg2 ...)' cuando el
     traductor no sabe si 'fn' va a ser una función lisp.


File: maxima.info,  Node: Programación,  Next: Depurado,  Prev: Definición de Funciones,  Up: Top

37 Programación
***************

* Menu:

* Lisp y Maxima::
* Recolector de basura::
* Introducción a la programación::  
* Funciones y variables para la programación::  


File: maxima.info,  Node: Lisp y Maxima,  Next: Recolector de basura,  Prev: Programación,  Up: Programación

37.1 Lisp y Maxima
==================

Maxima fue escrito en Lisp, y es muy fácil tener acceso a funciones y
variables Lisp desde Maxima y viceversa.  Los símbolos Lisp y los
símblos Maxima están claramente diferenciados por medio de una
convención de nombres.  Un símblo Lisp el cual comienza con un signo
pesos '$' corresponde a un símbolo Maxima sin el signo pesos.  Un
símbolo Maxima el cual comienza con un signo de cierre de interrogación
'?' corresponde a un símbolo Lisp sin dicho signo.  Por ejemplo, el
símbolo Maxima 'foo' corresponde a el símbolo Lisp '$FOO', mientras que
el símbolo Maxima '?foo' corresponde a el símbolo Lisp 'FOO', tenga en
cuenta que '?foo' esta escrito sin espacio entre '?' y 'foo'; de otra
manera se estaría invocando a 'describe ("foo")'.

El guión '-', asterisco '*', u otros carácteres especiales en símbolos
Lisp deben ser escritos mediante un backslash '\' si aparecen en código
Maxima.  Por ejemplo, el identificador Lisp '*foo-bar*' se debe escribir
'?\*foo\-bar\*' en Maxima.

Se puede ejecutar código Lisp desde una sesión de Maxima.  Una línea
Lisp (que contenga una o más formas) puede ser ejecutada por medio de un
comando especial ':lisp'.  Por ejemplo,

     (%i1) :lisp (foo $x $y)

se llama a la función Lisp 'foo' con variables Maxima 'x' y 'y' como
argumentos.  La instrucción ':lisp' puede aparecer en el prompt
interactivo o en un archivo que sea procesado por 'batch' o 'demo', pero
no en un archivo que sea procesado por 'load', 'batchload',
'translate_file' o 'compile_file'.

La función 'to_lisp()' abre una sesión interactiva con el interprete
Lisp.  Escribiendo '(to-maxima)' se cierra la sesión con Lisp y se
retorna a Maxima.

Las funciones y variables Lisp las cuales esten para ser visibles en
Maxima como funciones y variables con nombres oridinarios (sin una
puntuación especial), deben tener nombres tipo Lisp que comiencen con el
signo pesos '$'.

Maxima distingue entre letras minúsculas y mayúsculas en
identificadores.  Existen algunas reglas que gobiernan la traducción de
nombres entre Lisp y Maxima.

  1. Un identificador Lisp que no se encuentra encerrado en barras
     verticales corresponde a un identificador Maxima en minúscula.  Que
     el idenficador Lisp esté en mayúscula, minúscula o una combinación
     de ambas, no afecta en nada.  Por ejemplo, los identificadores Lisp
     '$foo', '$FOO', y '$Foo', todos corresponden al identificador
     Maxima 'foo'.  Esto es así porque '$foo', '$FOO' y '$Foo' se
     convierten por defecto al símbolo '$FOO' de Lisp.

  2. Un identificador Lisp el cual se encuentre todo en mayúscula o todo
     en minúscula y encerrado entre barras verticales corresponde a un
     identicador Maxima con el caso contrario.  Esto es, de mayúsculas
     cambia a minúsculas y de minúsculas cambia a mayúsculas.  E.g., el
     identificador Lisp '|$FOO|' y '|$foo|' corresponden los
     identificadores Maxima 'foo' y 'FOO', respectivamente.
  3. Un identificador Lisp el cual esta escrito mezclando letras
     mayúsculas y minúsculas y se encuentra entre barras verticales
     corresponde a un identificador Maxima con la misma escritura.
     E.g., el identificador Lisp '|$Foo|' corresponde a el identificador
     Maxima 'Foo'.

La macro Lisp '#$' permite el uso de expresiones Maxima dentro de código
Lisp.  '#$<expr>$' extiende a una expresión Lisp equivalente a la
expresión Maxima <expr>.

     (msetq $foo #$[x, y]$)

Esto tiene el mismo efecto que:

     (%i1) foo: [x, y];

La función Lisp 'displa' imprime una expresión en formato Maxima.

     (%i1) :lisp #$[x, y, z]$
     ((MLIST SIMP) $X $Y $Z)
     (%i1) :lisp (displa '((MLIST SIMP) $X $Y $Z))
     [x, y, z]
     NIL

Las funciones definidas en Maxima no son funciones Lisp ordinarias.  La
función Lisp 'mfuncall' llama a una función Maxima.  Por ejemplo:

     (%i1) foo(x,y) := x*y$
     (%i2) :lisp (mfuncall '$foo 'a 'b)
     ((MTIMES SIMP) A B)

Algunas funciones Lisp son compartidas en el paquete Maxima, las cuales
se listan a continuación:

'complement', 'continue', '//', 'float', 'functionp', 'array', 'exp',
'listen', 'signum', 'atan', 'asin', 'acos', 'asinh', 'acosh', 'atanh',
'tanh', 'cosh', 'sinh', 'tan', 'break', y 'gcd'.


File: maxima.info,  Node: Recolector de basura,  Next: Introducción a la programación,  Prev: Lisp y Maxima,  Up: Programación

37.2 Recolector de basura
=========================

La computación simbólica tiende a crear una buena cantidad de basura
(resultados temporales que ya no serán utilizados), y un manejo efectivo
de esto puede ser crucial para el término exitoso de algunos programas.

Bajo GCL (GNU Common Lisp), en aquellos sistemas UNIX donde la llamada
al sistema mprotect está disponible (incluyendo SUN OS 4.0 y algunas
variantes de BSD) se dispone de un recolector de basura estratificado.
Véase la documentación de GCL para ALLOCATE y GBC. A nivel Lisp,
ejecutando (setq si::*notify-gbc* t) pemitirá determinar qué áreas
necesitan más espacio.

En cuanto al resto de Lisps bajo los que funciona Maxima, se remite al
lector a la documentación correspondiente para controlar la recolección
de basura.


File: maxima.info,  Node: Introducción a la programación,  Next: Funciones y variables para la programación,  Prev: Recolector de basura,  Up: Programación

37.3 Introducción a la programación
===================================

Maxima dispone de los bucles 'do' para hacer iteraciones, así como
estructuras más primitivas del estilo de 'go'.


File: maxima.info,  Node: Funciones y variables para la programación,  Prev: Introducción a la programación,  Up: Programación

37.4 Funciones y variables para la programación
===============================================

 -- Función: backtrace ()
 -- Función: backtrace (<n>)
     Devuelve la pila de llamadas, esto es, la lista de funciones que
     han llamado a la función actualmente activa.

     La llamada a 'backtrace()' devuelve la pila completa de llamadas.

     Ejemplos:

          (%i1) h(x) := g(x/7)$
          (%i2) g(x) := f(x-11)$
          (%i3) f(x) := e(x^2)$
          (%i4) e(x) := (backtrace(), 2*x + 13)$
          (%i5) h(10);
          #0: e(x=4489/49)
          #1: f(x=-67/7)
          #2: g(x=10/7)
          #3: h(x=10)
                                        9615
          (%o5)                         ----
                                         49

     La llamada 'backtrace (<n>)' devuelve las <n> funciones más
     recientes, incluyendo a la función actualmente activa.

     Ejemplos:

          (%i1) h(x) := (backtrace(1), g(x/7))$
          (%i2) g(x) := (backtrace(1), f(x-11))$
          (%i3) f(x) := (backtrace(1), e(x^2))$
          (%i4) e(x) := (backtrace(1), 2*x + 13)$
          (%i5) h(10);
          #0: h(x=10)
          #0: g(x=10/7)
          #0: f(x=-67/7)
          #0: e(x=4489/49)
                                        9615
          (%o5)                         ----
                                         49

 -- Operador especial: do
     La sentencia 'do' se utiliza para realizar iteraciones.  Debido a
     su generalidad la sentencia 'do' se describirá en dos partes.  En
     primer lugar se mostrará su forma más usual, análoga a la de otros
     lenguajes de programación (Fortran, Algol, PL/I, etc.); después se
     mencionarán otras formas de uso.

     Hay tres variantes de esta sentencia que se diferencian entre sí
     únicamente por las condiciones de fin de bucle.  Son las
     siguientes:

        * 'for <variable>: <valor_inicial> step <incremento> thru
          <límite> do <cuerpo>'
        * 'for <variable>: <valor_inicial> step <incremento> while
          <condición> do <cuerpo>'
        * 'for <variable>: <valor_inicial> step <incremento> unless
          <condición> do <cuerpo>'

     El <valor_inicial>, el <incremento>, el <límite> y el <cuerpo>
     pueden ser cualquier tipo de expresión válida de Maxima.  Si el
     incremento es igual a la unidad (1) entonces "'step 1'" puede
     omitirse.

     La ejecución de la sentencia 'do' se realiza asignando el
     valor_inicial a la variable (llamada de aquí en adelante
     variable-control).  A continuación: (1) si la variable-control ha
     excedido el límite de la especificación dada por un 'thru', o si la
     condición impuesta por 'unless' es verdadera ('true'), o si la
     condición dada por 'while' es falsa ('false') entonces la iteración
     'do' termina.  (2) El cuerpo se evalúa.  (3) El incremento es
     sumado a la variable-control.  El proceso de (1) a (3) se repite
     hasta que la condición de fin de iteración se satisfaga.  También
     es posible especificar varias condiciones de terminación del bucle,
     en cuyo caso 'do' terminará cuando se satisfaga alguna de ellas.

     En general la condición 'thru' se satisfará cuando la
     variable-control sea mayor que el límite si el incremento es no
     negativo, o cuando la variable-control sea menor que el límite
     cuando el incremento es negativo.  El incremento y el límite pueden
     ser expresiones no numéricas, tanto en cuanto esta desigualdad
     pueda quedar determinada.  Sin embargo, a menos que el incremento
     sea un número negativo en el momento de comenzar el cómputo de
     'do', Maxima supondrá que se evaluará a una cantidad positiva.  En
     caso de no ser efectivamente positivo, la sentencia 'do' puede dar
     un resultado inesperado.

     Nótese que el límite, el incremento y la condición de terminación
     se evalúan en cada iteración del bucle.  Así, si alguna de
     expresiones necesitan de muchos cálculos y devuelven un resultado
     que no va a cambiar durante toda la ejecución del cuerpo, será más
     eficiente dar este valor a una variable antes de comenzar la
     sentencia 'do' y utilizarla luego durante su ejecución.

     El valor que habitualmente devuelva la sentencia 'do' será el átomo
     'done'.  Sin embargo, la función 'return' puede usarse dentro del
     cuerpo para salir de 'do' de forma prematura retornando un valor
     determinado.  Nótese no obstante que un 'return' dentro de un 'do'
     que está dentro de un bloque ('block') provocará una salida de 'do'
     pero no de 'block'.  Repárese también en que la función 'go' no
     puede usarse para salir de 'do' e ir a algún lugar de 'block'.

     La variable-control es siempre local respecto de 'do', por lo que
     se puede utilizar cualquier nombre de variable sin afectar el valor
     de cualquier otra variable externa a 'do' y que tenga el mismo
     nombre.  La variable-control no tendrá asignado ningún valor una
     vez se haya concluido el 'do'.

          (%i1) for a:-3 thru 26 step 7 do display(a)$
                                       a = - 3

                                        a = 4

                                       a = 11

                                       a = 18

                                       a = 25

          (%i1) s: 0$
          (%i2) for i: 1 while i <= 10 do s: s+i;
          (%o2)                         done
          (%i3) s;
          (%o3)                          55

     Nótese que la condición 'while i <= 10' es equivalente a 'unless i
     > 10' y a 'thru 10'.

          (%i1) series: 1$
          (%i2) term: exp (sin (x))$
          (%i3) for p: 1 unless p > 7 do
                    (term: diff (term, x)/p,
                     series: series + subst (x=0, term)*x^p)$
          (%i4) series;
                            7    6     5    4    2
                           x    x     x    x    x
          (%o4)            -- - --- - -- - -- + -- + x + 1
                           90   240   15   8    2

     lo que da ocho términos del desarrollo de Taylor de la función
     'e^sin(x)'.

          (%i1) poly: 0$
          (%i2) for i: 1 thru 5 do
                    for j: i step -1 thru 1 do
                        poly: poly + i*x^j$
          (%i3) poly;
                            5      4       3       2
          (%o3)          5 x  + 9 x  + 12 x  + 14 x  + 15 x
          (%i4) guess: -3.0$
          (%i5) for i: 1 thru 10 do
                    (guess: subst (guess, x, 0.5*(x + 10/x)),
                     if abs (guess^2 - 10) < 0.00005 then return (guess));
          (%o5)                  - 3.162280701754386

     Este ejemplo calcula la raíz cuadrada negativa de 10 haciendo 10
     iteraciones del método de Newton-Raphson.  De no haberse alcanzado
     el criterio de convergencia el valor devuelto hubiese sido 'done'.

     En lugar de añadir siempre una cantidad a la variable-control a
     veces se puede querer que cambie en cada iteración siguiendo algún
     otro criterio.  En tal caso se puede hacer uso de 'next
     <expresión>' en lugar de 'step <incremento>'.  Esto hará que a la
     variable-control se le asigne el resultado de evaluar la expresión
     en cada iteración del bucle.

          (%i6) for count: 2 next 3*count thru 20 do display (count)$
                                      count = 2

                                      count = 6

                                     count = 18

     En ocasiones puede interesar realizar una iteración en la que la
     variable-control no se utilice nunca.  Se podrá entonces dar
     únicamente las condiciones de terminación del bucle omitiendo la
     inicialización y actualizando la información, tal como se hace en
     el siguiente ejemplo para calcular la raíz cuadrada de 5 utilizando
     un valor inicial alejado de la solución.

          (%i1) x: 1000$
          (%i2) thru 20 do x: 0.5*(x + 5.0/x)$
          (%i3) x;
          (%o3)                   2.23606797749979
          (%i4) sqrt(5), numer;
          (%o4)                   2.23606797749979

     Si así se quiere, incluso es posible omitir las condiciones de
     terminación completamente y escribir únicamente 'do <body>', lo que
     provocará entrar en un bucle infinito.  En tal caso, debería usarse
     la función 'return' a fin de terminar con la ejecución de 'do'.

          (%i1) newton (f, x):= ([y, df, dfx], df: diff (f ('x), 'x),
                    do (y: ev(df), x: x - f(x)/y,
                        if abs (f (x)) < 5e-6 then return (x)))$
          (%i2) sqr (x) := x^2 - 5.0$
          (%i3) newton (sqr, 1000);
          (%o3)                   2.236068027062195

     (En este ejemplo, cuando se ejecuta 'return' obliga a que sea 'x'
     el valor devuelto por 'do'.  Al salirse del bloque, 'x' es también
     el valor que devuelve 'block' por ser 'do' la última sentencia del
     bloque.)

     Hay todavía otra forma de 'do' en Maxima.  Su sintaxis es:

          for <variable> in <lista> <test_de_parada> do <cuerpo>

     Los elementos de <list> son cualesquiera expresiones que se irán
     asignando sucesivamente a la variable en cada repetición del
     cuerpo.  El test de parada <end_tests> (que es opcional) puede
     usarse para terminar la ejecución de 'do'; de otro modo las
     iteraciones se pararán cuando la lista se haya agotado o cuando se
     ejecute un 'return' dentro del cuerpo.  (De hecho, la lista puede
     ser cualquier expresión no atómica, de la cual se irán extrayendo
     de forma sucesiva sus diferentes partes.)

          (%i1)  for f in [log, rho, atan] do ldisp(f(1))$
          (%t1)                                  0
          (%t2)                                rho(1)
                                               %pi
          (%t3)                                 ---
                                                4
          (%i4) ev(%t3,numer);
          (%o4)                             0.78539816

 -- Función: errcatch (<expr_1>, ..., <expr_n>)
     Evalúa las expresiones <expr_1>, ..., <expr_n> una a una y devuelve
     '[<expr_n>]' (una lista) en caso de que no ocurra ningún error.  En
     caso de aparecer algún error durante el cálculo de alguno de los
     argumentos, 'errcatch' evita que el error se propague y devuelve la
     lista vacía '[]' sin evaluar más argumentos.

     La función 'errcatch' es útil en ficheros 'batch' donde se sospeche
     que pueda aparecer algún error, el cual provocaría la terminación
     de la ejecución del 'batch' de no ser previamente detectado.

 -- Función: error (<expr_1>, ..., <expr_n>)
 -- Variable del sistema: error
     Calcula y devuelve <expr_1>, ..., <expr_n>, enviando posteriormente
     una seãl de error a Maxima o al 'errcatch' más cercano.

     A la variable 'error' se le asigna una lista con la descripción del
     error.  El primer elemento de 'error' es una cadena de formato, la
     cual une todas las cadenas de los argumentos <expr_1>, ...,
     <expr_n>, siendo los demás elementos de la lista los valores de los
     argumentos que no son cadenas.

     La llamada a 'errormsg()' formatea e imprime 'error'.  Se reimprime
     así el mensaje de error más reciente.

 -- Variable opcional: error_size
     Valor por defecto: 10

     La variable 'error_size' modifica los mensajes de error de acuerdo
     con el tamaño de las expresiones que aparecen en él.  Si el tamaño
     de una expresión (tal como lo determina la función Lisp
     'ERROR-SIZE') es mayor que 'error_size', la expresión se reemplaza
     en el mensaje por un símbolo, asignándole a éste una expresión.
     Los símbolos se toman de la lista 'error_syms'.

     En caso contrario, si la expresión es menor que 'error_size', la
     expresión se muestra en el propio mensaje.

     Véanse también 'error' y 'error_syms'.

     Ejemplo:

     El tamaño de 'U', tal como lo determina 'ERROR-SIZE', es 24.

          (%i1) U: (C^D^E + B + A)/(cos(X-1) + 1)$

          (%i2) error_size: 20$

          (%i3) error ("Example expression is", U);

          Example expression is errexp1
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i4) errexp1;
                                      E
                                     D
                                    C   + B + A
          (%o4)                    --------------
                                   cos(X - 1) + 1
          (%i5) error_size: 30$

          (%i6) error ("Example expression is", U);

                                   E
                                  D
                                 C   + B + A
          Example expression is --------------
                                cos(X - 1) + 1
           -- an error.  Quitting.  To debug this try debugmode(true);

 -- Variable opcional: error_syms
     Valor por defecto: '[errexp1, errexp2, errexp3]'

     En los mensajes de error, las expresiones mayores que 'error_size'
     son reemplazadas por símbolos a los cuales se les asignas estas
     expresiones.  Los símbolos se toman de la lista 'error_syms'.  La
     primera expresión que resulte ser demasiado larga se reemplaza por
     'error_syms[1]', la segunda por 'error_syms[2]' y así
     sucesivamente.

     Si hay más expresiones largas que elementos en 'error_syms', los
     símbolos se construyen automáticamente, siendo el <n>-ésimo símbolo
     equivalente a 'concat ('errexp, <n>)'.

     Véanse también 'error' y 'error_size'.

 -- Función: errormsg ()

     Reimprime el mensaje de error más reciente.  La variable 'error'
     guarda el mensaje y 'errormsg' lo formatea e imprime.

 -- Variable opcional: errormsg
     Valor por defecto: 'true'

     Cuando 'errormsg' vale 'false' se suprimen los contenidos de los
     mensajes de error.

     La variable 'errormsg' no se puede asignar a un valor local dentro
     de un bloque.  El valor global de 'errormsg' está siempre presente.

     Ejemplos:

          (%i1) errormsg;
          (%o1)                                true
          (%i2) sin(a,b);
          Wrong number of arguments to sin
           -- an error. To debug this try: debugmode(true);
          (%i3) errormsg:false;
          (%o3)                                false
          (%i4) sin(a,b);

           -- an error. To debug this try: debugmode(true);

     La variable 'errormsg' no se puede asignar a un valor local dentro
     de un bloque.

          (%i1) f(bool):=block([errormsg:bool],
                               print ("value of errormsg is",errormsg))$
          (%i2) errormsg:true;
          (%o2)                                true
          (%i3) f(false);
          value of errormsg is true
          (%o3)                                true
          (%i4) errormsg:false;
          (%o4)                                false
          (%i5) f(true);
          value of errormsg is false
          (%o5)                                false

 -- Operador especial: for
     Utilizado en las iteraciones.  Véase 'do' para una descripción de
     las técnicas de iteración en Maxima.

 -- Función: go (<etiqueta>)
     Se utiliza dentro de un bloque ('block') para transferir el control
     a la sentencia del bloque que esté etiquetada con el argumento de
     'go'.  Una sentencia queda etiquetada cuando está precedida por un
     argumento de tipo átomo como cualquier otra sentencia de 'block'.
     Por ejemplo:

          block ([x], x:1, tururu, x+1, ..., go(tururu), ...)

     El argumento de 'go' debe ser el nombre de una etiqueta que
     aparezca en el mismo bloque ('block').  No se puede utilizar 'go'
     para transferir el control a un bloque que no sea aquel que
     contenga la sentencia 'go'.

 -- Operador especial: if
     Evaluación condicionada.  Se reconocen varias formas de expresiones
     'if'.

     La expresión 'if <cond_1> then <expr_1> else <expr_0>' devuelve
     <expr_1> si <cond_1> vale 'true', en caso contrario la respuesta es
     'expr_0'.

     La expresión 'if <cond_1> then <expr_1> elseif <cond_2> then
     <expr_2> elseif ... else <expr_0>' devuelve <expr_k> si <cond_k>
     vale 'true' y todas las condiciones anteriores toman el valor
     'false'.  Si ninguna de las condiciones vale 'true', la respuesta
     es 'expr_0'.

     La falta de un 'else' final se interpreta como un 'else false';
     esto es, la expresión 'if <cond_1> then <expr_1>' equivale a 'if
     <cond_1> then <expr_1> else false', y 'if <cond_1> then <expr_1>
     elseif ... elseif <cond_n> then <expr_n>' equivale a su vez a 'if
     <cond_1> then <expr_1> elseif ... elseif <cond_n> then <expr_n>
     else false'.

     Las alternativas <expr_0>, ..., <expr_n> pueden ser expresiones
     válidas de Maxima, incluidas expresiones 'if' anidadas.  Las
     alternativas ni se simplifican ni se evalúan, a menos que su
     condición asociada valga 'true'.

     Las condiciones <cond_1>, ..., <cond_n> deben ser expresiones
     capaces de dar como resultado 'true' o 'false' al ser evaluadas.
     Si en un momento dado una condición no da como resultado un valor
     de verdad ('true' o 'false'), el comportamiento de 'if' se controla
     con la variable global 'prederror'.  Si 'prederror' vale 'true', se
     considera un error que la condición evaluada no dé como resultado
     un valor de verdad; en caso contrario, las condiciones que no den
     como resultado un valor de verdad se aceptan, dándose el resultado
     como una expresión condicional.

     Las condiciones pueden contener operadores lógicos y relacionales,
     así como otros elementos, tal como se indica a continuación:

          Operación               Símbolo     Tipo

          menor que               <           operador relacional infijo
          menor o igual que       <=          operador relacional infijo
          igualdad (sintáctica)   =           operador relacional infijo
          negación de =           #           operador relacional infijo
          igualdad (por valor)    equal       operador relacional infijo
          negación de equal       notequal    operador relacional infijo
          mayor o igual que       >=          operador relacional infijo
          mayor que               >           operador relacional infijo
          y                       and         operador lógico infijo
          o                       or          operador lógico infijo
          no                      not         operador lógico prefijo

 -- Función: map (<f>, <expr_1>, ..., <expr_n>)
     Devuelve una expresión cuyo operador principal es el mismo que
     aparece en las expresiones <expr_1>, ..., <expr_n> pero cuyas
     subpartes son los resultados de aplicar <f> a cada una de las
     subpartes de las expresiones; <f> puede ser tanto el nombre de una
     función de n argumentos como una expresión 'lambda' de n
     argumentos.

     Uno de los usos que tiene 'map' es la de aplicar (o mapear) una
     función (por ejemplo, 'partfrac') sobre cada término de una
     expresión extensa en la que normalmente no se podría utilizar la
     función debido a insuficiencias en el espacio de almacenamiento
     durante el curso de un cálculo.

          (%i1) map(f,x+a*y+b*z);
          (%o1)                        f(b z) + f(a y) + f(x)
          (%i2) map(lambda([u],partfrac(u,x)),x+1/(x^3+4*x^2+5*x+2));
                                     1       1        1
          (%o2)                     ----- - ----- + -------- + x
                                   x + 2   x + 1          2
                                                   (x + 1)
          (%i3) map(ratsimp, x/(x^2+x)+(y^2+y)/y);
                                                1
          (%o3)                            y + ----- + 1
                                              x + 1
          (%i4) map("=",[a,b],[-0.5,3]);
          (%o4)                          [a = - 0.5, b = 3]

     Véase también 'maperror' .

 -- Función: mapatom (<expr>)
     Devuelve 'true' si y sólo <expr> es tratado por las rutinas de
     mapeo como un átomo.

 -- Variable opcional: maperror
     Valor por defecto: 'true'

     Cuando 'maperror' toma el valor 'false', hace que todas las
     funciones de mapeo, como por ejemplo

          map (f, <expr_1>, <expr_2>, ...)

     (1) paren cuando hayan terminado de procesar la <expr_i> más corta,
     a menos que todas ellas sean del mismo tamaño y (2) apliquen 'f' a
     '[expr_1, expr_2, ...]' si es el caso que las 'expr_i' no son todas
     del mismo tipo de objeto.

     Cuando 'maperror' toma el valor 'true' entonces se emite un mensaje
     de error cuando se presenta cualquiera de los dos casos anteriores.

 -- Variable opcional: mapprint
     Valor por defecto: 'true'

     Si 'mapprint' vale 'true', se producirán ciertos mensajes por parte
     de las funciones 'map', 'mapl' y 'fullmap' en determinadas
     situaciones, como cuando 'map' hace uso de 'apply'.

     Si 'mapprint' vale 'false', no se emitirán tales mensajes.

 -- Función: maplist (<f>, <expr_1>, ..., <expr_n>)
     Devuelve una lista con las aplicaciones de <f> a las partes de las
     expresiones <expr_1>, ..., <expr_n>; <f> es el nombre de una
     función ou una expresión lambda.

     La función 'maplist' difiere de 'map (<f>, <expr_1>, ...,
     <expr_n>)', la cual devuelve una expresión con el mismo operador
     principal que tenga <expr_i>, excepto en simplificaciones y en el
     caso en el que 'map' hace un 'apply'.

 -- Variable opcional: prederror
     Valor por defecto: 'false'

     Cuando 'prederror' toma el valor 'true', se emite un mensaje de
     error siempre que el predicado de una sentencia 'if' o de una
     función 'is' no se pueda evaluar ni a verdadero ('true') ni a falso
     ('false').

     Si toma el valor 'false', se devuelve bajo las mismas
     circunstancias anteriores el valor 'unknown'.  El modo 'prederror:
     false' no está soportado en el código traducido; sin embargo,
     'maybe' está soportado en código traducido.

     Véanse también 'is' y 'maybe'.

 -- Función: return (valor)
     Puede utilizarse para salir de un bloque, devolviendo su argumento.
     Véase 'block' para más información.

 -- Función: scanmap (<f>, <expr>)
 -- Función: scanmap (<f>, <expr>, bottomup)
     Aplica recursivamente <f> sobre <expr>, de arriba hacia abajo.
     Esto es más útil cuando se busca una factorización completa, por
     ejemplo:

          (%i1) exp:(a^2+2*a+1)*y + x^2$
          (%i2) scanmap(factor,exp);
                                              2      2
          (%o2)                         (a + 1)  y + x

     Nótese que cómo 'scanmap' aplica la función dada 'factor' a las
     subexpresiones que forman a <expr>; si se presenta otra forma de
     <expr> a 'scanmap' entonces el resultado puede ser diferente.  Así,
     '%o2' no se restaura cuando 'scanmap' se aplica a la forma
     expandida de exp:

          (%i3) scanmap(factor,expand(exp));
                                     2                  2
          (%o3)                      a  y + 2 a y + y + x

     Aquí hay otro ejemplo de la forma en que 'scanmap' aplica
     recursivamente una función dada a todas las subexpresiones,
     incluyendo exponentes:

          (%i4) expr : u*v^(a*x+b) + c$
          (%i5) scanmap('f, expr);
                              f(f(f(a) f(x)) + f(b))
          (%o5) f(f(f(u) f(f(v)                      )) + f(c))

     'scanmap (<f>, <expr>, bottomup)' aplica <f> a <expr> de abajo
     hacia arriba.  Por ejemplo, para 'f' no definida,

          scanmap(f,a*x+b) ->
             f(a*x+b) -> f(f(a*x)+f(b)) -> f(f(f(a)*f(x))+f(b))
          scanmap(f,a*x+b,bottomup) -> f(a)*f(x)+f(b)
              -> f(f(a)*f(x))+f(b) ->
               f(f(f(a)*f(x))+f(b))

     En este caso se obtiene la misma respuesta por cualquiera de los
     dos métodos.

 -- Función: throw (<expr>)
     Evalúa <expr> y devuelve el valor del 'catch' más reciente.  La
     función 'throw' se utiliza junto con 'catch' como un mecanismo de
     retorno no local.

 -- Operador especial: while
 -- Operador especial: unless

     Véase 'do'.

 -- Función: outermap (<f>, <a_1>, ..., <a_n>)
     Aplica la función <f> a cada uno de los elementos del producto
     vectorial <a_1> por <a_2> ...  por <a_n>.

     El argumento <f> debe ser el nombre de una función de n argumentos,
     o una expresión lambda de n argumentos.  Cada uno de los argumentos
     <a_k> puede ser una lista, una lista anidada, una matriz o
     cualquier otro tipo de expresión.

     El valor devuelto por 'outermap' es una estructura anidada.  Si <x>
     es la respuesta dada por 'outermap', entonces tiene la misma
     estructura que la primera lista, lista anidada o matriz,
     '<x>[i_1]...[i_m]' tiene la misma estructura que la segunda lista,
     lista anidada o matriz, '<x>[i_1]...[i_m][j_1]...[j_n]' tiene la
     misma estructura que la tercera lista, lista anidada o matriz, y
     así sucesivamente, siendo <m>, <n>, ...  los números índice
     necesarios para acceder a los elementos de cada argumento: uno para
     las listas, dos para las matrices y uno o más para las listas
     anidadas.  Aquellos argumentos que no sean listas ni matrices no
     tienen efecto alguno sobre la estructura del valor retornado.

     Nótese que el efecto producido por 'outermap' es diferente del que
     se obtiene al aplicar <f> a cada uno de los elementos del producto
     devuelto por 'cartesian_product'.  La función 'outermap' mantiene
     la estructura de los argumentos en la respuesta, miemtras que
     'cartesian_product' no lo hace.

     La función 'outermap' evalúa sus argumentos.

     Véanse también 'map', 'maplist' y 'apply'.

     Ejemplos:

     Ejemplos elementales de uso de 'outermap'.  Con el fin de mostrar
     con mayor claridad las combinaciones del argumento, se mantiene sin
     definir 'F'.

          (%i1) outermap (F, [a, b, c], [1, 2, 3]);
          (%o1) [[F(a, 1), F(a, 2), F(a, 3)], [F(b, 1), F(b, 2), F(b, 3)],
                                               [F(c, 1), F(c, 2), F(c, 3)]]
          (%i2) outermap (F, matrix ([a, b], [c, d]), matrix ([1, 2], [3, 4]));
                   [ [ F(a, 1)  F(a, 2) ]  [ F(b, 1)  F(b, 2) ] ]
                   [ [                  ]  [                  ] ]
                   [ [ F(a, 3)  F(a, 4) ]  [ F(b, 3)  F(b, 4) ] ]
          (%o2)    [                                            ]
                   [ [ F(c, 1)  F(c, 2) ]  [ F(d, 1)  F(d, 2) ] ]
                   [ [                  ]  [                  ] ]
                   [ [ F(c, 3)  F(c, 4) ]  [ F(d, 3)  F(d, 4) ] ]
          (%i3) outermap (F, [a, b], x, matrix ([1, 2], [3, 4]));
                 [ F(a, x, 1)  F(a, x, 2) ]  [ F(b, x, 1)  F(b, x, 2) ]
          (%o3) [[                        ], [                        ]]
                 [ F(a, x, 3)  F(a, x, 4) ]  [ F(b, x, 3)  F(b, x, 4) ]
          (%i4) outermap (F, [a, b], matrix ([1, 2]), matrix ([x], [y]));
                 [ [ F(a, 1, x) ]  [ F(a, 2, x) ] ]
          (%o4) [[ [            ]  [            ] ],
                 [ [ F(a, 1, y) ]  [ F(a, 2, y) ] ]
                                        [ [ F(b, 1, x) ]  [ F(b, 2, x) ] ]
                                        [ [            ]  [            ] ]]
                                        [ [ F(b, 1, y) ]  [ F(b, 2, y) ] ]
          (%i5) outermap ("+", [a, b, c], [1, 2, 3]);
          (%o5) [[a + 1, a + 2, a + 3], [b + 1, b + 2, b + 3],
                                                     [c + 1, c + 2, c + 3]]

     El siguiente ejemplo permite hacer un análisis más profundo del
     valor retornado por 'outermap'.  Los tres primeros argumentos son
     una matriz, una lista y otra matriz, en este orden.  El valor
     devuelto es una matriz, cuyos elementos son listas y cada elemento
     de cada una de estas listas es a su vez una matriz.

          (%i1) arg_1 :  matrix ([a, b], [c, d]);
                                      [ a  b ]
          (%o1)                       [      ]
                                      [ c  d ]
          (%i2) arg_2 : [11, 22];
          (%o2)                       [11, 22]
          (%i3) arg_3 : matrix ([xx, yy]);
          (%o3)                      [ xx  yy ]
          (%i4) xx_0 : outermap(lambda([x, y, z], x / y + z), arg_1,
                                                             arg_2, arg_3);
                         [  [      a        a  ]  [      a        a  ]  ]
                         [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                         [  [      11       11 ]  [      22       22 ]  ]
          (%o4)  Col 1 = [                                              ]
                         [  [      c        c  ]  [      c        c  ]  ]
                         [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                         [  [      11       11 ]  [      22       22 ]  ]
                           [  [      b        b  ]  [      b        b  ]  ]
                           [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                           [  [      11       11 ]  [      22       22 ]  ]
                   Col 2 = [                                              ]
                           [  [      d        d  ]  [      d        d  ]  ]
                           [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                           [  [      11       11 ]  [      22       22 ]  ]
          (%i5) xx_1 : xx_0 [1][1];
                     [      a        a  ]  [      a        a  ]
          (%o5)     [[ xx + --  yy + -- ], [ xx + --  yy + -- ]]
                     [      11       11 ]  [      22       22 ]
          (%i6) xx_2 : xx_0 [1][1] [1];
                                [      a        a  ]
          (%o6)                 [ xx + --  yy + -- ]
                                [      11       11 ]
          (%i7) xx_3 : xx_0 [1][1] [1] [1][1];
                                            a
          (%o7)                        xx + --
                                            11
          (%i8) [op (arg_1), op (arg_2), op (arg_3)];
          (%o8)                  [matrix, [, matrix]
          (%i9) [op (xx_0), op (xx_1), op (xx_2)];
          (%o9)                  [matrix, [, matrix]

     La función 'outermap' mantiene la estructura de los argumentos en
     su respuesta, mientras que 'cartesian_product' no lo hace.

          (%i1) outermap (F, [a, b, c], [1, 2, 3]);
          (%o1) [[F(a, 1), F(a, 2), F(a, 3)], [F(b, 1), F(b, 2), F(b, 3)],
                                               [F(c, 1), F(c, 2), F(c, 3)]]
          (%i2) setify (flatten (%));
          (%o2) {F(a, 1), F(a, 2), F(a, 3), F(b, 1), F(b, 2), F(b, 3),
                                                 F(c, 1), F(c, 2), F(c, 3)}
          (%i3) map (lambda ([L], apply (F, L)), cartesian_product ({a, b, c}, {1, 2, 3}));
          (%o3) {F(a, 1), F(a, 2), F(a, 3), F(b, 1), F(b, 2), F(b, 3),
                                                 F(c, 1), F(c, 2), F(c, 3)}
          (%i4) is (equal (%, %th (2)));
          (%o4)                         true


File: maxima.info,  Node: Depurado,  Next: augmented_lagrangian,  Prev: Programación,  Up: Top

38 Depurado
***********

* Menu:

* Depuración del código fuente::
* Claves de depuración::
* Funciones y variables para depurado::


File: maxima.info,  Node: Depuración del código fuente,  Next: Claves de depuración,  Up: Depurado

38.1 Depuración del código fuente
=================================

Maxima es capaz de dar asistencia en la depuración del código fuente.
Un usuario puede establecer un punto de referencia dentro del código de
una función a partir del cual se siga la ejecución línea a línea.  La
compliación puede ser posteriormente examinada, conjuntamente con los
valores que se han ido asignando a las variables.

La instrucción ':help', o ':h', muestra la lista de comandos para la
depuración.  (En general, los comandos pueden abreviarse; en algunos
casos la lista de alternativas podrá ser listada.)  Dentro del
depurador, el usuario podrá examinar también cualquier función propia de
Maxima, definirla y manipular variables y expresiones.

El punto de referencia se establecerá con la instrucción ':br'.  Ya
dentro del depurador, el usuario podrá avanzar una línea de cada vez
utilizando la instrucción ':n' (de "next", en inglés).  La orden ':bt'
(de "backtrace") muestra la lista de la pila.  Finalmente, con el
comando ':r' ("resume") se abandona el depurador continuando con la
ejecución.  El uso de estas instrucciones se muestra en el siguiente
ejemplo.

     (%i1) load ("/tmp/foobar.mac");

     (%o1)                           /tmp/foobar.mac

     (%i2) :br foo
     Turning on debugging debugmode(true)
     Bkpt 0 for foo (in /tmp/foobar.mac line 1)

     (%i2) bar (2,3);
     Bkpt 0:(foobar.mac 1)
     /tmp/foobar.mac:1::

     (dbm:1) :bt                  <-- pulsando :bt se retrocede
     #0: foo(y=5)(foobar.mac line 1)
     #1: bar(x=2,y=3)(foobar.mac line 9)

     (dbm:1) :n                   <-- pulsando :n se avanza una línea
     (foobar.mac 2)
     /tmp/foobar.mac:2::

     (dbm:1) :n                   <-- pulsando :n se avanza otra línea
     (foobar.mac 3)
     /tmp/foobar.mac:3::

     (dbm:1) u;                   <-- se pide el valor de u
     28

     (dbm:1) u: 33;               <-- se cambia el valor de u a 33
     33

     (dbm:1) :r                   <-- pulsando :r se termina la depuración

     (%o2)                                1094

El fichero '/tmp/foobar.mac' contiene lo siguiente:

     foo(y) := block ([u:y^2],
       u: u+3,
       u: u^2,
       u);

     bar(x,y) := (
       x: x+2,
       y: y+2,
       x: foo(y),
       x+y);

USO DEL DEPURADOR EN EMACS

Si el usuario está corriendo el código bajo GNU emacs en un entorno de
texto (dbl shell), o está ejecutando el entorno gráfico 'xmaxima',
entonces cuando una función pare en el punto de referencia, podrá
observar su posición actual en el archivo fuente, el cual será mostrado
en la otra mitad de la ventana, bien resaltada en rojo, o con una
pequeña flecha apuntando a la línea correcta.  El usuario puede avanzar
líneas simples tecleando M-n (Alt-n).

Bajo Emacs se debe ejecutar el programa en una ventana de texto 'dbl',
la cual requiere el archivo 'dbl.el' que está en el directorio elisp.
El usuario debe instalar los archivos elisp o agregar el directorio
elisp de Maxima a la ruta de búsqueda: por ejemplo, se puede añadir lo
siguiente al archivo '.emacs' o al 'site-init.el'

     (setq load-path (cons "/usr/share/maxima/5.9.1/emacs" load-path))
     (autoload 'dbl "dbl")

entonces en emacs

     M-x dbl

debería abrir una ventana del sistema en la cual se pueden ejecutar
programas, por ejemplo Maxima, gcl, gdb, etc.  En esta ventana también
se puede ejecutar el depurador, mostrando el código fuente en la otra
ventana.

El usuario puede colocar un punto de referencia en una línea determinada
sin más que teclear 'C-x space'.  Con esto se le hace saber al depurador
en qué función está el cursor y en qué línea del mismo.  Si el cursor
está en la línea 2 de 'foo', entonces insertará en la otra ventana la
instrucción "':br foo 2'", a fin de detener 'foo' justo en la segunda
línea.  Para tener esto operativo, el usuario debe tener activo
maxima-mode.el (modo-maxima.el) en la ventana en la que está
'foobar.mac'.  Hay otros comandos disponibles en la ventana, como
evaluar la función dentro de Maxima tecleando 'Alt-Control-x'.


File: maxima.info,  Node: Claves de depuración,  Next: Funciones y variables para depurado,  Prev: Depuración del código fuente,  Up: Depurado

38.2 Claves de depuración
=========================

Las claves de depuración son palabras que no son interpretadas como
expresiones de Maxima.  Una clave de depuración puede introducirse
dentro de Maxima o del depurador.  Las claves de depuración comienzan
con dos puntos, ':'.  Por ejemplo, para evaluar una expresión Lisp, se
puede teclear ':lisp' seguido de la expresión a ser evaluada.

     (%i1) :lisp (+ 2 3)
     5

El número de argumentos depende del comando en particular.  Además,
tampoco es necesario teclear el nombre completo de la instrucción, tan
solo lo justo para diferenciarla de las otras instrucciones.  Así, ':br'
sería suficiente para ':break'.

Las claves de depuración se listan a continuación.

':break F n'
     Establece un punto de referencia en la función 'F' en la línea 'n'
     contando a partir del comienzo de la función.  Si 'F' es una
     cadena, entonces se entiende que se trata de un fichero, siendo
     entonces 'n' el número de línea a partir del comienzo del fichero.
     El valor 'n' es opcional; en caso de no ser suministrado, se
     entenderá que vale cero (primera línea de la función o fichero).
':bt'
     Retrocede en la pila.
':continue'
     Continua el cómputo de la función.
':delete'
     Borra los punto de referencia especificados, o todos si no se
     especifica ninguno.
':disable'
     Deshabilita los puntos de referencia especificados, o todos si no
     se especifica ninguno.
':enable'
     Habilita los puntos de referencia especificados, o todos si no se
     especifica ninguno.
':frame n'
     Imprime el elemento 'n' de la pila, o el actualmente activo si no
     se especifica ninguno.
':help'
     Imprime la ayuda sobre un comando del depurador, o de todos los
     comandos si no se especifica ninguno.
':info'
     Imprime información sobre un elemento.
':lisp expresión'
     Evalúa la 'expresión' Lisp.
':lisp-quiet expresión'
     Evalúa la 'expresión' Lisp sin devolver el resultado.
':next'
     Como ':step', excepto que ':next' se salta las llamadas a
     funciones.
':quit'
     Sale del nivel actual del depurador sin completar el cómputo.
':resume'
     Continúa con el cómputo.
':step'
     Sigue con el cómputo de la función o fichero hasta que alcance una
     nueva línea fuente.
':top'
     Retorna a Maxima desde cualquier nivel del depurador sin completar
     el cómputo.


File: maxima.info,  Node: Funciones y variables para depurado,  Prev: Claves de depuración,  Up: Depurado

38.3 Funciones y variables para depurado
========================================

 -- Variable opcional: debugmode
     Valor por defecto: 'false'

     Cuando en Maxima ocurre un error, Maxima inicializará el depurador
     si 'debugmode' tiene el valor 'true'.  El usuario puede ingresar
     comandos para examinar la pila de llamadas, los puntos de
     interrupción; en pocas palabras ir a través del código de Maxima.
     Vea 'debugging' para una lista de los comandos del depurador.

     Habilitando 'debugmode' no se capturarán los errores tipo Lisp.

 -- Variable opcional: refcheck
     Valor por defecto: 'false'

     Cuando 'refcheck' vale 'true', Maxima imprime un mensaje cada vez
     que una variable es utilizada por vez primera en un cálculo.

 -- Variable opcional: setcheck
     Valor por defecto: 'false'

     Cuando el valor de 'setcheck' es una lista de variables (se admite
     que tengan subíndices) Maxima devuelve un mensaje indicando si los
     valores que han sido asignados a las variables lo han sido con el
     operador ordinario ':', o con el operador de asignación '::' o como
     resultado de haberse realizado una llamada de función, pero en
     ningún caso cuando la asignación haya sido hecha mediante los
     operadores ':=' o '::='.  El mensaje contiene el nombre de la
     variable y su valor.

     La variable 'setcheck' admite también los valores 'all' o 'true'
     con lo que el informe incluirá todas las variables.

     Cada nueva asignación de 'setcheck' establece una nueva lista de
     variables a ser monitorizada, de forma que cualquier otra variable
     previamente asignada a 'setcheck' es olvidada.

     Los nombres asignados a 'setcheck' deben estar precedidos del
     apóstrofo ''' a fin de evitar que las variables sean evaluadas
     antes de ser almacenadas en 'setcheck'.  Por ejemplo, si 'x', 'y' y
     'z' ya guardan algún valor entoces se hará

          setcheck: ['x, 'y, 'z]$

     para colocarlas en la lista de variables a monitorizar.

     No se generará ninguna salida cuando una variable de la lista
     'setcheck' sea asignada a ella misma, como en 'X: 'X'.

 -- Variable opcional: setcheckbreak
     Valor por defecto: 'false'

     Si 'setcheckbreak' es igual 'true', Maxima se detendrá siempre que
     a una variable de la lista 'setcheck' se le asigne un nuevo valor.
     La detención tendrá lugar justo antes de hacerse la asignación.  En
     ese momento 'setval' guarda el valor que se le va a dar a la
     variable.  Entonces el usuario podrá darle un valor diferente
     pasándoselo a la variable 'setval'.

     Véanse también 'setcheck' y 'setval'.

 -- Variable del sistema: setval

     Guarda el valor que va a ser asignado a una variable cuando
     'setcheckbreak' realiza una detención.  Entonces se podrá asignarle
     otro valor pasándoselo previamente a 'setval'.

     Véanse también 'setcheck' y 'setcheckbreak'.

 -- Función: timer (<f_1>, ..., <f_n>)
 -- Función: timer (all)
 -- Función: timer ()
     Dadas las funciones <f_1>, ..., <f_n>, 'timer' coloca cada una de
     ellas en la lista de funciones para las cuales se generarán
     estadísticas relativas al tiempo de cómputo.  Así, 'timer(f)$
     timer(g)$' coloca a 'f' y luego a 'g' en dicha lista de forma
     acumulativa.

     La sentencia 'timer(all)' coloca todas las funciones de usuario
     (las referenciadas por la variable global 'functions') en la lista
     de funciones cuyos tiempos de ejecución se quieren monitorizar.

     Si no se le pasan argumentos a 'timer' se obtendrá la lista de
     funciones cuyos tiempos de ejecución se quieren monitorizar.

     Maxima almacena la duración del cómputo de cada función de la
     lista, de forma que 'timer_info' devolverá las estadísticas
     correspondientes, incluyendo el tiempo medio de cada llamada a la
     función, el número de llamadas realizadas y el tiempo total
     transcurrido.  La instrucción 'untimer' borra las funciones de la
     lista.

     La función 'timer' no evalúa sus argumentos, de forma que 'f(x) :=
     x^2$ g:f$ timer(g)$' no coloca a 'f' en la lista.

     Si 'trace(f)' está activada, entonces 'timer(f)' está desactivada;
     'trace' y 'timer' no pueden estar operativas al mismo tiempo.

     Véase también 'timer_devalue'.

 -- Función: untimer (<f_1>, ..., <f_n>)
 -- Función: untimer ()
     Dadas las funciones <f_1>, ..., <f_n>, 'untimer' las elimina de la
     lista de funciones cuyos tiempos de ejecución se quiere
     monitorizar.

     Si no se le suministran argumentos, 'untimer' borra completamente
     la lista.

     Tras la ejecución de 'untimer (f)', 'timer_info (f)' aún devuelve
     las estadísticas de tiempo previamente registradas, pero
     'timer_info()' (sin argumentos) no devuelve información sobre
     aquellas funciones que ya no están en la lista.  La ejecución de
     'timer (f)' inicializa todas las estadísticas a cero y coloca 'f'
     nuevamente en la lista.

 -- Variable opcional: timer_devalue
     Valor por defecto: 'false'

     Si 'timer_devalue' es igual a 'true', Maxima le resta a cada
     función cuyos tiempos de ejecución se quiere monitorizar el tiempo
     gastado en llamadas a otras funciones presentes también en la lista
     de monitorización.  En caso contrario, los tiempos que se obtienen
     para cada función incluyen también los consumidos en otras
     funciones.  Nótese que el tiempo consumido en llamadas a otras
     funciones que no están en la lista de monitorización no se resta
     del tiempo total.

     Véanse también 'timer' y 'timer_info'.

 -- Función: timer_info (<f_1>, ..., <f_n>)
 -- Función: timer_info ()
     Dadas las funciones <f_1>, ..., <f_n>, 'timer_info' devuelve una
     matriz con información relativa a los tiempos de ejecución de cada
     una de estas funciones.  Sin argumentos, 'timer_info' devuelve la
     información asociada a todas las funciones cuyos tiempos de
     ejecución se quiere monitorizar.

     La matriz devuelta por 'timer_info' incluye los nombres de las
     funciones, tiempo de ejecución en cada llamada, número de veces que
     ha sido llamada, tiempo total de ejecución y tiempo consumido en la
     recolección de basura, 'gctime' (del inglés, "garbage collection
     time") en la versión original de Macsyma, aunque ahora toma el
     valor constante cero.

     Los datos con los que 'timer_info' construye su respuesta pueden
     obtenerse también con la función 'get':

          get(f, 'calls);  get(f, 'runtime);  get(f, 'gctime);

     Véase también 'timer'.

 -- Función: trace (<f_1>, ..., <f_n>)
 -- Función: trace (all)
 -- Función: trace ()

     Dadas las funciones <f_1>, ..., <f_n>, 'trace' imprime información
     sobre depuración cada vez que estas funciones son llamadas;
     'trace(f)$ trace(g)$' coloca de forma acumulativa a 'f' y luego a
     'g' en la lista de funciones a ser rastradas.

     La sentencia 'trace(all)' coloca todas las funciones de usuario
     (las referenciadas por la variable global 'functions') en la lista
     de funciones a ser rastreadas.

     Si no se suministran argumentos, 'trace' devuelve una lista con
     todas las funciones a ser rastreadas.

     La función 'untrace' desactiva el rastreo.  Véase también
     'trace_options'.

     La función 'trace' no evalúa sus argumentos, de forma que 'f(x) :=
     x^2$ g:f$ trace(g)$' no coloca a 'f' en la lista de rastreo.

     Cuando una función se redefine es eliminada de la lista de rastreo.
     Así, tras 'timer(f)$ f(x) := x^2$', la función 'f' dejará de estar
     en dicha lista.

     Si 'timer (f)' está activado, entonces 'trace (f)' está
     desactivado, ya que 'trace' y 'timer' no pueden estar ambos activos
     para la misma función.

 -- Función: trace_options (<f>, <option_1>, ..., <option_n>)
 -- Función: trace_options (<f>)

     Establece las opciones de rastreo para la función <f>.  Cualquier
     otra opción previamente especificada queda reemplazada por las
     nuevas.  La ejecución de 'trace_options (<f>, ...)' no tiene ningún
     efecto, a menos que se haya invocado previamente a 'trace (<f>)'
     (es indiferente que esta invocación sea anterior o posterior a
     'trace_options').

     'trace_options (<f>)' inicializa todas las opciones a sus valores
     por defecto.

     Las claves de opciones son:

        * 'noprint': No se imprime mensaje alguno ni a la entrada ni a
          la salida de la función.
        * 'break': Coloca un punto de referencia antes de que la función
          comience a ejecutarse y otro después de que termine su
          ejecución.  Véase 'break'.
        * 'lisp_print': Muestra los argumentos y valores retornados como
          objetos de Lisp.
        * 'info': Imprime '-> true' tanto a la entrada como a la salida
          de la función.
        * 'errorcatch': Detecta errores, otorgando la posibilidad de
          marcar un error, reintentar la llamada a la función o
          especificar un valor de retorno.

     Las opciones de rastreo se especifican de dos formas.  La única
     presencia de la clave de opción ya activa la opción.  (Nótese que
     la opción <foo> no se activa mediante '<foo>: true' u otra forma
     similar; se tendrá en cuenta también que las claves no necesitan ir
     precedidas del apóstrofo.)  Especificando la clave de opción junto
     con una función de predicado se hace que la opción quede
     condicionada al predicado.

     La lista de argumentos para las funciones de predicado es siempre
     '[level, direction, function, item]' donde 'level' es el nivel de
     recursión para la función, 'direction' puede ser tanto 'enter' como
     'exit', 'function' es el nombre de la función y 'item' es la lista
     de argumentos (a la entrada) o el valor de retorno (a la salida).

     A continuación un ejemplo de opciones de rastreo no condicionales:

          (%i1) ff(n) := if equal(n, 0) then 1 else n * ff(n - 1)$

          (%i2) trace (ff)$

          (%i3) trace_options (ff, lisp_print, break)$

          (%i4) ff(3);

     Para la misma función, con la opción 'break' condicionada a un
     predicado:

          (%i5) trace_options (ff, break(pp))$

          (%i6) pp (level, direction, function, item) := block (print (item),
              return (function = 'ff and level = 3 and direction = exit))$

          (%i7) ff(6);

 -- Función: untrace (<f_1>, ..., <f_n>)
 -- Función: untrace ()
     Dadas las funciones <f_1>, ..., <f_n>, 'untrace' desactiva el
     rastreo previamente activado por la función 'trace'.  Si no se
     aportan argumentos, 'untrace' desactiva el rastreo de todas las
     funciones.

     La llamada a 'untrace' devuelve una lista con las funciones para
     las que el rastreo se ha desactivado.


File: maxima.info,  Node: augmented_lagrangian,  Next: Bernstein,  Prev: Depurado,  Up: Top

39 augmented_lagrangian
***********************

* Menu:

* Funciones y variables para augmented_lagrangian::


File: maxima.info,  Node: Funciones y variables para augmented_lagrangian,  Prev: augmented_lagrangian,  Up: augmented_lagrangian

39.1 Funciones y variables para augmented_lagrangian
====================================================

 -- Función: augmented_lagrangian_method (<FOM>, <xx>, <C>, <yy>)
 -- Función: augmented_lagrangian_method (<FOM>, <xx>, <C>, <yy>,
          optional_args)
 -- Función: augmented_lagrangian_method ([<FOM>, <grad>], <xx>, <C>,
          <yy>)
 -- Función: augmented_lagrangian_method ([<FOM>, <grad>], <xx>, <C>,
          <yy>, optional_args)

     Devuelve una aproximación del valor mínimo de la expresión <FOM>
     respecto de las variables <xx>, manteniendo las restricciones <C>
     igual a cero.  La lista <yy> contiene las soluciones iniciales para
     <xx>.  El algoritmo que se utiliza es el método del lagrangiano
     aumentado (ver referencias [1] y [2]).

     Si <grad> está presente en la llamada a la función, se interpreta
     como el gradiente de <FOM> respecto de <xx>, representado como una
     lista de tantas expresiones como variables tenga <xx>.  Si el
     argumento <grad> no está, se calculará de forma automática.

     Tanto <FOM> como cada uno de los elementos de <grad>, si se da como
     argumento, deben ser expresiones ordinarias; no admitiéndose ni
     nombres de funciones ni expresiones lambda.

     El argumento 'optional_args' hace referencia a otros argumentos
     adicionales, los cuales se especifican de la forma '<symbol> =
     <value>'.  Los argumentos opcionales reconocidos son:

     'niter'
          Número de iteraciones del algoritmo.
     'lbfgs_tolerance'
          Tolerancia que se pasa a LBFGS.
     'iprint'
          Parámetro IPRINT (lista de dos enteros que controlan la
          frecuencia de mensajes) que se pasa a LBFGS.
     '%lambda'
          Valor inicial de '%lambda' que será utilizado para calcular el
          lagrangiano aumentado.

     Esta función minimiza el lagrangiano aumentado haciendo uso del
     algoritmo LBFGS, que es un método de los llamados quasi-Newton.

     Antes de hacer uso de esta función ejecútense
     'load("augmented_lagrangian")'.

     Véase también 'lbfgs'.

     Referencias:

     [1]
     <http://www-fp.mcs.anl.gov/otc/Guide/OptWeb/continuous/constrained/nonlinearcon/auglag.html>

     [2] <http://www.cs.ubc.ca/spider/ascher/542/chap10.pdf>

     Ejemplos:

          (%i1) load (lbfgs);
          (%o1)     /maxima/share/lbfgs/lbfgs.mac
          (%i2) load (augmented_lagrangian);
          (%o2)
             /maxima/share/contrib/augmented_lagrangian.mac
          (%i3) FOM: x^2 + 2*y^2;
                                         2    2
          (%o3)                       2 y  + x
          (%i4) xx: [x, y];
          (%o4)                        [x, y]
          (%i5) C: [x + y - 1];
          (%o5)                      [y + x - 1]
          (%i6) yy: [1, 1];
          (%o6)                        [1, 1]
          (%i7) augmented_lagrangian_method(FOM, xx, C, yy, iprint=[-1,0]);
          (%o7) [[x = 0.66665984108002, y = 0.33334027245545],
                                           %lambda = [- 1.333337940892525]]

     Mismo ejemplo que en el caso anterior, pero ahora el gradiente se
     suministra como argumento.

          (%i1) load (lbfgs)$
          (%i2) load (augmented_lagrangian)$
          (%i3) FOM: x^2 + 2*y^2;
                                         2    2
          (%o3)                       2 y  + x
          (%i4) FOM: x^2 + 2*y^2;
                                         2    2
          (%o4)                       2 y  + x
          (%i5) xx: [x, y];
          (%o5)                        [x, y]
          (%i6) grad : [2*x, 4*y];
          (%o6)                      [2 x, 4 y]
          (%i7) C: [x + y - 1];
          (%o7)                      [y + x - 1]
          (%i8) yy: [1, 1];
          (%o8)                        [1, 1]
          (%i9) augmented_lagrangian_method ([FOM, grad], xx, C, yy,
                                             iprint = [-1, 0]);
          (%o9) [[x = 0.666659841080025, y = .3333402724554462],
                                           %lambda = [- 1.333337940892543]]


File: maxima.info,  Node: Bernstein,  Next: bode,  Prev: augmented_lagrangian,  Up: Top

40 Bernstein
************

* Menu:

* Funciones y variables para Bernstein::


File: maxima.info,  Node: Funciones y variables para Bernstein,  Prev: Bernstein,  Up: Bernstein

40.1 Funciones y variables para Bernstein
=========================================

 -- Función: bernstein_poly (<k>, <n>, <x>)

     Si 'k' no es un entero negativo, los polinomios de Bernstein se
     definen como 'bernstein_poly(k,n,x) = binomial(n,k) x^k
     (1-x)^(n-k)'; en cambio, si 'k' es un entero negativo, el polinomio
     de Bernstein 'bernstein_poly(k,n,x)' se anula.  Cuando o bien 'k' o
     'n' no son enteros, la variable opcional 'bernstein_explicit'
     controla la expansión de los polinomios de Bernstein a su forma
     explícita.

     Ejemplo:

          (%i1) load(bernstein)$

          (%i2) bernstein_poly(k,n,x);
          (%o2)                bernstein_poly(k, n, x)
          (%i3) bernstein_poly(k,n,x), bernstein_explicit : true;
                                                 n - k  k
          (%o3)            binomial(n, k) (1 - x)      x

     Los polinomios de Bernstein tienen definidas su derivada e
     integral:

          (%i4) diff(bernstein_poly(k,n,x),x);
          (%o4) (bernstein_poly(k - 1, n - 1, x)
                                           - bernstein_poly(k, n - 1, x)) n
          (%i5) integrate(bernstein_poly(k,n,x),x);
          (%o5)
                                                                      k + 1
           hypergeometric([k + 1, k - n], [k + 2], x) binomial(n, k) x
           ----------------------------------------------------------------
                                        k + 1

     Cuando los argumentos contienen números decimales en coma flotante,
     los polinomios de Bernstein también devuelven resultados decimales.

          (%i6) bernstein_poly(5,9, 1/2 + %i);
                                  39375 %i   39375
          (%o6)                   -------- + -----
                                    128       256
          (%i7) bernstein_poly(5,9, 0.5b0 + %i);
          (%o7)           3.076171875b2 %i + 1.5380859375b2

     Para hacer uso de 'bernstein_poly', ejecútese primero
     'load("bernstein")'.

 -- Variable opcional: bernstein_explicit
     Valor por defecto: 'false'

     Cuando o bien 'k' o 'n' no son enteros, la variable opcional
     'bernstein_explicit' controla la expansión de los polinomios de
     Bernstein a su forma explícita.

     Ejemplo:

          (%i1) bernstein_poly(k,n,x);
          (%o1)                       bernstein_poly(k, n, x)
          (%i2) bernstein_poly(k,n,x), bernstein_explicit : true;
                                                        n - k  k
          (%o2)                   binomial(n, k) (1 - x)      x

     Cuando tanto 'k' como 'n' son enteros, 'bernstein(k,n,x)' se
     expande siempre a su forma explícita.

 -- Función: multibernstein_poly (<[k1,k2,...,kp]>,<[n1,n2,...,
          np]>,<[x1,x2,..., xp]>)

     La sentencia 'multibernstein_poly (<[k1,k2,...,kp]>,<[n1,n2,...,
     np]>,<[x1,x2,..., xp]>)' es el producto de polinomios de Bernstein
     'bernstein_poly(k1,n1,x1) bernstein_poly(k2,n2,x2) ...
     bernstein_poly(kp,np,xp)'.

     Para hacer uso de 'multibernstein_poly', ejecútese primero
     'load("bernstein")'.

 -- Función: bernstein_approx (<f>,<[x1,x1,...,xn]>,n)

     Devuelve el polinomio de Bernstein uniforme de 'n'-ésimo orden que
     aproxima la función '(x1,x2,..xn) |--> f'.

     Ejemplos:

          (%i1) bernstein_approx(f(x),[x], 2);
                                  2       1                          2
          (%o1)             f(1) x  + 2 f(-) (1 - x) x + f(0) (1 - x)
                                          2
          (%i2) bernstein_approx(f(x,y),[x,y], 2);
                         2  2       1                2                  2  2
          (%o2) f(1, 1) x  y  + 2 f(-, 1) (1 - x) x y  + f(0, 1) (1 - x)  y
                                    2
                    1   2                 1  1
           + 2 f(1, -) x  (1 - y) y + 4 f(-, -) (1 - x) x (1 - y) y
                    2                     2  2
                    1         2                      2        2
           + 2 f(0, -) (1 - x)  (1 - y) y + f(1, 0) x  (1 - y)
                    2
                 1                      2                  2        2
           + 2 f(-, 0) (1 - x) x (1 - y)  + f(0, 0) (1 - x)  (1 - y)
                 2

     Para hacer uso de 'bernstein_approx', ejecútese primero
     'load("bernstein")'.

 -- Función: bernstein_expand (<e>, <[x1,x1,...,xn]>)

     Expresa el polinomio 'e' como una combinación lineal de polinomios
     de Bernstein multivariantes.

          (%i1) bernstein_expand(x*y+1,[x,y]);
          (%o1)           2 x y + (1 - x) y + x (1 - y) + (1 - x) (1 - y)
          (%i2) expand(%);
          (%o2)                               x y + 1

     Maxima devuelve un error si el primer argumento no es un polinomio.

     Para hacer uso de 'bernstein_expand', ejecútese primero
     'load("bernstein")'.


File: maxima.info,  Node: bode,  Next: cobyla,  Prev: Bernstein,  Up: Top

41 bode
*******

* Menu:

* Funciones y variables para bode::


File: maxima.info,  Node: Funciones y variables para bode,  Prev: bode,  Up: bode

41.1 Funciones y variables para bode
====================================

 -- Función: bode_gain (<H>, <range>, ...<plot_opts>...)
     Función para dibujar el gráfico de ganancia de Bode.

     Ejemplos (1 a 7 de
          <http://www.swarthmore.edu/NatSci/echeeve1/Ref/Bode/BodeHow.html>,
     8 de Ron Crummett):
          (%i1) load("bode")$

          (%i2) H1 (s) := 100 * (1 + s) / ((s + 10) * (s + 100))$

          (%i3) bode_gain (H1 (s), [w, 1/1000, 1000])$

          (%i4) H2 (s) := 1 / (1 + s/omega0)$

          (%i5) bode_gain (H2 (s), [w, 1/1000, 1000]), omega0 = 10$

          (%i6) H3 (s) := 1 / (1 + s/omega0)^2$

          (%i7) bode_gain (H3 (s), [w, 1/1000, 1000]), omega0 = 10$

          (%i8) H4 (s) := 1 + s/omega0$

          (%i9) bode_gain (H4 (s), [w, 1/1000, 1000]), omega0 = 10$

          (%i10) H5 (s) := 1/s$

          (%i11) bode_gain (H5 (s), [w, 1/1000, 1000])$

          (%i12) H6 (s) := 1/((s/omega0)^2 + 2 * zeta * (s/omega0) + 1)$

          (%i13) bode_gain (H6 (s), [w, 1/1000, 1000]),
                            omega0 = 10, zeta = 1/10$

          (%i14) H7 (s) := (s/omega0)^2 + 2 * zeta * (s/omega0) + 1$

          (%i15) bode_gain (H7 (s), [w, 1/1000, 1000]),
                            omega0 = 10, zeta = 1/10$

          (%i16) H8 (s) := 0.5 / (0.0001 * s^3 + 0.002 * s^2 + 0.01 * s)$

          (%i17) bode_gain (H8 (s), [w, 1/1000, 1000])$

     Antes de hacer uso de esta función ejecútese 'load("bode")'.  Véase
     también 'bode_phase'.

 -- Función: bode_phase (<H>, <range>, ...<plot_opts>...)
     Función para dibujar el gráfico de fase de Bode.

     Ejemplos (1 a 7 de
          <http://www.swarthmore.edu/NatSci/echeeve1/Ref/Bode/BodeHow.html>,
     8 de Ron Crummett):
          (%i1) load("bode")$

          (%i2) H1 (s) := 100 * (1 + s) / ((s + 10) * (s + 100))$

          (%i3) bode_phase (H1 (s), [w, 1/1000, 1000])$

          (%i4) H2 (s) := 1 / (1 + s/omega0)$

          (%i5) bode_phase (H2 (s), [w, 1/1000, 1000]), omega0 = 10$

          (%i6) H3 (s) := 1 / (1 + s/omega0)^2$

          (%i7) bode_phase (H3 (s), [w, 1/1000, 1000]), omega0 = 10$

          (%i8) H4 (s) := 1 + s/omega0$

          (%i9) bode_phase (H4 (s), [w, 1/1000, 1000]), omega0 = 10$

          (%i10) H5 (s) := 1/s$

          (%i11) bode_phase (H5 (s), [w, 1/1000, 1000])$

          (%i12) H6 (s) := 1/((s/omega0)^2 + 2 * zeta * (s/omega0) + 1)$

          (%i13) bode_phase (H6 (s), [w, 1/1000, 1000]),
                             omega0 = 10, zeta = 1/10$

          (%i14) H7 (s) := (s/omega0)^2 + 2 * zeta * (s/omega0) + 1$

          (%i15) bode_phase (H7 (s), [w, 1/1000, 1000]),
                             omega0 = 10, zeta = 1/10$

          (%i16) H8 (s) := 0.5 / (0.0001 * s^3 + 0.002 * s^2 + 0.01 * s)$

          (%i17) bode_phase (H8 (s), [w, 1/1000, 1000])$

          (%i18) block ([bode_phase_unwrap : false],
                        bode_phase (H8 (s), [w, 1/1000, 1000]));

          (%i19) block ([bode_phase_unwrap : true],
                        bode_phase (H8 (s), [w, 1/1000, 1000]));

     Antes de hacer uso de esta función ejecútese 'load("bode")'.  Véase
     también 'bode_gain'.


File: maxima.info,  Node: cobyla,  Next: contrib_ode,  Prev: bode,  Up: Top

42 cobyla
*********

* Menu:

* Introducción a cobyla::
* Funciones y variables para cobyla::
* Ejemplos para cobyla::  


File: maxima.info,  Node: Introducción a cobyla,  Next: Funciones y variables para cobyla,  Prev: cobyla,  Up: cobyla

42.1 Introducción a cobyla
==========================

'fmin_cobyla' es una traducción a Common Lisp hecha con el programa
'f2cl' de la rutina Fortran COBYLA, (Powell, [1][2][3]), para
optimización con restricciones.

COBYLA minimiza una función objetivo F(X) sujeta a M restricciones con
desigualdades de la forma g(X) >= 0 sobre X, siendo X un vector de
variables de N componentes.

Las restricciones en forma de igualdades se pueden implementar por pares
de desigualdades de la forma g(X)>=0 y -g(X)>= 0.  El interfaz Maxima
para COBYLA admite restricciones de igualdad, transformándolas luego
internamente a pares de desigualdades.

El algoritmo hace uso de aproximaciones lineales, tanto de la función
objetivo como de las funciones de restricción; tales aproximaciones se
hacen mediante interpolación lineal de N+1 puntos en el espacio de
variables.  Los puntos de interpolación se consideran vértices de un
simplejo o símplex.  El parámetro RHO controla el tamaño del simplejo y
se reduce automáticamente de RHOBEG a RHOEND. Para cada RHO la subrutina
intenta alcanzar un buen vector de variables para el tamaño actual,
reduciéndose entonces RHO hasta alcanzar el valor de RHOEND. Por eso,
tanto a RHOBEG como a RHOEND se les deben asignar valores razonables, lo
que requiere cierto trabajo empírico previo.  La rutina trata cada
restricción individualmente cuando se calcula un en las variables.  El
nombre de la rutina se deriva de la frase Constrained Optimization BY
Linear Approximations.

Referecias:

[1] Código Fortran procede de
<http://plato.asu.edu/sub/nlores.html#general>

[2] M. J. D. Powell, "A direct search optimization method that models
the objective and constraint functions by linear interpolation," en
Advances in Optimization and Numerical Analysis, eds.  S. Gomez and
J.-P. Hennart (Kluwer Academic: Dordrecht, 1994), p.  51-67.

[3] M. J. D. Powell, "Direct search algorithms for optimization
calculations," Acta Numerica 7, 287-336 (1998).  Also available as
University of Cambridge, Department of Applied Mathematics and
Theoretical Physics, Numerical Analysis Group, Report NA1998/04 from
<http://www.damtp.cam.ac.uk/user/na/reports.html>


File: maxima.info,  Node: Funciones y variables para cobyla,  Next: Ejemplos para cobyla,  Prev: Introducción a cobyla,  Up: cobyla

42.2 Funciones y variables para cobyla
======================================

 -- Función: fmin_cobyla (<F>, <X>, <Y>)
 -- Función: fmin_cobyla (<F>, <X>, <Y>, optional_args)

     Devuelve una aproximación del valor mínimo de la expresión <F>
     respecto de las variables <X>, sujeta a un conjunto opcional de
     restricciones.  <Y> es una lista que contiene una solución semilla
     inicial en <X>.

     <F> debe ser una expresión ordinaria, no valen nombres de funciones
     ni expresiones lambda.

     'optional_args' hace referencia a argumentos adicionales, que se
     especifican de la forma '<symbol> = <value>'.  Los argumentos
     opcionales que se reconocen son:

     'constraints'
          Lista de restricciones en forma de desigualdades e igualdades
          que debe satisfacer <X>.  Las desigualdades deben ser de la
          forma 'g(<X>) >= h(<X>)' o 'g(<X>) <= h(<X>)'.  Las
          restricciones de igualdad deben ser de la forma 'g(<X>) =
          h(<X>)'.
     'rhobeg'
          Valor inicial de la variable interna RHO, que controla el
          tamaño del simplejo.  Su valor por defecto es 1.0.
     'rhoend'
          El valor final deseado para el parámetro RHO. Es
          aproximadamente la precisión de las variables.  Su valor por
          defecto es 1d-6.
     'iprint'
          Nivel de información de salida.  Su valor por defecto es 0.
             * 0 - Sin información de salida
             * 1 - Sumario al final de los cálculos
             * 2 - Se van mostrando los nuevos valores de RHO y SIGMA,
               incluyendo el vector de variables.
             * 3 - Como en 2, pero la información se muestra cuando se
               calcula F(X).
     'maxfun'
          Número máximo de evaluaciones de la función.  Su valor por
          defecto es 1000.

     El resultado devuelto es un vector:
       1. Los valores de las variables con las que se alcanza el valor
          mínimo.  Es una lista de elementos de la forma '<var> =
          <value>' para cada una de las variables listadas en <X>.
       2. El valor mínimo de la función objetivo.
       3. El número de evaluaciones de la función.
       4. Código de retorno con los siguientes significados:
            1. 0 - No ha habido errores.
            2. 1 - Alcanzado el máximo número permitido de evaluaciones
               de la función.
            3. 2 - Errores de redondeo han impedido el avance del
               proceso.

     El código 'load(fmin_cobyla)' carga en memoria esta función..

 -- Función: bf_fmin_cobyla (<F>, <X>, <Y>)
 -- Función: bf_fmin_cobyla (<F>, <X>, <Y>, optional_args)

     Esta función es idéntica a 'fmin_cobyla', excepto por el hecho de
     que utiliza aritmética de precisión arbitraria (bigfloat) y que el
     valor por defecto de <rhoend> es '10^(fpprec/2)'.

     Véase 'fmin_cobyla'.

     El código 'load(fmin_cobyla)' carga en memoria esta función..


File: maxima.info,  Node: Ejemplos para cobyla,  Prev: Funciones y variables para cobyla,  Up: cobyla

42.3 Ejemplos para cobyla
=========================

Minimizar x1*x2 bajo la condición 1-x1^2-x2^2 >= 0.  La solución teórica
es x1 = 1/sqrt(2), x2 = -1/sqrt(2).

     (%i1) load(fmin_cobyla)$

     (%i2) fmin_cobyla(x1*x2, [x1, x2], [1,1], constraints = [x1^2+x2^2<=1], iprint=1);

        Normal return from subroutine COBYLA

        NFVALS =   66   F =-5.000000E-01    MAXCV = 1.999845E-12
        X = 7.071058E-01  -7.071077E-01
     (%o2) [[x1 = 0.70710584934848, x2 = - 0.7071077130248], - 0.49999999999926,
            [[-1.999955756559757e-12],[]], 66]

Hay más ejemplos en el directorio 'share/cobyla/ex'.


File: maxima.info,  Node: contrib_ode,  Next: descriptive,  Prev: cobyla,  Up: Top

43 contrib_ode
**************

* Menu:

* Introducción a contrib_ode::
* Funciones y variables para contrib_ode::
* Posibles mejoras a contrib_ode::
* Pruebas realizadas con contrib_ode::
* Referencias para contrib_ode::


File: maxima.info,  Node: Introducción a contrib_ode,  Next: Funciones y variables para contrib_ode,  Prev: contrib_ode,  Up: contrib_ode

43.1 Introducción a contrib_ode
===============================

La función 'ode2' de Maxima resuelve ecuaciones diferenciales ordinarias
(EDO) simples de primer y segundo orden.  La función 'contrib_ode'
extiende las posibilidades de 'ode2' con métodos adicionales para ODEs
lineales y no lineales de primer orden y homogéneas lineales de segundo
orden.  El código se encuentra en estado de desarrollo y la syntaxis
puede cambiar en futuras versiones.  Una vez el código se haya
estabilizado podrá pasar a integrarse dentro de Maxima.

El paquete debe cargarse con la instrucción 'load('contrib_ode)' antes
de utilizarlo.

La sintaxis de 'contrib_ode' es similar a la de 'ode2'.  Necesita tres
argumentos: una EDO (sólo se necesita el miembro izquierdo si el derecho
es igual cero), la variable dependiente y la independiente.  Si
encuentra la solución, devolverá una lista de resultados.

La forma de los resultados devueltos es diferente de la utilizada por
'ode2'.  Puesto que las ecuaciones no lineales pueden tener múltiples
soluciones, 'contrib_ode' devuelve una lista de soluciones.  Las
soluciones pueden tener diferentes formatos:
   * una función explícita para la variable dependiente,

   * una función implícita para la variable dependiente,

   * una solución paramétrica en términos de la variable '%t' o

   * una transformación en otra EDO de variable '%u'.

'%c' hace referencia a la constante de integración en las ecuaciones de
primer orden.  '%k1' y '%k2' son las constantes para las ecuaciones de
segundo orden.  Si por cualquier razón contrib_ode no pudiese encontrar
una solución, devolverá 'false', quizás después de mostrar un mensaje de
error.

Ejemplos:

En ocasiones es necesario devolver una lista de soluciones, pues algunas
EDOs pueden tener múltiples soluciones:

     (%i1) load('contrib_ode)$

     (%i2) eqn:x*'diff(y,x)^2-(1+x*y)*'diff(y,x)+y=0;

                         dy 2             dy
     (%o2)            x (--)  - (x y + 1) -- + y = 0
                         dx               dx
     (%i3) contrib_ode(eqn,y,x);

                                                  x
     (%o3)             [y = log(x) + %c, y = %c %e ]
     (%i4) method;

     (%o4)                        factor

Las EDOs no lineales pueden tener soluciones singulares sin constantes
de integración, como en la segunda solución del ejemplo siguiente:

     (%i1) load('contrib_ode)$

     (%i2) eqn:'diff(y,x)^2+x*'diff(y,x)-y=0;

                            dy 2     dy
     (%o2)                 (--)  + x -- - y = 0
                            dx       dx
     (%i3) contrib_ode(eqn,y,x);

                                                2
                                      2        x
     (%o3)              [y = %c x + %c , y = - --]
                                               4
     (%i4) method;

     (%o4)                       clairault

La siguiente ODE tiene dos soluciones paramétricas en términos de la
variable '%t'.  En este caso, las soluciones paramétricas se pueden
manipular para dar soluciones explícitas.

     (%i1) load('contrib_ode)$

     (%i2) eqn:'diff(y,x)=(x+y)^2;

                               dy          2
     (%o2)                     -- = (y + x)
                               dx
     (%i3) contrib_ode(eqn,y,x);

     (%o3) [[x = %c - atan(sqrt(%t)), y = - x - sqrt(%t)],
                          [x = atan(sqrt(%t)) + %c, y = sqrt(%t) - x]]
     (%i4) method;

     (%o4)                       lagrange

En el siguiente ejemplo (Kamke 1.112) se obtiene una solución implícita.

     (%i1) load('contrib_ode)$

     (%i2) assume(x>0,y>0);

     (%o2)                    [x > 0, y > 0]
     (%i3) eqn:x*'diff(y,x)-x*sqrt(y^2+x^2)-y;

                          dy           2    2
     (%o3)              x -- - x sqrt(y  + x ) - y
                          dx
     (%i4) contrib_ode(eqn,y,x);

                                       y
     (%o4)                  [x - asinh(-) = %c]
                                       x
     (%i5) method;

     (%o5)                          lie

La siguiente ecuación de Riccati se transforma en una EDO lineal de
segundo orden de variable '%u'.  Maxima es incapaz de resolver la nueva
EDO, por lo que la devuelve si resolver:

     (%i1) load('contrib_ode)$

     (%i2) eqn:x^2*'diff(y,x)=a+b*x^n+c*x^2*y^2;

                         2 dy      2  2      n
     (%o2)              x  -- = c x  y  + b x  + a
                           dx
     (%i3) contrib_ode(eqn,y,x);

                    d%u
                    ---                            2
                    dx        2     n - 2   a     d %u
     (%o3)  [[y = - ----, %u c  (b x      + --) + ---- c = 0]]
                    %u c                     2      2
                                            x     dx
     (%i4) method;

     (%o4)                        riccati

Para EDOs de primer orden, 'contrib_ode' llama a 'ode2'.  Entonces trata
de aplicar los siguientes métodos: factorización, Clairault, Lagrange,
Riccati, Abel y Lie.  El método de Lie no se intenta aplicar a las
ecuaciones de Abel si el propio método de Abel no obtiene solución, pero
sí se utiliza si el método de Riccati devuelve una EDO de segundo orden
sin resolver.

Para EDOs de segundo orden, 'contrib_ode' llama a 'ode2' y luego a
'odelin'.

Se mostrarán mensajes de depurado si se ejecuta la sentencia
'put('contrib_ode,true,'verbose)'.


File: maxima.info,  Node: Funciones y variables para contrib_ode,  Next: Posibles mejoras a contrib_ode,  Prev: Introducción a contrib_ode,  Up: contrib_ode

43.2 Funciones y variables para contrib_ode
===========================================

 -- Función: contrib_ode (<eqn>, <y>, <x>)

     Devuelve la lista de soluciones de la ecuación diferencia ordinaria
     (EDO) <eqn> de variable independiente <x> y variable dependiente
     <y>.

 -- Función: odelin (<eqn>, <y>, <x>)

     La función 'odelin' resulve EDOs homogéneas lineales de primer y
     segundo orden con variable independiente <x> y variable dependiente
     <y>.  Devuelve un conjunto fundamental de soluciones de la EDO.

     Para EDOs de segundo orden, 'odelin' utiliza un método desarrollado
     por Bronstein y Lafaille, que busca las soluciones en términos de
     funciones especiales dadas.

          (%i1) load('contrib_ode);

          (%i2) odelin(x*(x+1)*'diff(y,x,2)+(x+5)*'diff(y,x,1)+(-4)*y,y,x);
          ...trying factor method
          ...solving 7 equations in 4 variables
          ...trying the Bessel solver
          ...solving 1 equations in 2 variables
          ...trying the F01 solver
          ...solving 1 equations in 3 variables
          ...trying the spherodial wave solver
          ...solving 1 equations in 4 variables
          ...trying the square root Bessel solver
          ...solving 1 equations in 2 variables
          ...trying the 2F1 solver
          ...solving 9 equations in 5 variables
                 gauss_a(- 6, - 2, - 3, - x)  gauss_b(- 6, - 2, - 3, - x)
          (%o2) {---------------------------, ---------------------------}
                              4                            4
                             x                            x

 -- Función: ode_check (<eqn>, <soln>)

     Devuelve el valor de la ecuación diferencia ordinaria (EDO) <eqn>
     después de sustituir una posible solución <soln>.  El valor es cero
     si <soln> es una solución de <eqn>.

          (%i1) load('contrib_ode)$

          (%i2) eqn:'diff(y,x,2)+(a*x+b)*y;

                                   2
                                  d y
          (%o2)                   --- + (a x + b) y
                                    2
                                  dx
          (%i3) ans:[y = bessel_y(1/3,2*(a*x+b)^(3/2)/(3*a))*%k2*sqrt(a*x+b)
                   +bessel_j(1/3,2*(a*x+b)^(3/2)/(3*a))*%k1*sqrt(a*x+b)];

                                            3/2
                              1  2 (a x + b)
          (%o3) [y = bessel_y(-, --------------) %k2 sqrt(a x + b)
                              3       3 a
                                                    3/2
                                      1  2 (a x + b)
                           + bessel_j(-, --------------) %k1 sqrt(a x + b)]
                                      3       3 a
          (%i4) ode_check(eqn,ans[1]);

          (%o4)                           0

 -- Variable opcional: 'method'

     A la variable 'method' se le asigna el método aplicado.

 -- Variable: '%c'

     '%c' es la constante de integración para EDOs de primer orden.

 -- Variable: '%k1'

     '%k1' es la primera constante de integración para EDOs de segundo
     orden.

 -- Variable: '%k2'

     '%k2' es la segunda constante de integración para EDOs de segundo
     orden.

 -- Función: gauss_a (<a>, <b>, <c>, <x>)

     'gauss_a(a,b,c,x)' y 'gauss_b(a,b,c,x)' son funciones geométricas
     2F1 .  Representan dos soluciones independientes cualesquiera de la
     ecuación diferencial hipergeométrica 'x(1-x) diff(y,x,2) +
     [c-(a+b+1)x] diff(y,x) - aby = 0' (A&S 15.5.1).

     El único uso que se hace de estas funciones es en las soluciones de
     EDOs que devuelven 'odelin' y 'contrib_ode'.  La definición y
     utilización de estas funciones puede cambiar en futuras
     distribuciones de Maxima.

     Véanse también 'gauss_b', 'dgauss_a' y 'gauss_b'.

 -- Función: gauss_b (<a>, <b>, <c>, <x>)
     Véase también 'gauss_a'.

 -- Función: dgauss_a (<a>, <b>, <c>, <x>)
     The derivative with respect to x of 'gauss_a(a,b,c,x)'.

 -- Función: dgauss_b (<a>, <b>, <c>, <x>)
     Derivada de 'gauss_b(<a>,<b>,<c>,<x>)' respecto de <x>.

 -- Función: kummer_m (<a>, <b>, <x>)

     Función M de Kummer, tal como la definen Abramowitz y Stegun,
     Handbook of Mathematical Functions, Sección 13.1.2.

     El único uso que se hace de esta función es en las soluciones de
     EDOs que devuelven 'odelin' y 'contrib_ode'.  La definición y
     utilización de estas funciones puede cambiar en futuras
     distribuciones de Maxima.

     Véanse también 'kummer_u', 'dkummer_m' y 'dkummer_u'.

 -- Función: kummer_u (<a>, <b>, <x>)

     Función U de Kummer, tal como la definen Abramowitz y Stegun,
     Handbook of Mathematical Functions, Sección 13.1.3.

     Véase también 'kummer_m'.

 -- Función: dkummer_m (<a>, <b>, <x>)
     Derivada de 'kummer_m(<a>,<b>,<x>)' respecto de <x>.

 -- Función: dkummer_u (<a>, <b>, <x>)
     Derivada de 'kummer_u(<a>,<b>,<x>)' respecto de <x>.


File: maxima.info,  Node: Posibles mejoras a contrib_ode,  Next: Pruebas realizadas con contrib_ode,  Prev: Funciones y variables para contrib_ode,  Up: contrib_ode

43.3 Posibles mejoras a contrib_ode
===================================

Este paquete aún se encuentra en fase de desarrollo.  Aspectos
pendientes:

   * Extender el método FACTOR 'ode1_factor' para que trabaje con raíces
     múltiples.

   * Extender el método FACTOR 'ode1_factor' para que intente resolver
     factores de orden superior.  En este momento sólo intenta resolver
     factores lineales.

   * Modificar la rutina LAGRANGE 'ode1_lagrange' para que prefiera
     raíces reales a las complejas.

   * Añadir más métodos para las ecuaciones de RIccati.

   * Mejorar la identificación de las ecuaciones de Abel de segunda
     especie.  El procedimiento actual no es muy bueno.

   * Trabajar la rutina del grupo simétrico de Lie 'ode1_lie'.  Existen
     algunos problemas: algunas partes no están implementadas, algunos
     ejemplos no terminan de ejecutarse, otros producen errors, otros
     devuelven respuestas muy complejas.

   * Hacer más pruebas.


File: maxima.info,  Node: Pruebas realizadas con contrib_ode,  Next: Referencias para contrib_ode,  Prev: Posibles mejoras a contrib_ode,  Up: contrib_ode

43.4 Pruebas realizadas con contrib_ode
=======================================

Los procedimientos fueron probados con cerca de mil ecuaciones tomadas
de Murphy, Kamke, Zwillinger y otros.  Éstas se encuentran en el
directorio de pruebas.

   * La rutina de Clairault 'ode1_clairault' encuentra todas las
     soluciones conocidas, incluídas las singulares, de las ecuaciones
     de Clairault en Murphy y Kamke.

   * Las otras rutinas a veces devuelven una sola solución cuando
     existen más.

   * Algunas de las soluciones devueltas por 'ode1_lie' son demasiado
     complejas e imposibles de interpretar.

   * A veces se producen detenciones imprevistas del procedimiento.


File: maxima.info,  Node: Referencias para contrib_ode,  Prev: Pruebas realizadas con contrib_ode,  Up: contrib_ode

43.5 Referencias para contrib_ode
=================================

  1. E. Kamke, Differentialgleichungen Losungsmethoden und Losungen, Vol
     1, Geest & Portig, Leipzig, 1961

  2. G. M. Murphy, Ordinary Differential Equations and Their Solutions,
     Van Nostrand, New York, 1960

  3. D. Zwillinger, Handbook of Differential Equations, 3rd edition,
     Academic Press, 1998

  4. F. Schwarz, Symmetry Analysis of Abel's Equation, Studies in
     Applied Mathematics, 100:269-294 (1998)

  5. F. Schwarz, Algorithmic Solution of Abel's Equation, Computing 61,
     39-49 (1998)

  6. E. S. Cheb-Terrab, A. D. Roche, Symmetries and First Order ODE
     Patterns, Computer Physics Communications 113 (1998), p 239.
     (<http://lie.uwaterloo.ca/papers/ode_vii.pdf>)

  7. E. S. Cheb-Terrab, T. Kolokolnikov, First Order ODEs, Symmetries
     and Linear Transformations, European Journal of Applied
     Mathematics, Vol.  14, No.  2, pp.  231-246 (2003).
     (<http://arxiv.org/abs/math-ph/0007023>,
     <http://lie.uwaterloo.ca/papers/ode_iv.pdf>)

  8. G. W. Bluman, S. C. Anco, Symmetry and Integration Methods for
     Differential Equations, Springer, (2002)

  9. M Bronstein, S Lafaille, Solutions of linear ordinary differential
     equations in terms of special functions, Proceedings of ISSAC 2002,
     Lille, ACM Press, 23-28.
     (<http://www-sop.inria.fr/cafe/Manuel.Bronstein/publications/issac2002.pdf>)


File: maxima.info,  Node: descriptive,  Next: diag,  Prev: contrib_ode,  Up: Top

44 descriptive
**************

* Menu:

* Introducción a descriptive::
* Funciones y variables para el tratamiento de datos::
* Funciones y variables de parámetros descriptivos::
* Funciones y variables para gráficos estadísticos::


File: maxima.info,  Node: Introducción a descriptive,  Next: Funciones y variables para el tratamiento de datos,  Prev: descriptive,  Up: descriptive

44.1 Introducción a descriptive
===============================

El paquete 'descriptive' contiene funciones para realizar cl'culos y
gráficos estadísticos descriptivos.  Junto con el código fuente se
distribuyen tres conjuntos de datos: 'pidigits.data', 'wind.data' y
'biomed.data'.

Cualquier manual de estadística se puede utilizar como referencia al
paquete 'descriptive'.

Para comentarios, fallos y sugerencias, por favor contactar con
<'riotorto AT yahoo DOT com'>.

Aquí un sencillo ejemplo sobre cómo operan las funciones de
'descriptive', dependiendo de la naturaleza de sus argumentos, listas o
matrices,

     (%i1) load (descriptive)$
     (%i2) /* muestra univariate */   mean ([a, b, c]);
                                 c + b + a
     (%o2)                       ---------
                                     3
     (%i3) matrix ([a, b], [c, d], [e, f]);
                                 [ a  b ]
                                 [      ]
     (%o3)                       [ c  d ]
                                 [      ]
                                 [ e  f ]
     (%i4) /* muestra multivariante */ mean (%);
                           e + c + a  f + d + b
     (%o4)                [---------, ---------]
                               3          3

Nótese que en las muestras multivariantes la media se calcula para cada
columna.

En caso de varias muestras de diferente tamaño, la función 'map' de
Maxima puede utilizarse para obtener los resultados deseados para cada
muestra,

     (%i1) load (descriptive)$
     (%i2) map (mean, [[a, b, c], [d, e]]);
                             c + b + a  e + d
     (%o2)                  [---------, -----]
                                 3        2

En este caso, dos muestras de tamaños 3 y 2 han sido almacenadas en una
lista.

Muestras univariantes deben guardarse en listas como en

     (%i1) s1 : [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
     (%o1)           [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]

y muestras multivariantes en matrices como las del siguiente ejemplo

     (%i1) s2 : matrix ([13.17, 9.29], [14.71, 16.88], [18.50, 16.88],
                  [10.58, 6.63], [13.33, 13.25], [13.21,  8.12]);
                             [ 13.17  9.29  ]
                             [              ]
                             [ 14.71  16.88 ]
                             [              ]
                             [ 18.5   16.88 ]
     (%o1)                   [              ]
                             [ 10.58  6.63  ]
                             [              ]
                             [ 13.33  13.25 ]
                             [              ]
                             [ 13.21  8.12  ]

En este caso, el número de columnas es igual al de la dimensión de la
variable aleatoria y el número de filas coincide con el tamaño muestral.

Los datos pueden suministrarse manualmente, pero las muestras grandes se
suelen almacenar en ficheros de texto.  Por ejemplo, el fichero
'pidigits.data' contiene los 100 primeros dígitos del número '%pi':
           3
           1
           4
           1
           5
           9
           2
           6
           5
           3 ...

A fin de leer estos dígitos desde Maxima,

     (%i1) s1 : read_list (file_search ("pidigits.data"))$
     (%i2) length (s1);
     (%o2)                          100

Por otro lado, el archivo 'wind.data' contiene los promedios diarios de
la velocidad del viento en cinco estaciones meteorológicas en Irlanda
(esta muestra es parte de un conjunto de datos correspondientes a 12
estaciones meteorológicas.  El fichero original se puede descargar
libremente del 'StatLib Data Repository' y se analiza en Haslett, J.,
Raftery, A. E. (1989) <Space-time Modelling with Long-memory Dependence:
Assessing Ireland's Wind Power Resource, with Discussion>.  Applied
Statistics 38, 1-50).  Así se leen los datos:

     (%i1) s2 : read_matrix (file_search ("wind.data"))$
     (%i2) length (s2);
     (%o2)                          100
     (%i3) s2 [%]; /* last record */
     (%o3)            [3.58, 6.0, 4.58, 7.62, 11.25]

Algunas muestras contienen datos no numéricos.  Como ejemplo, el archivo
'biomed.data' (el cual es parte de otro mayor descargado también del
'StatLib Data Repository') contiene cuatro mediciones sanguíneas tomadas
a dos grupos de pacientes, 'A' y 'B', de diferentes edades,

     (%i1) s3 : read_matrix (file_search ("biomed.data"))$
     (%i2) length (s3);
     (%o2)                          100
     (%i3) s3 [1]; /* first record */
     (%o3)            [A, 30, 167.0, 89.0, 25.6, 364]

El primer individuo pertenece al grupo 'A', tiene 30 años de edad y sus
medidas sanguíneas fueron 167.0, 89.0, 25.6 y 364.

Debe tenerse cuidado cuando se trabaje con datos categóricos.  En el
siguiente ejemplo, se asigna al símbolo 'a' cierto valor en algún
momento previo y luego se toma una muestra con el valor categórico 'a',

     (%i1) a : 1$
     (%i2) matrix ([a, 3], [b, 5]);
                                 [ 1  3 ]
     (%o2)                       [      ]
                                 [ b  5 ]


File: maxima.info,  Node: Funciones y variables para el tratamiento de datos,  Next: Funciones y variables de parámetros descriptivos,  Prev: Introducción a descriptive,  Up: descriptive

44.2 Funciones y variables para el tratamiento de datos
=======================================================

 -- Función: build_sample (<list>)
 -- Función: build_sample (<matrix>)
     Construye una muestra a partir de una tabla de frecuencias
     absolutas.  La tabla de entrada puede ser una una matriz o una
     lista de listas, todas ellas de igual tamaño.  El número de
     columnas o la longitud de las listas debe ser mayor que la unidad.
     El último elemento de cada fila o lista se interpreta como la
     frecuencia absoluta.  El resultado se devuelve siempre en formato
     de matriz.

     Ejemplos:

     Tabla de frecuencias univariante.

          (%i1) load (descriptive)$
          (%i2) sam1: build_sample([[6,1], [j,2], [2,1]]);
                                 [ 6 ]
                                 [   ]
                                 [ j ]
          (%o2)                  [   ]
                                 [ j ]
                                 [   ]
                                 [ 2 ]
          (%i3) mean(sam1);
                                2 j + 8
          (%o3)                [-------]
                                   4
          (%i4) barsplot(sam1) $

     Tabla de frecuencias multivariante.

          (%i1) load (descriptive)$
          (%i2) sam2: build_sample([[6,3,1], [5,6,2], [u,2,1],[6,8,2]]) ;
                                     [ 6  3 ]
                                     [      ]
                                     [ 5  6 ]
                                     [      ]
                                     [ 5  6 ]
          (%o2)                      [      ]
                                     [ u  2 ]
                                     [      ]
                                     [ 6  8 ]
                                     [      ]
                                     [ 6  8 ]
          (%i3) cov(sam2);
                 [   2                 2                            ]
                 [  u  + 158   (u + 28)     2 u + 174   11 (u + 28) ]
                 [  -------- - ---------    --------- - ----------- ]
          (%o3)  [     6          36            6           12      ]
                 [                                                  ]
                 [ 2 u + 174   11 (u + 28)            21            ]
                 [ --------- - -----------            --            ]
                 [     6           12                 4             ]
          (%i4) barsplot(sam2, grouping=stacked) $

 -- Función: continuous_freq (<list>)
 -- Función: continuous_freq (<list>, <m>)
     El argumento de 'continuous_freq' debe ser una lista de números.
     Divide el rango en intervalos y cuenta cuántos valores hay en
     ellos.  El segundo argumento es opcional y puede ser el número de
     clases deseado, 10 por defecto, o una lista que contenga los
     límites de las clases y el número de éstas, o una lista que
     contenga únicamente los límites.  Si los valores muestrales son
     todos iguales, esta función devuelve solamente una clase de
     amplitud 2.

     Ejemplos:

     El argumento opcional indica el número de clases deseadas.  La
     primera lista de la respuesta contiene los límites de los
     intervalos y la segunda los totales correspondientes: hay 16
     dígitos en el intervalo '[0, 1.8]', 24 en '(1.8, 3.6]' y así
     sucesivamente.

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) continuous_freq (s1, 5);
          (%o3) [[0, 1.8, 3.6, 5.4, 7.2, 9.0], [16, 24, 18, 17, 25]]

     El argumento opcional indica que queremos 7 clases con límites -2 y
     12:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) continuous_freq (s1, [-2,12,7]);
          (%o3) [[- 2, 0, 2, 4, 6, 8, 10, 12], [8, 20, 22, 17, 20, 13, 0]]

     El argumento opcional indica que queremos el número por defecto de
     clases y límites -2 y 12:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) continuous_freq (s1, [-2,12]);
                          3  4  11  18     32  39  46  53
          (%o3)  [[- 2, - -, -, --, --, 5, --, --, --, --, 12],
                          5  5  5   5      5   5   5   5
                         [0, 8, 20, 12, 18, 9, 8, 25, 0, 0]]

 -- Función: discrete_freq (<list>)
     Calcula las frecuencias absolutas en muestras discretas, tanto
     numéricas como categóricas.  Su único argumento debe ser una lista.

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) discrete_freq (s1);
          (%o3) [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
                                       [8, 8, 12, 12, 10, 8, 9, 8, 12, 13]]

     La primera lista son los valores de la muestra y la segunda sus
     frecuencias absolutas.  Las instrucciones '? col' y '? transpose'
     pueden ayudar a comprender la última entrada.

 -- Función: standardize (<list>)
 -- Función: standardize (<matrix>)

     Resta a cada elemento de la lista la media muestral y luego divide
     el resultado por la desviación típica.  Si la entrada es una
     matriz, 'standardize' resta a cada fila la media multivariante y
     luego divide cada componente por la desviación típica
     correspondiente.

 -- Función: subsample (<data_matrix>, <predicate_function>)
 -- Función: subsample (<data_matrix>, <predicate_function>, <col_num>,
          <col_num>, ...)
     Esta es una variante de la función 'submatrix' de Maxima.  El
     primer argumento es una matriz de datos, el segundo es una función
     de predicado y el resto de argumentos opcionales son los números de
     las columnas a tomar en consideración.

     Estos son los registros multivariantes en los que la velocidad del
     viento en la primera estación meteorológica fue menor de 18 nudos.
     Véase cómo en la expresión lambda la <i>-ésima componente se la
     referencia como 'v[i]'.
          (%i1) load (descriptive)$
          (%i2) s2 : read_matrix (file_search ("wind.data"))$
          (%i3) subsample (s2, lambda([v], v[1] > 18));
                        [ 19.38  15.37  15.12  23.09  25.25 ]
                        [                                   ]
                        [ 18.29  18.66  19.08  26.08  27.63 ]
          (%o3)         [                                   ]
                        [ 20.25  21.46  19.95  27.71  23.38 ]
                        [                                   ]
                        [ 18.79  18.96  14.46  26.38  21.84 ]

     En el siguiente ejemplo, se solicitan únicamente la primera,
     segunda y quinta componentes de aquellos registros con velocidades
     del viento mayores o iguales que 16 nudos en la estación número 1 y
     menores que 25 nudos en la estación número 4.  La muestra sólo
     contiene los datos referidos a las estaciones 1, 2 y 5.  En este
     caso, la función de predicado se define por medio de una función de
     Maxima ordinaria.
          (%i1) load (descriptive)$
          (%i2) s2 : read_matrix (file_search ("wind.data"))$
          (%i3) g(x):= x[1] >= 16 and x[4] < 25$
          (%i4) subsample (s2, g, 1, 2, 5);
                               [ 19.38  15.37  25.25 ]
                               [                     ]
                               [ 17.33  14.67  19.58 ]
          (%o4)                [                     ]
                               [ 16.92  13.21  21.21 ]
                               [                     ]
                               [ 17.25  18.46  23.87 ]

     He aquí un ejemplo con las variables categóricas de 'biomed.data'.
     Se piden los registros correspondientes a aquellos pacientes del
     grupo 'B' mayores de 38 anños,
          (%i1) load (descriptive)$
          (%i2) s3 : read_matrix (file_search ("biomed.data"))$
          (%i3) h(u):= u[1] = B and u[2] > 38 $
          (%i4) subsample (s3, h);
                          [ B  39  28.0  102.3  17.1  146 ]
                          [                               ]
                          [ B  39  21.0  92.4   10.3  197 ]
                          [                               ]
                          [ B  39  23.0  111.5  10.0  133 ]
                          [                               ]
                          [ B  39  26.0  92.6   12.3  196 ]
          (%o4)           [                               ]
                          [ B  39  25.0  98.7   10.0  174 ]
                          [                               ]
                          [ B  39  21.0  93.2   5.9   181 ]
                          [                               ]
                          [ B  39  18.0  95.0   11.3  66  ]
                          [                               ]
                          [ B  39  39.0  88.5   7.6   168 ]

     Es probable que el análisis estadístico requiera únicamente de las
     medidas sanguíneas.
          (%i1) load (descriptive)$
          (%i2) s3 : read_matrix (file_search ("biomed.data"))$
          (%i3) subsample (s3, lambda([v], v[1] = B and v[2] > 38),
                     3, 4, 5, 6);
                             [ 28.0  102.3  17.1  146 ]
                             [                        ]
                             [ 21.0  92.4   10.3  197 ]
                             [                        ]
                             [ 23.0  111.5  10.0  133 ]
                             [                        ]
                             [ 26.0  92.6   12.3  196 ]
          (%o3)              [                        ]
                             [ 25.0  98.7   10.0  174 ]
                             [                        ]
                             [ 21.0  93.2   5.9   181 ]
                             [                        ]
                             [ 18.0  95.0   11.3  66  ]
                             [                        ]
                             [ 39.0  88.5   7.6   168 ]

     Esta es la media multivariante de 's3'.
          (%i1) load (descriptive)$
          (%i2) s3 : read_matrix (file_search ("biomed.data"))$
          (%i3) mean (s3);
                 65 B + 35 A  317          6 NA + 8145.0
          (%o3) [-----------, ---, 87.178, -------------, 18.123,
                     100      10                100
                                                              3 NA + 19587
                                                              ------------]
                                                                  100

     Aquí la primera componente carece de significado, ya que tanto 'A'
     como 'B' son categóricas, la segunda componente es la edad media de
     los individuos en forma racional, al tiempo que los valores cuarto
     y quinto muestran cierto comportamiento extraño; lo cual se debe a
     que el símbolo 'NA' se utiliza para indicar datos no disponibles,
     por lo que ambas medias no tienen sentido.  Una posible solución
     puede ser extraer de la matriz aquellas filas con símbolos 'NA', lo
     que acarrearía cierta pérdida de información.
          (%i1) load (descriptive)$
          (%i2) s3 : read_matrix (file_search ("biomed.data"))$
          (%i3) g(v):= v[4] # NA and v[6] # NA $
          (%i4) mean (subsample (s3, g, 3, 4, 5, 6));
          (%o4) [79.4923076923077, 86.2032967032967, 16.93186813186813,
                                                                      2514
                                                                      ----]
                                                                       13

 -- Función: transform_sample (<matriz>, <varlist>, <exprlist>)

     Transforma la <matriz> de datos, en la que a cada columna se le
     asigna un nombre de acuerdo con la lista <varlist>, según las
     expresiones de <exprlist>.

     Ejemplos:

     El segundo argumento asigna nombres a las tres columnas, con ellos
     la lista de expresiones define la transformación de la muestra.

          (%i1) load (descriptive)$
          (%i2) data: matrix([3,2,7],[3,7,2],[8,2,4],[5,2,4]) $
          (%i3) transform_sample(data, [a,b,c], [c, a*b, log(a)]);
                                         [ 7  6   log(3) ]
                                         [               ]
                                         [ 2  21  log(3) ]
          (%o3)                          [               ]
                                         [ 4  16  log(8) ]
                                         [               ]
                                         [ 4  10  log(5) ]

     Añade una columna constante y elimina la tercera variable.

          (%i1) load (descriptive)$
          (%i2) data: matrix([3,2,7],[3,7,2],[8,2,4],[5,2,4]) $
          (%i3) transform_sample(data, [a,b,c], [makelist(1,k,length(data)),a,b]);
                                            [ 1  3  2 ]
                                            [         ]
                                            [ 1  3  7 ]
          (%o3)                             [         ]
                                            [ 1  8  2 ]
                                            [         ]
                                            [ 1  5  2 ]


File: maxima.info,  Node: Funciones y variables de parámetros descriptivos,  Next: Funciones y variables para gráficos estadísticos,  Prev: Funciones y variables para el tratamiento de datos,  Up: descriptive

44.3 Funciones y variables de parámetros descriptivos
=====================================================

 -- Función: mean (<list>)
 -- Función: mean (<matrix>)
     Es la media muestral, definida como
                                 n
                               ====
                       _   1   \
                       x = -    >    x
                           n   /      i
                               ====
                               i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) mean (s1);
                                         471
          (%o3)                          ---
                                         100
          (%i4) %, numer;
          (%o4)                         4.71
          (%i5) s2 : read_matrix (file_search ("wind.data"))$
          (%i6) mean (s2);
          (%o6)     [9.9485, 10.1607, 10.8685, 15.7166, 14.8441]

 -- Función: var (<list>)
 -- Función: var (<matrix>)
     Es la varianza muestral, definida como
                               n
                             ====
                     2   1   \          _ 2
                    s  = -    >    (x - x)
                         n   /       i
                             ====
                             i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) var (s1), numer;
          (%o3)                   8.425899999999999

     Véase también 'var1'.

 -- Función: var1 (<list>)
 -- Función: var1 (<matrix>)
     Es la cuasivarianza muestral, definida como
                               n
                             ====
                         1   \          _ 2
                        ---   >    (x - x)
                        n-1  /       i
                             ====
                             i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) var1 (s1), numer;
          (%o3)                    8.5110101010101
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) var1 (s2);
          (%o5) [17.39586540404041, 15.13912778787879, 15.63204924242424,
                                      32.50152569696971, 24.66977392929294]

     Véase también 'var'.

 -- Función: std (<list>)
 -- Función: std (<matrix>)
     Es la desviación típica muestral, raíz cuadrada de 'var'.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) std (s1), numer;
          (%o3)                   2.902740084816414
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) std (s2);
          (%o5) [4.149928523480858, 3.871399812729241, 3.933920277534866,
                                      5.672434260526957, 4.941970881136392]

     Véanse también 'var' y 'std1'.

 -- Función: std1 (<list>)
 -- Función: std1 (<matrix>)
     Es la cuasidesviación típica muestral, raíz cuadrada de 'var1'.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) std1 (s1), numer;
          (%o3)                   2.917363553109228
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) std1 (s2);
          (%o5) [4.17083509672109, 3.89090320978032, 3.953738641137555,
                                      5.701010936401517, 4.966867617451963]

     Véanse también 'var1' y 'std'.

 -- Función: noncentral_moment (<list>, <k>)
 -- Función: noncentral_moment (<matrix>, <k>)
     Es el momento no central de orden k, definido como
                                 n
                               ====
                           1   \      k
                           -    >    x
                           n   /      i
                               ====
                               i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) noncentral_moment (s1, 1), numer; /* the mean */
          (%o3)                         4.71
          (%i5) s2 : read_matrix (file_search ("wind.data"))$
          (%o5) [319793.8724761506, 320532.1923892463, 391249.5621381556,
                                      2502278.205988911, 1691881.797742255]
          (%i6) noncentral_moment (s2, 5);

     Véase también 'central_moment'.

 -- Función: central_moment (<list>, <k>)
 -- Función: central_moment (<matrix>, <k>)
     Es el momento central de orden k, definido como
                              n
                            ====
                        1   \          _ k
                        -    >    (x - x)
                        n   /       i
                            ====
                            i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) central_moment (s1, 2), numer; /* the variance */
          (%o3)                   8.425899999999999
          (%i5) s2 : read_matrix (file_search ("wind.data"))$
          (%o5) [11.29584771375004, 16.97988248298583, 5.626661952750102,
                                       37.5986572057918, 25.85981904394192]
          (%i6) central_moment (s2, 3);

     Véanse también 'central_moment' y 'mean'.

 -- Función: cv (<list>)
 -- Función: cv (<matrix>)
     Es el coeficiente de variación, o cociente entre la desviación
     típica muestral ('std') y la media ('mean'),

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) cv (s1), numer;
          (%o3)                   .6193977819764815
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) cv (s2);
          (%o5) [.4192426091090204, .3829365309260502, 0.363779605385983,
                                      .3627381836021478, .3346021393989506]

     Véanse también 'std' y 'mean'.

 -- Función: smin (<list>)
 -- Función: smin (<matrix>)
     Es el valor mínimo de la muestra <list>.  Cuando el argumento es
     una matriz, 'smin' devuelve una lista con los valores mínimos de
     las columnas, las cuales están asociadas a variables estadísticas.

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) smin (s1);
          (%o3)                           0
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) smin (s2);
          (%o5)             [0.58, 0.5, 2.67, 5.25, 5.17]

     Véase también 'smax'.

 -- Función: smax (<list>)
 -- Función: smax (<matrix>)
     Es el valor máximo de la muestra <list>.  Cuando el argumento es
     una matriz, 'smax' devuelve una lista con los valores máximos de
     las columnas, las cuales están asociadas a variables estadísticas.

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) smax (s1);
          (%o3)                           9
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) smax (s2);
          (%o5)          [20.25, 21.46, 20.04, 29.63, 27.63]

     Véase también 'smin'.

 -- Función: range (<list>)
 -- Función: range (<matrix>)
     Es la diferencia entre los valores extremos.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) range (s1);
          (%o3)                           9
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) range (s2);
          (%o5)          [19.67, 20.96, 17.37, 24.38, 22.46]

 -- Función: quantile (<list>, <p>)
 -- Función: quantile (<matrix>, <p>)
     Es el <p>-cuantil, siendo <p> un número del intervalo [0, 1], de la
     muestra <list>.  Aunque existen varias definiciones para el cuantil
     muestral (Hyndman, R. J., Fan, Y. (1996) <Sample quantiles in
     statistical packages>.  American Statistician, 50, 361-365), la
     programada en el paquete 'descriptive' es la basada en la
     interpolación lineal.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) /* 1st and 3rd quartiles */
                   [quantile (s1, 1/4), quantile (s1, 3/4)], numer;
          (%o3)                      [2.0, 7.25]
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) quantile (s2, 1/4);
          (%o5)    [7.2575, 7.477500000000001, 7.82, 11.28, 11.48]

 -- Función: median (<list>)
 -- Función: median (<matrix>)
     Una vez ordenada una muestra, si el tamaño muestral es impar la
     mediana es el valor central, en caso contrario será la media de los
     dos valores centrales.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) median (s1);
                                          9
          (%o3)                           -
                                          2
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) median (s2);
          (%o5)         [10.06, 9.855, 10.73, 15.48, 14.105]

     La mediana es el cuantil 1/2.

     Véase también 'quantile'.

 -- Función: qrange (<list>)
 -- Función: qrange (<matrix>)
     El rango intercuartílico es la diferencia entre el tercer y primer
     cuartil, 'quantile(<list>,3/4) - quantile(<list>,1/4)',

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) qrange (s1);
                                         21
          (%o3)                          --
                                         4
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) qrange (s2);
          (%o5) [5.385, 5.572499999999998, 6.0225, 8.729999999999999,
                                                         6.650000000000002]

     Véase también 'quantile'.

 -- Función: mean_deviation (<list>)
 -- Función: mean_deviation (<matrix>)
     Es la desviación media, definida como
                               n
                             ====
                         1   \          _
                         -    >    |x - x|
                         n   /       i
                             ====
                             i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) mean_deviation (s1);
                                         51
          (%o3)                          --
                                         20
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) mean_deviation (s2);
          (%o5) [3.287959999999999, 3.075342, 3.23907, 4.715664000000001,
                                                         4.028546000000002]

     Véase también 'mean'.

 -- Función: median_deviation (<list>)
 -- Función: median_deviation (<matrix>)
     Es la desviación mediana, definida como
                           n
                         ====
                     1   \
                     -    >    |x - med|
                     n   /       i
                         ====
                         i = 1

     siendo 'med' la mediana de <list>.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) median_deviation (s1);
                                          5
          (%o3)                           -
                                          2
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) median_deviation (s2);
          (%o5)           [2.75, 2.755, 3.08, 4.315, 3.31]

     Véase también 'mean'.

 -- Función: harmonic_mean (<list>)
 -- Función: harmonic_mean (<matrix>)
     Es la media armónica, definida como
                            n
                         --------
                          n
                         ====
                         \     1
                          >    --
                         /     x
                         ====   i
                         i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) y : [5, 7, 2, 5, 9, 5, 6, 4, 9, 2, 4, 2, 5]$
          (%i3) harmonic_mean (y), numer;
          (%o3)                   3.901858027632205
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) harmonic_mean (s2);
          (%o5) [6.948015590052786, 7.391967752360356, 9.055658197151745,
                                      13.44199028193692, 13.01439145898509]

     Véanse también 'mean' y 'geometric_mean'.

 -- Función: geometric_mean (<list>)
 -- Función: geometric_mean (<matrix>)
     Es la media geométrica, definida como
                           /  n      \ 1/n
                           | /===\   |
                           |  ! !    |
                           |  ! !  x |
                           |  ! !   i|
                           | i = 1   |
                           \         /

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) y : [5, 7, 2, 5, 9, 5, 6, 4, 9, 2, 4, 2, 5]$
          (%i3) geometric_mean (y), numer;
          (%o3)                   4.454845412337012
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) geometric_mean (s2);
          (%o5) [8.82476274347979, 9.22652604739361, 10.0442675714889,
                                      14.61274126349021, 13.96184163444275]

     Véanse también 'mean' y 'harmonic_mean'.

 -- Función: kurtosis (<list>)
 -- Función: kurtosis (<matrix>)
     Es el coeficiente de curtosis, definido como
                              n
                            ====
                      1     \          _ 4
                     ----    >    (x - x)  - 3
                        4   /       i
                     n s    ====
                            i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) kurtosis (s1), numer;
          (%o3)                  - 1.273247946514421
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) kurtosis (s2);
          (%o5) [- .2715445622195385, 0.119998784429451,
             - .4275233490482866, - .6405361979019522, - .4952382132352935]

     Véanse también 'mean', 'var' y 'skewness'.

 -- Función: skewness (<list>)
 -- Función: skewness (<matrix>)
     Es el coeficiente de asimetría, definido como
                              n
                            ====
                      1     \          _ 3
                     ----    >    (x - x)
                        3   /       i
                     n s    ====
                            i = 1

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) skewness (s1), numer;
          (%o3)                  .009196180476450306
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) skewness (s2);
          (%o5) [.1580509020000979, .2926379232061854, .09242174416107717,
                                      .2059984348148687, .2142520248890832]

     Véanse también 'mean', 'var' y 'kurtosis'.

 -- Función: pearson_skewness (<list>)
 -- Función: pearson_skewness (<matrix>)
     Es el coeficiente de asimetría de Pearson, definido como
                          _
                       3 (x - med)
                       -----------
                            s

     siendo <med> la mediana de <list>.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) pearson_skewness (s1), numer;
          (%o3)                   .2159484029093895
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) pearson_skewness (s2);
          (%o5) [- .08019976629211892, .2357036272952649,
                   .1050904062491204, .1245042340592368, .4464181795804519]

     Véanse también 'mean', 'var' y 'median'.

 -- Función: quartile_skewness (<list>)
 -- Función: quartile_skewness (<matrix>)
     Es el coeficiente de asimetría cuartílico, definido como
                         c    - 2 c    + c
                          3/4      1/2    1/4
                         --------------------
                             c    - c
                              3/4    1/4

     siendo c_p el <p>-cuantil de la muestra <list>.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s1 : read_list (file_search ("pidigits.data"))$
          (%i3) quartile_skewness (s1), numer;
          (%o3)                  .04761904761904762
          (%i4) s2 : read_matrix (file_search ("wind.data"))$
          (%i5) quartile_skewness (s2);
          (%o5) [- 0.0408542246982353, .1467025572005382,
                 0.0336239103362392, .03780068728522298, 0.210526315789474]

     Véase también 'quantile'.

 -- Función: km (<list>, <option> ...)
 -- Función: km (<matrix>, <option> ...)

     Estimador Kaplan-Meier de la función de supervivencia o fiabilidad
     S(x)=1-F(x).

     Los datos se pueden introducir como una lista de pares de números o
     como una matriz de dos columnas.  La primera componente es el
     tiempo observado y la segunda componente es el índice de censura (1
     = no censurado, 0 = censurado por la derecha).

     El argumento opcional es el nombre de la variable en la expresión
     devuelta, la cual es <x> por defecto.

     Ejemplos:

     Muestra como una lista de pares.

          (%i1) load (descriptive)$
          (%i2) S: km([[2,1], [3,1], [5,0], [8,1]]);
                                 charfun((3 <= x) and (x < 8))
          (%o2) charfun(x < 0) + -----------------------------
                                               2
                          3 charfun((2 <= x) and (x < 3))
                        + -------------------------------
                                         4
                        + charfun((0 <= x) and (x < 2))
          (%i3) load (draw)$
          (%i4) draw2d(
                  line_width = 3, grid = true,
                  explicit(S, x, -0.1, 10))$

     Estimación de probabilidades de supervivencia.

          (%i1) load (descriptive)$
          (%i2) S(t):= ''(km([[2,1], [3,1], [5,0], [8,1]], t)) $
          (%i3) S(6);
                                      1
          (%o3)                       -
                                      2

 -- Función: cdf_empirical (<list>, <option> ...)
 -- Función: cdf_empirical (<matrix>, <option> ...)

     Función de distribución empírica F(x).

     Los datos se pueden introducir como una lista de números o como una
     matriz columna.

     El argumento opcional es el nombre de la variable en la expresión
     devuelta, la cual es <x> por defecto.

     Ejemplo:

     Función de distribución empírica.

          (%i1) load (descriptive)$
          (%i2) F(x):= ''(cdf_empirical([1,3,3,5,7,7,7,8,9]));
          (%o2) F(x) := (charfun(x >= 9) + charfun(x >= 8)
                         + 3 charfun(x >= 7) + charfun(x >= 5)
                         + 2 charfun(x >= 3) + charfun(x >= 1))/9
          (%i3) F(6);
                                     4
          (%o3)                      -
                                     9
          (%i4) load(draw)$
          (%i5) draw2d(
                  line_width = 3,
                  grid       = true,
                  explicit(F(z), z, -2, 12)) $

 -- Función: cov (<matrix>)
     Es la matriz de covarianzas de una muestra multivariante, definida
     como
                        n
                       ====
                    1  \           _        _
                S = -   >    (X  - X) (X  - X)'
                    n  /       j        j
                       ====
                       j = 1

     siendo X_j la j-ésima fila de la matriz muestral.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s2 : read_matrix (file_search ("wind.data"))$
          (%i3) fpprintprec : 7$  /* change precision for pretty output */
                [ 17.22191  13.61811  14.37217  19.39624  15.42162 ]
                [                                                  ]
                [ 13.61811  14.98774  13.30448  15.15834  14.9711  ]
                [                                                  ]
          (%o4) [ 14.37217  13.30448  15.47573  17.32544  16.18171 ]
                [                                                  ]
                [ 19.39624  15.15834  17.32544  32.17651  20.44685 ]
                [                                                  ]
                [ 15.42162  14.9711   16.18171  20.44685  24.42308 ]
          (%i5) cov (s2);

     Véase también 'cov1'.

 -- Función: cov1 (<matrix>)
     Es la matriz de cuasivarianzas de una muestra multivariante,
     definida como
                        n
                       ====
                   1   \           _        _
             S  = ---   >    (X  - X) (X  - X)'
              1   n-1  /       j        j
                       ====
                       j = 1

     siendo X_j la j-ésima fila de la matriz muestral.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s2 : read_matrix (file_search ("wind.data"))$
          (%i3) fpprintprec : 7$ /* change precision for pretty output */
                [ 17.39587  13.75567  14.51734  19.59216  15.5774  ]
                [                                                  ]
                [ 13.75567  15.13913  13.43887  15.31145  15.12232 ]
                [                                                  ]
          (%o4) [ 14.51734  13.43887  15.63205  17.50044  16.34516 ]
                [                                                  ]
                [ 19.59216  15.31145  17.50044  32.50153  20.65338 ]
                [                                                  ]
                [ 15.5774   15.12232  16.34516  20.65338  24.66977 ]
          (%i5) cov1 (s2);

     Véase también 'cov'.

 -- Función: global_variances (<matrix>)
 -- Función: global_variances (<matrix>, <options> ...)
     La función 'global_variances' devuelve una lista de medidas
     globales de variabilidad:

        * <varianza total>: 'trace(S_1)',
        * <varianza media>: 'trace(S_1)/p',
        * <varianza generalizada>: 'determinant(S_1)',
        * <desviación típica generalizada>: 'sqrt(determinant(S_1))',
        * <varianza efectiva> 'determinant(S_1)^(1/p)', (definida en:
          Peña, D. (2002) <Análisis de datos multivariantes>;
          McGraw-Hill, Madrid.)
        * <desviación típica efectiva>: 'determinant(S_1)^(1/(2*p))'.
     donde <p> es la dimensión de la variable aleatoria multivariante y
     S_1 la matriz de covarianzas devuelta por la función 'cov1'.

     Opción:

        * ''data', por defecto ''true', indica si la matriz de entrada
          contiene los datos muestrales, en cuyo caso la matriz de
          covarianzas 'cov1' debe ser calculada; en caso contrario, se
          le debe pasar ésta a la función como matriz simétrica en lugar
          de los datos.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s2 : read_matrix (file_search ("wind.data"))$
          (%i3) global_variances (s2);
          (%o3) [105.338342060606, 21.06766841212119, 12874.34690469686,
                   113.4651792608502, 6.636590811800794, 2.576158149609762]

     Cálculo de 'global_variances' a partir de la matriz de covarianzas.

          (%i1) load (descriptive)$
          (%i2) s2 : read_matrix (file_search ("wind.data"))$
          (%i3) s : cov1 (s2)$
          (%i4) global_variances (s, data=false);
          (%o4) [105.338342060606, 21.06766841212119, 12874.34690469686,
                   113.4651792608502, 6.636590811800794, 2.576158149609762]

     Véanse también 'cov' y 'cov1'.

 -- Función: cor (<matrix>)
 -- Función: cor (<matrix>, <options> ...)
     Es la matriz de correlaciones de la muestra multivariante.

     Opción:

        * ''data', por defecto ''true', indica si la matriz de entrada
          contiene los datos muestrales, en cuyo caso la matriz de
          covarianzas 'cov1' debe ser calculada; en caso contrario, se
          le debe pasar ésta a la función como matriz simétrica en lugar
          de los datos.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) fpprintprec:7$
          (%i3) s2 : read_matrix (file_search ("wind.data"))$
          (%i4) cor (s2);
                [   1.0     .8476339  .8803515  .8239624  .7519506 ]
                [                                                  ]
                [ .8476339    1.0     .8735834  .6902622  0.782502 ]
                [                                                  ]
          (%o4) [ .8803515  .8735834    1.0     .7764065  .8323358 ]
                [                                                  ]
                [ .8239624  .6902622  .7764065    1.0     .7293848 ]
                [                                                  ]
                [ .7519506  0.782502  .8323358  .7293848    1.0    ]

     Cálculo de la matriz de correlaciones a partir de la matriz de
     covarianzas.

          (%i1) load (descriptive)$
          (%i2) fpprintprec : 7 $
          (%i3) s2 : read_matrix (file_search ("wind.data"))$
          (%i4) s : cov1 (s2)$
          (%i5) cor (s, data=false); /* this is faster */
                [   1.0     .8476339  .8803515  .8239624  .7519506 ]
                [                                                  ]
                [ .8476339    1.0     .8735834  .6902622  0.782502 ]
                [                                                  ]
          (%o5) [ .8803515  .8735834    1.0     .7764065  .8323358 ]
                [                                                  ]
                [ .8239624  .6902622  .7764065    1.0     .7293848 ]
                [                                                  ]
                [ .7519506  0.782502  .8323358  .7293848    1.0    ]

     Véanse también 'cov' y 'cov1'.

 -- Función: list_correlations (<matrix>)
 -- Función: list_correlations (<matrix>, <options> ...)
     La función 'list_correlations' devuelve una lista con medidas de
     correlación:

        * <matriz de precisión>: es la inversa de la matriz de
          covarianzas S_1,
                      -1     ij
                     S   = (s  )
                      1         i,j = 1,2,...,p

        * <multiple correlation vector>: (R_1^2, R_2^2, ..., R_p^2),
          with
                      2          1
                     R  = 1 - -------
                      i        ii
                              s   s
                                   ii
          es un indicador de la bondad de ajuste del modelo de regresión
          lineal multivariante de X_i cuando el resto de variables se
          utilizan como regresores.

        * <matriz de correlaciones parciales>: en la que el elemento (i,
          j) es
                                        ij
                                       s
                     r        = - ------------
                      ij.rest     / ii  jj\ 1/2
                                  |s   s  |
                                  \       /

     Opción:

        * ''data', por defecto ''true', indica si la matriz de entrada
          contiene los datos muestrales, en cuyo caso la matriz de
          covarianzas 'cov1' debe ser calculada; en caso contrario, se
          le debe pasar ésta a la función como matriz simétrica en lugar
          de los datos.

     Ejemplo:

          (%i1) load (descriptive)$
          (%i2) s2 : read_matrix (file_search ("wind.data"))$
          (%i3) z : list_correlations (s2)$
          (%i4) fpprintprec : 5$ /* for pretty output */
                [  .38486   - .13856   - .15626   - .10239    .031179  ]
                [                                                      ]
                [ - .13856   .34107    - .15233    .038447   - .052842 ]
                [                                                      ]
          (%o5) [ - .15626  - .15233    .47296    - .024816  - .10054  ]
                [                                                      ]
                [ - .10239   .038447   - .024816   .10937    - .034033 ]
                [                                                      ]
                [ .031179   - .052842  - .10054   - .034033   .14834   ]
          (%o6)       [.85063, .80634, .86474, .71867, .72675]
                 [  - 1.0     .38244   .36627   .49908   - .13049 ]
                 [                                                ]
                 [  .38244    - 1.0    .37927  - .19907   .23492  ]
                 [                                                ]
          (%o7)  [  .36627    .37927   - 1.0    .10911    .37956  ]
                 [                                                ]
                 [  .49908   - .19907  .10911   - 1.0     .26719  ]
                 [                                                ]
                 [ - .13049   .23492   .37956   .26719    - 1.0   ]

     Véanse también 'cov' y 'cov1'.

 -- Función: principal_components (<matrix>)
 -- Función: principal_components (<matrix>, <options> ...)
     Calcula las componentes principales de una muestra multivariante.
     Las componentes principales se utilizan en el análisis estadístico
     multivariante para reducir la dimensionalidad de la muestra.

     Opción:

        * ''data', por defecto ''true', indica si la matriz de entrada
          contiene los datos muestrales, en cuyo caso la matriz de
          covarianzas 'cov1' debe ser calculada; en caso contrario, se
          le debe pasar ésta a la función como matriz simétrica en lugar
          de los datos.

     La salida de la función 'principal_components' es una lista con los
     siguientes resultados:

        * varianzas de las componentes principales,
        * porcentajes de variación total explicada por cada componente
          principal,
        * matriz de rotación.

     Ejemplos:

     En este ejemplo, la primera componente explica el 83.13 por ciento
     de la varianza total.

          (%i1) load (descriptive)$
          (%i2) s2 : read_matrix (file_search ("wind.data"))$
          (%i3) fpprintprec:4 $
          (%i4) res: principal_components(s2);
          0 errors, 0 warnings
          (%o4) [[87.57, 8.753, 5.515, 1.889, 1.613],
          [83.13, 8.31, 5.235, 1.793, 1.531],
          [ .4149  .03379   - .4757  - 0.581   - .5126 ]
          [                                            ]
          [ 0.369  - .3657  - .4298   .7237    - .1469 ]
          [                                            ]
          [ .3959  - .2178  - .2181  - .2749    .8201  ]]
          [                                            ]
          [ .5548   .7744    .1857    .2319    .06498  ]
          [                                            ]
          [ .4765  - .4669   0.712   - .09605  - .1969 ]
          (%i5) /* porcentajes acumulados  */
              block([ap: copy(res[2])],
                for k:2 thru length(ap) do ap[k]: ap[k]+ap[k-1],
                ap);
          (%o5)                 [83.13, 91.44, 96.68, 98.47, 100.0]
          (%i6) /* dimension de la muestra */
                p: length(first(res));
          (%o6)                                  5
          (%i7) /* dibuja porcentajes para seleccionar el numero de
                   componentes principales para el analisis ulterior */
               draw2d(
                  fill_density = 0.2,
                  apply(bars, makelist([k, res[2][k], 1/2], k, p)),
                  points_joined = true,
                  point_type    = filled_circle,
                  point_size    = 3,
                  points(makelist([k, res[2][k]], k, p)),
                  xlabel = "Variances",
                  ylabel = "Percentages",
                  xtics  = setify(makelist([concat("PC",k),k], k, p))) $

     En caso de que la matriz de covarianzas sea conocida, se le puede
     pasar a la función, pero debe utilizarse la opción 'data=false'.

          (%i1) load (descriptive)$
          (%i2) S: matrix([1,-2,0],[-2,5,0],[0,0,2]);
                                          [  1   - 2  0 ]
                                          [             ]
          (%o2)                           [ - 2   5   0 ]
                                          [             ]
                                          [  0    0   2 ]
          (%i3) fpprintprec:4 $
          (%i4) /* el argumento es una matriz de covarianzas */
                res: principal_components(S, data=false);
          0 errors, 0 warnings
                                                            [ - .3827  0.0  .9239 ]
                                                            [                     ]
          (%o4) [[5.828, 2.0, .1716], [72.86, 25.0, 2.145], [  .9239   0.0  .3827 ]]
                                                            [                     ]
                                                            [   0.0    1.0   0.0  ]
          (%i5) /* transformacion para obtener las componentes principales a
                   partir de los registros originales */
                matrix([a1,b2,c3],[a2,b2,c2]).last(res);
                       [ .9239 b2 - .3827 a1  1.0 c3  .3827 b2 + .9239 a1 ]
          (%o5)        [                                                  ]
                       [ .9239 b2 - .3827 a2  1.0 c2  .3827 b2 + .9239 a2 ]

