SLUD 2006
Programación de Máxima
In memoriam William Schelter
Robert Dodier
Proyecto Máxima
Libero este documento por el
GNU General Public License version 2
1
Toda cosa es expresión
Toda cosa en Máxima (casi todas) es un objeto de forma
foo(a, b, c), es decir, una expresión que comprende un
operador como foo y sus argumentos a, b, c
Programación en Máxima es más o menos la creación y
modificación de expresiones
(Se puede modificar la aparencia de una expresión por medida
de los códigos mostrantes. Sin eso, toda cosa aparecería como
foo(a, b, c).)
2
Estructura de expresiones: op y args
Funciones normales
Foo(x, y)
(%i1) expr : Foo (x, y);
(%o1)
(%i2) op (expr);
(%o2)
(%i3) args (expr);
(%o3)
(%i4) apply (op (expr), args (expr));
Foo(x, y)
(%o4)
Foo
[x, y]
3
Estructura . . .
Expresiones con operadores
(%i5) expr : 1 + %pi + %e + x + a;
(%o5)
(%i6) [op (expr), args (expr)];
(%o6)
x + a + %pi + %e + 1
[+, [x, a, %pi, %e, 1]]
4
Estructura . . .
(%i1) [expr_1 : ’sum (F(i), i, 1, n), "
",
expr_2 : ’integrate (sin(x), x, 0, %pi)];
n
====
\
(%o1)
[ >
F(i),
/
====
i = 1
%pi
/
[
, I
]
/
0
sin(x) dx]
(%i2) [op (expr_1), args (expr_1)];
(%o2)
(%i3) [op (expr_2), args (expr_2)];
(%o3)
[sum, [F(i), i, 1, n]]
[integrate, [sin(x), x, 0, %pi]]
5
Estructura . . .
Objetos: lista, conjunto, matriz son expresiones
[[, [1, 2, u, v]]
{a, b, c, x, y}
[set, [a, b, c, x, y]]
[1, 2, u, v]
(%i11) L : [1, 2, u, v];
(%o11)
(%i12) [op (L), args (L)];
(%o12)
(%i13) S : {a, b, c, x, y};
(%o13)
(%i14) [op (S), args (S)];
(%o14)
(%i15) M : matrix ([1, 2], [a, b]);
(%o15)
[ 1 2 ]
[
]
[ a b ]
6
(%i16) [op (M), args (M)];
(%o16)
[matrix, [[1, 2], [a, b]]]
7
Estructura . . .
Condicional if – then, bucle for son expresiones
(%i2) expr_1 : ’(if x > a then F(x) else G(x));
(%o2)
(%i3) expr_2 : ’(for i:10 thru 1 step -1
if x > a then F(x) else G(x)
do suma : suma + F(i));
(%o3) for i from 10 step - 1 thru 1
do suma : suma + F(i)
(%i4) [op (expr_1), args (expr_1)];
(%o4) [if, [x > a, F(x), true, G(x)]]
(%i5) [op (expr_2), args (expr_2)];
(%o5) [mdo, [i, 10, - 1, false, 1, false,
suma : suma + F(i)]]
8
Evaluación y simplificación
Evaluación = sustitución de valores por símbolos y invocación
de funciones
Simplificación = sustitución de expresiones por equivalentes
Evaluación cambia el valor de una expresión, mientras que
simplificación cambia la forma
9
Más detalles de evaluación
Se puede aumentar o evitar evaluación por medida de varias
opciones
Operador comilla ’ evita evaluación de un símbolo o expresión.
Ejemplos: a : 17; ’a; ⇒ a, a : 17; b : 29; ’(a + b); ⇒ a + b
Operador comilla trasforma una función hasta “expresión
nombre” (como opuesto a “expresión verba”). Ejemplo:
f (x) := 1 − x; ’f (a); ⇒ f (a)
Operador comilla-comilla ’ ’ (dos comillas simples) causa una
más evaluación cuando se encuentra en una expresión
entregada
Función ev causa una más evaluación cada vez que se evalua
la expresión
10
Más detalles de simplificación
Identidades matemáticas son expresadas como simplificación
en Máxima. Ejemplo: x + x ⇒ 2x
La distinción entre evaluación y simplificación es un poco
nublado. Ejemplos: En Máxima, 1 + 1 ⇒ 2 es una
simplificación. También sin(1.0) ⇒ 0.84147
Simplificación se hace con funciones asociadas al nombre de
una función o operador. Se puede asociar nuevamente una
función (que se llama una régula de simplificación) con
cualquier función o operador por tellsimp y tellsimpafter.
11
Más detalles . . .
Se puede aplicar simplificación a un operador o una función
que no existe. Simplificación maneja una expresión sin que
invoque funciones que aparezcan en ella; es sólo una
manipulación formal.
Hay muchas identidades que no son aplicadas
automaticamente; el usuario tiene que pedirlas
especificamente.
Ejemplos: ratsimp(a/x + b/x);⇒ (b + a)/x
trigreduce(2 sin x cos x);⇒ sin(2x)
12
Funciones cotidianas
Definición de una función normal. A la derecha se pone sólo
una expresión; se puede agrupar multiples expresiónes con
block.
(%i2) foo_bar (x, y) := y - x;
(%o2)
(%i3) baz_quux (a, b, c) :=
foo_bar(x, y) := y - x
block ([u, v], u : b - c, v : a - b, u/v);
(%o3) baz_quux(a, b, c) :=
block([u, v], u : b - c, v : a - b, -)
u
v
13
Funciones cotidianas . . .
(%i4) foo_bar (1729, %pi);
(%o4)
(%i5) baz_quux (%pi, %e, %i);
%pi - 1729
(%o5)
%e - %i
--------
%pi - %e
No es necesario poner return (devolver) en una función. Se
devuelve el valor computado por la expresión a la derecha.
14
Funciones cotidianas . . .
No se evalua la expresión a la derecha en el momento en que se
define la función. El operador comilla-comilla (dos comillas
simples) causa evaluación.
(%i6) integrate (2 * sin(x) * cos(x), x);
2
- cos (x)
(%o6)
(%i7) F (x) := integrate (2 * sin(x) * cos(x), x);
(%o7) F(x) := integrate(2 sin(x) cos(x), x)
(%i8) F (42);
Attempt to integrate wrt a number: 42
#0: F(x=42)
-- an error.
15
Funciones cotidianas . . .
¡Qué lástima! Esperábamos el resultado de la integración.
Obtenemos el resultado por el operador comilla-comilla.
(%i9) F (x) :=
’’(integrate (2 * sin(x) * cos(x), x));
(%o9)
(%i10) F (42);
F(x) := - cos (x)
2
2
- cos (42)
(%o10)
Para indicar que el número de argumentos no es fijo, se escribe
un argumento como lista en la definición. Tal argumento tiene
que ser final o el único argumento. Cuando está invocada la
función, el argumento aparece como lista.
16
(%i2) G (x, y, [z]) := if x > y then first (z)
else last (z);
(%o2) G(x, y, [z]) :=
if x > y then first(z) else last(z)
H([a]) := map(sin, a)
(%i3) H ([a]) := map (sin, a);
(%o3)
(%i4) G (17, 29, aa, bb, cc);
(%o4)
(%i5) G (29, 17, aa, bb, cc);
(%o5)
(%i6) H (1, 2, 3, a, b, c);
(%o6) [sin(1), sin(2), sin(3), sin(a),
cc
aa
sin(b), sin(c)]
17
Programación funcional
Es decir, programación con enfásis en funciones
apply: aplicar una función a sus argumentos
(%i1) F : Foo;
(%o1)
(%i2) a : [1, 2, z];
(%o2)
(%i3) apply (F, a);
(%o3)
Foo
[1, 2, z]
Foo(1, 2, z)
18
Programación funcional . . .
map: aplicar una función a una lista de argumentos. (1) Es
muy común que reemplace bucles for con map. (2) No es
necesario definir una función prestando atención en objetos
compuestos — usemos map.
[a, b, c, x, y, z]
(%i2) L : [a, b, c, x, y, z];
(%o2)
(%i3) sin (L);
(%o3)
(%i4) map (sin, L);
(%o4) [sin(a), sin(b), sin(c), sin(x),
sin([a, b, c, x, y, z])
sin(y), sin(z)]
19
Programación funcional . . .
lambda: crear una función sin nombre
(%i2) map (lambda ([x], is (x > 0)),
[-2, -1, 0, 1, 2, 3]);
(%o2) [false, false, false, true, true, true]
(%i3) subset ({x, y, %pi, 1.729, 42, 47},
lambda ([a], integerp (a)));
(%o3)
{42, 47}
20
Funciones de array
(1) F [x] := . . . indica una función “de memoria”, es decir, que
recuerda resultados anteriores
(%i1) F[x] := block (print ("Saludos!"), x^2 + 1);
2
(%o1)
F
:= block(print("Saludos!"), x + 1)
x
(%i2) [F[10], F[20], F[30]];
Saludos!
Saludos!
Saludos!
(%o2)
(%i3) [F[10], F[20], F[30]];
(%o3)
[101, 401, 901]
[101, 401, 901]
21
(2) G[x](y) := . . . indica una función “de array”. Es una
diferente función de y por cada valor de x.
(%i6) G[x](y) := x^y;
(%o6)
(%i7) G[1];
(%o7)
(%i8) G[2];
(%o8)
(%i9) G[3];
(%o9)
y
G (y) := x
x
lambda([y], 1)
y
lambda([y], 2 )
y
lambda([y], 3 )
22
(%i10) G[3](u + v);
v + u
(%o10)
(%i11) map (G[3], [2, 3, 5, 7]);
(%o11)
3
[9, 27, 243, 2187]
23
Es muy fácil declarar nuevos operadores
Operadores
(%i1) prefix ("FOO");
(%o1)
(%i2) infix ("##");
(%o2)
(%i3) nary ("@@");
(%o3)
(%i4) postfix ("%!");
(%o4)
(%i5) matchfix ("!<", ">!");
(%o5)
(%i6) FOO a;
(%o6)
FOO
##
@@
%!
!<
FOO a
24
(%i7) a ## b;
(%o7)
(%i8) a @@ b @@ c @@ d;
(%o8)
(%i9) 42 %!;
(%o9)
(%i10) !< 17, 29 >!;
(%o10)
a ## b
a @@ b @@ c @@ d
42 %!
!<17, 29>!
25
Operadores . . .
Se puede definir (o no) una función correspondente al
operador.
(%i11) "##" (x, y) := y/x;
(%o11)
y
x ## y := -
x
(%i12) "@@"([L]) := apply("+", L) / apply("*", L);
(%o12)
apply("+", L)
"@@"([L]) := -------------
apply("*", L)
26
Operadores . . .
(%i13) (a + b) ## c;
(%o13)
c
-----
b + a
(%i14) 17 @@ 29 @@ x @@ y @@ z;
(%o14)
z + y + x + 46
--------------
493 x y z
27
Lisp y Máxima
Referencia a variables en Lisp desde Máxima. Variables en
Máxima normalmente tiene símbolo dolar inicial en Lisp. Si
no, tiene que poner signo de interrogación inicial en Máxima.
(%i1) :lisp (defvar foo-bar 1729)
FOO-BAR
(%i1) :lisp (defvar $foo_bar ’$z)
$FOO_BAR
(%i1) ?foo\-bar + foo_bar;
(%o1)
z + 1729
28
Lisp y Máxima . . .
Referencia a variables en Máxima desde Lisp. Como siempre
tenemos que prestar atención en el primer carácter de los
símbolos.
(%i1) x : 1729;
(%o1)
(%i2) y : a * b;
(%o2)
(%i3) :lisp (m+ $x $y)
((MPLUS SIMP) 1729 ((MTIMES SIMP) $A $B))
1729
a b
29
Lisp y Máxima . . .
Toda expresión (casi todas) en Maxima se representa en Lisp
como ((FOO) A B C) donde FOO es nombre de función o
operador y A B C son los argumentos
(%i1) expr_1 : foo (1, 2, 3)$
(%i2) expr_2 : a * b * c$
(%i3) expr_3 : (a + b) * (17 + c)$
(%i4) :lisp $expr_1
(($FOO SIMP) 1 2 3)
(%i4) :lisp $expr_2
((MTIMES SIMP) $A $B $C)
(%i4) :lisp $expr_3
((MTIMES SIMP) ((MPLUS SIMP) $A $B)
((MPLUS SIMP) 17 $C))
30
Lisp y Máxima . . .
Invocación de una función en Lisp desde Máxima. Una función
normal en Lisp es una función normal en Máxima también.
(%i1) :lisp (defun $baz_quux (x y) (m+ x y))
$BAZ_QUUX
(%i1) baz_quux (42, a * b);
(%o1)
a b + 42
31
Lisp y Máxima . . .
Invocación de una función en Máxima desde Lisp. Una
función de Máxima no es una función normal en Lisp. Tiene
que invocarla por mfuncall.
(%i1) f (x, y) := x * y;
(%o1)
(%i2) :lisp (mfuncall ’$f 42 ’$z)
((MTIMES SIMP) 42 $Z)
f(x, y) := x y
32
Funciones que no evaluan sus argumentos
La mayor parte de funciones en Máxima evaluan
Comentarios de: SLUD 2006 Programación de Máxima (0)
No hay comentarios