You are on page 1of 29

Introduccin a Mathematica

(en construccin...)
Alberto Ruiz <aruiz@um.es>
Departamento de Informtica y Sistemas
Universidad de Murcia, Spain
Preliminares
Mathematica es un entorno de clculo simblico, compuesto por un lenguaje de programacin de alto nivel, una
coleccin extensa de funciones matemticas y de propsito general, y un sistema para editar interactivamente
documentos como ste que contienen texto normal, rdenes sencillas, programas ms complejos, grficos, etc.
Los documentos estn organizados por "celdas" indicadas en azul a la derecha. Hay varios tipos de celdas: las ms
importantes son las de texto normal, y las de entrada (input) y salida de informacin (output), como las siguientes:
In[1]:= 2 + 2
Out[1]= 4
El lenguaje de Mathematica es interpretado: no hace falta compilacin. Est basado en reglas de transformacin de
expresiones y aprovecha muchas construcciones de programacin funcional.
Para ejecutar una orden o evaluar una expresin se edita en una celda tipo "input" y cuando est terminada se pulsa
ShiftEnter(tecla de maysculas + tecla de nueva lnea). A continuacin aparecer una celda con el resultado.
Mathematica se puede usar directamente como una calculadora:
In[2]:= 1.5 + 2.5
Out[2]= 4.
El espacio en blanco significa multiplicacin (tambin se puede usar *):
In[3]:= 2 (5 + 5)
Out[3]= 20
La aritmtica es exacta:
In[4]:= 1000/350
Out[4]=
20
-------
7
y sin lmite en el tamao de los nmeros:
In[5]:= 2^100
Out[5]= 1267650600228229401496703205376
In[6]:= 100!
Out[6]= 93326215443944152681699238856266700490715968264381621468592963895217599993229
9156089414639761565182862536979208272237582511852109168640000000000000000000
00000
intromat.nb 1
Pero si en las operaciones aparecen nmeros aproximados, el resultado tambin lo ser:
In[7]:= 1000.0/350
Out[7]= 2.85714
Siempre se puede convertir un valor exacto en un valor aproximado usando la funcin N (convertir en un nmero).
En Mathematica los argumentos se encierran entre corchetes:
In[8]:= N[1000/350]
Out[8]= 2.85714
In[9]:=
Out[9]=
In[10]:= N[]
Out[10]= 3.14159
Como argumento opcional se puede especificar la precisin del nmero:
In[11]:= N[, 100]
Out[11]= 3.14159265358979323846264338327950288419716939937510582097494459230781640628
6208998628034825342117068
Disponemos de todas las funciones matemticas usuales :
In[12]:= Exp[3.8]
Out[12]= 44.7012
In[13]:= Cos[0.12]
Out[13]= 0.992809
In[14]:= Sin[30 Degree]
Out[14]=
1
----
2
Existen bibliotecas con constantes y unidades fsicas.
Principio Fundamental de Mathematica
Todo son expresiones que se evalan mediante la aplicacin de reglas de transformacin estructural.
Expresiones
Una expresin es o bien un tomo (nmero o smbolo) o bien una "cabeza" y "argumentos", que, a su vez, son
expresiones. Este tipo de estructura recursiva permite representar cualquier cosa: frmulas matemticas, progra-
mas, dibujos, etc. Este mismo documento es en realidad una expresin de ese tipo.
Las expresiones tienen una representacin externa, visualmente conveniente, pero en realidad estn constituidas
por este tipo de estructuras anidadas. Por ejemplo:
intromat.nb 2
a + b
es en realidad
Plus[a, b]
(Los componentes de una expresin (o argumentos de una funcin) se escriben con corchetes.) Otro ejemplo:
a Sin[3 + b x]
se representa internamente mediante
Times[a, Sin[Plus[3, Times[b, x]]]]
La forma interna de cualquier expresin se obtiene mediante la orden FullForm:
In[15]:= FullForm]a Sin]
b x + 3
-------- --------
_------

Out[15]//FullForm=
Times[a, Sin[Times[Power[Power[Pi, m], Rational[-1, 2]], Plus[3, Times[b, x]]]]]
Los "arrays" se representan mediante la estructura ms general de lista, que es una coleccin de expresiones
encerradas entre llaves:
{4, a + b, 17, {1, 2, 3}, 5}
aunque, por supuesto, internamente son expresiones con cabeza "Lista":
List[4, Plus[a, b], 17, List[1, 2, 3], 5]
Evaluacin
El funcionamiento de Mathematica consiste en leer una expresin (y pasarla a la forma interna), evaluarla, y
mostrar el resultado (en forma externa).
La evaluacin consiste en la aplicacin de ciertas "reglas" que modifican la estructura de la expresin. Estas reglas
son de varios tipos: a) reglas que se aplican automticamente (manipulacin matemtica usual) b) transformaciones
y algoritmos de distinto tipo ya preprogramados, y c) algoritmos definidos por nosotros para manipular las expre-
siones de acuerdo con nuestros intereses.
En primer lugar veremos algunos ejemplos de transformaciones automticas y de instrucciones que realizan
transformaciones tiles:
Simplificacin:
In[16]:= 2 + 3 + 5 x + y + 10 x - 5
Out[16]= 15 x + y
Expansin de potencias:
intromat.nb 3
In[17]:= Expand[(1 + x)
10
(1 - y)
5
]
Out[17]= 1 + 10 x + 45 x
2
+ 120 x
3
+ 210 x
4
+ 252 x
5
+ 210 x
6
+ 120 x
7
+ 45 x
8
+ 10 x
9
+ x
10
- 5 y -
50 x y - 225 x
2
y - 600 x
3
y - 1050 x
4
y - 1260 x
5
y - 1050 x
6
y - 600 x
7
y - 225 x
8
y -
50 x
9
y - 5 x
10
y + 10 y
2
+ 100 x y
2
+ 450 x
2
y
2
+ 1200 x
3
y
2
+ 2100 x
4
y
2
+ 2520 x
5
y
2
+
2100 x
6
y
2
+ 1200 x
7
y
2
+ 450 x
8
y
2
+ 100 x
9
y
2
+ 10 x
10
y
2
- 10 y
3
- 100 x y
3
-
450 x
2
y
3
- 1200 x
3
y
3
- 2100 x
4
y
3
- 2520 x
5
y
3
- 2100 x
6
y
3
- 1200 x
7
y
3
- 450 x
8
y
3
-
100 x
9
y
3
- 10 x
10
y
3
+ 5 y
4
+ 50 x y
4
+ 225 x
2
y
4
+ 600 x
3
y
4
+ 1050 x
4
y
4
+ 1260 x
5
y
4
+
1050 x
6
y
4
+ 600 x
7
y
4
+ 225 x
8
y
4
+ 50 x
9
y
4
+ 5 x
10
y
4
- y
5
- 10 x y
5
- 45 x
2
y
5
-
120 x
3
y
5
- 210 x
4
y
5
- 252 x
5
y
5
- 210 x
6
y
5
- 120 x
7
y
5
- 45 x
8
y
5
- 10 x
9
y
5
- x
10
y
5
Solucin simblica de sistemas de ecuaciones:
In[18]:= Solve[5 x - 8 a = 4, x]
Out[18]= x -
4
----
5
(1 + 2 a)
Derivadas simblicas:
In[19]:= D[Sin[Exp[Cos[x]]], x]
Out[19]= -c
Cos[x]
Cos[c
Cos[x]
] Sin[x]
Integrales simblicas:
In[20]:=
_
Sin[x]
2
dx
Out[20]=
x
----
2
-
1
----
4
Sin[2 x]
Desarrollos en serie:
In[21]:= Series[Exp[x], {x, 0, 5}]
Out[21]= 1 + x +
x
2
-------
2
+
x
3
-------
6
+
x
4
-------
24
+
x
5
----------
120
+ O[x]
6
Lmites:
In[22]:= Limit]
1
\
.
.1 +
1
--------
2 x
)
!
.
.
5 x
, x -
Out[22]= c
5/2
Representaciones grficas 2D:
In[23]:= Plot[Sin[x] + Sin[10 x], {x, 0, 2 }];
1 2 3 4 5 6
-2
-1
1
2
intromat.nb 4
Y 3D:
In[24]:= Plot3D[Exp[-.5 (x x + y y)], {x, -3, 3}, {y, -3, 3}, Mesh - False, PlotPoints - 50] ;
-2
0
2
-2
0
2
0
0.25
0.5
0.75
1
-2
0
2
La aritmtica es exacta:
In[25]:= Solve[5 x
2
- 8 + 5 x
3
= 4, x]
Out[25]= x - -
1
----
3
+
1
-------
15
3925 - 900
_
19
1/3
+
1
----
3

