Matemáticas con Mathematica

Números complejos y visualización de funciones complejas

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

Descripción de la práctica

Esta práctica consta de dos partes. En la primera se introducen algunos comandos básicos de Mathematica para trabajar con números complejos. Comprobarás que el conocimiento de las funciones elementales complejas, en particular los logaritmos y las potencias complejas, es importante para entender algunas respuestas de Mathematica. En la segunda parte se introducen comandos específicos para representar gráficamente funciones complejas. Tu trabajo consiste en leer y entender lo que sigue y realizar los ejercicios que te propongo.

Aritmética. Forma polar. Raíces, logaritmos y potencias complejas.

Empezaremos aprendiendo algunos comandos específicos que tiene Mathematica para trabajar con números complejos. En Mathematica la letra I mayúscula representa la unidad imaginaria. No olvides dejar un espacio libre al escribirla. También puedes escribir la unidad imaginaria tecleando "Esc ii Esc".

z = -5 + I 4;
Re[z]Im[z]Abs[z]Arg[z]Conjugate[z]Clear[z]

Como ves "Re[]" e "Im[]" dan la parte real e imaginaria, "Abs[]" nos da el módulo, "Arg[]" es el argumento principal y "Conjugate[]" es el conjugado.

Te recuerdo que Mathematica  trabaja  con números complejos por defecto, por eso cuando una expresión contenga variables no debes olvidar que Mathematica las tratará como números complejos.  Por ejemplo, no debes pensar que Re[a + i b] debe ser a, puesto que ello sólo es así cuando a y b son números reales.

Re[a + I b]Conjugate[a  +  I b]Re[(a +  I b) (c  +  I d)]

Podemos decirle a Mathematica que ciertas variables son reales con la orden "ComplexExpand[expr]" que desarrolla "expr" suponiendo que todas las variables que figuran en la misma son reales.

ComplexExpand[Re[a + I b]]ComplexExpand[Re[(a +  I b) (c  +  I d)]]ComplexExpand[Conjugate[a  +  I b]]

Para que te convenzas de que Arg[z] es el argumento principal de z, observa en la siguiente gráfica la disontinuidad del argumento en t=π punto en el que salta de π a -π.

Plot[Arg[Cos[t] +  I Sin[t]], {t, 0, 2  π}, 
      Ticks -> {π/3 Range[6], {-π, π}}];

Mathematica tiene otra función que hace lo mismo que la función Arg[], es la función ArcTan[x,y] que proporciona el argumento principal del número complejo x + I y.

Plot[ArcTan[Cos[t], Sin[t]], {t, 0, 2  π}, 
      Ticks -> {π/3 Range[6], {-π, π}}];

No hay ninguna novedad en lo referente a la multiplicación y a la división de números complejos: se hacen de la forma usual. También se hacen de la forma usual las potencias. Mererece la pena detenerse en las potencias de exponente racional y complejo para entender cómo trabaja Mathematica con ellas. Vamos a considerar las raíces de un número complejo. Ya sabes que todo número complejo distinto de cero tiene n raíces n-ésimas distintas. ¿Cuál de ellas es la que se representa en Mathematica por z^(1/n) o, lo que es igual, por (z^(1/n))? Para saberlo podemos usar ComplexExpand.

ComplexExpand[(x  +  I y)^{1/3}]

Es decir, Mathematica proporciona siempre el valor principal de la raíz. Ahora puedes comprender por qué si le pides a Mathematica que calcule (((x^3))^(1/3))la respuesta no puede ser x. Fíjate que si x es real entonces sí es cierto es que x es la única raíz cúbica real de (x^3), pero Mathematica, por defecto, trata x como un número complejo y hay tres complejos distintos que tienen igual cubo. Por eso la igualdad (((z^3))^(1/3)) = z no es cierta en general. Ya debes saber que dicha igualdad se verificará solamente cuando -π/3<Arg[z]≤π/3. También puedes entender por qué si pides a Mathematica que calcule (Sqrt[z]) (Sqrt[w]) la respuesta no puede ser (Sqrt[z w]).

