Realizando Cálculos

Utilizando resultados previos

Cuando se realizan cálculos, es frecuente requerir el uso de resultados previos. Mathematica permite hacer referencia aresultado previos utilizando el objeto % (éste hace simpre referencia al valor de la última celda de  salida).

Por ejemplo:

3*4

agregar 1 al resultado

%+1

Utilizar los dos resultados previos

3 %+% %+%%

para hacer referencia al nth resultado se utiliza %n donde n es el número de la celda de salida

%2+%3

Definición de variables

Se realiza de  igual forma que en los otros lenguajes

asignar el valor de 5 a la variable x

x=5

cuando aparesca la variable x Mathematica la reemplazará con el valor 5

x^3

para asignar un valor nuevo a x

x=5+2

Asignación

x=valor 	asignar valor a la variable x
x=y=valor	asignar valor a las varibles x y y simultaneamente
x=. o Clear[x]	remover el valor de x

Es importante recordar que los valores a las variables son permanentes. Una vez asignadas el valor se mantendrá hasta que se remuevade forma especifica o bien se reinicie el kernel de Mathematica. 
Olvidar las definiciones previas es la fuente más común de errores, por eso se recomienda no utilizar variables globales.  En caso de ser necesarias remover tan pronto se terminen de utilizar.

Valores para símbolos.

Cuando Mathematica  transforma una expresión como 3 x + x en 4 x, significa que está tratando a la expresión en forma simbólica. En ese caso, x es un símbolo que puede representar cualquier expresión. 
Frecuentemente es necesario remplazar a x  con un valor particular. Puede ser un número u otra expresión.  Para realizar ésta transformación es necesario crea regla de transformación. Por ejemplo para remplazar a x  en la expresión 1 + 2 x,  se crearía la regla x->3 (los caracteres - y > deben escribirse seguidos y sin espacio entre ellos). Para aplicar la regla, se escribe expr /. regla. El operador de reemplazo /.  son los símbolos  / y . sin espacios.

1 + 2 x /. x->3

puede relizarse el reemplazo para una expresión

1+x^2 /. x->x+y

se puede definir una variable de una regla, para después utilizarla

regla=x->3x+b

x^3+1/. regla

también aplica para el operador %

x->y+1

(x+1)^2/. %

Se pueden aplicar multiples reglas poniendolas en una lista

(x+y)(z-y)^2 /. {x->3,y->1-a,z->1}

Se pueden mezclar reemplazos y asignaciones. Por ejemplo

la siguiente instrucción asigna el valor al símbolo t

t=1+x^2

La siguiente instrucción sutituye x con 3 en el valor de it

t/. x->3

Encontrar el valor de t para un valor diferente de x

t/. x->7

encontrar el valor de para x=Pi cuando

t /.x->Pi // N

¿Cómo funciona el operador //?

Secuancia de operaciones

Se pueden especificar multiples opetaciones en una sóla celda separandolas por “;” ,  expr1;expr2; ..exprn;

Se imprime el resultado de la útlma operación

x=1;z=6;x+z

si no se queire que se imprima se agrega ; al final

x=1;z=15;x+z;

aún cuando no se imprime la celda de salida existe

%

Asignación diferida

Es importante distinguir entre el operador de asignación inmediata (=) y la  asignación diferida (:= “SetDelayed[ ]”). Cuando se escribe “expr1 := expr2”  se asigna “expr1” al valor diferido de “expr2” pero “expr2” no se evalúa inmediatamente sino que para ello hay que llamar a “expr1” y cada vez que lo hacemos “expr2” se evalúa de nuevo. Para explicar  la diferencia, en el siguiente ejemplo se utiliza la función “Random[ ]”, está función regresa un número aleatorio entre 0 y 1. 
Probar Random

Random[]

Asignando a una variable con el operador de asignación inmediata

rand=Random[];

rand

rand

Asingando con el operador de evaluación diferida

rand1:=Random[];

rand1

rand1

rand1

Definición Básica de Fuciones

Para definir funciones en Mathematica no es necesario definir los tipo de variables que recibe como argumentos. Para definir una función en Mathematica podríamos tener la tentación de hacerlo como se hace en lenguaje matemático (sólo reemplazando los  símbolo ()  por  [])