1
----
5
157 + 36
_
19
1/3
,
x - -
1
----
3
-
1
-------
30
1 + f
_
3 3925 - 900
_
19
1/3
-
1
----
6
1 - f
_
3
1
----
5
157 + 36
_
19
1/3
,
x - -
1
----
3
-
1
-------
30
1 - f
_
3 3925 - 900
_
19
1/3
-
1
----
6
1 + f
_
3
1
----
5
157 + 36
_
19
1/3

Pero siempre podemos obtener nmeros aproximados.


In[26]:= Solve[5 x
2
- 8 + 5 x
3
= 4, x] // N
Out[26]= {{x - 1.07537], {x - -1.03768 + 1.07471 f], {x - -1.03768 - 1.07471 f]]
La notacin x//f es equivalente a f[x] (se utiliza para ir encadenando o componiendo funciones cmodamente).
Se pueden resolver sistemas de ecuaciones polinomiales con varias incgnitas:
In[27]:= Solve[{x
2
+ x y = y, x = y
2
}, {x, y}] // N
Out[27]= {{x - 0., y - 0.], {x - 0.56984, y - 0.754878],
{x - 0.21508 - 1.30714 f, y - -0.877439 + 0.744862 f],
{x - 0.21508 + 1.30714 f, y - -0.877439 - 0.744862 f]]
La solucin de ecuaciones no lineales debe hacerse numricamente, indicando el punto de partida en la bsqueda:
In[28]:= FindRoot[Sin[(x - .3) Cos[x]], {x, 89 Degree}]
Out[28]= {x - 1.5708]
Factorizacin de polinomios:
intromat.nb 5
In[29]:= Factor[x
99
+ y
99
]
Out[29]= (x + y) (x
2
- x y + y
2
) (x
6
- x
3
y
3
+ y
6
)
(x
10
- x
9
y + x
8
y
2
- x
7
y
3
+ x
6
y
4
- x
5
y
5
+ x
4
y
6
- x
3
y
7
+ x
2
y
8
- x y
9
+ y
10
)
(x
20
+ x
19
y - x
17
y
3
- x
16
y
4
+ x
14
y
6
+ x
13
y
7
- x
11
y
9
-
x
10
y
10
- x
9
y
11
+ x
7
y
13
+ x
6
y
14
- x
4
y
16
- x
3
y
17
+ x y
19
+ y
20
)
(x
60
+ x
57
y
3
- x
51
y
9
- x
48
y
12
+ x
42
y
18
+ x
39
y
21
- x
33
y
27
- x
30
y
30
-
x
27
y
33
+ x
21
y
39
+ x
18
y
42
- x
12
y
48
- x
9
y
51
+ x
3
y
57
+ y
60
)
Y de nmeros enteros:
In[30]:= FactorInteger[192492352]
Out[30]= {{2, 6], {13, 3], {37, 2]]
In[31]:= 2
6
13
3
37
2
Out[31]= 192492352
Se pueden obtener sumas infinitas:
In[32]:= _
n=2

1
-------
n
2
Out[32]=
1
----
6
(-6 +
2
)
otro ejemplo:
In[33]:= _
n=2

1
-------- -------
n
2
+ 5
Out[33]= --2 f +
_
5 2 f +
_
5 Csch
_
5 -15 Cosh
_
5 + 8
_
5 Sinh
_
5
45
_
5 -f +
_
5 f +
_
5
Aunque no siempre convergen:
In[34]:= _
n=2

1
----
n
Sum::div : Sum does not converge.
Out[34]= _
n=2

1
----
n
Las derivadas se pueden expresar explcitamente:
In[35]:= D[Sin[Exp[Cos[a x]]], x]
Out[35]= -a c
Cos[a x]
Cos[c
Cos[a x]
] Sin[a x]
O con la notacin abreviada:
In[36]:= Sin[x]
Out[36]= Cos[x]
In[37]:= Tan[x]
Out[37]= 2 Sec[x]
2
Tan[x]
intromat.nb 6
Las integrales definidas se calculan simblicamente, no numricamente sumando reas:
In[38]:=
_
0
1
4
-------- ----
1 + x
dx
Out[38]= 4 Log[2]
In[39]:=
_
0
1
4
-------- -------
1 + x
2
dx
Out[39]=
Lo que nos permite que los extremos sean smbolos:
In[40]:=
_
1
t
1
-------- ----
1 + x
dx
Out[40]= -Log[2] + Log[1 + t]
In[41]:= % // Simplify
Out[41]= Log
1 + t
-------- ----
2

