May 15, 2024 | 4 min read
Números sin complejos#
\( \newcommand{\bra}[1]{\langle #1|} \) \( \newcommand{\ket}[1]{|#1\rangle} \) \( \newcommand{\braket}[2]{\langle #1|#2\rangle} \) \( \newcommand{\i}{{ i}} \) \( \newcommand{\Hil}{{\mathbb H}} \)
Show code cell source
%run ../../macro_tQ.py
import sys
sys.path.append('../../')
import macro_tQ as tQ
import numpy as np
Introducción#
La mecánica cuántica no se entiende sin los números complejos. Para introducirlos, empezaremos recordando que el cuadrado de un número real siempre es positivo \(a^2 >0\). Por ejemplo \(~~2^2 = 4~~\) pero también \(~~(-2)^2 = 4~~\). Por eso, decimos que la raíz cuadrada de un número sólo existe si dicho número es positivo. Es decir, \(\sqrt{4}=\pm 2\), mientras que, no sabríamos dar sentido a
\(~~~\) Pregunta: \(~\) ¿cómo podríamos definir la raíz cuadrada de un número real negativo?
\(~~~\) Respuesta: \(~\) para hacerlo, es necesario ampliar el conjunto de los números reales
Definición: número \(i\)
se postula la existencia de un nuevo número, \(~i\), que es la solución única de la ecuación \(~\)
Equivalentemente podíamos haber requerido que \(\i = \sqrt{-1}\). Ahora podemos dar sentido a la raíz cuadrada de un número negativo. Por ejemplo, \((2i)(2i) = 4 i^2 = - 4\) implica que
Con el número \(i\) se opera igual que con los números reales
Observar que el inverso multiplicativo \(1/i\) también es \(-i\)
por tanto hay una identificación importante
Resumen
La solución al problema planteado consiste en extender el conjunto de números reales \({\mathbb R}\) al de los complejos \({\mathbb C}\) que, ahora, incluyen el número \(i\)
Formas cartesiana y polar#
Forma Cartesiana#
Un número complejo, \(z \in {\mathbb C}\), se representa en forma cartesiana mediante dos números reales \(x,y\in {\mathbb R}\)
Numeros complejos en python:#
En python, el número imaginario \(\i\) se representa con la letra j. Añadiendo +0j convertimos un float en un complex
print(isinstance(1,complex))
print(isinstance(1+0j,complex))
False
True
Un número complejo se puede visualizar como un vector de componentes \((x,y)\) en un plano, el plano complejo. La parte real, \(x\), es la coordenada en el eje horizontal, y la parte imaginaria, \(y\), es la coordenada en el eje vertical.
'''Forma cartesiana'''
z = 3 + 2j
'''Extraemos las partes real e imaginaria'''
x=z.real
y=z.imag
print('z=x+iy=',x + 1j*y)
''' Representamos en el plano complejo '''
tQ.plot_complex_number(z,show_name=False,vcolor="b",sides=False,side_color="b",lwidth=1)
z=x+iy= (3+2j)
Forma Polar#
Teorema: Fórmula de Euler
para todo ángulo \(\theta \in \mathbb{R}\) se cumple la siguiente identidad matemática
La fórmula de Euler ahora nos permite representar cualquier número complejo \(z=x + \i y\) en forma polar
Los números reales \(\rho\) y \(\theta\) se denominan módulo y fase. Las componentes cartesianas son
y por tanto \(\rho^2 = x^2 + y^2\). De la periodicidad de las funciones trigonométricas
se sigue que las fases \(\theta\) y \(\theta+ 2\pi n\) con \(n=0,1,2,...\) representan el mismo número complejo
'''Forma polar'''
r=2
th=2.5
z = r*np.exp(th*1j)
print('z=',np.round(z,3))
tQ.plot_complex_number(z,show_name=False,vcolor="b",sides=False,side_color="b",lwidth=1)
z= (-1.602+1.197j)
Usar la forma polar es útil en situaciones en las que aparecen productos y potencias del número \(i\)
Ejercicio
intenta demostrar las siguientes igualdades
Solución
Conversión entre formas cartesiana y polar#
La conversión de la representación polar a cartesiana es muy sencilla gracias a las fórmula de Euler
La conversión inversa, de cartesiana a polar es un poco más delicada. Formalmente sería
A la hora de la verdad hay que fijar el signo de la función \(\arctan(y/x)\). La siguiente función examina esto mirando a los signos de \(x\) y de \(y\) para saber en qué cuadrante estamos.
'Conversión de Cartesianas a Polares'
def cartes2polar(z):
r = np.abs(z)
y = z.imag
x = z.real
if r==0:
print('el número 0+i0 no admite representación polar')
th='indefinido'
elif x==0 and y>0: #si x=0 hay que dar la solución a mano, porque arctan(y/0) no está definido
th=np.pi/2
elif x==0 and y<0:
th=3*np.pi/2
elif x>0 and y>=0: #primer cuadrante
th=np.arctan(y/x)
elif x<0 and y>=0: #segundo cuadrante
th=np.arctan(-y/x)+np.pi/2
elif x<0 and y<0: #tercer cuadrante
th=np.arctan(y/x)+np.pi
elif x>0 and y<0: #cuarto cuadrante
th=np.arctan(-y/x)+3*np.pi/2.
return r,th
#el signo correcto también se puede conseguir usando la funcion np.arctan2(x,y)
Ejercicio
Calcula la forma polar del número complejo \(z = 4 + 3 i\) a mano y verificalo con la función que acabamos de definir
'A la inversa no es necesario definir ninguna funcion, ya que numpy directamente escribe un numero complejo en forma cartesiana'
z = 3*np.exp(1j*0.5)
print('z=',np.round(z,2))
tQ.plot_complex_number(z,show_name=False,vcolor="b",sides=False,side_color="b",lwidth=1)
z= (2.63+1.44j)
Conjugacion compleja#
Todo número complejo, \(z\), lleva asociado otro, \(z^*\), denominado el complejo conjugado que se obtiene cambiando \(\i \to -\i\)
Es evidente que \((z^*)^* = z\). Es decir, la conjugación compleja es una involución.
'''Conjugacion compleja'''
zc = np.round(z.conjugate(),2)
print('z* = ',zc)
tQ.plot_complex_number(zc,show_name=False,vcolor="r",sides=False,side_color="r",lwidth=1)
z* = (2.63-1.44j)
En forma polar la conjugación compleja se obtiene cambiando el signo de la fase
Operaciones básicas#
Los numeros complejos \({\mathbb C}\) forman una estructura matemática, denominada cuerpo, que admiten dos operaciones internas: la suma y la multiplicación. Vamos a estudiarlas por separado
Suma#
En representación cartesiana se suman las partes real e imaginaria por separado
La resta es obvia, ya que \(a,b,c,d\) pueden ser números negativos.
'''Suma en cartesianas'''
z1 = 1+4j
z2 = 2+2j
'''Suma y resta'''
zs = z1+z2
zd = z1-z2
print('z1+z2=',zs)
print('z1-z2=',zd)
print('************************************')
tQ.plot_2D_plane(left=-2,right=4,up=6,down=-1) #cambiar las dimensiones para que encuadrar la figura
tQ.draw_vector(z1.real,z1.imag,'b')
tQ.draw_vector(z2.real,z2.imag,'b')
tQ.draw_vector(zs.real,zs.imag,vcolor='r')
tQ.draw_vector(zd.real,zd.imag,vcolor='g')
z1+z2= (3+6j)
z1-z2= (-1+2j)
************************************
En forma polar, la suma de dos números complejos no admite ninguna simplificación, y deben transformarse primeramente a forma cartesiana, para sumarse.
'python directamente escribe un numero complejo en forma cartesiana'
z1 = 3*np.exp(1j*0.5)
z2 = 1*np.exp(-1j*0.7)
'''Suma y resta'''
zs = z1+z2
zd = z1-z2
print('z1+z2=',np.round(zs,4))
print('z1-z2=',np.round(zd,4))
print('************************************')
tQ.plot_2D_plane(left=-2,right=4,up=2,down=-1) #cambiar las dimensiones para que encuadrar la figura
tQ.draw_vector(z1.real,z1.imag,'b')
tQ.draw_vector(z2.real,z2.imag,'b')
tQ.draw_vector(zs.real,zs.imag,vcolor='r')
tQ.draw_vector(zd.real,zd.imag,vcolor='g')
z1+z2= (3.3976+0.7941j)
z1-z2= (1.8679+2.0825j)
************************************
Multiplicación#
En forma cartesiana la multiplicación es complicada, debiendo multiplicarse todos los factores entre sí, y teniendo en cuenta que \(\i^2= -1\)
En forma polar la multiplicación es simple: se multiplican los módulos y se suman las fases
z1 = 3*np.exp(1j*0.5)
z2 = 1*np.exp(-1j*0.7)
'''Producto'''
print('z1*z2 = ', np.round(z1*z2,4))
print('z1**3 = ', np.round(pow(z1,6)))
print('************************************')
z1*z2 = (2.9402-0.596j)
z1**3 = (-722+103j)
************************************
Valor absoluto#
El cuadrado de un número real \(a\in {\mathbb R}\) es otro número real positivo \(a^2 >0\). Ello nos permite definir el valor absoluto \(|a| = \sqrt{a^2}\) que es el mismo para \(a\) y para \(-a\).
Esto no sucede con un número complejo \(z\). Su cuadrado $\(z^2 = x^2 - y^2 +2\i xy\)$
es complejo.\(~\) Sin embargo, el producto de un número por su conjugado es un número real y positivo
Ello nos permite definir el valor absoluto de un número complejo
Nota
el valor absoluto de un número complejo escrito en forma polar coincide con su módulo
En consecuencia, el valor absoluto de una fase pura \(z = e^{i\theta}\) es \(\rho =1\)
División#
Al igual que la multiplicación, en forma cartesiana, la división no es simple. Sea \(z = a+ \i b\) y \(w=c+\i d\)
En forma polar la división es tan sencilla como la multiplicación. Se toma el cociente de los módulos y la resta de las fases
'''Valor absoluto'''
print('|z1|=',abs(z1))
print('comprobación |z1|=',np.sqrt(z1*z1.conjugate()).real)
print('************************************')
'''Division'''
print('z1/z2=',np.round(z1/z2,5))
print('comprobación z1/z2=', np.round(z1*z2.conjugate()/(z2*z2.conjugate()),5))
|z1|= 3.0
comprobación |z1|= 3.0
************************************
z1/z2= (1.08707+2.79612j)
comprobación z1/z2= (1.08707+2.79612j)
Casos particulares#
Vamos a ver algunas relaciones que son de uso muy frecuente.
Sumas nulas#
La interferencia cuántica, en ultima instancia, procede de la posibilidad de sumar muchas fases complejas de manera que se anule el resultado. Sea \(N\) un número entero cualquiera, se verifica que
Vamos a representar los números complejos y su suma. Puedes cambiar \(N\) y también multiplicar por un módulo constante \(\rho\) y observar el resultado.
# modifica el número N
N=9
rho=1
''' Creamos las fases'''
lista_de_fases=np.exp(2*np.pi*1j*np.array(range(N))/N)
#print('lista de fases =', np.round(lista_de_fases,2))
''' Dibujamos los números complejos '''
tQ.plot_2D_plane(fsize=(6,6))
for z in rho*lista_de_fases:
tQ.draw_vector(x=z.real,y=z.imag)
#draw_unit_circle()
plt.gca().add_patch(plt.Circle((0.,0.),1.,color='black',fill=False))
''' Calculamos la suma. '''
#print(lista_de_fases)
print(np.round(sum(rho*lista_de_fases),10))
(-0+0j)
Aun podemos obtener sumas nulas (interferencias) más generales. Sea \(1\leq j \leq N-1\) un número entero por el que multiplicamos todas las fases. El resultado es el mismo
# cambiar el número N
N=9
rho=1
j=3
''' Creamos las fases'''
lista_de_fases=np.exp(2*j*np.pi*1j*np.array(range(N))/N)
#print('lista de fases =', np.round(lista_de_fases,2))
''' Dibujamos los números complejos '''
tQ.plot_2D_plane(fsize=(6,6))
for z in rho*lista_de_fases:
tQ.draw_vector(x=z.real,y=z.imag)
#draw_unit_circle()
plt.gca().add_patch(plt.Circle((0.,0.),1.,color='black',fill=False))
''' Calculamos la suma. '''
#print(lista_de_fases)
print(np.round(sum(rho*lista_de_fases),10))
(-0+0j)
Sin embargo si \(j = 0, N, 2N,... = 0\,\hbox{mod} N\), entonces la suma no se anula y su valor es igual a \(N\).
Tomemos por ejemplo \(j=N\)
# cambiar el número N
N=9
rho=1
j=N
''' Creamos las fases'''
lista_de_fases=np.exp(2*j*np.pi*1j*np.array(range(N))/N)
#print('lista de fases =', np.round(lista_de_fases,2))
''' Dibujamos los números complejos '''
tQ.plot_2D_plane(fsize=(6,6))
for z in rho*lista_de_fases:
tQ.draw_vector(x=z.real,y=z.imag)
#draw_unit_circle()
plt.gca().add_patch(plt.Circle((0.,0.),1.,color='black',fill=False))
''' Calculamos la suma. '''
#print(lista_de_fases)
print(np.round(sum(rho*lista_de_fases),10))
(9-0j)
Ejercicio
modifica la lista de fases cambiando \(j\) y \(N\) para convencerte de que todos los resultados anteriores son correctos.
Una manera de resumir todos los casos anteriores en una sola expresión involucra la función \(\delta\) de Kronecker
Con ella podemos enunciar el siguiente resultado general
que usaremos con frecuencia al estudiar la Transformada de Fourier Cuántica.
Desigualdad triangular#
El módulo de la suma de dos números complejos verifica que
Donde la igualdad sólo se verifica cuando ambos números complejos son paralelos en el plano complejo.
'''Comprueba que sólo cuando z1 y z2 son paralelos, se satura la desigualdad triangular'''
'''Suma en cartesianas'''
z1 = 1+2j
ang = 0.3 #el ángulo entre z1 y z2
z2 = z1*(1.2*np.exp(1j*ang))
'''Suma '''
zs = z1+z2
print('|z1|+|z2|=',abs(z1)+abs(z2))
print('|z1+z2|=',abs(z1+z2))
tQ.plot_2D_plane(left=-2,right=4,up=5,down=-0) #cambiar las dimensiones para que encuadrar la figura
tQ.draw_vector(z1.real,z1.imag,'b')
tQ.draw_vector(z2.real,z2.imag,'b')
tQ.draw_vector(zs.real,zs.imag,vcolor='r')
|z1|+|z2|= 4.919349550499537
|z1+z2|= 4.8645696489522345