Clear[x];
F[x]=x^2

si esto lo anterior funciono esperariamos poder hacer los siguiente

F[2]

¿Qué ocurrio?

Cuando supuestamente definimos la función sólo asignamos el valor de x^2 al símbolo F[x].
Dado que los argumentos en una función en Mathematica no tienen tipo pueden ser cualquier cosa, por ello es necesario especificar que ese argumento debe sutituirse y esto se hace mediante la especificacion de un patrón (pattern). Retomaremos esto después por ahora solo necesitamos saber que se especifica el patrón (variable) mediante la adición de un guión bajo  _ al nombre del símbolo. 
Por ejemplo

F[x_]=x^2;

ahora al evaluar

F[5]

el patrón tambien puede ser una constante, en éste caso no se requiere el _.

Fac[0]=1

Con lo anterior ya podemos definir algunas funciones recursivas básicas. Por ejemplo si recuerda la definición del Factorial temenos que:
Factorial(1)=1 y Factorial x>1 es x*Factorial(x-1)

Fac[0]=1;
Fac[x_]=x*Fac[x-1];

ups! no  funciona como lo podemos resolver?

Fac[50]

Matématica también permite la definición de funciones por intervalos. Por ejemplo la función de factorial la podríamos definir para n=0,n=1, n<0 y n>0. Esto lot hariamos con el Operador Conditon “/;” de la siguiente forma:

Fac1[x_/; x==0]=0;
Fac1[x_/; x==1]=1;
Fac1[x_/; x≥1]:=x*Fac1[x-1];
Fac1[x_/; x<=0]:=Print["No existe el Factorial para un número ", x];

la  condición puede escribirse con la notación que utilizamos para desigualdades.


Ejercicio 1: Con lo visto hasta ahora, generar la siguiente grafica.

Listas
Construyendo listas de Objetos

En programación frecuentemente se requiere agrupar múltiples objetos, para que estos sean tratado como una sólo entidad. En Mathematia la forma de crear y manejar colecciones de objetos son las listas. 
Una lista {a,b,c,d,e} es una lista de cinco objetos. Pero por diferentes razones, es posible y desable tratatla como un sólo objeto. Por ejemplo para asignar una referencia a variable a la lista o aplicar una operación aritmetica a la lista completa.

Asignar el valor de la lista a un variable:

A={1,3,5,7}

Obtener el cuadrado de los elementos en una lista:

A^2

Suma elemento a elemento de dos listas:

{1,2,5}+{6,5,2}

Es posible aplicar cualquier función matemática a una lista completa

Exp[%]//N

también se pueden asignar listas a variables.

v={5,3,7,2,1}

{5,3,7,2,1}

v/(v-1)

Construyendo tablas

Es posible utilizar las listas como tablas de valores.  Se pueden generar tablas de una expresión para diferentes valore de un patametro.

La siguiente expresiós genera uan lista con la  raíz cuadrada de números del 1 al 10

Table[Sqrt[i],{i,10}]

el coseno de  0 a 2π con incrementos de (π/2)

Table[Cos[θ],{θ,0,2π,π/2}]

También se pueden tabular formulas

Table[x^2+2x-3,{x,-5,5}]

Se pueden variar multiples parametros

Table[x^i-y^j,{i,1,3},{j,1,2}]

¿Que genera la siguiente expresión?