(El smbolo % representa el resultado anterior)
Si deseamos integrales numricas hacemos lo siguiente:
In[42]:=
_
0
1
4
-------- ----
1 + x
dx // N
Out[42]= 2.77259
In[43]:= Integrate]
4
-------- ----
1 + x
, {x, 0, v}
Out[43]= 4 Log[1 + v]
Se pueden aplicar transformaciones trigonomtricas:
In[44]:= Sin[34 x]
Out[44]= Sin[34 x]
In[45]:= % // TrigExpand
Out[45]= 34 Cos[x]
33
Sin[x] - 5984 Cos[x]
31
Sin[x]
3
+ 278256 Cos[x]
29
Sin[x]
5
-
5379616 Cos[x]
27
Sin[x]
7
+ 52451256 Cos[x]
25
Sin[x]
9
-
286097760 Cos[x]
23
Sin[x]
11
+ 927983760 Cos[x]
21
Sin[x]
13
-
1855967520 Cos[x]
19
Sin[x]
15
+ 2333606220 Cos[x]
17
Sin[x]
17
-
1855967520 Cos[x]
15
Sin[x]
19
+ 927983760 Cos[x]
13
Sin[x]
21
-
286097760 Cos[x]
11
Sin[x]
23
+ 52451256 Cos[x]
9
Sin[x]
25
- 5379616 Cos[x]
7
Sin[x]
27
+
278256 Cos[x]
5
Sin[x]
29
- 5984 Cos[x]
3
Sin[x]
31
+ 34 Cos[x] Sin[x]
33
Las reglas de simplificacin son muy potentes. Por ejemplo, pueden deshacer la anterior expansin:
In[46]:= % // Simplify
Out[46]= Sin[34 x]
La integracin simblica permite abordar la solucin de ecuaciones diferenciales:
intromat.nb 7
In[47]:= DSolve[f[x] = k, f[x], x]
Out[47]= {{f[x] - k x + C[1]]]
In[48]:= DSolve[{f[x] = w
2
f[x], f[0] = 1}, f[x], x]
Out[48]= {{f[x] - c
-w x
(1 - C[2] + c
2 w x
C[2])]]
Mathematica dispone de todas las funciones necesarias para efectuar eficientemente clculo matricial. Por ejemplo,
el producto matricial y matriz vector se representa mediante "." (Dot):
In[49]:= m1 = Table[i + j, {i, 3}, {j, 4}]
Out[49]= {{2, 3, 4, 5], {3, 4, 5, 6], {4, 5, 6, 7]]
In[50]:= m1 // MatrixForm
Out[50]//MatrixForm=

2 3 4 5
3 4 5 6
4 5 6 7
|

In[51]:= (m2 = Table[i + j


2
, {i, 4}, {j, 2}]) // MatrixForm
(m1.m2) // MatrixForm
Out[51]//MatrixForm=

2 5
3 6
4 7
5 8
|

Out[52]//MatrixForm=

54 96
68 122
82 148
|

Es posible automatizar que las matrices se muestren como tales y no como listas de listas...
In[53]:= MakeBoxes[x_?MatrixQ, StandardForm] := ToBoxesMatrixFormx
Off[MatrixQ::argt]
In[55]:= m1
Out[55]=

2 3 4 5
3 4 5 6
4 5 6 7
|

Al ser un entorno de clculo simblico, tiene la ventaja de que los elementos de las matrices pueden ser smbolos:
In[56]:= m = ]
1 a
c 7

Out[56]=
1 a
c 7

In[57]:= Transpose[m]
Out[57]=
1 c
a 7

In[58]:= Inverse[m]
Out[58]=

7
-------- ---
7-a c
-
a
-------- ---
7-a c
-
c
-------- ---
7-a c
1
-------- ---
7-a c
|

intromat.nb 8
No confundamos el producto elemento a elemento (*):
In[59]:= m +Inverse[m]
Out[59]=

7
-------- ---
7-a c
-
a
2
-------- ---
7-a c
-
c
2
-------- ---
7-a c
7
-------- ---
7-a c
|

Con el producto de matrices (.):


In[60]:= m.Inverse[m]
Out[60]=

7
-------- ---
7-a c
-
a c
-------- ---
7-a c
0
0
7
-------- ---
7-a c
-
a c
-------- ---
7-a c
|

In[61]:= % // Simplify
Out[61]=
1 0
0 1

Muchos ms ejemplos pueden consultarse en la ayuda del sistema.


