Matemáticas con Mathematica

Práctica 3. Listas. Reglas de sustitución

Francisco Javier Pérez González
Departamento de Análisis Matemático
Universidad de Granada

Listas

En Mathematica una lista es cualquier expresión que empiece con "{" y termine con "}". Ejemplos de listas son {1,2,3}, {Cos[x],Sin[y]}, {a,{b,c}}, {{1,2},{3,4}}. Una lista es realmente un vector (cuyos elementos pueden ser de muy variada naturaleza) por eso el orden en que se escriben sus elementos es importante.

{1, 2} == {2, 1}

Los comandos que se usan con mayor frecuencia para generar listas son Table[ ] y Range[ ].

Table[expr, {k}] genera una lista con k copias de expr. 
Table[expr, {i, imax}] genera una lista de los valores de expr cuando i recorre los valores 1,2,... hasta imax. 
Table[expr, {i, imin, imax}] genera una lista de los valores de expr cuando i recorre los valores imin, imin+1,... hasta llegar sin exceder imax. Los valores imin, imax pueden o no ser enteros.
Table[expr, {i, imin, imax, inc}] igual que el anterior pero con incrementos iguales a inc. 
Table[expr, {i, imin, imax}, {j, jmin, jmax}, … ] produce una lista de listas (una lista anidada). Para cada valor del índice i se recorren todos los valores del índice j.
Range[k] genera una lista con los primeros k enteros positivos.
Range[a, b] genera una lista que empieza en a con incrementos de una unidad hasta llegar a b sin excederlo. Los números a y b pueden o no ser enteros.
Range[a, b, inc]  igual que el anterior pero con incrementos iguales a inc.

Table[Sin[x], {3}]Table[Random[ ], {10}]   Table[2^i, {i, 6}]Table[i^2, {i, 3, 7}]Table[i^2, {i, 3.5, 7}]Table[i^2, {i, 3.5, 7, 0.5}]Table[n^m, {m, 2}, {n, 3.5, 7, 0.5}]Range[5]Range[2.7, 9]Range[2.7, 9,  .8]

Cuando tengas que trabajar con listas de muchos elementos el comando Range[ ] suele ser más rápido que Table[ ].

Timing[Table[i, {i, 200000}]][[1]]   \(\(Timing[Range[200000]]\)[\([1]\)]
 (*\ 
      tiempo\ que\ tarda\ Range[\ ]\ en\ generar\ los\ primeros\ doscientos\ 
        mil\ números\ *) \)

Una particularidad de Mathematica extraordinariamente útil es que casi todas las funciones pueden trabajar con listas. Aquí tienes unos ejemplos.

Sin[Range[1. , 2,  .1]]Range[1, 7]^21/Range[1, 7]{Range[1, 3], Range[4, 7]}^2

En general, para aplicar una función a los elementos de una lista, se usa el comando Map[funcion,lista] donde "funcion" debe ser el nombre de la función.

Map[funcion, {a, b, c}]Map[1/x, {1, 2, 3}]   inverso[x_] := 1/xMap[inverso, {1, 2, 3}]

Con frecuencia hay que sumar o multiplicar todos los elementos de una lista lo que se hace con los comandos Apply[Plus,lista] y Apply[Times,lista].

Apply[Plus, Range[1, 1000]]   Apply[Times, Range[1, 10]]   Apply[Plus, {{2, 3}, {4, 5}}]   Apply[Times, {{2, 3}, {4, 5}}]

El comando Length[lista] proporciona el número de elementos de una lista.

Length[Range[23]]Length[Table[Range[k], {k, 7}]]

Una matriz es una lista cuyos elementos son listas simples (las filas) de igual longitud (número de columnas).

A = Table[-i*j + 2  j, {i, 3}, {j, 4}]

Podemos escribir A en forma matricial.

MatrixForm[A]

Podemos sumar y multiplicar listas de igual longitud. El producto de listas se hace elemento a elemento, es decir, se multiplican los elementos que ocupan el mismo lugar en cada una de las listas.

{a, b, c} + {x, y, z}   {a, b, c} {x, y, z}   {{a, b}, {1, 2, 3}} {{2, 3}, {x, y, z}}

Para multiplicar dos matrices con las dimensiones apropiadas se escribe "." entre ellas dos. Para multiplicar matrices debes representarlas como listas y no usar la forma matricial MatrixForm[ ].

B = Table[i*j - 2  j, {i, 4}, {j, 3}]

MatrixForm[B]

