Tracks
/
Python
Python
/
Temario
/
Números complejos
Nú

Números complejos en Python

{one: "1 ejercicio", many: "%{count} ejercicios", other: "%{count} ejercicios"}

Acerca de Números complejos

Los Complex numbers no son complicados. Solo necesitan un nombre menos alarmante.

Son tan útiles, sobre todo en ingeniería y en ciencia, que Python incluye complex como tipo numérico estándar, junto con los números enteros (ints) y los números de coma flotante (floats).

Conceptos básicos

Un valor complex en Python es esencialmente un par de números de coma flotante. Estas partes se denominan la «real» y la «imaginaria», por desafortunadas razones históricas. De nuevo, lo mejor es centrarse en la sencillez que hay debajo y no en los nombres extraños.

Hay dos formas habituales de crear números complejos.

  1. El constructor complex(real, imag) recibe dos parámetros de tipo float:
>>> z1 = complex(1.5, 2.0)
>>> z1
(1.5+2j)

El constructor también puede analizar una entrada de tipo string. Tiene la extraña limitación de que falla si la string contiene espacios.

>>> complex('4+2j')
(4+2j)

>>> complex('4 + 2j')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: complex() arg is a malformed string
  1. El número complejo se puede especificar con el literal <real part> + <complex part>j, o solo con <complex part>j si la parte real es cero:
>>> z2 = 2.0 + 1.5j
>>> z2
(2+1.5j)

El resultado final es idéntico al de usar el constructor complex().

Hay dos reglas para esa parte imaginaria del número complejo:

  • Se designa con j (no con i, como puedes ver en los libros de matemáticas).

  • La j debe ir inmediatamente después de un número, para evitar que Python la interprete como el nombre de una variable. Si es necesario, usa 1j.

>>> j
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'j' is not defined

>>> 1j
1j

>>> type(1j)
<class 'complex'>

La mayoría de los ingenieros se conforma con j. La mayoría de los científicos y matemáticos prefiere la notación matemática i para imaginario, pero esa notación entra en conflicto con el uso de i para referirse a la corriente en ingeniería eléctrica. Así que, al diseñar Python, ganaron los ingenieros eléctricos.

Para acceder a cada parte de un número complejo por separado:

>>> z2.real
2.0
>>> z2.imag
1.5

Cualquiera de las dos partes puede ser cero, y entonces los matemáticos pueden hablar de un número «completamente real» o «completamente imaginario». Sin embargo, en Python sigue siendo un número complejo:

>>> complex(0, 1)
1j
>>> type(complex(0, 1))
<class 'complex'>

>>> complex(1, 0)
(1+0j)

Es posible que hayas oído que «i (o j) es la raíz cuadrada de -1».

Por ahora, todo esto significa que la parte imaginaria por definición cumple la igualdad

1j * 1j == -1  # => True

Es una idea sencilla, pero conduce a consecuencias interesantes.

Aritmética

La mayoría de los operators que se usan con números de coma flotante y con enteros también funcionan con números complejos:

>>> z1 = (1.5+2j)
>>> z2 = (2+1.5j)


>>> z1 + z2  # addition
(3.5+3.5j)

>>> z1 - z2  # subtraction
(-0.5+0.5j)

>>> z1 * z2  # multiplication
6.25j

>>> z1 / z2  # division
(0.96+0.28j)

>>> z1 ** 2  # exponentiation
(-1.75+6j)

>>> 2 ** z1  # another exponentiation
(0.5188946835878313+2.7804223253571183j)

>>> 1j ** 2  # j * j == -1
(-1+0j)

Explicar las reglas de la multiplicación y la división de números complejos queda fuera del alcance de este concepto (y es poco probable que tengas que realizar esas operaciones «a mano» muy a menudo).

Cualquier introducción matemática o de ingeniería eléctrica a los números complejos lo cubrirá, si quieres profundizar en el tema.

Como alternativa, Exercism tiene un ejercicio de práctica Complex Numbers en el que puedes implementar una clase de números complejos con estas operaciones desde los primeros principios.

La división entera no es posible con números complejos, así que los operadores // y % y la función divmod() fallarán con el tipo de número complejo.

