29
Introducción a Mathematica (en construcción...) Alberto Ruiz <[email protected]> Departamento de Informática y Sistemas Universidad de Murcia, Spain Preliminares Mathematica es un entorno de cálculo simbólico, compuesto por un lenguaje de programación de alto nivel, una colección extensa de funciones matemáticas y de propósito general, y un sistema para editar interactivamente documentos como éste que contienen texto normal, órdenes sencillas, programas más complejos, gráficos, etc. Los documentos están organizados por "celdas" indicadas en azul a la derecha. Hay varios tipos de celdas: las más importantes son las de texto normal, y las de entrada (input) y salida de información (output), como las siguientes: In[1]:= 2 + 2 Out[1]= 4 El lenguaje de Mathematica es interpretado: no hace falta compilación. Está basado en reglas de transformación de expresiones y aprovecha muchas construcciones de programación funcional. Para ejecutar una orden o evaluar una expresión se edita en una celda tipo "input" y cuando esté terminada se pulsa Shift-Enter (tecla de mayúsculas + tecla de nueva línea). A continuación 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 multiplicación (también se puede usar *): In[3]:= 2 H5 + 5L Out[3]= 20 La aritmética es exacta: In[4]:= 1000 350 Out[4]= 20 7 y sin límite en el tamaño de los números: In[5]:= 2^100 Out[5]= 1267650600228229401496703205376 In[6]:= 100 ! Out[6]= 93326215443944152681699238856266700490715968264381621468592963895217599993229 9156089414639761565182862536979208272237582511852109168640000000000000000000 00000