M = A . B

MatrixForm[M]

Observa la diferencia.

M M   M . M   {a, b, c} {x, y, z}   {a, b, c} . {x, y, z}

Para indicar el elemento que ocupa el lugar k en una lista se usa la sintaxis "lista[[k]]".

{a, b, c, d}[[2]]   A[[1]]

En una lista de listas se usa la sintaxis "lista[[i,j]]" para seleccionar el elemento que ocupa el lugar i de la lista (la fila) y dentro de él el que ocupa el lugar j (la columna).

A[[1, 4]]

El comando Reverse[lista] invierte el orden de los elementos de la lista.

Reverse[{a, b, c, d, e}]

El comando Transpose[listadelistas] intercambia los primeros dos niveles en "listadelistas". Cuando se trata de una matriz cambia filas por columnas.

Transpose[A]

% // MatrixForm

Transpose[{{{1, 2}, {3, 4}}, {5, 6}, {7, 8}}]

El comando Sort[lista] ordena los elementos de una lista. Last[lista] y First[lista] nos dan el último y el primer elemento de una lista. Max[lista] y Min[lista] nos dan el máximo y el mínimo elemento de una lista numérica.

\(Sort[{u, x, v, c, a, f, e}]\ \  (*\ 
      ordena\ lexicográficamente\ *) 
\)\(Sort[{0.5, 0.12, 0.23, 0.67, 0.765, 0.07}]\ \  (*\ 
      ordena\ de\ menor\ a\ mayor\ *) 
\)\(Last[{0.5, 0.12, 0.23, 0.67, 0.765, 0.07}]\ \  (*\ 
      último\ elemento\ *) 
		\)\(First[{u, x, v, c, a, f, e}]\ \ \  (*\ primer\ elemento\ *) 
		\)\(Max[{0.5, 0.12, 0.23, 0.67, 0.765, 0.07}]\ \ 
		\)Min[{0.5, 0.12, 0.23, 0.67, 0.765, 0.07}]

Una operación importante es la de seleccionar elementos en una lista lo que se hace con el comando Select[lista,criterio]. Hay que definir previamente el criterio de selección el cual debe ser una función boleana. Para definir esa función es obligado que uses la asignación diferida porque en otro caso Mathematica tratará de evaluar inmediatamente la expresión a la derecha lo que dará un error. Aquí tienes algunos ejemplos.

mayorque7[x_] := x > 7   Select[Range[-2, 10], mayorque7]

multiplodetres[x_] := IntegerQ[x/3]   
      Select[Range[-15, 15], multiplodetres]

A veces podemos necesitar un criterio de selección que depende de un parámetro.  Por ejemplo, supón que queremos seleccionar  en una lista los números x con la propiedad de que k ≤ x < k + 1 y que eso queremos hacerlo para valores de k = 0, 1, 2,  ... , 9.  Podríamos definir diez criterios de selección de la forma "comprendidoentre2y3[x_]:=2≤x<3" y aplicar dichos criterios de uno en uno para seleccionar los elementos de la lista comprendidos en cada uno de esos intervalos. Pero es mejor hacerlo como sigue.

\(milista = Table[Random[\ Real, {0, 10}], {50}]\ ;  (*\ 
      generamos\ una\ lista\ con\ 50\ números\ aleatorios\ reales\ 
        comprendidos\ entre\ 0\ y\ 10\ *) 

    \(comprendidoentre[k_]\)[x_] := k ≤ x < k + 1\  (*\ 
      así\ definimos\ de\ golpe\ todos\ los\ criterios\ de\ 
        selección, \ 
      pues\ la\ función\ "comprendidoentre[k]"\ elige\ los\ 
          números\ comprendidos\ entre\ k\ y\ k + 1\ *) \)Table[Select[milista, comprendidoentre[k]], {k, 0, 9}]

Las funciones boleanas OddQ, EvenQ, IntegerQ, NumberQ, VectorQ, PrimeQ, NumericQ, Positive, Negative pueden usarse como criterios de selección.

Select[Table[3*k, {k, 15}], EvenQ]   Select[Table[3*k, {k, 15}], OddQ]   Select[{1, {2, 3}, a, {c}, d, e}, VectorQ]   
      Select[Sin[Range[2. , 5. ,  .25]], Positive]Select[Sin[Range[2. , 5. ,  .25]], Negative]

Los comandos Append[lista,elemento] y Prepend[lista,elemento] agregan "elemento" al final o al principio de "lista".