(((z^3))^(1/(3 )))(Sqrt[z]) (Sqrt[w])

Nota importante. Esta práctica la preparé con la versión 5.0 de Mathematica. Al probarla con la versión 3.0 he comprobado que el comando "Simplify" que en la versión 5.0 y en la 4.1 admite ser usado de la forma "Simplify[expr,condiciones]" no puede ser usado con "condiciones" en la versión 3.0. Por ello, en lo que sigue, hay algunas celdas que ya están ejecutadas usando la versión 5.0 y no debes volver a ejecutarlas porque Mathematica te dará un mensaje de error y perderás la información.

\(\( (*\ no\ evalúes\ esta\ celda\ *) 

    Simplify[\@\(z\^3\)\%3\ , \(-π\)/3 < Arg[z] ≤ \ π/3]\ 
    \)\)

\(\( (*\ no\ evalúes\ esta\ celda\ *) 

    Simplify[\@\(z\^3\)\%3\ , 
      \(-π\)/3 ≤ \ Arg[z] ≤ \ π/3]\  (*\ 
      \(Una\ pequeña\ diferencia\ con\ la\ anterior\ pero ... \)\ 
        ¡las\ matemáticas\ son\ \(exactas!\)\ *) 
      \)\)

ComplexExpand[(((I^3))^(1/3))]

ComplexExpand[((-1)^(1/3))] (* los números reales negativos son tratados como números complejos .  Ya ves que Mathematica proporciona siempre el valor principal de la raíz *)

(Sqrt[-I]) (Sqrt[-I])          (Sqrt[(-I)*(-I)])

Ya ves que saber un poquito de números complejos ayuda a entender lo que hace Mathematica. Para obtener todas las raíces de orden n de un número complejo puedes usar el comando "Solve".

Veamos cómo trabaja Mathematica con los logaritmos complejos.

ComplexExpand[Log[x  +  I y]]

Es decir, la función Log[z] nos da el valor principal del logaritmo de z. Ahora puedes entender la siguiente respuesta de Mathematica.

Exp[Log[z]]Log[Exp[z]]    
      Log[Exp[7 I]]

Veamos lo que vale Log[Exp[z]].

ComplexExpand[Log[Exp[x  +  I y]]]

Ya has visto antes que no siempre es cierto que ArcTan[Cos[y],Sin[y]] sea igual a y. De hecho la igualdad ArcTan[Cos[y],Sin[y]]=y es cierta solamente cuando -π<y≤π. Esto se pone de manifiesto en ls siguiente gráfica.

Plot[ArcTan[Cos[y], Sin[y]], {y, -π, π}];

\(\( (*\ no\ evalúes\ esta\ celda\ *) 

    Simplify[Log[Exp[z]], z > 0]\ 
    
 (*informamos\ a\ Mathematica\ que\ z > 
        0. 
No\ sé\ por\ qué\ Mathematica\ 5.0\ no\ responde
            \ si\ le\ decimos\ que\  - π < Arg[z] ≤ 
        π
	en\ cuyo\ caso\ es\ cierto\ que\ Log[Exp[z]] es\ igual\ a\ 
          z*) \)\)

ComplexExpand[Log[-1 + I (Sqrt[3])] + Log[-(Sqrt[3]) + I]]   ComplexExpand[Log[(-1 + I (Sqrt[3])) (-(Sqrt[3]) + I)]]

Consideremos a continuación las potencias de base y exponente complejos.

ComplexExpand[(a  +  I b)^(c  +  I d)]

Parece demasiado complicado. Recordemos la definición del valor principal de la potencia (a + I b)^(c + I d)=Exp[(c + I d)Log[a + I b]].

ComplexExpand[Exp[(c  +  I d) Log[a  +  I b]]]

Está claro que Mathematica calcula el valor principal de la potencia.

ComplexExpand[((-I)*(-I))^I]    ComplexExpand[(-I)^I *(- I)^I]Clear["Global`*"]

Visualización de funciones complejas