Introducción a Mathematicadis.um.es/profesores/alberto/material/intromat.pdf · Introducción a Mathematica (en construcción...) Alberto Ruiz Departamento de

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

  • Introducció n a Mathematica

    (en construcción...)

    Alberto Ruiz Departamento de Informática y SistemasUniversidad de Murcia, Spain

    à Preliminares

    Mathematica es un entorno de cálculo simbólico, compuesto por un lenguaje de programación de alto nivel, unacolección extensa de funciones matemáticas y de propósito general, y un sistema para editar interactivamentedocumentos como éste que contienen texto normal, órdenes sencillas, programas más complejos, gráficos, etc.

    Los documentos están organizados por "celdas" indicadas en azul a la derecha. Hay varios tipos de celdas: las másimportantes son las de texto normal, y las de entrada (input) y salida de información (output), como las siguientes:

    In[1]:= 2 + 2

    Out[1]= 4

    El lenguaje de Mathematica es interpretado: no hace falta compilación. Está basado en reglas de transformación deexpresiones y aprovecha muchas construcciones de programación funcional.Para ejecutar una orden o evaluar una expresión se edita en una celda tipo "input" y cuando esté terminada se pulsaShift−Enter (tecla de mayúsculas + tecla de nueva línea). A continuación 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 multiplicación (también se puede usar *):

    In[3]:= 2 H5 + 5LOut[3]= 20

    La aritmética es exacta:

    In[4]:= 1000350Out[4]=

    207

    y sin límite en el tamaño de los números:

    In[5]:= 2^100

    Out[5]= 1267650600228229401496703205376

    In[6]:= 100!

    Out[6]= 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

    intromat.nb 1

  • Pero si en las operaciones aparecen números aproximados, el resultado también lo será:

    In[7]:= 1000.0350Out[7]= 2.85714

    Siempre se puede convertir un valor exacto en un valor aproximado usando la función N (convertir en un número).En Mathematica los argumentos se encierran entre corchetes:

    In[8]:= N@1000350DOut[8]= 2.85714

    In[9]:= Π

    Out[9]= Π

    In[10]:= N@ΠDOut[10]= 3.14159

    Como argumento opcional se puede especificar la precisión del número:

    In[11]:= N@Π, 100DOut[11]= 3.14159265358979323846264338327950288419716939937510582097494459230781640628

    6208998628034825342117068

    Disponemos de todas las funciones matemáticas usuales :

    In[12]:= [email protected][12]= 44.7012

    In[13]:= [email protected][13]= 0.992809

    In[14]:= Sin@30 DegreeDOut[14]=

    12

    Existen bibliotecas con constantes y unidades físicas.

    à Principio Fundamental de Mathematica

    Todo son expresiones que se evalú an mediante la aplicación de reglas de transformación estructural.

    Expresiones

    Una expresión es o bien un átomo (número o símbolo) o bien una "cabeza" y "argumentos", que, a su vez, sonexpresiones. Este tipo de estructura recursiva permite representar cualquier cosa: fórmulas matemáticas, progra-mas, dibujos, etc. Este mismo documento es en realidad una expresión de ese tipo.

    Las expresiones tienen una representación externa, visualmente conveniente, pero en realidad están constituidaspor este tipo de estructuras anidadas. Por ejemplo:

    intromat.nb 2

  • a + b

    es en realidad

    Plus@a, bD(Los componentes de una expresión (o argumentos de una función) se escriben con corchetes.) Otro ejemplo:

    a Sin@3 + b xDse representa internamente mediante

    Times@a, Sin@Plus@3, Times@b, xDDDDLa forma interna de cualquier expresión se obtiene mediante la orden FullForm:

    In[15]:= FullFormAa SinA b x + 3!!!!!!Πm

    EEOut[15]//FullForm=

    Times@a, Sin@Times@Power@Power@Pi, mD, Rational@-1, 2DD, Plus@3, Times@b, xDDDDDLos "arrays" se representan mediante la estructura más general de lista, que es una colección de expresionesencerradas entre llaves:

    84, a + b, 17, 81, 2, 3

  • In[17]:= Expand@H1 + xL10 H1 - yL5DOut[17]= 1 + 10 x + 45 x2 + 120 x3 + 210 x4 + 252 x5 + 210 x6 + 120 x7 + 45 x8 + 10 x9 + x10 - 5 y -

    50 x y - 225 x2 y - 600 x3 y - 1050 x4 y - 1260 x5 y - 1050 x6 y - 600 x7 y - 225 x8 y -50 x9 y - 5 x10 y + 10 y2 + 100 x y2 + 450 x2 y2 + 1200 x3 y2 + 2100 x4 y2 + 2520 x5 y2 +2100 x6 y2 + 1200 x7 y2 + 450 x8 y2 + 100 x9 y2 + 10 x10 y2 - 10 y3 - 100 x y3 -450 x2 y3 - 1200 x3 y3 - 2100 x4 y3 - 2520 x5 y3 - 2100 x6 y3 - 1200 x7 y3 - 450 x8 y3 -100 x9 y3 - 10 x10 y3 + 5 y4 + 50 x y4 + 225 x2 y4 + 600 x3 y4 + 1050 x4 y4 + 1260 x5 y4 +1050 x6 y4 + 600 x7 y4 + 225 x8 y4 + 50 x9 y4 + 5 x10 y4 - y5 - 10 x y5 - 45 x2 y5 -120 x3 y5 - 210 x4 y5 - 252 x5 y5 - 210 x6 y5 - 120 x7 y5 - 45 x8 y5 - 10 x9 y5 - x10 y5

    Solución simbólica de sistemas de ecuaciones:

    In[18]:= Solve@5 x - 8 a 4, xDOut[18]= 99x ® 4

    5H1 + 2 aL==

    Derivadas simbólicas:

    In[19]:= D@Sin@Exp@Cos@xDDD, xDOut[19]= -ãCos@xD Cos@ãCos@xD D Sin@xDIntegrales simbólicas:

    In[20]:= à Sin@xD2 âxOut[20]=

    x2

    -14Sin@2 xD

    Desarrollos en serie:

    In[21]:= Series@Exp@xD, 8x, 0, 5

  • Y 3D:

    In[24]:= Plot3D@[email protected] Hx x + y yLD, 8x, -3, 3

  • In[29]:= Factor@x99 + y99DOut[29]= Hx + yL Hx2 - x y + y2L Hx6 - x3 y3 + y6LHx10 - x9 y + x8 y2 - x7 y3 + x6 y4 - x5 y5 + x4 y6 - x3 y7 + x2 y8 - x y9 + y10LHx20 + x19 y - x17 y3 - x16 y4 + x14 y6 + x13 y7 - x11 y9 -

    x10 y10 - x9 y11 + x7 y13 + x6 y14 - x4 y16 - x3 y17 + x y19 + y20LHx60 + x57 y3 - x51 y9 - x48 y12 + x42 y18 + x39 y21 - x33 y27 - x30 y30 -x27 y33 + x21 y39 + x18 y42 - x12 y48 - x9 y51 + x3 y57 + y60L

    Y de números enteros:

    In[30]:= FactorInteger@192492352DOut[30]= 882, 6

  • Las integrales definidas se calculan simbólicamente, no numéricamente sumando áreas:

    In[38]:= à0

    1 41 + x

    âx

    Out[38]= 4 Log@2DIn[39]:= à

    0

    1 41 + x2

    âx

    Out[39]= Π

    Lo que nos permite que los extremos sean símbolos:

    In[40]:= à1

    t 11 + x

    âx

    Out[40]= -Log@2D + Log@1 + tDIn[41]:= % SimplifyOut[41]= LogA 1 + t

    2E

    (El símbolo % representa el resultado anterior)

    Si deseamos integrales numéricas hacemos lo siguiente:

    In[42]:= à0

    1 41 + x

    âx NOut[42]= 2.77259

    In[43]:= IntegrateA 41 + x

    , 8x, 0, v

  • In[47]:= DSolve@f’@xD k, f@xD, xDOut[47]= 88f@xD ® k x + C@1D

  • No confundamos el producto elemento a elemento (*):

    In[59]:= m *Inverse@mDOut[59]=

    ikjjjjjj 77-a c - a2

    7-a c

    - c2

    7-a c77-a c

    y{zzzzzzCon el producto de matrices (.):

    In[60]:= m.Inverse@mDOut[60]=

    ikjjjjj 77-a c - a c7-a c 00 77-a c - a c7-a c y{zzzzzIn[61]:= % SimplifyOut[61]= J 1 0

    0 1N

    Muchos más ejemplos pueden consultarse en la ayuda del sistema.

    Reglas de transformación estructural

    La descripción de los algoritmos en Mathematica se hace mediante un estilo de programación diferente a C.Aunque es posible usar construcciones de tipo for, while, etc., para controlar la asignación de valores a variables deacuerdo con la lógica del algoritmo (estilo "imperativo"), Mathematica está orientado hacia un estilo de progra-mación llamado "funcional" y, sobre todo, a la descripción de los algoritmos mediante lo que podemos llamartransformación estructural basada en "pattern matching" (reconocimiento de patrones sintácticos, o "esquemas deexpresión").

    El siguiente ejemplo muetra la aplicación de una regla de transformación muy simple. La notación "/." es unconvenio para indicar que la expresión de la izquierda se va a transformar de acuerdo con la regla de la derecha:

    In[62]:= p + jp . p ® 3 yOut[62]= j3 y + 3 y

    Aquí solo transformamos el número 3:

    In[63]:= p3 + jv+3 + 6 . 3 ® 4Out[63]= 6 + j4+v + p4

    Cuando combinamos la aplicación de reglas con pattern matching se obtiene un estilo de programación muy claroy expresivo. Por ejemplo, para indicar que una función es lineal podemos hacer algo como:

    In[64]:= f@a + g@cD + bD . f@x_ + y_D ® f@xD + f@yDOut[64]= f@aD + f@b + g@cDDPero la regla se ha aplicado solo una vez. Es mejor:

    In[65]:= f@a + g@cD + bD . f@x_ + y_D ® f@xD + f@yDOut[65]= f@aD + f@bD + f@g@cDDdonde //. significa que la regla se aplica hasta que la expresión no cambie.

    La parte izquierda de una regla es un patrón: un esquema de expresión donde algunas partes, indicadas con unsímbolo subrayado, representan variables o "comodines" que coinciden con cualquier expresión. La parte derechade la regla indica cómo se construye la expresión resultante recomponiendo trozos de la expresión original(denotados por los símbolos anteriores, ya sin subrayar).

    intromat.nb 9

  • La parte izquierda de una regla es un patrón: un esquema de expresión donde algunas partes, indicadas con unsímbolo subrayado, representan variables o "comodines" que coinciden con cualquier expresión. La parte derechade la regla indica cómo se construye la expresión resultante recomponiendo trozos de la expresión original(denotados por los símbolos anteriores, ya sin subrayar).

    En lugar de aplicar reglas concretas en cada caso, en la práctica resulta más cómodo suministrar reglas que sedeberán aplicar siempre que sea posible, en forma de definiciones.

    Definiciones

    En lenguajes de programación imperativos, del estilo de C, las variables son contenedores de números (o decódigos de otros objetos), y las funciones se definen para que admitan unos parámetros y devuelvan resultados deun cierto tipo. En Mathematica la filosofía es diferente: la programación consiste en asociar a cada símbolo unconjunto de reglas que se deben aplicar siempre, automáticamente.

    Cuando evaluamos una asignación 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 asignación como

    In[68]:= a = 3 + b

    Out[68]= 3 + b

    sustituye la regla a®2 por a®3+b.

    In[69]:= a2

    Out[69]= H3 + bL2Podemos 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 expresión. En realidad loque hacemos es introducir una regla de transformación automática asociada a ese símbolo.

    Este concepto se lleva a sus últimas consecuencias en lo que podríamos considerar como la definición de funci-ones. En este caso, lo que se hace es crear una serie de reglas automáticas para un símbolo, con patrones que hacenreferencia a posibles argumentos. Si evaluamos la siguiente asignación:

    In[70]:= sincos@x_D := Sin@xD + Cos@xDdefinimos la función sincos, pero lo que estamos haciendo en realidad es crear la reglasincos@x_D ® Sin@xD + Cos@xD y solicitar que sea evaluada siempre que sea posible. Observa el operador de asignación ":=" (dos puntos igual). Más adelante explicaremos la diferencia con "=". Por elmomento basta saber que en la mayoría de las situaciones en que definimos funciones usamos ":=",y cuandoasignamos variables usamos "=".

    La función ya está disponible:

    intromat.nb 10

  • In[71]:= sincos@3DOut[71]= Cos@3D + Sin@3DIn[72]:= sincos@2 ΠDOut[72]= 1

    In[73]:= [email protected][73]= -0.848872

    In[74]:= Plot@sincos@xD, 8x, 0, 2 Π

  • In[80]:= sinc@2 + 3 + a + b*bDOut[80]=

    Sin@8 + b + b2D

    8 + b + b2

    En general, las definiciones consisten de varias reglas, para considerar diferentes casos de interés:

    In[81]:= fact@0D = 1;fact@n_D := n fact@n - 1D

    En C se utilizaba la construcción "if" para determinar la acción a tomar. En Mathematica también se utiliza, peromuchas veces es más 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 evalúa en mismo momento de la definición.":=" define una regla cuya parte derecha se evalúa en el momento de usar la regla.

    In[83]:= a = 10100;b := 10100

    Lo que guardamos es:

    In[85]:= ?a

    Global‘a

    a =10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    In[86]:= ?b

    Global‘b

    b := 10100

    El resultado de la evaluación es el mismo

    In[87]:= a

    Out[87]= 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    In[88]:= b

    Out[88]= 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    Pero a ya lo tiene precalculado, y b lo tiene que calcular cada vez que se utilice.

    En general usaremos := en la definición de funciones y = para definir símbolos como si fueran variables con unvalor

    In[89]:= Remove@"Global‘*"D Patrones avanzados

    En muchos casos es conveniente especificar en un patrón secuencias de argumentos, condiciones de los elementosde una estructura, etc. Consideremos la anterior definción de fact:

    intromat.nb 12

  • In[90]:= fact@0D := 1fact@n_D := n fact@n - 1D

    El problema es que fracasa con números negativos o números no enteros:

    In[92]:= [email protected]$RecursionLimit::reclim : Recursion depth of 256 exceeded.

    $RecursionLimit::reclim : Recursion depth of 1024 exceeded.

    Out[92]= 3.4049139272933´10492 Hold@[email protected] - 1DDVamos a mejorarla un poco. Primero borramos todas las reglas asociadas a fact:

    In[93]:= Clear@factDY damos la nueva definición:

    In[94]:= fact@0D := 1fact@n_Integer?PositiveD := n fact@n - 1D

    La regla sólo "se dispara" en los casos permitidos:

    In[96]:= [email protected][96]= [email protected][97]:= fact@4DOut[97]= 24

    In[98]:= fact@-4DOut[98]= fact@-4D(Podríamos añadir una regla que recogiese el resto de los casos indicando un error.)

    El símbolo ? indica que el elemento de un patrón tiene que cumplir una condición. Por ejemplo x_?OddQ hacecoincidencia con un número impar, al que se denota por x.

    Por ejemplo, la función OddQ detecta números impares:

    In[99]:= OddQ@5DOut[99]= True

    In[100]:= OddQ@6DOut[100]= False

    Esto nos permite definir una función con valores diferentes según sea el argumento par o impar:

    In[101]:= g@n_?OddQD := 3 n + 1g@n_?EvenQD := n2

    Funciona como deseamos:

    In[103]:= g@3DOut[103]= 10

    intromat.nb 13

  • In[104]:= g@4DOut[104]= 2

    Dado cualquier símbolo del sistema (no de los definidos por nosotros, al menos en principio) podemos obtenerayuda sobre él pinchando encima y pulsando F1. P.ej. pruébalo con OddQ. También se puede pedir ayuda medi-ante la orden "Information" o símplemente con "?":

    In[105]:= ?OddQ

    OddQ@exprD gives True if expr is an odd integer, and False otherwise.La interrogación también sirve para mostrar las reglas que hemos asocidado a un símbolo:

    In[106]:= ?g

    Global‘g

    g@n_?OddQD := 3 n + 1g@n_?EvenQD := n

    2

    (se usa el mismo símbolo para las condiciones de los patrones y para pedir información sobre un símbolo)

    Continuamos con los patrones avanzados. Un símbolo detrás del subrayado indica el tipo de cabeza que tiene quetener la expresión para que haya coincidencia.

    La siguiente función f está definida para argumentos que sean listas o que sean q[.]

    In[107]:= f@x_ListD := Reverse@xDf@x_qD := 1 + x

    Cuando el argumento es un número no hay definición para f:

    In[109]:= f@3DOut[109]= f@3DCuando es una lista se dispara primera regla:

    In[110]:= f@81, 2, 3

  • In[114]:= s@810, 5, 18

  • El estilo de "programación funcional" trata de aproximarse a la práctica matemática usual, donde se utilizan"definiciones" de objetos que luego podrían sustituirse en cualquier otro punto del programa sin afectar a sufuncionamiento (transparencia referencial). No existe el concepto de "variable" a la que podamos asignar un valor,y la ejecución del programa consiste ú nicamente en la evaluación de funciones que con la misma entrada siempreproducirán la misma salida. Se han inventado muchos lenguajes funcionales. Uno particularmente atractivo esHaskell, que posee evaluación "no estricta" y una forma restringida pero muy práctica de pattern matching. Laevaluación no estricta (perezosa) permite trabajar de forma muy elegante con estructuras potencialmente infinitasde las que se calcularán sólo los términos necesarios. El pattern matching se usa para expresar las definiciones deuna función en diferentes tipos de entrada de manera mucho más clara que usando preguntas explícitas. Estelenguaje y otros de su estilo son muy prácticos para el prototipado rápido de muchos problemas de programacióntípicos, a veces sin demasiada pérdida de eficiencia. Sin embargo, por ahora no disponen del conjunto de bibliote-cas matemáticas necesarias para el cálculo científico ni permiten manipular cómodamente expresiones matemáticasarbitrarias.

    Mathematica incluye muchas construcciones de programación funcional. En realidad,es el estilo de programaciónrecomendado y eficiente para este sistema (aunque la sintaxis no es siempre tan elegante y concisa como p.ej. la deHaskell). La evaluación es estricta (más próxima a la programación convencional) por lo que las estructurassiempre tienen un tamaño finito concreto y se evalú an completamente aunque sólo necesitemos una parte de ellas(esto solo significa que tenemos que ser un poco más cuidadosos al programar). Por otro lado, el "motor" depattern matching es tremendamente potente y eficiente, permitiendo patrones de una gran complejidad y poderexpresivo, imprescindibles en un entorno de cálculo simbólico.

    Veamos algunos ejemplos de programación funcional. En primer lugar vamos a definir funciones numéricassencillas. En todos los casos se sustituye la iteración y la asignación por recursión.

    Potencias enteras:

    In[124]:= pot@n_, 0D := 1pot@n_, m_D := n pot@n, m - 1D

    Máximo común divisor:

    In[126]:= mcd@x_, 0D := xmcd@x_, y_D := mcd@y, Mod@x, yDD

    Cualquier función (no solo el ejemplo típico del factorial) se puede expresar de esta forma. Sin embargo, el enormepoder expresivo de la programación funcional se manifiesta en la manipulación de expresiones estructuradas,especialmente listas.

    Cualquier operación de manipulación de listas se puede expresar en términos de las primitivas First, Rest, yPrepend (históricamente, "cons").

    First devuelve el primer elemento de la lista y Rest la lista sin el primer elemento. Prepend[a,l] añade como cabeza a l. Por cuestiones deeficiencia,dependiendo de la implementación,muchas operaciones de listas se hacen directamente, sin recurrir a las primitivas básicas.

    Longitud de una lista (por supuesto,disponemos de la primitiva Length):

    In[128]:= lon@8

  • Como se usa mucho tiene la abreviatura /@ :

    In[135]:= Sqrt 81, 4, 9, 100, 144<Out[135]= 81, 2, 3, 10, 12<¿Cómo definirías Map?

    Apply es otro ejemplo de construcción funcional. Simplemente cambia la "cabeza" de una expresión. Sirve p.ej.para pasar a una función una lista de argumentos que están en una lista. El símbolo @@ es una abreviatura deApply:

    Cálculo de factorial mediante cambio de cabeza a la lista de números:

    In[136]:= Times Range@5DOut[136]= 120

    Definimos una función que calcula la media de los elementos de una lista.

    In[137]:= med@x_ListD := Plus xLength@xD

    In[138]:= med@84, 8, 16, 32

  • (Curiosamente, podemos derivar funciones puras:)

    In[145]:= Function@x, 2 x2 + 3 Cos@xDD’Out[145]= Function@x, 4 x - 3 Sin@xDDIn[146]:= Log@#D &’’Out[146]= -

    1#12

    &

    Otra construcción funcional importante es Select, que sirve para extraer de una lista los elementos que cumplan unpredicado:

    In[147]:= Select@Range@100D, PrimeQDOut[147]= 82, 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 patrón, yademaś permite transormarlo en el resultado. Es muy función muy potente:

    In[148]:= Cases@881, 2

  • In[154]:= Nest@h, x, 5DOut[154]= h@h@h@h@h@xDDDDDIn[155]:= Nest@1 H1 + #L &, x, 20DOut[155]=

    11 + 1

    1+ 11+ 1

    1+ 11+ 1

    1+ 11+ 1

    1+ 11+ 1

    1+ 11+ 1

    1+ 11+ 1

    1+ 11+ 1

    1+ 11+ 1

    1+ 11+ 11+x

    Los puntos fijos de funciones se calculan mediante FixedPoint:

    In[156]:= FixedPoint@Sqrt, 0.5DOut[156]= 1.

    Se puede construir una lista de los valores por los que va pasando:

    In[157]:= FixedPointList@Sqrt, 2.DOut[157]= 82., 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 función g que definimos antes:

    La volvemos a definir (por si acaso la habíamos borrado)

    In[158]:= g@n_?OddQD := 3 n + 1g@n_?EvenQD := n2

    Se cree que esta función aplicada repetidamente desde cualquier número siempre acaba por caer a 1. Vamos acomprobarlo en algunos casos. Primero definimos una función que comprueba la conjetura con un cierto número.NestWhileList sirve para hacer llamadas anidadas, guardando los resultados en una lista, mientras se cumpla unacondición:

    In[160]:= conj@n_D := NestWhileList@g, n, # ¹ 1 &DProbamos la conjetura con algunos valores. Por ejemplo con 11 se regresa pronto al 1:

    In[161]:= conj@11DOut[161]= 811, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1<In[162]:= conj@11D LengthOut[162]= 15

    Con 27 tarda algo más en regresar, pero lo hace:

    intromat.nb 19

  • In[163]:= conj@27DOut[163]= 827, 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 gráficamente 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@jDD, 8j, 2, 3000

  • Ejercicio: intentar la definición recursiva, funcional, de la transpuesta de una matriz.

    Construcciones de control de flujo de tipo imperativo

    Por supuesto, disponemos de las construcciones de programación usuales (for, if, etc.):

    In[168]:= For@i = 1, i £ 5, i++, Print@2iDD2

    4

    8

    16

    32

    Cuando necesitamos definir variables locales usamos la construcción Module:

    In[169]:= mcd@n_, m_D := Module@8a, b, r m, a = n; b = m,

    a = m; b = nD;While@Hr = Mod@a, bDL ¹ 0,a = b;b = rD;Return@bDD

    In[170]:= mcd@100, 150DOut[170]= 50

    Sin embargo muchas veces es mejor usar otras construcciones más naturales del lenguaje.

    Borramos:

    In[171]:= Remove@"Global‘*"Dà Listas, matrices, dot

    Los "arrays" (listas) se construyen mediante Table y se accede a sus elementos con doble corchete [[ ]]:

    In[172]:= m = Table@2i, 8i, 0, 10

  • In[175]:= Attributes@PlusDOut[175]= 8Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected<La suma es asociativa, se mete en las "listas", si acepta números dará números, Plus[1] = 1, conmutativa

    In[176]:= 2m

    Out[176]= 82, 4, 16, 256, 65536, 4294967296,18446744073709551616, 340282366920938463463374607431768211456,115792089237316195423570985008687907853269984665640564039457584007913129639936,13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096,179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216<

    In[177]:= Log@2, 2mDOut[177]= 81, 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 función Dot)

    Creamos dos matrices:

    In[178]:= m1 = Table@i*j, 8i, 2

  • In[183]:= Inverse@m3DOut[183]=

    ikjjjjjjjjjjj

    278 -54

    524- 54

    105194 -1091164

    524 -1091164

    1156984

    y{zzzzzzzzzzz

    In[184]:= Inverse@m3D NOut[184]=

    ikjjjjjj 3.375 -1.25 0.208333-1.25 0.541237 -0.09364260.208333 -0.0936426 0.0164662 y{zzzzzzMuchas operaciones matriciales funcionan también con matrices simbólicas:

    In[185]:= InverseAJ 1 21 b

    NEOut[185]=

    ikjjjjj b-2+b - 2-2+b- 1-2+b 1-2+b y{zzzzzEjemplo de una función Listable...

    In[186]:= SetAttributes@g, ListableDg@x_D := 8x, x<

    In[188]:= g@4DOut[188]= 84, 4<Se "mete dentro" de un argumento de tipo lista:

    In[189]:= g@8a, b, c

  • In[195]:= fil.col

    Out[195]= H a x + b y + c z LEl único problema es que no produce un escalar, sin una matrix 1x1.

    In[196]:= col.fil

    Out[196]=ikjjjjjj a x a y a zb x b y b zc x c y c z y{zzzzzz

    Mejor Outer:

    In[197]:= Outer@Times, 8a, b, c

  • In[204]:= Sort@%D

    Out[204]=

    i

    k

    jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj

    0.0535312 40.135592 90.264338 60.268539 70.318965 20.561153 80.697993 30.765438 100.983696 50.996618 1

    y

    {

    zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzIn[205]:= Last %Out[205]= 84, 9, 6, 7, 2, 8, 3, 10, 5, 1<(Por supuesto, en una biblioteca tenemos RandomPermutation)

    Tenemos operaciones matriciales típicas de cálculo científico: valores y vectores propios, valores singulares, etc.

    Borramos:

    In[206]:= Remove@"Global‘*"Dà Ajuste de mínimo error cuadrá tico

    En Mathematica podemos resolver cómodamente ajustes de mínimos cuadrados.

    In[207]:= datos = Table@8x, x2 + Random@Real, 8-2, 2

  • In[211]:= g2 = Plot@sol, 8x, -2, 7

  • In[215]:= Show@g1, g3D

    -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, g3D

    -2 2 4 6

    -20

    -10

    10

    20

    30

    Out[216]= Graphics

    El problema también puede resolverse fácilmente programando la solución en el lenguaje de Mathematica. Pero en este caso resulta mucho másconveniente utilizar la función incorporada Fit.

    Borramos:

    In[217]:= Remove@"Global‘*"Dà Gráficos

    Son expresiones como las demás, pero hay funciones que, como efecto colateral, las muestran.

    Las expresiones gráficas combinan en listas anidadas primitivas gráficas (puntos, líneas, etc.) y directivas gráficas(tamaños, colores, ancho, etc.):

    In[218]:= dibu = 88RGBColor@1, 0.5, 0D, [email protected], Point@81, 4

  • In[219]:= Graphics@dibuD Show@#, AspectRatio ® Automatic, Frame ® TrueD &;

    -2 -1.5 -1 -0.5 0 0.5 10

    1

    2

    3

    4

    También hay primitivas 3D. (Y visores OpenGL gratuitos.)

    Se pueden exportar los objetos gráficos a cualquier formato (jpeg, eps, etc.).

    à Otras cosas

    Se puede invocar una función de varias maneras:

    In[220]:= Sqrt@4DOut[220]= 2

    In[221]:= Sqrt4

    Out[221]= 2

    In[222]:= 4 SqrtOut[222]= 2

    Los corchetes son los más seguros porque no hay problema de ambigüedad. Las dos barras sirven para tomar toda la expresión de la izquierda yaplicar finalmente una función.

    En una celda podemos poner varias expresiones que se evaluarán una detrás de otra. Si no deseamos mostrar el resultado de una expresiónponemos punto y coma detrás.

    In[223]:= 2 + 23 + 3;4 + 4

    Out[223]= 4

    Out[225]= 8

    Cuando estamos corrigiendo la definición de un símbolo que tenga varias reglas asociadas, conviene poner Clear al principio para que cada vez quese evalúe el juego de definiciones, las reglas anteriores, erróneas, se borren. Si no se hace así puede ser que en las pruebas se obtenganresultados incorrectos.

    In[226]:= f@x_IntegerD := 3 x

    intromat.nb 28

  • In[227]:= f@3DOut[227]= 9

    Si ahora cambiamos la definición

    In[228]:= f@x_D := 2 xEl resultado no cambia porque toma la regla anterior que es más específica:

    In[229]:= f@3DOut[229]= 9

    Las dos reglas coexisten:

    In[230]:= [email protected][230]= 6.

    En estos casos conviene borrar al principio las definiciones del símbolo para que se quede sólo con las definiciones explícitamente evaluadasdespués.

    In[231]:= Clear@fDf@x_D := 2 x

    In[233]:= f@3DOut[233]= 6

    Por supuesto, en programas grandes conviene organizar un documento con secciones de definición, de ejemplos de uso, etc.

    Borramos:

    In[234]:= Remove@"Global‘*"D

    intromat.nb 29