Table[x^i-y^j+z^`k,{i,1,3},{j,1,2},{k,1,2}]

Podemos presentar el resultado en forma matricial

MatrixForm[%]

o de tabla

TableForm[%]

Ejecicio 1: Implementat una Función que reciba dos parametros n y m genere una matriz de números aleatorioes de dimension nxm.

Ejercicio 2: Implementar una función que genere una matriz cuadrada en la que los elementos en la posiciones en que la suma de los indices sea multiplo de 3 sean igual a  0 y de cualquier otra forma igual a 1.

Resumen pare el uso de Table: 

Table[expr, {k}] genera una lista con k copias de expr. 
Table[expr, {i, imax}] genera una lista de los valores de expr  evaluada en  los valores 1,2,... hasta imax. 
Table[expr, {i, imin, imax}] genera una lista de los valores de expr  evaluada en  los valores  i recorre los valores desde imin, hasta imax. Los valores imin, imax pueden o no ser enteros.
Table[expr, {i, imin, imax, inc}] igual que el anterior pero con incrementos de inc. 
Table[expr, {i, imin, imax}, {j, jmin, jmax}, … ] produce una lista de listas (una lista anidada o nested list). Para cada valor del índice i se recorren todos los valores del índice j.

Otra forma de generar listas es con la función Range 

Range[k] genera una lista con los primeros k enteros positivos.

Range[5]

Range[a,b] genera una lista comenzando en a con incrementos  unitarios hasta  b sin excederlo.

Range[0.1, 9]

Range[a,b,in]  igual que el anterior pero con incrementos de inc.

Range[-5,5,0.9]

Para listas grandes es evidente que Range es más rápido que table. Usando la función Timing

Timing[Table[x,{x,2000000}]]

Timing[Range[2000000]]

Más operaciones sobre listas

Length[Range[15]] (* obtiene el tamaño de una lista *)

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}]

Obtener el i-esimo elemeto de una lista

lista={a,b,c,d,e};
Part[lista,3]

o

lista[[3]]

mútiples elementos

Part[lista,{1,3,5}]

rango de elementos

Part[lista,2;;4]

Take[lista,n]		Los primeros n elementos de lista
Take[lista,-n]		Los últimos n elementos de lista
Take[lista,{m,n}]	Los elementos de la psocicion m  a n(inclusivo)
Rest[lista]		lista con el primer elmeto removido	
Drop[lista,n]		lista con los primeros n elmetos removidos	
Most[lista]		lista con e último elmeto removido	
Drop[lista,-n]		lista con  los utimos n elmetos removidos
Drop[lista,{m,n }]	lista con los elementos de la posición m a n removidos

Take[lista,3]

Take[lista,-2]

Rest[lista]

Drop[lista,3]

Drop[lista,{3,3}]

Busqueda y prueba de elementos en las listas

Position[lista,form]		Regresa la posición en la que ocurre form en lista
Count[lista,form]		Regresa el número de veces que ocurre form en lista
MemberQ[lista,form]		Prueba si form ocurre  en lista
FreeQ[lista,form]		Prueba si form no ocurre  en lista

lista1={a,b,c,a,d,e,a}

Position[lista1,b]

Position[lista1,a]

Count[lista1,a]

Matriz=MatrixForm[Table[Mod[i*j,3],{i,3},{j,3}]]

FreeQ[Matriz,3]

Position[Matriz,0]

Agregar, borrar y modificar listas

Prepend[lista, elemento]		Agrega elemento  al inicio de lista
Append[lista, elemento]		Agrega elemento  al  final de lista
Insert[lista, elemento,i]		Agrega elemento  en la posción i  de lista
Insert[lista, elemento,-i]		Agrega elemento  en la posción i  contando desde el final de  lista
Riffle[lista, elemento]			Agrega elemento  entre cada elemento de  lista

Riffle[{a,b,c,d},x]

Delete[lista,i]			borra el elemento en la posción i l de  lista
ReplacePart[lista,i->new]	Reemplaza el elemento  en la posción i  de  lista con new (equivalente a lista[[i]]=new)
ReplacePart[lista,{i,j}->new]	Reemplaza los elemento de  i,j  de  lista con new (equivalente a lista[[i,j]]=new)

ReplacePart[{a,b,c,d},3->x]

ReplacePart[{{a,b},{c,d}},{1,2}->x]

Cuando M  es una matriz

M[[i]]=new	Reemplaza la i-esima fila
M[[All,i]]=new	Reemplaza la i-esima columna

M={{a,b},{c,d}}

M[[1]]={x,y};

M

M[[All,1]]={a,b};

M

Mezcla de Listas

Join[lista1,lista2]	Concatena las listas lista1 y lista2
Union[lista1,lista2]	Concatena las listas lista1 y lista2 eliminando elementos repetidos

Agrupando y Combinado

Partition[list,n]		particiona la lista en sublistas de n elementos
Partition[list,n,d]	utiliza un offset d  para listas sucecivas
Split[list]		Divide la lista en piezas que consisten de elementos identicos

lista={a,b,c,d,e,f,g,h}

Partition[lista,3]

Partition[lista,3,1]

Partition[lista,3,3]

Split[{a,a,b,b,b,a,a,a,b}]

Tuples[list, n]			genera todos los posibles n-tuples de la lista
Tuples[{list1, list2, ...}]		genera todos los posibles tuples de las combinaciones de tomar un elemento de cada lista

Tuples[{a,b,c},2]

Tuples[{{a,b},{1,2}}]

Una operación importante es la de seleccionar elementos en una lista lo que se hace con la función Select[lista,criterio]. En necesario definir  criterio de selección el cual debe ser una función boleana. Para definir esa función debe utilizarse asignación diferida.

mayorque5[x_]:=x>5
Select[Range[-2,10],mayorque5]

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

Funciones y Lista

Casi todas las Funciones ya definidas en Mathematica pueden operar sobre lista.

Sin[Range[0,2π,π/6]]

Exp[Range[0,10]]

pero que ocurre con las definidas por el usario

Fac[1]=1;
Fac[x_]:=Fac[x-1]*x;

Fac[Range[10]]

Tarea: Explicar que ocurrio en la celda anterior

Uso de Map, MapThread y Apply

Para aplicar una función definida por el usuario se utiliza  la función Map[funcion, expr]  o funcion /@ expr donde funcion, deber ser el nombre de la función.

Map[Fac,Range[10]]

Fac /@ Range[10]

Map[1/x, Range[10]] (* incorrecto *)

Map[funcion, expr, splevel] en éste caso splevel especifica el nivel al que se aplicara la función.

al nível superior

Map[F,{{{a,b},{c,d}},{{e,f},{g,h}}}]

segundo nivel

Map[F,{{{a,b},{c,d}},{{e,f},{g,h}}},{2}]

tercer nivel

Map[F,{{{a,b},{c,d}},{{e,f},{g,h}}},{3}]

multiples niveles, niveles 1 y 2

Map[F,{{{a,b},{c,d}},{{e,f},{g,h}}},2]

Map permite aplicar una función a una expresión de un argumento. Perp algunas veces es necesario aplicar una función de múltiples agumentos que corresponden a partes de muchas expresiones. En éste caso se utiliza MapThread.

MapThread[f,{expr1,expr2,...,}]		Aplica f  a los elemtos correspondientes en cada expresión expr
MapThread[f,{expr1,expr2,...,}, level]	Aplica f  a los elemtos correspondientes en cada expresión expr, al nivel level

MapThread opera sobre una expresión cin cualquier número de parametros, siempre y cuando tengan la misma estructura

MapThread[F,{{a,b},{c,d},{e,f}}]

MapThread[F,{{a,b,c},{d,e,f}}]

Apply  
Apply[f, expr] o f @@ expr			Reemplaza cabeza(head) de la expresión por f
Apply[f, expr,{1}] o f @@@ expr		Reemplaza cabeza en el nivel 1 de la expresión por f
Apply[f, expr,level] o				Reemplaza cabeza en el nivel espcificado por level de la expresión por f

Apply[f,{a,b,c,d}]

f@@ {a,b,c,d}

Plus @@ {a,b,c,d}

f @@ {{a,b},c,d}

Plus@@ {{a,b},c,d}

f@@ {{a,b},{c},d}

Plus @@ {{a,b},{c},d}

Funciones Puras

Function[x, body]		Una funcion pura en el que x es reemplazada por cualquier argumento proporcionado
Function[{x1,x2,...,}, body]	Una funcion pura en el que toma múltiples argumentos
body &				Una función pura en la cual los argumentos son especificados como # o #1, #2, #3, etc.

Cuando se utilizan opereaciones como Nest o Map, siempre se tiene que especificar la función a aplicar.

h[x_]:=f[x]+g[x]

Usandos Map

Map[h,{a,b,c}]

para obtener el mismo resultado utilizando una función pura

Map[f[#]+g[#]&,{a,b,c}]

Existen muchas formas equivalentes de escribir funciones puras en Mathematica. La idea en todos los casos es construir un objeto el cuál, cuando se le proporciones los argumentos adecuados, compute una función particular. Por ejemplo si f  es una función pura, entonces f[a] evalua la función con el argumento a.

La función cuadrado como función pura

cuadrado:=Function[x,x^2]

cuadrado[n]

Map[cuadrado,a+b+c]

para dos argumentos

Function[{x,y},x^2+y][a,b]

Las funciones puras son el equivalente a las funciones anonimas o lamdba en LISP. Así como el nombre de la función es irrelevante, también los nombres de los argumentos los son. Mathematica permite omitir el uso explicito de nombres de los argumentos en funciones puras, en su lugar se pueden especificar utilizando el número de slot #n. En una función pura de Mathematica, #n indica el n-esimo argumento. Mientras # indica e primer argumentol

por ejemplo #^2 & es la forma corta de una función que eleva al cuadrado el argumento

Map[#^2&,a+b+c]

la sigueinte instrucción toma los primeros dos elementos de cada lista

Map[Take[#,2]&,{{1,2,3},{2,4,6},{4,8,12}}]

en las funciones purar el amperson le indica a Mathematica la definición de una función pura, por eso es importante simpre recoradar ponerlo.

Las funciones puras pueden tomar cualquier número de argumentos

## indica el uso de todos los argumentos

f[##,##]&[x,y]

##2 ndica el uso de tosos los argumentos a partir de la segunda posición

Apply[f[##2,#1]&,{{a,b,c},{ap,bp}},{1}]

Ejercicio 1
Implementat una función para el valor absoluto

a) Genera una lista de 30 elementos cuyos elementos sean listas de dos números que no sean valores exactos.
b) Usando una regla de sustitución apropiada transforma la lista anterior en otra en la que la primera coordenada 
    de cada lista sea multiplicado por 3 y la segunda coordenada sea  el cuadrado de la original.
Ejercicio 2
a) Crear una función GeneraDatos[n_,N_]  que genere  una lista de coordenadas aleatorias  de n dimensiones y con N coordenadas. Por ejemplo  GeneraDatos[2,3] generara una lista de 3 elementos de dos cordenadas (un posible resultado sería {{0,1},{3,2},{-4,2}}). Los valores para las cordenadas deberar oscilar entre -N y N. 
b) Crear un criterio de ordenamiento que ordene de acuerdo con la distancias euclidiana de las coordenada al origen.

Module y Block

Al escribir programas en Mathematica, al igual que en otros lenguajes es deseable mantener cada pieza de software tan independitned como sea posible. Una forma de graantizar que las diferentes partes de un programa no interfieran entre si es proporcionado a las variables un ambiente “scope”. En Mathematica se cuenta con dos mecanismos para proporcionar esa funcinalidad Blocks y  Modules

Module[{x, y, ...}, expr] 		Indica que las ocurrencias de los símbolos x,y,... en expr  deben ser tratados como locales.  
Module[{x=x0, y=y0, ...}, expr] 	Indica que las ocurrencias de los símbolos x,y,... en expr  deben ser tratados como locales y con 						valores inciales x0  y y0  respectivamente.

Clear[FacM]
FacM[n_]:=Module[{fac},
fac[1]=1;
fac[x_]:=x*fac[x-1];
fac[n] (* la última liena es el valor de regreso *)
]

FacM[10]

Block[{x, y, ...}, expr] 		            Indica que las ocurrencias de los símbolos x,y,... son evaluadas con valores locales.  
Block[{x=x0, y=y0, ...}, expr] 		Define valores inciales locales para los símbolos x,y,...

Clear[FacB]
FacB[n_]:=Block[{fac},
fac[1]=1;
fac[x_]:=x*fac[x-1];
fac[n] (* la última liena es el valor de regreso *)
]

FacB[1023]

Diferencia

m=z^2

Module[{z=a}, z+m]

Block[{z=a}, z+m] (*Para todos los símbolos z=a*)

Modificar la variable $RecursionLimit de forma local

Clear[FacBM]
FacBM[n_]:=Block[{fac,$RecursionLimit=Infinity},
fac[1]=1;
fac[x_]:=x*fac[x-1];
fac[n] (* la última liena es el valor de regreso *)
]

Timing[FacBM[2000]]