Cualquier función \(TraditionalForm
      \`f\  : \ ℂ -> ℂ\)  podemos verla como una función de (ℝ^2) en  (ℝ^2) y  por tanto para su representación necesitariamos gráficos en cuatro dimensiones. Lo que podemos hacer para visualizar su comportamiento es representar cómo se transforma una familia de curvas como, por ejemplo, rectas paralelas a los ejes o circunferencias centradas en el origen.

Mathematica posee un comando que nos permite ver la imagen de una familia de rectas paralelas a los ejes mediante una función compleja. Para ello es necesario cargar el paquete ComplexMap.

<< Graphics`ComplexMap`

También es conveniente cargar el siguiente paquete para trabajar con comodidad con colores.

\(\(Needs["Graphics`Colors`"]; 
    \ \  (*para\ usar\ colores\ con\ comodidad*) 
Off[General::spell1]; \ \ 
    
 (*para\ que\ Mathematica\ no\ nos\ moleste\ con\ avisos\ de\ error\ en
        \ los\ nombres\ de\ los\ comandos*) \)\)

? CartesianMap

Utilizando este comando puedes ver cómo una determinada función actúa sobre una región del plano y además cómo transforma los segmentos verticales y los horizontales. Aquí tienes un bonito ejemplo con la aplicación f(z)=1/z.

\(f[z_] = 1/z; 

    CartesianMap[Identity, \ {0.5, 10, 0.5}, {\(-5\), 5, 0.5}, 
      
Ticks 
        -> {Range[0, 10, 2], Range[\(-5\), 5, 1]}, 
      AxesLabel -> {"x", "y"}, PlotStyle -> {Blue, Red}]; 

    Print["El semiplano Re[z] > 1/2"]; 

    CartesianMap[f, \ {0.5, 10, 0.5}, {\(-5\), 5, 0.5}, 
      
PlotRange 
        -> {{\(-0.1\), 2.1}, {\(-1.1\), 1.1}}, 
      
AspectRatio -> 1, 
      Ticks -> {Range[0, 2, 1], Range[\(-2\), 2, 1]}, 
      AxesLabel -> {"u", "v"}, PlotStyle -> {Blue, Red}]; 

    Print["Su imagen por f(z)=1/z es el disco |w - 1| < 1"]; 

    Clear[f]\)

Teniendo en cuenta que:

ComplexExpand[Exp[x  +  I y]]

Es evidente que la imagen por la función exponencial de una recta vertical (x constante) es una circunferencia centrada en el origen de radio (e^x), y la imagen de una recta horizontal (y constante) es una semirecta con extremo en el origen y vector de dirección (Cos[y],Sin[y]).

Aquí puedes ver cómo la función exponencial transforma rectángulos en sectores de corona circular. Utiliza los controles para ver despacio la animación. Observa cómo la imagen de la función exponencial va cambiando. Mantenemos fijo el intervalo de abscisas (la anchura del rectángulo) [-1,1] (del cual depende el módulo de la imagen) y vamos aumentando el intervalo de ordenadas (la altura del rectángulo) desde [-π/10, π/10] hasta [-π, π] (del que dependen los argumentos de la imagen).

\(Do[Show[
        GraphicsArray[{
            CartesianMap[Identity, 
              \ {\(-1\), 1, 0.1}, {\(-k\)\ π, k\ π, 0.1}, 
              AxesLabel -> {"x", "y"}, 
              PlotStyle -> {Red, Blue}, Ticks -> None, 
              PlotRange -> {{\(-3\), 3}, {\(-3\), 3}}, 
              ImageSize -> {356, 170}, 
              DisplayFunction -> Identity], 
            CartesianMap[Exp, 
              \ {\(-1\), 1, 0.1}, {\(-k\)\ π, k\ π, 0.1}, 
              
AxesLabel -> {"u", "v"}, 
              PlotStyle -> {Red, Blue}, Ticks -> None, 
              PlotRange -> {{\(-3\), 3}, {\(-3\), 3}}, 
              ImageSize -> {356, 170}, 
              DisplayFunction -> Identity]}]], {k,  .1, 1,  .2}]; 

    SelectionMove[EvaluationNotebook[], All, GeneratedCell]; 

    FrontEndTokenExecute["CellGroup"]\)FrontEndTokenExecute["OpenCloseGroup"]

Mathematica posee un comando que nos permite ver la imagen por una función compleja de una familia de rectas que pasan por el origen y de una familia de circunferencias centradas en el origen.

?PolarMap

PolarMap[Identity,  {0, 1}, {-Pi  +  .00001,  Pi}, 
      PlotStyle -> {Red, Blue}];

Aquí tienes la imagen por la función logaritmo de la corona circular {z ϵ 𝕔  : (e^(-3)) <  | z | (( < e)^3)} . Observa cómo los radios se convierten en segmentos horizontales y las circunferencias en segmentos verticales.

Show[
      GraphicsArray[{{
            PolarMap[Identity, {E^-3, E^3}, {-Pi +  .00001, Pi}, 
              PlotStyle -> {Red, Blue}, 
              DisplayFunction -> Identity], 
            
PolarMap[
              Log, {E^-3, E^3, E^-2}, {-Pi +  .00001, Pi}, 
              PlotStyle -> {Red, Blue}, 
              PlotRange -> {{-3.1, 3.1}, {-3.6, 3.6}}, 
              DisplayFunction -> Identity]}}], 
      ImageSize -> {430, 204.625}];

Ejercicio 1. Te propongo que realices un programa para dibujar polígonos regulares de cualquier número de lados inscritos en la circunferencia unidad y que también represente las raíces k-ésimas de la unidad por vectores (para dibujar vectores necesitarás "<<Graphics`Arrow`"). Los pasos y las funciones de Mathematica que quiero que uses te los indico a continuación (cada paso debe ser una corta línea de código). Naturalmente, hay formas mucho más inmediatas de hacer esto pero se trata de que uses ciertos recursos de Mathematica que quizás no conoces.
1. Obtén una lista "raices[k]" con las raíces k-ésimas de la unidad. Combina para ello el operador de sustitución "/." y "Solve".
2. Ordena los argumentos principales de las raíces obtenidas de menor a mayor en una lista "argumentos[k]". Combina "Sort", "Arg", "Less".
3. Pasa la lista anterior a coordenadas cartesianas "cartesianas[k]". Necesitas aplicar una función a los puntos de la lista anterior. Consulta el comando /@.
4. Aplica de forma apropiada "Arrow" a los puntos de la lista anterior para representar las raíces por vectores "vectores[k]". Obtendrás una lista con los vectores correspondientes.
5. Salvo un detalle que tú mismo decubrirás, ya sólo te queda usar "Show","Line", "Circle" con las opciones adecuadas para obtener la función "poligonoregular[k]" que realiza las tareas deseadas. Dale un valor a k y comprueba que todo funciona bien..

Observación. Para aplicar una función a a los elementos de una lista puedes hacerlo como sigue.

\(f[z_] = z^2; 
Range[5]\)f/@Range[5]

O utilizar lo que se llaman "funciones puras o anónimas" (la diferencia está en que te ahorras definir la función de forma explícita).

#^2&/@Range[5]

Consulta "Function" en la ayuda de Mathematica.

Ejercicio 2. Utiliza CartesianMap para obtener las imágenes del cuadrado unidad por las funciones seno y tangente.

Ejercicio 3. Utiliza ComplexExpand y ParametricPlot para obtener las imágenes por la función seno y tangente de un segmento vertical y de un segmento horizontal.

Ejercicio 4. Haz una animación para ver la imagen por la función raíz cuadrada de un sector del disco unidad cuya amplitud va aumentando a saltos de π/5.

Ejercicio 5. Representa la imagen del disco D((1 + i)/2, 1/2) y su imagen por la función f(z) = (z^4). Elige de forma apropiada el número de radios y de circunferencias que se representarán.

Ejercicio 6. Justifica gráficamente que la aplicación  w = f (z) = Log (((1  +  z)/(1  -  z)))  lleva el disco unidad  | z |  <  1  sobre la banda horizontal  |v|<(( π)/2)