Append[{a, b, c}, 1]Append[{a, b, c}, {1, 2}]Prepend[{a, b, c}, 1]Prepend[{a, b, c}, {1, 2}]

Para extraer o eliminar elementos de una lista se usan Take[lista,{numero1,numero2}] y Drop[lista,{numero1,numero2}].

Take[{a, b, c, d, e, f}, {2, 4}]   Take[{a, b, c, d, e, f}, 3]   Take[{a, b, c, d, e, f}, -3]

Drop[{a, b, c, d, e, f}, {2, 4}]   Drop[{a, b, c, d, e, f}, 3]   Drop[{a, b, c, d, e, f}, -3]

El comando Partition[lista,k] hace una partición de "lista" en sublistas disjuntas de k elementos consecutivos. Si el número de elementos de "lista" no es múltiplo de k los últimos elementos se eliminan. Partition[lista,k,j] hace una lista con sublistas de k elementos consecutivos que empiezan en los elementos de "lista" que ocupan los lugares 1, j+1, 2j+1,...

Partition[{a, b, c, d, e, f, g}, 2]Partition[{a, b, c, d, e, f, g}, 3, 2]Partition[{a, b, c, d, e, f, g}, 4, 1]

Mathematica dispone de muchísimos comandos para trabajar con listas. Uno de los más útiles con el que acabamos esta sección es el comando Outer[f, lista1, lista2] donde f puede ser una función o un comando.

Outer[f, {a, b, c}, {1, 2, 3, 4}]

Outer[List, {a, b, c}, {u, v, x}]

Transpose[%]

Clear["@"]

Reglas de sustitución. Operador de sustitución

Cuando queremos sustituir en una expresión un símbolo por un valor o por otro símbolo puede no ser conveniente usar el comando de asignación (=) porque dicho comando atribuye un valor fijo "para siempre". El siguiente ejemplo explica lo que quiero decirte.

\(\(polixy = x*y^2 + 3  x + 4  y\ 
    
 (*\ una\ expresión\ algebraica\ en\ la\ que\ intervienen\ dos\ 
        variables\ "x"\ e\ "y"\ *) \)\)

Podemos querer sustituir en dicha expresión la variable "x" por 7. Una forma de hacerlo es como sigue.

x = 7polixy

El inconveniente de esto es que "polixy" ha cambiado y "x" ya no es una variable. Hay otra forma de proceder que consiste en decirle a Mathematica "sustituye x por 7" pero deja "polixy" igual que está y además "x" debe seguir siendo una variable. Para ello necesitas DOS comandos: una regla de sustitución (x -> 7) y el comando de sustitución ( /. ). Una regla de sustitución inmediata es un comando de la forma "expr1 -> expr2" que representa una regla que transforma "expr1" en "expr2". Puedes escribir  ->  con mejor apariencia tecleando "Esc -> Esc". Este es el resultado ->. Por sí sola una regla no hace nada. Para aplicar una regla necesitas el operador de sustitución cuya sintaxis es de la forma "expr /. regla" o "expr /. {regla1, regla2,...}" que aplica una regla o varias reglas después de evaluar "expr". Por ejemplo "expr1 /. b->c" significa que en la expresión "expr1" después de ser evaluada todas las apariciones de b deben ser sustituidas por c. Observa su uso.

Clear[x]      polixy
               \(polixy /. x -> 7\ \ \ \ 

    		 (*\ atribuimos\ a\ x\ el\ valor\ 7\ obteniendo\ igual\ resultado\ que
        \ antes\ *) \)polixy

?x

Cuando en un comando del tipo "expr /. regla" no puede aplicarse ninguna regla de sustitución Mathematica devuelve "expr" sin cambio ninguno.

a + 3  b /. c -> 2

Es importante advertir que el operador de sustitución aplica las reglas de sustitución exactamente una sola vez en cada parte de la expresión que hay a su izquierda.

3  (x^2) Cos[1 + x + (x^2)] /. {(x^2) -> x, x -> a}

Si aplicamos una lista de listas de reglas de sustitución obtenemos como resultado una lista cuyos elementos se obtienen aplicando cada una de las reglas de sustitución a la expresión que hay a la izquierda.

3  (x^2) Cos[1 + x + (x^2)] /. {{(x^2) -> x}, {x -> a}}

Ejercicio 1

sumalista[q_] := 
      (temp = Table[Random[], {q}]  ;  Apply[Plus, temp]   )

sumalista[1000]

Ejercicio 2

Ejercicio 3