Reglas de transformacin estructural
La descripcin de los algoritmos en Mathematica se hace mediante un estilo de programacin diferente a C.
Aunque es posible usar construcciones de tipo for, while, etc., para controlar la asignacin de valores a variables de
acuerdo con la lgica del algoritmo (estilo "imperativo"), Mathematica est orientado hacia un estilo de progra-
macin llamado "funcional" y, sobre todo, a la descripcin de los algoritmos mediante lo que podemos llamar
transformacin estructural basada en "pattern matching" (reconocimiento de patrones sintcticos, o "esquemas de
expresin").
El siguiente ejemplo muetra la aplicacin de una regla de transformacin muy simple. La notacin "/." es un
convenio para indicar que la expresin de la izquierda se va a transformar de acuerdo con la regla de la derecha:
In[62]:= p + j
p
/. p - 3 y
Out[62]= j
3 y
+ 3 y
Aqu solo transformamos el nmero 3:
In[63]:= p
3
+ j
v+3
+ 6 /. 3 - 4
Out[63]= 6 + j
4+v
+ p
4
Cuando combinamos la aplicacin de reglas con pattern matching se obtiene un estilo de programacin muy claro
y expresivo. Por ejemplo, para indicar que una funcin es lineal podemos hacer algo como:
In[64]:= f[a + g[c] + b] /. f[x_ + y_] - f[x] + f[y]
Out[64]= f[a] + f[b + g[c]]
Pero la regla se ha aplicado solo una vez. Es mejor:
In[65]:= f[a + g[c] + b] //. f[x_ + y_] - f[x] + f[y]
Out[65]= f[a] + f[b] + f[g[c]]
donde //. significa que la regla se aplica hasta que la expresin no cambie.
La parte izquierda de una regla es un patrn: un esquema de expresin donde algunas partes, indicadas con un
smbolo subrayado, representan variables o "comodines" que coinciden con cualquier expresin. La parte derecha
de la regla indica cmo se construye la expresin resultante recomponiendo trozos de la expresin original
(denotados por los smbolos anteriores, ya sin subrayar).
intromat.nb 9
La parte izquierda de una regla es un patrn: un esquema de expresin donde algunas partes, indicadas con un
smbolo subrayado, representan variables o "comodines" que coinciden con cualquier expresin. La parte derecha
de la regla indica cmo se construye la expresin resultante recomponiendo trozos de la expresin original
(denotados por los smbolos anteriores, ya sin subrayar).
En lugar de aplicar reglas concretas en cada caso, en la prctica resulta ms cmodo suministrar reglas que se
debern aplicar siempre que sea posible, en forma de definiciones.
Definiciones
En lenguajes de programacin imperativos, del estilo de C, las variables son contenedores de nmeros (o de
cdigos de otros objetos), y las funciones se definen para que admitan unos parmetros y devuelvan resultados de
un cierto tipo. En Mathematica la filosofa es diferente: la programacin consiste en asociar a cada smbolo un
conjunto de reglas que se deben aplicar siempre, automticamente.
Cuando evaluamos una asignacin del tipo
In[66]:= a = 2
Out[66]= 2
Lo que hacemos es crear la regla a 2 que se aplicar siempre:
In[67]:= a + a
Out[67]= 4
Una nueva asignacin como
In[68]:= a = 3 + b
Out[68]= 3 + b
sustituye la regla a2 por a3+b.
In[69]:= a
2
Out[69]= (3 + b)
2
Podemos interpretar lo anterior como que en Mathematica las variables no tienen un tipo predeterminado y fijo
(como en C, que deben ser int, double, etc.) sino que pueden tomar como valor cualquier expresin. En realidad lo
que hacemos es introducir una regla de transformacin automtica asociada a ese smbolo.
Este concepto se lleva a sus ltimas consecuencias en lo que podramos considerar como la definicin de funci-
ones. En este caso, lo que se hace es crear una serie de reglas automticas para un smbolo, con patrones que hacen
referencia a posibles argumentos. Si evaluamos la siguiente asignacin:
In[70]:= sincos[x_] := Sin[x] + Cos[x]
definimos la funcin sincos, pero lo que estamos haciendo en realidad es crear la regla
sincos[x_] - Sin[x] + Cos[x] y solicitar que sea evaluada siempre que sea posible.
Observa el operador de asignacin ":=" (dos puntos igual). Ms adelante explicaremos la diferencia con "=". Por el
momento basta saber que en la mayora de las situaciones en que definimos funciones usamos ":=",y cuando
asignamos variables usamos "=".
La funcin ya est disponible:
intromat.nb 10
In[71]:= sincos[3]
Out[71]= Cos[3] + Sin[3]
In[72]:= sincos[2 ]
Out[72]= 1
In[73]:= sincos[3.0]
Out[73]= -0.848872
In[74]:= Plot[sincos[x], {x, 0, 2 }]
1 2 3 4 5 6
-1
-0.5
0.5
1
Out[74]= ~ Graphics ~
A veces la defincin de una funcin debe tener en cuenta casos particulares:
In[75]:= sinc[0] = 1;
sinc[x_] :=
Sin[x]
-------- -------- ---
x
Observa que
In[77]:=
Sin[x]
-------- -------- ---
x
/. x - 0
General::dbyz : Division by zero.
Power::infy : Infinite expression
1
-----
0
encountered.
Out[77]= Indeterminate
Y que
In[78]:= Limit]
Sin[x]
-------- -------- ---
x
, x - 0
Out[78]= 1
Las expresiones se evalan hasta donde sea posible:
In[79]:= ?sinc
Globalsinc
sinc[0] = 1
sinc[x_] :=
Sin[x]
-------- ------
x
intromat.nb 11
In[80]:= sinc[2 + 3 + a + b+b]
Out[80]=
Sin[8 + b + b
2
]
---------------- ---------------- -----
8 + b + b
2
En general, las definiciones consisten de varias reglas, para considerar diferentes casos de inters:
In[81]:= fact[0] = 1;
fact[n_] := n fact[n - 1]
En C se utilizaba la construccin "if" para determinar la accin a tomar. En Mathematica tambin se utiliza, pero
muchas veces es ms claro dar diferentes reglas para cada tipo de argumento.
Diferencia entre = e :=
La diferencia entre los operadores ":=" y "=" es la siguiente:
"=" define una regla cuya parte derecha se evala en mismo momento de la definicin.
":=" define una regla cuya parte derecha se evala en el momento de usar la regla.
In[83]:= a = 10
100
;
b := 10
100
Lo que guardamos es:
In[85]:= ?a
Globala
a =
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000
In[86]:= ?b
Globalb
b := 10
100
El resultado de la evaluacin es el mismo
In[87]:= a
Out[87]= 1000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000
In[88]:= b
Out[88]= 1000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000
Pero a ya lo tiene precalculado, y b lo tiene que calcular cada vez que se utilice.
En general usaremos := en la definicin de funciones y = para definir smbolos como si fueran variables con un
valor
In[89]:= Remove["Global+"]
Patrones avanzados
En muchos casos es conveniente especificar en un patrn secuencias de argumentos, condiciones de los elementos
de una estructura, etc. Consideremos la anterior defincin de fact:
intromat.nb 12
In[90]:= fact[0] := 1
fact[n_] := n fact[n - 1]
El problema es que fracasa con nmeros negativos o nmeros no enteros:
In[92]:= fact[4.5]
$RecursionLimit::reclim : Recursion depth of 256 exceeded.
$RecursionLimit::reclim : Recursion depth of 1024 exceeded.
Out[92]= 3.4049139272933x10
492
Hold[fact[-249.5 - 1]]
Vamos a mejorarla un poco. Primero borramos todas las reglas asociadas a fact:
In[93]:= Clear[fact]
Y damos la nueva definicin:
In[94]:= fact[0] := 1
fact[n_Integer?Positive] := n fact[n - 1]
La regla slo "se dispara" en los casos permitidos:
In[96]:= fact[4.5]
Out[96]= fact[4.5]
In[97]:= fact[4]
Out[97]= 24
In[98]:= fact[-4]
Out[98]= fact[-4]
(Podramos aadir una regla que recogiese el resto de los casos indicando un error.)
El smbolo ? indica que el elemento de un patrn tiene que cumplir una condicin. Por ejemplo x_?OddQ hace
coincidencia con un nmero impar, al que se denota por x.
Por ejemplo, la funcin OddQ detecta nmeros impares:
In[99]:= OddQ[5]
Out[99]= True
In[100]:= OddQ[6]
Out[100]= False
Esto nos permite definir una funcin con valores diferentes segn sea el argumento par o impar:
In[101]:= g[n_?OddQ] := 3 n + 1
g[n_?EvenQ] := n/2
Funciona como deseamos:
In[103]:= g[3]
Out[103]= 10
intromat.nb 13
In[104]:= g[4]
Out[104]= 2
Dado cualquier smbolo del sistema (no de los definidos por nosotros, al menos en principio) podemos obtener
ayuda sobre l pinchando encima y pulsando F1. P.ej. prubalo con OddQ. Tambin se puede pedir ayuda medi-
ante la orden "Information" o smplemente con "?":
In[105]:= ?OddQ
OddQ[expr] gives True if expr is an odd integer, and False otherwise.
La interrogacin tambin sirve para mostrar las reglas que hemos asocidado a un smbolo:
In[106]:= ?g
Globalg
g[n_?OddQ] := 3 n + 1
g[n_?EvenQ] :=
n
----
2
(se usa el mismo smbolo para las condiciones de los patrones y para pedir informacin sobre un smbolo)
Continuamos con los patrones avanzados. Un smbolo detrs del subrayado indica el tipo de cabeza que tiene que
tener la expresin para que haya coincidencia.
La siguiente funcin f est definida para argumentos que sean listas o que sean q[.]
In[107]:= f[x_List] := Reverse[x]
f[x_q] := 1 + x
Cuando el argumento es un nmero no hay definicin para f:
In[109]:= f[3]
Out[109]= f[3]
Cuando es una lista se dispara primera regla:
In[110]:= f[{1, 2, 3}]
Out[110]= {3, 2, 1]
Para lo siguiente tampoco tenemos una definicin:
In[111]:= f[h[3]]
Out[111]= f[h[3]]
Pero s para esto:
In[112]:= f[q[3]]
Out[112]= 1 + q[3]
La siguiente definicin usa patrones con secuencias de argumentos:
Definimos una regla para s que se dispare cuando el argumento es una lista de 1 ms elementos, todos ellos numeros.
In[113]:= s[a : {__?NumberQ}] := Apply[Plus, a]
La funcin Apply sirve para cambiar la cabeza de una expresin por la que nosotros deseemos. Fjate que al cambiar a una lista de cosas la cabeza
List por la cabeza Plus, fabricamos una expresin en la que se van a sumar los elementos de la lista.
intromat.nb 14
In[114]:= s[{10, 5, 18}]
Out[114]= 33
Observa el proceso de evaluacin:
In[115]:= Trace[s[{10, a, 18}]] // ColumnForm
Out[115]= s[{10, a, 18]]
{NumberQ[10], True]
{NumberQ[a], False]
s[{10, a, 18]]
Se comprueba si los argumentos de la lista son todos nmeros, despus se fabrica la expresin de suma y se evala.
Con otro tipo de argumentos el smbolo s se queda sin evaluar:
In[116]:= s[3]
Out[116]= s[3]
In[117]:= s[{1, a, 3}]
Out[117]= s[{1, a, 3]]
x_ se refiere a una sola expresin, x_ _ se refiere a una o ms expresiones y x _ _ _ se refiere a cero o ms expre-
siones. El resultado es una "secuencia desnuda", que automticamente desaparece cuando va metida en cualquier
otra expresin:
In[118]:= r[x__] := Reverse[{x}]
In[119]:= r[a, b, c]
Out[119]= {c, b, a]
In[120]:= q[x__] := x
In[121]:= q[a, b, c]
Out[121]= Sequence[a, b, c]
In[122]:= f[q[a, b, c]]
Out[122]= f[a, b, c]
Borramos:
In[123]:= Remove["Global+"]
Programacin Funcional
El estilo de programacin convencional, "imperativo", est basado en la modificacin de los contenidos de ciertas
"variables" mediante construcciones de control de flujo. Las asignaciones no son "igualdades" en el sentido
matemtico del trmino y, por tanto, el orden de las instrucciones es fundamental para la correccin del programa.
El anlisis de un programa no es sencillo, dado que existe un "estado" de las variables, que va cambiando, y que
modifica el efecto que tendr cada instruccin en distintos momentos de un programa.
El estilo de "programacin funcional" trata de aproximarse a la prctica matemtica usual, donde se utilizan
"definiciones" de objetos que luego podran sustituirse en cualquier otro punto del programa sin afectar a su
funcionamiento (transparencia referencial). No existe el concepto de "variable" a la que podamos asignar un valor,
y la ejecucin del programa consiste nicamente en la evaluacin de funciones que con la misma entrada siempre
producirn la misma salida. Se han inventado muchos lenguajes funcionales. Uno particularmente atractivo es
Haskell, que posee evaluacin "no estricta" y una forma restringida pero muy prctica de pattern matching. La
evaluacin no estricta (perezosa) permite trabajar de forma muy elegante con estructuras potencialmente infinitas
de las que se calcularn slo los trminos necesarios. El pattern matching se usa para expresar las definiciones de
una funcin en diferentes tipos de entrada de manera mucho ms clara que usando preguntas explcitas. Este
lenguaje y otros de su estilo son muy prcticos para el prototipado rpido de muchos problemas de programacin
tpicos, a veces sin demasiada prdida de eficiencia. Sin embargo, por ahora no disponen del conjunto de bibliote-
cas matemticas necesarias para el clculo cientfico ni permiten manipular cmodamente expresiones matemticas
arbitrarias.
intromat.nb 15
El estilo de "programacin funcional" trata de aproximarse a la prctica matemtica usual, donde se utilizan
"definiciones" de objetos que luego podran sustituirse en cualquier otro punto del programa sin afectar a su
funcionamiento (transparencia referencial). No existe el concepto de "variable" a la que podamos asignar un valor,
y la ejecucin del programa consiste nicamente en la evaluacin de funciones que con la misma entrada siempre
producirn la misma salida. Se han inventado muchos lenguajes funcionales. Uno particularmente atractivo es
Haskell, que posee evaluacin "no estricta" y una forma restringida pero muy prctica de pattern matching. La
evaluacin no estricta (perezosa) permite trabajar de forma muy elegante con estructuras potencialmente infinitas
de las que se calcularn slo los trminos necesarios. El pattern matching se usa para expresar las definiciones de
una funcin en diferentes tipos de entrada de manera mucho ms clara que usando preguntas explcitas. Este
lenguaje y otros de su estilo son muy prcticos para el prototipado rpido de muchos problemas de programacin
tpicos, a veces sin demasiada prdida de eficiencia. Sin embargo, por ahora no disponen del conjunto de bibliote-
cas matemticas necesarias para el clculo cientfico ni permiten manipular cmodamente expresiones matemticas
arbitrarias.
Mathematica incluye muchas construcciones de programacin funcional. En realidad,es el estilo de programacin
recomendado y eficiente para este sistema (aunque la sintaxis no es siempre tan elegante y concisa como p.ej. la de
Haskell). La evaluacin es estricta (ms prxima a la programacin convencional) por lo que las estructuras
siempre tienen un tamao finito concreto y se eval an completamente aunque slo necesitemos una parte de ellas
(esto solo significa que tenemos que ser un poco ms cuidadosos al programar). Por otro lado, el "motor" de
pattern matching es tremendamente potente y eficiente, permitiendo patrones de una gran complejidad y poder
expresivo, imprescindibles en un entorno de clculo simblico.
Veamos algunos ejemplos de programacin funcional. En primer lugar vamos a definir funciones numricas
sencillas. En todos los casos se sustituye la iteracin y la asignacin por recursin.
Potencias enteras:
In[124]:= pot[n_, 0] := 1
pot[n_, m_] := n pot[n, m - 1]
Mximo comn divisor:
In[126]:= mcd[x_, 0] := x
mcd[x_, y_] := mcd[y, Mod[x, y]]
Cualquier funcin (no solo el ejemplo tpico del factorial) se puede expresar de esta forma. Sin embargo, el enorme
poder expresivo de la programacin funcional se manifiesta en la manipulacin de expresiones estructuradas,
especialmente listas.
Cualquier operacin de manipulacin de listas se puede expresar en trminos de las primitivas First, Rest, y
Prepend (histricamente, "cons").
First devuelve el primer elemento de la lista y Rest la lista sin el primer elemento. Prepend[a,l] aade como cabeza a l. Por cuestiones de
eficiencia,dependiendo de la implementacin,muchas operaciones de listas se hacen directamente, sin recurrir a las primitivas bsicas.
Longitud de una lista (por supuesto,disponemos de la primitiva Length):
In[128]:= lon[{}] := 0
lon[{a_, b___}] := 1 + lon[{b}]
Otra posiblidad:
In[130]:= lon2[{}] := 0
lon2[x_] := 1 + lon2[Rest[x]]
Suma de los elementos de una lista:
In[132]:= sumalist[{}] := 0
sumalist[x_] := First[x] + sumalist[Rest[x]]
Una construccin funcional muy importante es Map. Map[f,list] construye una lista que contiene el resultado de
aplicar una funcin f a cada elemento.
In[134]:= Map[Sqrt, {1, 4, 9, 100, 144}]
Out[134]= {1, 2, 3, 10, 12]
intromat.nb 16
Como se usa mucho tiene la abreviatura /@ :
In[135]:= Sqrt / {1, 4, 9, 100, 144}
Out[135]= {1, 2, 3, 10, 12]
Cmo definiras Map?
Apply es otro ejemplo de construccin funcional. Simplemente cambia la "cabeza" de una expresin. Sirve p.ej.
para pasar a una funcin una lista de argumentos que estn en una lista. El smbolo @@ es una abreviatura de
Apply:
Clculo de factorial mediante cambio de cabeza a la lista de nmeros:
In[136]:= Times Range[5]
Out[136]= 120
Definimos una funcin que calcula la media de los elementos de una lista.
In[137]:= med[x_List] :=
Plus x
---------------- -------- ---
Length[x]
In[138]:= med[{4, 8, 16, 32}]
Out[138]= 15
In[139]:= med[{10, 20, c}]
Out[139]=
30 + c
-------- -------
3
Es posible definir funciones "puras", sin nombre (expresiones de "lambda" clculo):
In[140]:= Function[algo, algo
2
+ 1]
Out[140]= Function[algo, algo
2
+ 1]
A esa funcin se le pasan argumentos entre corchetes, igual que a las dems:
In[141]:= Function[algo, algo
2
+ 1][5]
Out[141]= 26
Se puede abreviar con la notacin & (Function) y # (el argumento):
In[142]:= (#
2
+ 1 &)[5]
Out[142]= 26
Range construye una lista desde 1 hasta el valor deseado:
In[143]:= Range[5]
Out[143]= {1, 2, 3, 4, 5]
En el siguiente ejemplo aplicamos una funcin pura:
In[144]:= #
2
+ 1 & / Range[10]
Out[144]= {2, 5, 10, 17, 26, 37, 50, 65, 82, 101]
intromat.nb 17
(Curiosamente, podemos derivar funciones puras:)
In[145]:= Function[x, 2 x
2
+ 3 Cos[x]]
Out[145]= Function[x, 4 x - 3 Sin[x]]
In[146]:= Log[#] &
Out[146]= -
1
----------
#1
2
&
Otra construccin funcional importante es Select, que sirve para extraer de una lista los elementos que cumplan un
predicado:
In[147]:= Select[Range[100], PrimeQ]
Out[147]= {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Una alternativa es usar Cases, que selecciona elementos teniendo en cuenta no un predicado sino un patrn, y
ademas permite transormarlo en el resultado. Es muy funcin muy potente:
In[148]:= Cases[{{1, 2}, 3, {5, 7}, 8}, x_List]
Out[148]=
1 2
5 7

In[149]:= Cases[{{1, 2}, 3, {5, 7}, 8}, x_List Length[x]]


Out[149]= {2, 2]
Usamos la flecha (se teclea como :>) para que la parte derecha de la regla se evale al usar la regla (anlogamente a :=) y no en el momento de
definirla.
In[150]:= Cases[{{1, 2}, 3, {3, 4, 5}, {5, 7}, 8}, {a_, b_} - b
2
]
Out[150]= {4, 49]
Aunque como tal no se usa mucho en la prctica, la funcin Fold es una de las herramientas bsicas de la progra-
macin funcional. La mejor manera de explicar su funcionamiento es pensar que Fold[f,x,list] cambia la "coma" de
separacin de los elementos de la lista por la funcin f, y como primer valor usa x:
In[151]:= Fold[f, x, {a, b, c}]
Out[151]= f[f[f[x, a], b], c]
In[152]:= Fold[Plus, 3, {a, b, c}]
Out[152]= 3 + a + b + c
Existe el correspondiente FoldList, que devuelve en una lista todos los pasos:
In[153]:= FoldList[Plus, x, {a, b, c}]
Out[153]= {x, a + x, a + b + x, a + b + c + x]
Ejercicio: calcular la distribucin emprica (acumulada) de un conjunto de observaciones aleatorias. (un "oneliner"?mejor no...).
Usando variantes de Fold podemos escribir muchsimos algoritmos y funciones tpicas.
Nest sirve para "anidar" funciones:
intromat.nb 18
In[154]:= Nest[h, x, 5]
Out[154]= h[h[h[h[h[x]]]]]
In[155]:= Nest[1/(1 + #) &, x, 20]
Out[155]=
1
-------------------------------- -------------------------------- -------------------------------- ----------
1 +
1
-------------------------------- -------------------------------- ---------------- -------- -------
1+
1
-------------------------------- -------------------------------- -------------------------------- ---------------- -------- -------- -----
1+
1
-------------------------------- -------------------------------- -------------------------------- -------------------------------- ---------------- -------- -------- -------
1+
1
-------------------------------- -------------------------------- -------------------------------- -------------------------------- ---------------- -------- -----
1+
1
-------------------------------- -------------------------------- -------------------------------- -------------------------------- -------- -----------
1+
1
-------------------------------- -------------------------------- -------------------------------- ---------------- ---------------- ----------
1+
1
-------------------------------- -------------------------------- -------------------------------- ---------------- -------- --------
1+
1
-------------------------------- -------------------------------- -------------------------------- -------- -------- ------
1+
1
-------------------------------- -------------------------------- ---------------- ---------------- -------- ----
1+
1
-------------------------------- -------------------------------- ---------------- -------- -----------
1+
1
-------------------------------- -------------------------------- ---------------- ---------
1+
1
-------------------------------- ---------------- ---------------- -------- -------
1+
1
-------------------------------- ---------------- -------- -------- -----
1+
1
-------------------------------- ---------------- ------------
1+
1
-------------------------------- -------- ----------
1+
1
---------------- -------- -------- --------
1+
1
---------------- -------- ------
1+
1
-------- -------- -----
1+
1
-----------
1+x
Los puntos fijos de funciones se calculan mediante FixedPoint:
In[156]:= FixedPoint[Sqrt, 0.5]
Out[156]= 1.
Se puede construir una lista de los valores por los que va pasando:
In[157]:= FixedPointList[Sqrt, 2.]
Out[157]= {2., 1.41421, 1.18921, 1.09051, 1.04427, 1.0219, 1.01089, 1.00543, 1.00271,
1.00135, 1.00068, 1.00034, 1.00017, 1.00008, 1.00004, 1.00002, 1.00001,
1.00001, 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]
Podemos aprovechar para experimentar con la funcin g que definimos antes:
La volvemos a definir (por si acaso la habamos borrado)
In[158]:= g[n_?OddQ] := 3 n + 1
g[n_?EvenQ] := n/2
Se cree que esta funcin aplicada repetidamente desde cualquier nmero siempre acaba por caer a 1. Vamos a
comprobarlo en algunos casos. Primero definimos una funcin que comprueba la conjetura con un cierto nmero.
NestWhileList sirve para hacer llamadas anidadas, guardando los resultados en una lista, mientras se cumpla una
condicin:
In[160]:= conj[n_] := NestWhileList[g, n, # , 1 &]
Probamos la conjetura con algunos valores. Por ejemplo con 11 se regresa pronto al 1:
In[161]:= conj[11]
Out[161]= {11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
In[162]:= conj[11] // Length
Out[162]= 15
Con 27 tarda algo ms en regresar, pero lo hace:
intromat.nb 19
In[163]:= conj[27]
Out[163]= {27, 82, 41, 124, 62, 31, 94, 47, 142, 71, 214, 107, 322, 161, 484,
242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233,
700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336,
668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638,
319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288,
3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308,
1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61,
184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1]
Vamos a representar grficamente lo que tardan en regresar los 1000 primeros valores (tarda un poco en calcu-
larlo). Primero construimos una lista con las longitudes:
In[164]:= lon = Table[Length[conj[j]], {j, 2, 3000}];
Luego la representamos. ListPlot sirve para representar grficamente los elementos de una lista.
In[165]:= ListPlot[lon]
500 1000 1500 2000 2500 3000
50
100
150
200
Out[165]= ~ Graphics ~
Parece que hay cierta textura...
Podemos modificar la representacin dando opciones de dibujo a la orden ListPlot. En este caso saco los primeros
100 elementos de la lista y los muestro con los puntos unidos por lneas. La opcin PlotRange sirve para que
aparezcan en el dibujo todos los puntos, incluyendo los ms extremos.
In[166]:= ListPlot[Take[lon, 100], PlotJoined - True, PlotRange - All]
20 40 60 80 100
20
40
60
80
100
120
Out[166]= ~ Graphics ~
Borramos:
In[167]:= Remove["Global+"]
Es conveniente estudiar en la ayuda todas las construccines funcionales.
intromat.nb 20
Ejercicio: intentar la definicin recursiva, funcional, de la transpuesta de una matriz.
Construcciones de control de flujo de tipo imperativo
Por supuesto, disponemos de las construcciones de programacin usuales (for, if, etc.):
In[168]:= For[i = 1, i s 5, i++, Print[2
i
]]
2
4
8
16
32
Cuando necesitamos definir variables locales usamos la construccin Module:
In[169]:= mcd[n_, m_] := Module[{a, b, r},
If[n > m, a = n; b = m,
a = m; b = n];
While[(r = Mod[a, b]) , 0,
a = b;
b = r];
Return[b]]
In[170]:= mcd[100, 150]
Out[170]= 50
Sin embargo muchas veces es mejor usar otras construcciones ms naturales del lenguaje.
Borramos:
In[171]:= Remove["Global+"]
Listas, matrices, dot
Los "arrays" (listas) se construyen mediante Table y se accede a sus elementos con doble corchete [[ ]]:
In[172]:= m = Table[2
i
, {i, 0, 10}]
Out[172]= {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
Si las listas contienen nicamente enteros o reales, internamente se usa una representacin muy eficiente.
In[173]:= m[[4]]
Out[173]= 8
Muchas operaciones se realizan sobre todos los elementos de una lista:
In[174]:= m + 10
Out[174]= {11, 12, 14, 18, 26, 42, 74, 138, 266, 522, 1034]
intromat.nb 21
In[175]:= Attributes[Plus]
Out[175]= {Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected]
La suma es asociativa, se mete en las "listas", si acepta nmeros dar nmeros, Plus[1] = 1, conmutativa
In[176]:= 2
m
Out[176]= {2, 4, 16, 256, 65536, 4294967296,
18446744073709551616, 340282366920938463463374607431768211456,
115792089237316195423570985008687907853269984665640564039457584007913129639
936,
134078079299425970995740249982058461274793658205923933777235614437217640300
73546976801874298166903427690031858186486050853753882811946569946433649006
084096,
179769313486231590772930519078902473361797697894230657273430081157732675805
50096313270847732240753602112011387987139335765878976881441662249284743063
94741243777678934248654852763022196012460941194530829520850057688381506823
42462881473913110540827237163350510684586298239947245938479716304835356329
624224137216]
In[177]:= Log[2, 2
m
]
Out[177]= {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
El producto de matrices y el producto matriz vector se representa con un punto: (o la funcin Dot)
Creamos dos matrices:
In[178]:= m1 = Table[i+j, {i, 2}, {j, 3}]
Out[178]=
1 2 3
2 4 6

La matriz es una lista de listas, pero tambin se puede representar como


In[179]:= m2 = Table[i
j
, {i, 3}, {j, 4}]
Out[179]=

1 1 1 1
2 4 8 16
3 9 27 81
|

Calculamos su producto matricial:


In[180]:= m1.m2
Out[180]=
14 36 98 276
28 72 196 552

El producto matriz vector tambin usa el punto:
In[181]:= m1.{1, 2, 3}
Out[181]= {14, 28]
Importante:
a) No se distingue entre vectores fila o columna.
b) Dot funciona para "tensores" matrices multidimensionales de cualquier nmero de dimensiones...
Disponemos de operaciones matriciales usuales:
In[182]:= m3 = m2.Transpose[m2]
Out[182]=

4 30 120
30 340 1554
120 1554 7380
|

intromat.nb 22
In[183]:= Inverse[m3]
Out[183]=

27
------
8
-
5
----
4
5
------
24
-
5
----
4
105
--------
194
-
109
----------
1164
5
------
24
-
109
----------
1164
115
----------
6984
|

In[184]:= Inverse[m3] // N
Out[184]=

3.375 -1.25 0.208333


-1.25 0.541237 -0.0936426
0.208333 -0.0936426 0.0164662
|

Muchas operaciones matriciales funcionan tambin con matrices simblicas:


In[185]:= Inverse]]
1 2
1 b

Out[185]=

b
----------
-2+b
-
2
----------
-2+b
-
1
----------
-2+b
1
----------
-2+b
|

Ejemplo de una funcin Listable...


In[186]:= SetAttributes[g, Listable]
g[x_] := {x, x}
In[188]:= g[4]
Out[188]= {4, 4]
Se "mete dentro" de un argumento de tipo lista:
In[189]:= g[{a, b, c}]
Out[189]=

a a
b b
c c
|

Esta funcin tiene la misma definicin, pero al no tener el atributo listable no se distribuye dentro los argumentos de tipo lista:
In[190]:= h[x_] := {x, x}
In[191]:= h[4]
Out[191]= {4, 4]
In[192]:= h[{a, b, c}]
Out[192]=
a b c
a b c

Si lo deseamos, podemos trabajar con vectores fila y columna explcitos, usando matrices de una sola fila o
columna:
In[193]:= col = List / {a, b, c}
Out[193]=

a
b
c
|

In[194]:= fil = {{x, y, z}}


Out[194]= ( x y z )
intromat.nb 23
In[195]:= fil.col
Out[195]= ( a x + b y + c z )
El nico problema es que no produce un escalar, sin una matrix 1x1.
In[196]:= col.fil
Out[196]=

a x a y a z
b x b y b z
c x c y c z
|

Mejor Outer:
In[197]:= Outer[Times, {a, b, c}, {x, y, z}]
Out[197]=

a x a y a z
b x b y b z
c x c y c z
|

In[198]:= Outer[h, {a, b, c}, {x, y, z}] // MatrixForm


Out[198]//MatrixForm=

h[a, x] h[a, y] h[a, z]


h[b, x] h[b, y] h[b, z]
h[c, x] h[c, y] h[c, z]
|

Tambin tenemos Inner, una generalizacin de Dot:


In[199]:= Inner[f, {a, b, c}, {x, y, z}, g]
Out[199]= g[f[a, x], f[b, y], f[c, z]]
In[200]:= Inner[Times, {a, b, c}, {x, y, z}, Plus]
Out[200]= a x + b y + c z
Vamos a escribir un algoritmo conciso para generar una permutacin aleatoria de nmeros. La idea es
pegar a los nmeros del 1 a 10 unos nmeros aleatorios, emparejando las dos listas con Transpose.
Se ordenan y se cogen todos los segundos elementos:
In[201]:= Last / ((Transpose{Table[Random[], {10}], Range[10]}) // Sort)
Out[201]= {2, 9, 8, 5, 4, 10, 1, 3, 7, 6]
Veamos el proceso paso a paso:
In[202]:= {Table[Random[], {10}], Range[10]}
Out[202]=
0.996618 0.318965 0.697993 0.0535312 0.983696 0.264338 0.268539 0.561153
1 2 3 4 5 6 7 8
In[203]:= Transpose[%]
Out[203]=

0.996618 1
0.318965 2
0.697993 3
0.0535312 4
0.983696 5
0.264338 6
0.268539 7
0.561153 8
0.135592 9
0.765438 10
|

intromat.nb 24
In[204]:= Sort[%]
Out[204]=

0.0535312 4
0.135592 9
0.264338 6
0.268539 7
0.318965 2
0.561153 8
0.697993 3
0.765438 10
0.983696 5
0.996618 1
|

In[205]:= Last / %
Out[205]= {4, 9, 6, 7, 2, 8, 3, 10, 5, 1]
(Por supuesto, en una biblioteca tenemos RandomPermutation)
Tenemos operaciones matriciales tpicas de clculo cientfico: valores y vectores propios, valores singulares, etc.
Borramos:
In[206]:= Remove["Global+"]
Ajuste de mnimo error cuadrtico
En Mathematica podemos resolver cmodamente ajustes de mnimos cuadrados.
In[207]:= datos = Table[{x, x
2
+ Random[Real, {-2, 2}]}, {x, 0, 5, .1}];
Mostramos los primeros:
In[208]:= Take[datos, 5]
Out[208]=

0 -1.96865
0.1 -1.85859
0.2 0.206314
0.3 -1.61708
0.4 0.575433
|

In[209]:= g1 = ListPlot[datos]
1 2 3 4 5
5
10
15
20
25
Out[209]= ~ Graphics ~
In[210]:= sol = Fit[datos, {1, x}, {x}]
Out[210]= -4.63811 + 5.09923 x
intromat.nb 25
In[211]:= g2 = Plot[sol, {x, -2, 7}]
-2 2 4 6
-10
10
20
30
Out[211]= ~ Graphics ~
Es muy cmodo unir los dos grficos de manera consistente:
In[212]:= Show[g1, g2]
-2 2 4 6
-10
10
20
30
Out[212]= ~ Graphics ~
El ajuste lineal es inadecuado. Vamos a probar con un polinomio de orden mayor:
In[213]:= sol2 = Fit[datos, {1, x, x
2
, x
3
, x
4
}, {x}]
Out[213]= -1.49295 + 3.65777 x - 2.03306 x
2
+ 0.905784 x
3
- 0.0877753 x
4
In[214]:= g3 = Plot[sol2, {x, -2, 7}]
-2 2 4 6
-20
-10
10
20
30
Out[214]= ~ Graphics ~
intromat.nb 26
In[215]:= Show[g1, g3]
-2 2 4 6
-20
-10
10
20
30
Out[215]= ~ Graphics ~
Por supuesto, en este caso el polinomio adecuado es de orden 2, pero esto puede no saberse en situaciones reales.
Podemos comparar las dos soluciones:
In[216]:= Show[g1, g2, g3]
-2 2 4 6
-20
-10
10
20
30
Out[216]= ~ Graphics ~
El problema tambin puede resolverse fcilmente programando la solucin en el lenguaje de Mathematica. Pero en este caso resulta mucho ms
conveniente utilizar la funcin incorporada Fit.
Borramos:
In[217]:= Remove["Global+"]
Grficos
Son expresiones como las dems, pero hay funciones que, como efecto colateral, las muestran.
Las expresiones grficas combinan en listas anidadas primitivas grficas (puntos, lneas, etc.) y directivas grficas
(tamaos, colores, ancho, etc.):
In[218]:= dibu = {
{RGBColor[1, 0.5, 0], PointSize[0.05], Point[{1, 4}], Point[{-2, 2}]},
{RGBColor[1, 0, 1], AbsoluteThickness[2],
Line[{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}]}
};
intromat.nb 27
In[219]:= Graphics[dibu] // Show[#, AspectRatio - Automatic, Frame - True] &;
-2 -1.5 -1 -0.5 0 0.5 1
0
1
2
3
4
Tambin hay primitivas 3D. (Y visores OpenGL gratuitos.)
Se pueden exportar los objetos grficos a cualquier formato (jpeg, eps, etc.).
Otras cosas
Se puede invocar una funcin de varias maneras:
In[220]:= Sqrt[4]
Out[220]= 2
In[221]:= Sqrt4
Out[221]= 2
In[222]:= 4 // Sqrt
Out[222]= 2
Los corchetes son los ms seguros porque no hay problema de ambigedad. Las dos barras sirven para tomar toda la expresin de la izquierda y
aplicar finalmente una funcin.
En una celda podemos poner varias expresiones que se evaluarn una detrs de otra. Si no deseamos mostrar el resultado de una expresin
ponemos punto y coma detrs.
In[223]:= 2 + 2
3 + 3;
4 + 4
Out[223]= 4
Out[225]= 8
Cuando estamos corrigiendo la definicin de un smbolo que tenga varias reglas asociadas, conviene poner Clear al principio para que cada vez que
se evale el juego de definiciones, las reglas anteriores, errneas, se borren. Si no se hace as puede ser que en las pruebas se obtengan
resultados incorrectos.
In[226]:= f[x_Integer] := 3 x
intromat.nb 28
In[227]:= f[3]
Out[227]= 9
Si ahora cambiamos la definicin
In[228]:= f[x_] := 2 x
El resultado no cambia porque toma la regla anterior que es ms especfica:
In[229]:= f[3]
Out[229]= 9
Las dos reglas coexisten:
In[230]:= f[3.0]
Out[230]= 6.
En estos casos conviene borrar al principio las definiciones del smbolo para que se quede slo con las definiciones explcitamente evaluadas
despus.
In[231]:= Clear[f]
f[x_] := 2 x
In[233]:= f[3]
Out[233]= 6
Por supuesto, en programas grandes conviene organizar un documento con secciones de definicin, de ejemplos de uso, etc.
Borramos:
In[234]:= Remove["Global+"]
intromat.nb 29

You might also like