Hay dos funciones implementadas para los tipos numéricos que resultan muy útiles al trabajar con números complejos:

  • <complex number>.conjugate() simplemente invierte el signo de la parte imaginaria de un número complejo (de + a - o viceversa).
    • Debido a cómo funciona la multiplicación de números complejos, esto es más útil de lo que podrías pensar.
  • abs(<complex number>) garantiza que se devuelva un número real sin parte imaginaria.
>>> z1
(1.5+2j)

>>> z1.conjugate() # flip the z1.imag sign
(1.5-2j)

>>> abs(z1) # sqrt(z1.real ** 2 + z1.imag ** 2)
2.5

El módulo cmath

La biblioteca estándar de Python tiene un módulo math lleno de funcionalidad útil para trabajar con números reales.

También tiene un módulo cmath equivalente para trabajar con números complejos.

Te animamos a leer el módulo y experimentar, pero las categorías principales son:

  • Conversión entre coordenadas cartesianas y polares,
  • Funciones exponenciales y logarítmicas,
  • Funciones trigonométricas,
  • Funciones hiperbólicas,
  • Funciones de clasificación, y
  • Constantes útiles.

Aquí tienes un ejemplo que usa algunas constantes:

>>> import cmath

>>> euler = cmath.exp(1j * cmath.pi) # Euler's equation

>>> euler.real
-1.0
>>> round(euler.imag, 15) # round to 15 decimal places
0.0

Así que una expresión sencilla con tres de las constantes más importantes de la naturaleza, e, i (o j) y pi, da como resultado -1. Algunas personas creen que es el resultado más bello de todas las matemáticas. Se remonta a alrededor de 1740.


Sección opcional: preguntas frecuentes sobre los números complejos

Puedes saltarte esta parte, a menos que te interese.

¿No es esto una extraña y nueva rama de las matemáticas puras?

Era extraño y nuevo en el siglo XVI.

500 años después, es central en la mayor parte de la ingeniería y de las ciencias físicas.

¿Por qué iba alguien a usarlos?

Resulta que los números complejos son la forma más sencilla de describir cualquier cosa que rote o que tenga una propiedad ondulatoria. Por eso se usan ampliamente en ingeniería eléctrica, procesamiento de audio, física, videojuegos y navegación, por nombrar solo algunas aplicaciones.

Puedes ver cosas que rotan. Puede que los números complejos no hagan girar el mundo, pero son magníficos para explicar lo que ocurre cuando el mundo gira: mira cualquier imagen por satélite de una gran tormenta.

Aunque no sea tan evidente, el sonido es ondulatorio, la luz es ondulatoria, las señales de radio son ondulatorias, e incluso la economía de tu país es, al menos en parte, ondulatoria.

Gran parte de este procesamiento de ondas se puede hacer con funciones trigonométricas (sin() y cos()), pero eso se vuelve complicado enseguida.

Las exponenciales complejas son mucho más fáciles de manejar.

¡Pero yo no necesito números complejos!

Solo es cierto si vives en una cueva y buscas tu comida.

Si estás leyendo esto en algún tipo de pantalla, dependes por completo de algunos avances útiles del siglo XX logrados gracias al uso de los números complejos.

  1. Chips semiconductores.

    • No tienen sentido en la física clásica y solo se pueden explicar (y diseñar) mediante la mecánica cuántica (MC).
    • En la MC, todo tiene valores complejos por definición. (son formas de onda hasta el fondo)
  2. El algoritmo de la transformada rápida de Fourier (FFT).

    • La FFT es una aplicación de los números complejos, y está en todo lo relacionado con la transmisión de sonido, el procesamiento de audio, las fotos y el vídeo.

    • El MP3 y otros formatos de audio usan la FFT para comprimir, lo que permite que quepa más audio en un espacio de almacenamiento más pequeño.

    • La compresión JPEG y el vídeo MP4, entre muchos otros formatos de imagen y vídeo, también usan la FFT para comprimir.

    • La FFT también se emplea en los filtros digitales que permiten a las torres de telefonía móvil separar tu señal de móvil personal de la de los demás.

Así que probablemente usas tecnología que depende de cálculos con números complejos miles de veces por segundo.

Editar en GitHub El enlace se abre en una nueva ventana o pestaña