Está en la página 1de 75

Tema-9.

pdf

Anónimo

Física Computacional

3º Grado en Física

Facultad de Ciencias Físicas


Universidad Complutense de Madrid

Reservados todos los derechos.


No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Tema-9

December 26, 2021

1 Tema 9: Métodos de Monte Carlo y procesos aleatorios.


• En física hay muchos procesos que son puramente aleatorios.

• No sabemos por ejemplo el momento exacto en el que un núcleo radiactivo o un neutrón se


desintegrará.
La mecánica cuántica o la teoría cuántica de campos predicen cual es la probabilidad de
que el fenómeno ocurra, pero, al menós hasta donde hemos sido capaces de averiguar, es
imposible saber cuando va a ocurrir.

• También hay otros fenómenos que aunque en principio no son completamente aleatorios,
dada nuestra incapacidad para determinar sus condiciones iniciales, lo sean al menos de
forma práctica. Es el caso del movimiento browniano, el movimiento aparentemente alaorio
de una particula en un fluido producido por su interacción con todas las moléculas de su
alrededor.

• En este último capítulo vamos a estudiar métodos computacionales para lidiar con los pro-
cesos aleatorios, a la vez que los vamos a usar para resolver diferentes tipos de problemas.

1.1 9.1 Números aleatorios.


• El primer paso para estudiar fenómenos aleatorios es generar números aleatorios.

• De forma precisa, nunca vamos a ser capaces de generar números completamente aleatorios
en un ordenador, sino pseudo-aleatorios: tienen una apariencia aleatoria aunque se generan
mediante uan fórmula determinista. Son los llamados generadores de números aleatorios .

1.1.1 9.1.1 Generadores de números aleatorios.


• Consideremos la siguiente ecuación:

f ( x ) = ( ax + c) mod m,
siendo a, c y m constantes enteras, y x una variable entera.

• Vamos a estudiar que números generamos con esa función cuando. partiendo de un valor
inicial x=1, la iteramos de forma sucesiva.

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
[1]: from matplotlib.pyplot import plot,show

N=100
a=1664525

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
c=1013904223
m=4294967296

x=1
xp=[]

for i in range(N):
x=(a*x+c)%m
xp.append(x)

show(plot(xp,"o"))

• Aparentemente, la posición de los números es aleatoria.

• Es el llamado generador de números aleatorios congruencial lineal.

• Hay varias cosas que es importante tener en cuenta:

1. Realmente no estamos generando números aleatorios, el program es completamente


determinista. Fijados a, c, m y x podemos predecir los números que se van a obtener.
Si ejecutamos el programa dos veces, volveremos a obtener exactamente la misma se-
cuencia.

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Física Computacional
Banco de apuntes de la
2. Todos los números generados se encuentras en el intervalo [0,m 1]. Si queremos un
número r, tal que 0 ≤ r < 1, sólo es necesario dividir los números de la congruencia
por m.
3. La elección de a, c, m y x es importante. Para nuestros valores, los números escogidos

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
funcionan razonablemente bien.
4. Para los mismos valores de a, c y m se puede obtener una secuencia completamente
distinta variando el valor de x inicial. Es la llamada semilla.

• Teniendo en cuenta todos estos aspectos, el generador de números aleatorios congruencial


lineal permite obtener secuencias de números pseudoaletorios que son adecuados para mu-
chos problemas en física.

• Sin embargo, no es un buen generador de números aleatorios. Genera correlaciones entre


los diferentes números de la secuencia, algo que no ocurre para números verdaderamente
aleatorios.

• Por suerte hay muchos otros generadores de números aleatorios que permiten obtener series
con pocas o nulas correlaciones.

• El generador que se usa de forma habitual en física hoy en día es el llamado generador
Mersenne Twister, desarrollado en 1997, y basado en una ley de recurrencia lineal para ma-
trices definidas sobre un cuerpo binario en dos dimensiones y cuyo periodo es un numéro
primo de Mersenne (números de la forma 2w − 1 para un w primo dado).

• En python este generador se encuentra dentro del paquete random.

– La función random(), genera un número aleatorio real uniformemente distribuido en el


intervalo (0, 1).
– La función randrange(n), genera un entero entre 0 y n − 1.
– La función randrange(m,n) genera un entero entre m y n − 1.
– La función randrange(m,n,k) genera un etero en el rango que va de m a n − 1, con pasos
de tamaño k.

• Es importante notar que estos programas van a generar números diferentes cada vez que los
llamemos.

[2]: from random import randrange

print(randrange(100))
print(randrange(100))
print(randrange(100))

6
94
58

• Por tanto, si queremos generar un número aleatorio y usarlo más de una vez, será necesario
guardarlo como una variable.

Ejercicio 9.1: Simulando un dado.

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
1. Escribir un programa que imprima dos números aleatorios entre 1 y 6 para simular el lanza-
miento de dos dados.
2. Ejecutar el programa un milón de veces y calcular la probabilidad con las que se obtiene un
doble seis.

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
[3]: from random import randrange

N=1000000
it=0

for i in range(N):

d1=randrange(1,7)
d2=randrange(1,7)

if d1 == 6 and d2 == 6:
it+=1

print("Probabilidad de obtener un 6 doble =", it/N)


print("Probabilidad exact:", 1/36)

Probabilidad de obtener un 6 doble = 0.027685


Probabilidad exact: 0.027777777777777776

1.1.2 9.1.2 Semillas de números aleatorios.


• Tal y como hemos visto en el generador de números aleatorios congruencial lineal, la semilla
de un generador especifica el comienzo de la secuencia de números aleatorios, y por tanto la
secuencia entera.

• En el caso del generador congruencial lineal la semilla es el primer número de la secuencia,


pero en muchos otros casos esto no es así; puede ser que la semilla se use indirectamente
dentro de una formula matemática para especificar el primer número de la serie.

• Esto es precisamente lo que ocurre pare el generador Mersenne twister; la semilla sólo se usa
indirectamente para obtener el primer número de la secuencia.

• De esa forma, fijando la semilla, podemos fijar exactamente la secuencia entera de números
aleatorios que vamos a obtener.

• En python, la semilla se fija usando la función seed(n), donde n es el valor de la semilla que
queremos fijar.

[4]: from random import randrange,seed

seed(17)

for i in range(5):
print(randrange(10))

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
8
6
4
5
4

• Si volvemos a ejecutar la misma línea de código.

[5]: seed(17)

for i in range(5):
print(randrange(10))

8
6
4
5
4

• Obtenemos exactamente la misma secuencia.


• Sin embargo, si no hubieramos especificado la semilla

[6]: for i in range(5):


print(randrange(10))

2
8
4
1
0

• La secuencia habría sido diferente.

• La cuestión es preguntarse por qué podría ser útil fijar la semilla y garantizar que vamos a
obtener la misma serie de números pseudoaleatorios.

• La respuesta es que es útil para escribir el código de un programa por primera vez.

• En ocasiones encontraremos que nuestro programa falla (da un error) para una determinada
secuencia inicial, pero que al volverlo a ejecutar parecezca funcionar bien.

• Esto puede pasar porque el programa no hace exactamente lo mismo para secuencias de
números diferentes, lo que hace aún más complicado encontrar los problemas y solucionar-
los.

• Al fijar la semilla evitamos este problema, y garantizamos que las secuencias serán la misma
al ejecutar el código.

• Una vez el código funcione correctamente se puede eliminar la semilla para garantizar una
aleatoriedad mayor del programa.

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
1.1.3 9.1.3 Probabilidad y números aleatorios.
• Como ya hemos comentado hay muchos fenómenos en física que suceden de forma aleatoria
con una probabilida p determinada.

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Este tipo de comportamiento puede ser descrito fácilmente usando números aleatorios.

• Sólo es necesario generar un número aleatorio entre 0 y 1 y asociarlo una probabilidad, de


forma que por si sólo determine si un determinado fenómeno aleatorio esta teniendo lugar.

• Por ejemplo, la forma de describir el resultado de tirar una moneda al aire podría venir dada
por el código:

[7]: from random import random

for i in range(10):
if random()<0.5:
print("C")
else:
print("X")

C
X
C
X
X
X
X
X
C
X

Ejercicio 9.2: la desintegración de un isótopo radiactivo.


EL isotopo radiactivo 208 Tl (Talio 208) se desintegra en 208 Pb (plomo 208), un elemento estable,
con una vida media de 3053 minutos. La vida media de un elemento radiactivo es el tiempo medio
necesario para que dada una muestra inicial de átomo de 208 Tl N (0) esta se reduzca a la mitad.
Esto nos permite obtener la ecuación de la desintegración radiactiva

N (t) = N (0) 2−t/τ ,


siendo el número de elementos radiactivos por unidad de tiempo y τ la vida media del ele-
mento.

1. Usa la formula de la desintegración radiactiva para definir la probabilidad con la que un


determinado átomo de 208 Tl se desintegrará en un tiempo t.

2. Supongamos que partimos de una muestra con 1000 átomos de talio. Describir como evolu-
ciona el número de átomos de 208 Tl y 208 Pb en un periodo de 103 segundos.

1. Después de un periddo t el número de átomos de Talio que permanecen en la muestra será

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
N (t)
= 2−t/τ ,
N (0)
por tanto la fracción de átomos que se han desintegrado, es decir, la probabilidad de que un

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
átomo se desintegre después de un tiempo t será

p(t) = 1 − 2−t/τ .
[8]: # 2. Vamos a describir la evolución de átomos en la muestra.

from random import random


from numpy import arange
from matplotlib.pyplot import plot,show,xlabel,ylabel,legend

# Constantes

NTl=1000 # Número de átomos de talio


NPb=0 # Número de átomos de plomo
tau=3.053*60 # vida media del talio en segundos
tmax=1000 # tiempo total d ela simulación
h=1 # tamaño de los pasos en el intervalo temporal
p=1-2**(-h/tau) # Probabilidad de decaimiento en un paso

# Listas de puntos para la gráfica

tp=arange(0,tmax,h)
Tlp=[]
Pbp=[]

# bucle principal

for t in tp:
Tlp.append(NTl)
Pbp.append(NPb)

# Calculamos el número de átomos que decaen

decay = 0
for i in range(NTl):
if random()<p:
decay+=1
NTl-=decay
NPb+=decay

# Hacemos el gráfico
plot(tp,Tlp,label="Átomos de Talio")
plot(tp,Pbp,label="Átomos de Plomo")

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
xlabel("Tiempo")
ylabel("Número de átomos")
legend()
show()

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Las pequeñas oscilaciones de las curvas de desintegración son consecuencia de la naturaleza
puramente aleatoria del proceso.

Ejercicio 9.3: desintegración en cadena.


El isótopo 213 Bi se desintegra a 209 Bi por medio las dos vias diferentes indicadas en la siguiente
figura
[9]: from IPython.display import display,Image
display(Image("decay_chain.png",width=400))

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
9

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Empezando con una muestra de 10000 átomos de 213 Bi simular su desintegración discretizando
el tiempo en intervalos de un segundo, en los cuales, se deberá hacer lo siguiente:

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
1. Para cada átomo de 209 Pb en la muestra establecer de forma aleatoria si se desintergra o no
en 209 Bi, y actualizar el número de átomos de cada tipo de forma correspondiente.
2. Aplicar el paso equivalente para los átomos de 209 Tl.
3. Finalmente estudiar la evolución de los átomos de 213 Bi teniendo en cuenta que si un átomo
se desintegra tiene una cierta probabilidad de desintegrase en 209 Pb y en 209 Tl.
Nota, es importante aplicar el proceso de abajo arriba y no de arriba abajo para evitar que en
un mismo paso un átomo de 213 Bi pueda desintegrase directamente más de una vez.
[6]: from random import random
from numpy import arange,log
from matplotlib.pyplot import plot,show,legend

# Constantes

nBi=10000 # muestra inicial de 213Bi


nTl=nPb=nst=0 # átomos iniciales de los demás elementos
h=1 # paso temporal

# vidas medias de los diferentes elementos

tauBi=46*60
tauTl=2.2*60
tauPb=3.3*60

# probabilidad de desinteración de cada elemento

pBi=1-2**(-h/tauBi)
pTl=1-2**(-h/tauTl)
pPb=1-2**(-h/tauPb)

# probabilidad de desintergración del 213Bi

rTl=0.0209
rPb=0.9791

# inicializamos nuestras listas

tp=arange(0,20000,h)
Bip=[]
Tlp=[]
Pbp=[]
stp=[]

10

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
# loop principal

for t in tp:

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
# estudiamos el Pb

for i in range(nPb):
if random()<pPb:
nPb-=1
nst+=1

for i in range(nTl):
if random()<pTl:
nTl-=1
nPb+=1

for i in range(nBi):
if random()<pBi:
nBi-=1
if random()<rTl:
nTl+=1
else:
nPb+=1

Bip.append(nBi)
Tlp.append(nTl)
Pbp.append(nPb)
stp.append(nst)
[7]: plot(tp,Bip,label="Átomos de Bi")
plot(tp,Tlp,label="Átomos de Tl")
plot(tp,Pbp,label="Átomos de Pb")
plot(tp,stp,label="Átomos estables")
xlabel("Tiemp en (s)")
ylabel("Número de átomos")
legend()
show()

11

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Ejercicio 9.4: el movimiento Browniano.
El movimiento Browiniano se refiere al movimiento de una partícula, por ejemplo de humo o
polvo, en un gas o líquido debido a las interacciones aleatorias con las móleculas del fluido.
En este ejercicio vamos a simular el movimiento de una de esas partículas en dos dimensiones.
Para ello discretizamos su posición en un retículo de L × L cuadrados, que nos permiten describir
la posición de la partícula por medio de dos índices, i, j = 0, · · · , L − 1.
Inicializamos la posición de nuestra partícula de forma que se encuentre en el centro del
retículo, y en cada paso, le asignamos una probabilidad aleatoria para que se desplace hacía cada
uno de los posiciones adjacentes en la cuadrícula. La partícula esta confinada dentro de la caja, por
lo que no puede moverse dentro de esta. Este proceso es lo que llamamos random walk (camino
aleatorio).
Escribir un programa que describa el movimiento de la partícula durante 1 millón de pasos
usando un retículo de tamaño L=101 y representar su posición por medio de una animación.
[ ]: from vpython import sphere,box,color,rate,canvas,vector

scene = canvas(width=500, height=500,


center=vector(0,0,0))
[ ]: from random import randrange

L=1001
N=10000

framerate=100

12

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
# Dibujamos nuestra caja

box(pos=vector(-L/2,0,0),length=1,height=L,width=2,color=color.green)
box(pos=vector(L/2,0,0),length=1,height=L,width=2,color=color.green)
box(pos=vector(0,-L/2,0),length=L,height=1,width=2,color=color.green)
box(pos=vector(0,L/2,0),length=L,height=1,width=2,color=color.green)

# posición inicial en el grid

i,j=0,0

# colocamos nuestra esfera

s=sphere(pos=vector(i,j,0),radius=1,color=color.white)

# Loop principal

for k in range(N):
dir=randrange(4) # la dirección viene marcada por un entero aleatorio␣
֒→[0,3]

if dir==0:
if i<L/2:
i+=1

elif dir==1:
if i>-L/2:
i-=1

elif dir==2:
if j<L/2:
j+=1

elif dir==3:
if j>-L/2:
j-=1

rate(framerate)
s.pos=vector(i,j,0)
Ejercicio 9.5: agregación limitada por difusión.
En este ejercicio vamos a programar una de los modelos más famosos en física computacional,
la agregación limitada por difusión o DMA.
El modelo funciona como sigue. Se toma un retículo con una sólo partícula en el medio. Esta
partícula realiza un camino aleatorio similar al del movimiento browniano hasta que llega a uno
de los bordes del retículo, punto en el que la partícula queda anclada de forma inamovible.

13

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
[44]: from IPython.display import Image,display
display(Image("DMA.png",width=400))

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Repetimos el proceso con una segunda partícula, hasta que llega a un nuevo punto del borde o
queda anclada junto a la primera partícula. Ejecutamos el mismo proceso hasta que una partícula
anclada llega al centro del retículo.
Programar el modélo DLA en un retículo de tamaño 101 × 101 y mostrar la evolución del
sistema en una animación.
[3]: # creamos el lienzo de la animación

from vpython import sphere,box,color,rate,canvas,vector

scene = canvas(width=500,height=500,center=vector(L/2,L/2,0))

14

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
<IPython.core.display.HTML object>

<IPython.core.display.Javascript object>

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
[4]: from numpy import zeros,sin
from random import random

# Constantes

L=200
# array donde se colocan las partículas ancladas

anclaje=zeros([L+1,L+1],int)

# Dibujamos nuestra caja

box(pos=vector(0,L/2,0),length=1,height=L,width=2,color=color.white)
box(pos=vector(L,L/2,0),length=1,height=L,width=2,color=color.white)
box(pos=vector(L/2,0,0),length=L,height=1,width=2,color=color.white)
box(pos=vector(L/2,L,0),length=L,height=1,width=2,color=color.white)

# loop principal
t=0
colscale=0.001 # vamos a dibujar cada partícula de un color

# mientras que en el centro no haya ninguna particula seguimos lanzando nuevas

while anclaje[L//2,L//2]==0:

# Empezamos una nueva partícula

x=y=L//2
col=sin(colscale*t)
t+=1
rate(1000000)
# hacemos el camino aleatorio

while True: # mientras no toque una pared o otra partícula

# comprobamos si ha alzanzado la pared

if x<=0 or x>=L or y<=0 or y>=L:


anclaje[x,y]=1
sphere(pos=vector(x,y,0),radius=1,color=vector(col,0,1-col))
break

15

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
# comprobamos que no ha tocado a ninguna partícula

if anclaje[x-1,y]==1 or anclaje[x+1,y]==1 or anclaje[x,y-1]==1 or␣


anclaje[x,y+1]==1:

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
֒→

anclaje[x,y]=1
sphere(pos=vector(x,y,0),radius=1,color=vector(col,0,1-col))
break

# si no seguimos moviendo la partícula

if random()<0.5:
if random()<0.5:
x+=1
else:
x-=1
else:
if random()<0.5:
y+=1
else:
y-=1

1.1.4 9.1.3 Números aleatorios con distribución no-uniforme.


• Todos los números aleatorios que hemos generados hasta ahora están distribuidos uniforme-
mente. Es decir todos los valores posibles que pueden tomar esos números tienen la misma
probabilidad de aparecer.
• Sin embargo, en física hay muchas procesos que suceden con probabilidad no-uniforme. Un
ejemplo es la situación anterior del decaimiento de un número N de átomos de un isótopos
radiactivos.
• Ya hemos visto que la probabilidad de que un átomo decaiga en un intervalo de tiempo dt
viene dado por

 
−dt/τ dt log 2
p(dt) = 1 − 2 = 1 − exp − log 2 ≃ dt,
τ τ
donde hemos despreciado términos O dt2 .


• Ahora podemos por tanto preguntarnos cual es la probabilidad de que un isótopo radiactivo
se desintegre en el intervalo t + dt.
• Para que un átomo se desintegre en el intervalo t + dt tiene en primer lugar que haber so-
brevivido hasta el tiempo t lo cual ocurre con la probabilidad 2−t/τ y luego desintegrase en
el intervalo dt por tanto, la probabilidad de que se desintegre entre los intevalor t y t + dt es

log 2
p(t)dt = 2−t/τ dt,
τ

16

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
que es el ejemplo de una distribución no uniforme pues los tiempos de desintegración t se
distribuyen con una proporción 2−t/τ , es decir, es más
probable que se desintegre en tiempo anteriores que en tiempos posteriores.

• Por tanto, una forma mucho más eficiente de calcular la desintegración de N isótopos ra-
diactivos habría sido generar N números aleatorios generados con la distribución derivada
arriba para representar el tiempo en el que cada uno de los átomos se desintegrarán.

• Con ello, la curva que describe la evolución del número de átomos del isótopo se podría
obtener contando simplemente el número de átomos que han decaído en un tiempo dado.

• El problema consiste en obtener un generador de números aleatorios con una distribución


dada. Para hacerlo usaremos el llamado método de la transformación.

El método de la transformación.

• Supongamos que tenemos un generador de números aleatorios en coma flotante asociado a


una densidad de probabilidad q(z), que implica que la probabilidad de generar un número
en el intervalo z + dz es q(z)dz.

• Supongamos a cotinuación que tenemos una función x = x (z). Por tanto, para un número
aleatorio z generado con la densidad de probabilidad q(z), x (z) será otro número aleatorio
que en general estará asociado a otra distribución de probabilidad p( x ).

• Nuestro objetivo no es otro que encontrar la función x (z) que noes permite generar un
número x con la probabilidad que queremos p( x ).

• Por definición, la probabilidad de generar un número x entre x + dx será igual que la prob-
abilidad de generar un número z en el intervalo z + dz

p( x )dx = q(z)dz,
donde ya hemos especificado que x = x (z).

• En general, tendremos un generador de números aleatorios uniforme en el intervalo [0, 1),


tal como el que obtenemos usando la función random.

• En ese caso, la probabilidad será q(z) en el intervalo (0, 1) y 0 fuera de él.

• Por tanto la probabilidad de obtener un número menor de z será

Z x (z) Z z
p( x ′ ) dx ′ = dz = z.
−∞ 0

• Si pudieramos hacer la integral de la izquierda, obtendríamos por tanto el valor que ha de


cumplir nuestra función x (z).

• No esta claro que siempre podamos resolver la integral, y que si lo hacemos, entonces po-
damos resolver la ecuación resultante; sin embargo, si lo hacemos, habremos obtenido exac-
tamente la función que queremos.

17

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• A modo de ejemplo, supongamos que tenemos la distribución exponencial

p( x ) = µe−µx , con x ∈ [0, ∞)

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
donde el factor mu es necesario para cumplir que
Z ∞

p( x )dx = µe−µx = −e−µx 0
= 1.
0

• Aplicando la formula anterior, la probabilidad de obtener un número menor de z será

Z x (z)

µe−µx dx ′ = 1 − e−µx(z) = z,
0
que implica que

1
x (z) = − log(1 − z).
µ

• Por tanto para obtener nuestros números aleatorios con distribución exponencial todo lo que
tenemos que hacer es generar números aleatorios con distribución uniforme en el intervalo
[0, 1) e introducirlos en la ecuación anterior.

Ejercicio 9.6: números aleatorios con distribución exponencial.


Repetir el ejercicio 9.2 pero usando en esta ocasión números aleatorios distribuidos con prob-
abilidad exponencial.
[12]: from numpy import log,empty,arange,sort
from random import random
from matplotlib.pyplot import plot,show

N=1000
tau=3.052*60
mu=log(2)/tau

# generamos el conjunto de tiempos en los que un elemento radiactivo decae

ti=empty(N,float)
for i in range(N):
ti[i]=-log(1-random())/mu

# ordenamos nuestro array de tiempos para mostrarlo uno a uno

ts=sort(ti)
plot(ts,arange(N,0,-1))
plot(ts,arange(N))
show()

18

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Ejercicio 9.7: Eligiendo un punto aleatorio en la superficie de la Tierra
En este ejercicio vamos a calcular un punto aleatorio en la superficie terrestre, es decir, vamos a
escoger aleatoriamente la latitud y longitud de cualquier punto de la Tierra. Para ello, recordar que
cualquier punto de la superfice viene determinado por sus coordenadas esféricas r, θ, ϕ, donde en
nuestro caso r = R, siendo R el radio de la tierra, θ es el ángulo polar, medido desde el polo norte,
y ϕ el ángulo azimutal o longitudinal.

1. Determinar cual es la probabilidad de que un punto aleatorio se encuentre en un elemento


diferencial de ángulo sólido dado, y factorizar la probabilidad total en función de la proba-
bilidad asociada a θ y ϕ.

2. Obtener las fórmulas que permiten generar los ángulos θ y ϕ a partir de sus correspondientes
distribuciones de probabilidad.

3. Usar esas fórumulas para generar 500 puntos en la superficie terrestre de forma aleatoria.
Representarlos por medio de una animación en una esfera de radio unidad.

1. La probabilidad de que un determinado punto se encuentre en un elemento diferencial de


ángulo sólido viene dada por

sin θdθdϕ sin θdθ dϕ


p(θ, ϕ)dθdϕ = = = p(θ )dθ × p(ϕ)dϕ,
4π 2 2π
donde los intervalos de cada variable son [0, π ) y [0, 2π ) y donde cada una de nuestra prob-
abilidades satisface la normalización correct
Z π Z 2π
p(θ )dθ = p(ϕ)dϕ = 1.
0 0

19

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
2. Obtener un número aleatorio con distribución p(ϕ)estrivial puesesunadistribucinuni f ormeentre0y2π.
En el caso de θ, aplicando el método de la transformación tenemos
Z θ
1 1

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
sin θ ′ dθ ′ = (1 − cos θ ) = z,
2 0 2

por lo que θ = cos−1 (1 − 2z).

3. Una vez podemos generar aleatoriamente los ángulos θ y ϕ los puntos de nuestra superficie
de radio unidad vendrán dados por las coordenadas cartesianas

x = sin θ cos ϕ, y = sin θ sin ϕ, z = cos θ.

[6]: # generamos la animación

from vpython import sphere,rate,canvas,vector

scene = canvas(width=500, height=500,


center=vector(0,0,0))

<IPython.core.display.HTML object>

<IPython.core.display.Javascript object>

[7]: from math import cos,sin,acos,pi


from random import random

for i in range(500):
phi=2*pi*random()
theta=acos(1-2*random())

֒→sphere(pos=vector(sin(theta)*cos(phi),sin(theta)*sin(phi),cos(theta)),radius=0.

֒→02)

1.1.5 9.1.4 Números aleatorios gaussianos.


• La distribución gaussiana o normal juega un papel fundamental tanto en física como en
matemáticas gracias al teorema central del límite que establece que, bajo ciertas condiciones
generales, la suma de N variables aleatorias tiene aproximadamente una distribución nor-
mal.

• El teorema del límite central implica por tanto que la distribución normal puede usarse como
aproximación de muchas otras distribuciones.

• La distribución gaussiana esta definida por la densidad de probabilidad

20

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
1 x −µ 2
e− 2 ( ),
1
p( x ) = √ con x ∈ (−∞, ∞),
σ
2π σ
donde µ es la media y σ la desviación típica o anchura de la destribución.

• Siguiendo el método de la transformación tenemos por tanto la igualdad

Z x (z)  ′ 2
1 − 21 x σ−µ
√ e dx ′ = z.
2π σ −∞

• Sin embargo la integral no se conoce de forma analítica, por lo que el método de la transfor-
mación falla en este caso.

• Por suerte, hay un truco que podemos emplear para generar números aleatorios distribuidos
normalmente a partir de números aleatorios con distribución uniforme.

• Imaginemos dos números aleatorios x e y extraidos de una distribución gaussiana con la


misma media µ y desviación típica σ.
La probabilidad de que esos números se encuentren en el elemento de superficie ( x +
dx )(y + dy) del plano xy es

!
1 ( x − µ )2 + ( y − µ )2
p( x )dx × p(y)dy = 2
exp − ,
2π σ 2σ2
que también se puede expresar en coordenadas polares. Haciendo

x ′ = x − µ, y′ = y − µ, x ′2 + y ′2 = r 2 y dxdy = r dr dθ,
podemos expresar nuestra probabilidad como

r2 r2
   
1 r dθ
p( x )dx × p(y)dy = p(r, θ )dr dθ = exp − r dr dθ = exp − dr = p(r )dr × p(θ )dθ,
2π σ2 2σ2 σ2 2σ2 2π
donde las densidades de probabilidad p(r ) y p(θ ) estás normalizadas correctamente.

• Es decir, sí generamos números aleatorios r y θ con las distribuciones de probabilidad p(r ) y


p(θ ) respectivamente, al hacer el cambio a coordenadas cartesianas tendremos dos variables
aleatorias con una densidad de probabilidad normal.

• Generar un número con distribución p(θ ) es trivial, no es más que una distribución uniforme
en el intervalo [0, 2π ).

• Para la variable r podemos usar de nuevo el método de la transformación

r ′2 r ( z )2
Z r (z)    
1
p(r )dr = exp − 2 r ′ dr ′ = 1 − exp − = z,
σ2 0 2σ 2σ2
que implica que
q
r (z) = −2σ2 log(1 − z).

21

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Una vez obtenidos dos variables aleatorias r y θ podemos convertirlas en cartesianas usando
que

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
x = µ + r cos θ, y = µ + r sin θ.
Ejercicio 9.8: dispersión de Coulomb o Rutherford.
A principio del S. XX, Ernest Rutherford y sus colaboradores mostraron que cuando una
partícula α, un núcleo de helio formado por dos protones y dos neutrones, es lanzada cerca de
un átomo, es dispersada principamente debido a la respulsión eléctrica asociada a dos cargas con
el mismo signo.
Esto permitio descartar el módelo atómico de Thomson, los átomos deben tener una extructura
con carga positiva diferenciada, que a partir de ese momento se llamaron núcleos atómicos.
A través del experimento se comprobo que el ángulo dispersado por la partícula alpha venía
dado por la expresión

1 Ze2
tan θ =
2 2πϵ0 E b
[13]: from IPython.display import Image,display

display(Image("rutherford.png",width=500))

siendo E la energía cinética de la partícula α, Z en número atómico del material sobre el que la
partícula α es lanzada, e la carga eléctrica, y b el parámetro de impacto, la distancia perpendicular
entre la trajectoria de la partícula α y el átomo.
Consideremos un haz de un milón partículas α con energía cinética 7.7 eV, que tienen un perfil
Gaussiano en el plano perpendicular a la dirección de incidencia, tanto en el eje x como el eje y con

22

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
una desviación estandar σ = a0 /100 donde a0 es el radio de Bohr, que se lanza sobre un átomo de
oro.
Calcular la fracción de partículas que rebotán hacia atras, es decir cuyo ángulo de dispersión
sea mayor de 90◦ .

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• En primer lugar si θ > π/2 las partículas rebotarán hacia atrás. Como la tangente incre-
menta con el ángulo en el intervalo [π/2, π ] tenemos que la partículas rebotaran si

π Ze2
tan θ > tan =1= ,
4 2πϵ0 Eb
o lo que es lo mismo, si el parámetro de impacto cumple

Ze2
b< .
2πϵ0 E

• Simulemos a continuación el proceso de dispersión

[11]: from numpy import sqrt,log,cos,sin,pi


from random import random

# Constantes

Z=79 # número atómico del oro


e=1.602e-19 # carga eléctrica
E=7.7e6*e # energía cinética de haz en eV
epsilon0=8.854e-12 # permitividad del vació
a0=5.292e-11 # radio de bohr
sigma=a0/100 # desviación típica de la distribución gaussiana␣
֒→incidente.

N=1000000 # número de partículas del haz

# Función para generar dos números aleatorios con una distribución Gaussiana

def gaussian():
r=sqrt(-2*sigma**2*log(1-random()))
theta=2*pi*random()
x=r*cos(theta)
y=r*sin(theta)

return x,y

# Programa principal

it = 0

for i in range(N):

23

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
x,y=gaussian()
b=sqrt(x*x + y*y)

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
if b<Z*e*e/(2*pi*epsilon0*E):
it+=1

print("Habrá", it,"partículas reflejadas de", N)


print("Que suponen el", it/N*100, "%")

Habrá 1593 partículas reflejadas de 1000000


Que suponen el 0.1593 %

Final de la Clase del 10/12/21.

1.2 9.2 Integración por Monte Carlo.


• Para entender porque los números aleatorios nos pueden ayudar a calcular integrales volva-
mos al Ejercicio 9.6.
• Las partículas que se verán reflejadas al interacturar con el núcleo de oro son aquellas cuyo
parámetro de impacto es menor que un bmax .
• Como las partículas tienen un perfil gaussiano en el plano cuya normal coincide con la di-
rección incidente, otra forma de calcular las partículas reflejadas será

r2 b2 Ze2
Z bmax      
Nrefl 1
= 2 exp − 2 r dr = 1 − exp − max = 1 − exp − .
Ntot σ 0 2σ 2σ2 4πϵ0 σ2 E
• Introduciendo números
[15]: from numpy import exp

100*(1-exp(-Z**2*e**4/(8*pi**2*epsilon0**2*sigma**2*E**2)))
[15]: 0.15572235058136652

• Que coincide bastante bien con nuestra estimación anterior.


• Y es que, en el fondo, lo que hemos hecho en el ejercicio 9.6 es estimar esa misma integral
usando números aleatorios.

1.2.1 9.2.2 Cálculo de integrales por el método de Monte Carlo.


• Para entender en más profundidad como funciona el método, consideremos la integral

Z 2  
1
I= sin2 dx,
0 x (2 − x )
cuyo cálculo no implica más que calcular el área bajo la curva

24

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
[16]: from numpy import sin,linspace
from matplotlib.pyplot import plot,show,fill_between

x=linspace(0.0001,1.9999,1000000)
y=sin(1/x/(2-x))**2
plot(x,y)
fill_between(x,y,step="pre",alpha=0.4)
plot(x,y,"0.")
show()

• El comportamiento de la función es perfecamente suave fuera de los extremos, pero, cerca


de ellos, la función empieza a oscilar infinitesimalmente rápido, lo que hace que calcular su
valor estudiando los métodos que hemos visto hasta ahora sea bastante complicado.

• Sin embargo, la integral esta perfectamente definida y acotada, pues está contenida en un
rectángulo de área 2.

• Por tanto una forma de replantear el problema es asociar la integral con la probabilidad de
que un punto generado aleatoriamente dentro del rectangulo de area A que contiene a la
gráfica, caiga en la zona en azul, es decir

I
, p=
A
donde A es el área del rectángulo total e I es nuestra integral.

25

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Por tanto, para estimar la integral sólo tenemos que calcular dicha probabilidad lo cual pode-
mos hacer de la siguiente forma

1. Generamos un número N de puntos dentro del área A que contiene nuestra curva.

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
2. Contamos el número de puntos que caen en la región azul, digamos que son por ejem-
plo k.
3. Estimamos la probabilidad a la fracción de puntos que cae debajo de la curva, es decir
con k/N.
4. Estimamos la integral a partir de la expresión

k
I= A.
N
• Este es el llamado de hit or miss (acertar o fallar).

Ejercicio 9.9: cálculo de una integral usando el método de Monte Carlo.


Calcular la integral
Z 2  
1
I= sin2 dx,
0 x (2 − x )
usando números aleatorios.
[17]: from numpy import sin
from random import random

def f(x):
return sin(1/x/(2-x))**2

N=1000000
it=0
A=2

for i in range(N):
x=2*random() #nž entre 0 y 2
y=random() #nž entre 0 y 1
if y<f(x):
it+=1
I=A*it/N
print(I)

1.451686

Un valor correcto hasta dos decimales.

1.2.2 9.2.3 Error de las integrales obtenidas por el método de Monte Carlo.
• El problema de los métodos de Monte Carlo es que no son muy precisos.

• Su error, por supuesto, esta asociado a nuestra limitación para estimar una probabilidad
usando números aleatorios.

26

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• Vamos a calcular cual es la precision que podemos esperar para dicha estimación.

1. La probabilidad de que un sólo número aleatorio se encuentre por debajo de la curva,


es tal y como hemos dicho

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
I
p= .
A
por lo que 1-p será la probabilidad de que se encuentre sobre la curva.

2. La probabilidad de que sólo k de entre N números aleatorios se encuentren bajo la curva


será por tanto pk (1 − p) N −k . Sin embargo eso puede ocurrir en ( Nk ) formas diferentes, es
decir, hay ( Nk ) posibilidades de escoger k números de entre N. Por tanto, la probabilidad
de tener exactamente k puntos bajo la curva es
 
N k
P(k) = p (1 − p ) N − k ,
k

que no es más que la probabilidad de la distribución binomial.

3. Para calcular el error de nuestra probabilidad sólo tebemos que calcular la variancia de
la distribución binomial.
– En primer lugar, el valor esperado después de haber lanzado N números aleatorios
será:

N N N
N−1 k
   
N k N −k
⟨k⟩ = ∑ kP(k) = ∑ k p (1 − p ) =∑N p (1 − p ) N − k (1)
k =0 k =1
k k =1
k − 1
N  N −1 
N − 1 k −1 N−1 k
 
=N p ∑ p (1 − p ) N − k = N p ∑ p (1 − p) N −1−k = N p. (2)
k =1
k − 1 k =0
k

– Mientras que el valor esperado al cuadrado vendrá dado por

N N
N − 1 k −1 N−1 k
   
N −k
2
⟨k ⟩ = N p ∑ k p (1 − p ) = N p ∑ ( k + 1) p (1 − p) N −1−k (3)
k =1
k−1 k =0
k
N 
N−1 k

=N p + ∑ k p ( 1 − p ) N −1− k = N p + N ( N − 1 ) p 2 . (4)
k =0
k

– La variancia de la distribución binomial es por tanto


 
I I
var(k ) = ⟨k2 ⟩ − ⟨k ⟩2 = N p(1 − p) = N 1− .
A A
– Por tanto teniendo en cuenta que estamos estimando nuestra integral como I =
kA/N, el error de nuestra estimación es

27

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
p
A I(A − I)
q
σ= var(k ) = √ ,
N N

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
es decir, nuestro error escala como N −1/2 .

• Por tanto el error de nuestra integral estimada usando el método de Monte Carlo varia como
N −1/2 .

• Si calculamos una intergral por el método de Monte Carlo con 100 puntos, es de esperar una
precisión del 10%; por supuesto el valor exacto dependerá de I y A.

• Este es un resultado mucho más modesto de lo que hemos obtenido con el método del
trapecio, que escala con N −2 , con el de Simpson, N −4 , o con el de la cuadratura gaussiana,
N−N .

• Sin embargo los métodos de Monte Carlo funcionan incluso para la integrales de funciones
patológicas con grandes variaciones, o, como veremos, para integrales multidimensionales.

1.2.3 9.2.4 El método del valor medio.


• El método de hit or miss no es el mejor para estimar una integral usando números aleato-
rios.

• El método más común para hacerlo se llama el método del valor medio.

• Sea una vez más la integral


Z b
I= f ( x )dx.
a

• La media de la función en el intervalo viene dada por

Z b
1 I
⟨f⟩ = f ( x ) dx = ,
b−a a b−a
por lo que conciendo la media podemos obtener la integral

I = (b − a)⟨ f ⟩.

• Pero la media se puede estimar facilmente eligiendo N puntos aleatorios en el intervalo [ a, b]


xi con i = 1, · · · , N, por lo que

(b − a) N
N i∑
I = (b − a)⟨ f ⟩ ≃ f ( x i ),
=1
que es el llamado método del valor medio.

• El error del método se puede estimar facilmente teniedo en cuenta que

28

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
var( f ) = ⟨ f 2 ⟩ − ⟨ f ⟩,
y que la varianza de una suma es la suma de las varianzs.
• Por tanto nuestro error será

v
uN p
(b − A) u var( f )
σ( I ) =
N
t
∑ var( f ) = (b − a) √ N ,
i =1

es decir, el error sigue yendo como N −1/2 .


• Sin embargo el factor de propocionalidad es siempre menor o igual que el método hit or
miss, que implica que el método del valor medio siempre va a ser mejor o igual.

Demostración de que el método del valor medio es más preciso que el método hit or miss.
• Para demostrar que este es el caso asumamos que nuestra función f ( x ) > 0 en todo el
dominio de integración y que área total de probabilidad, el área que engloba la función en
su intervalo, es

A = (b − a) H,
siendo a y b el punto inicial y final del intervalo en el que esta integrando la función y H la
altura.
• Definamos ahora la variable s, definda tal que para cada una de los i “lanzamientos” de
Monte Carlo, si = 1 si es un hit y 0 si es un miss.
• De esta forma, la estimación de la integral usando el método hit or miss, vendrá dada por

I = ( b − a ) A ⟨ s ⟩,
siendo ⟨s⟩ = k = ∑iN=1 si .
• De esta forma, el error de nuestra estimación usando el método hit or miss será

A (b − a) H (b − a) H
q q q
σ( I ) = var(k ) = Nvar(s) = var(s) √ ,
N N N
donde uno vez más, hemos tenido en cuenta que la varianza de una suma es la suma de las
varianzas.
• Comparando este resultado con el error correspondiente al método del valor medio ten-
dremos que el segundo es más o igual de preciso si
p
var( f ) (b − a) H
q
(b − a) √ ≤ var(s) √ ,
N N
o equivalentemente si

var( f ) ≤ var(s) H 2 .

29

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Por otro lado, la varianza de la variable s, viene dada por var(s) = ⟨s2 ⟩ − ⟨s⟩2 , siendo ⟨s⟩ =
p, la probabilidad media de un acierto, y ⟨s2 ⟩ = p × 12 + (1 − p) × 02 = p, la media al
cuadrado. Por tanto

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
var(s) = ⟨s2 ⟩ − ⟨s⟩2 = p(1 − p).

• Por otro lado tenemos que

I ⟨f⟩ I
⟨f⟩ = ⇒ = = p,
(b − a) H A
por lo que sustituyendo en var(s) tenemos

H 2 var(s) = p(1 − p) = ⟨ f ⟩ ( H − ⟨ f ⟩) .

• Por tanto, el método del valor medio será más preciso que el método hit or miss si

var( f ) = ⟨ f 2 ⟩ − ⟨ f ⟩2 ≤ ⟨ f ⟩ ( H − ⟨ f ⟩) ,

o lo que es lo mismo si

⟨ f 2 ⟩ ≤ H ⟨ f ⟩,

condición que se satisface trivialmente porque f y H cumplen 0 < f < H, en el dominio de


intrgración.

Ejercicio 9.10: cálculo de una integral usando el método del valor medio.
Volver a evaluar la integral
Z 2  
2 1
I= sin dx,
0 x (2 − x )
y su error usando un millón de puntos alatorios para

1. El método hit or miss.


2. El método del valor medio.

Comprobar que el error es menor en el segundo caso.


[18]: from numpy import sin,sqrt
from random import random

def f(x):
return(sin(1/(x*(2-x))))**2

a=0
b=2
N=1000000

# hit or miss:

30

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
A=2
it=0

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
for i in range(N):
x=2*random()
y=random()

if y<f(x):
it+=1

I=A*it/N
sigma=sqrt(I*(A-I)/N)

print(I,sigma)

1.45322 0.0008913986939635934

[19]: # método del valor medio:

sum=sumsq=0

for i in range(N):

fx=f(2*random())
sum+=fx
sumsq+=fx**2

media=sum/N
var=sumsq/N-media**2
I=(b-a)*media
sigma=(b-a)*sqrt(var/N)

print(I,sigma)

1.4505819358467136 0.0005282018437229834

1.2.4 9.2.5 Integrales multidimensionales.


• Aparte de para integrales con patalogias, los métodos de Monte Carlo son útiles en integrales
multidimensionales.

• Tal y como vimos en el Tema 3, la cuadratura gaussiana en más de una dimensión tiene el
problema de que no hay una forma clara de elegir los puntos y los pesos.

• Por otro lado, métodos más simples, como el del trapecio, exigen muestrar el integrando en
cada una de las variables, lo que hace que se vuelvan lentos cuando el número de dimen-
siones aumentan.

31

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• Por ejemplo, usar el método del trapecio o de Simpson en tres dimensions con 100 puntos
en cada una de ellas implica evaluar el integrando en 1003 = 106 , lo que para funciones
complicadas puede ser lento.

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Para cuatro dimensiones ya tendríamos 108 evaluaciones, lo que puede no ser una opción
desde el punto de vista del tiempo computacional.

• Los métodos de Monte Carlo se pueden generalizar trivialmente a dimensiones arbitrarias, y


su precisión sigue escalando con N −1/2 , es decir, siguen dando respuestas razonables usando
un número reducido de evaluaciones.

• La generalización del método del valor medio para integrales multidimensionales con
volumen V viene dada por

N
V
I≃
N ∑ f (r i ),
i =1

donde ri reprenseta los puntos escogidos aleatoriamente del volumen V.

Ejercicio 9.11: volumen de una hiperesfera.


Vamos a estimar el volumen de una esfera de radio unidad en 10 dimensiones usando el
método de Monte Carlo.
Para plantear el problema consideremos el ejemplo equivalente en dos dimensiones
[20]: from IPython.display import Image,display
display(Image("circle.png",width=500))

32

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
El área del cículo viene por tanto dado por la integral
ZZ 1
I= f ( x, y) dx dy,
−1
donde la función viene definda como

1 if x2 + y2 ≤ 1,

f ( x, y) =
0 de otra forma,
por lo que la estimación de la integral usando el método del valor medio será
N
4
I≃
N ∑ f ( x i , y i ).
i =1

Generalizar este caso para calcular el volumen de la hiperesfera en diez dimensiones.

33

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
[1]: from numpy import empty,dot
from random import random

d=10 # dimensiones de nuestra esfera

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
N=1000000 # número de puntos

# integrando

def f(r):
if dot(r,r)<=1:
return 1
else:
return 0

s=0 # suma de nuestra integral

for i in range(N):

r=empty(d,float)
for k in range(d):
r[k]=2*random()-1 #nž entre -1 y 1

s+=f(r)

print(2**d*s/N)

2.589696

• Muy cercano del resultado correcto que es π 5 /5!

[2]: from math import pi,factorial


pi**5/factorial(5)
[2]: 2.550164039877345

1.2.5 9.2.6 Muestreo por importancia (promedios con peso).


• Tal y como hemos visto los métodos de Monte Carlo son adecuados para calcular integrales
de funciones con patológicas, con rápidas variaciones.

• Sin embargo hay un tipo de funciones para las que la integración por Monte Carlo no fun-
ciona. Consideremos por ejemplo la integral

Z 1 −1/2
x
I= dx,
0 ex + 1
que aparece en los gases de Fermi.

• Aunque el integrando diverge para x=0, la integral tiene un valor finito.

34

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• Sin embargo, al aplicar el método del valor medio

(b − a) N
N i∑
I= f ( xi )

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
=1

podemos encontrar problemas pues f ( xi ) → ∞ cuando xi → 0, por lo que podemos obtener


resultados muy diferentes a la suma dependiendo de donde caigan nuestros puntos aleato-
rios.

• Esto obviamente implica que la incertidumbre de nuestra estimación va a ser mucho más
grande, pudiendo llegar incluso a infinito si estamos evaluando la función en x = 0.

• Una forma de solucionar este problema es escoger nuestros puntos de forma no uniforme
en el intervalo de integración, es decir, calcular un valor medio con un cierto peso para cada
valor de la variable aleatoria.

• Es lo que llamamos el muestreo de importancia, que funciona como sigue.

• Dada una función arbitraria g( x ) definimos su media ponderada con el peso ω sobre el
intervalo [ a, b] como
Rb
a
ω ( x ) g( x ) dx
⟨ g( x )⟩ω = Rb ,
a
ω ( x ) dx

donde ω ( x ) es cualquier función a elegir.

• Volviendo de nuevo a nuestra integral


Z b
I= f ( x ) dx.
a

y, haciendo g( x ) = f ( x )/ω ( x ), tenemos que


Rb
f (x) ω ( x ) f ( x )/ω ( x ) dx
 
a I
= Rb = Rb ,
ω(x) ω ω ( x ) dx ω ( x ) dx
a a

o lo que es lo mismo

f (x) b
  Z
I= ω ( x ) dx,
ω(x) ω a

que nos permite calcular el valor de nuestra integral a partir de cualquier media ponderada,
en vez de a partir de una media uniforme.

35

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Calculando la media ponderada.

• La cuestión ahora es calcular la media ponderada.

• Para ello, definamos la densidad de probabilidad

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
ω(x)
p( x ) = R b ,
a
ω ( x ) dx

que es como la función peso ω ( x ) pero normalizada a 1.

• Dados N números xi en el intervalo [a,b] generados con esa distribución aleatoria, p( x ) dx


será la probabilidad de que uno caiga en el intervalo [ x, x + dx ], de forma que el promedio
o valor esperado de números aleatorios que encontraremos en ese elemento diferencial será
N p( x ) dx.

• Usando este resultado, el promedio de evaluar una función g( x ) sobre los puntos xi genera-
dos con la distribución p( x ) en el intervalo [ a, b] será

N Z b Z b
1 1
N ∑ g ( xi ) ≃ N a
N p( x ) g( x ) dx =
a
p( x ) g( x ) dx,
i =1

donde estamos aproximando la suma por una integral ponderada, y por tanto, donde la
aproximación será mejor cuanto mayor sea el número de elementos de la suma.

• Con este resultado es trivial calcular la media ponderada pues


Rb N
a
ω ( x ) g( x ) dx Z b
1
⟨ g( x )⟩ω = Rb = p( x ) g( x ) dx ≃
N ∑ g ( x i ),
a
ω ( x ) dx a i =1

donde los puntos xi están generados con la distribución no uniforme p( x ).


de forma que nuestra integral I se puede expresar como

N Z b
1 f ( xi )
I≃
N ∑ ω ( xi ) a
ω ( x ) dx ,
i =1

que es la fórmula fundamental del muestreo por importancia.

• Por supuesto, escogiendo ω ( x ) = 1, recuperamos la expresión para el método del valor


medio.

• El muestreo por importancia nos permite calcular una estimación de la integral I evaluando
no la suma ∑i f ( xi ) sino ∑i f ( xi )/ω ( xi ), donde ω ( x ) puede ser cualquier función a elegir.

• Esta flexibilidad a la hora de elegir ω ( x ) es muy útil ya que podemos escogerla de forma
que podamos evitar las posibles patologías de la función. Por ejemplo, dada una singu-
laridad, podemos escoger ω ( x ) para cancelarla, de forma que la suma ∑i f ( xi )/ω ( xi ) este
perfectamente definida.

36

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• Finalmente el error de nuestra estimación se puede calcular de forma totalmente equivalente
a la dem método del valor medio, viniendo dado por
p Z b
varω ( f /ω )
σ( f ω ) = √ ω ( x ) dx,
N a

siendo una vez más varω ( f /ω ) = ⟨ g2 ⟩ω − ⟨ g⟩2ω .


Ejercicio 9.12: Calculando integrales con el muestreo por importancia.
Dada la integral
Z 1 −1/2
x
dx,I=
ex + 1 0
calcular su valor estimado usando el muestreo por importancia.

• Tal y como hemos visto, la función a integrar f ( x ) = x −1/2 /(exp( x ) + 1) tiene una diver-
gencia en x=0, consecuencia del término x −1/2 .

• Para cancelar su efecto en la suma ponderada, escogemos por tanto ω ( x ) = x −1/2 , de forma
que

f (x) 1
= x .
ω(x) e +1

• Por tanto, para evaluar nuestra integral tenemos que generar números aleatorios distribui-
dos con la densidad de probabilidad

ω(x) x −1/2 1
p( x ) = R 1 = R1 = √ ,
ω ( x ) x −1/2 dx 2 x
0 0

que podemos obtener a partir de números uniformemente distribuidos usando el método


de la transformación,

1
Z x √
( x ′ )−1/2 dx ′ = x = z, x = z2 .
2 0

• Por tanto, nuestra integral será

N Z b N
1 f ( xi ) 2 1
I≃
N ∑ ω ( xi ) a
ω ( x ) dx =
N ∑ exp (z2 ) + 1 ,
i =1 i i

donde tal y como hemos visto los puntos zi son números aleatorios generados en el intervalo
[0, 1].

[5]: from numpy import exp


from random import random

N=1000000
s=0.0

37

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
for i in range(N):
s+=1/(exp(random()**2) + 1)

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
print("La estimación de la integral es:",2*s/N)

La estimación de la integral es: 0.8388943123378856

El muestreo por importancia e integrales sobre rangos infinitos.

• El muestreo por importancia también puede usarse para evaluar integrales definidas en do-
minios infinitos.

• Este caso no se puede resolver con el método del valor medio, pues tendríamos que obtener
números aleatorios distribuidos uniformemente en el intervalo [0, ∞], lo cual no es posible,
porque es una distribución obviamente no integrable.

• Sin embargo, es algo que podemos hacer usando el muestreo por importancia, pues nos
permite calcular la integral a partir de distribuciones no uniformes, que aún extendiendose
a infinito sean intergrables.

• Es por ejemplo el caso de la distribución exponencial. Escogiendo ω ( x ) = e− x tenemos

N Z ∞ N
1 1
I≃ ∑ e xi f ( x i ) e− x dx = ∑ e x f ( x i ).
i
N i =1 0 N i =1

• Es decir podemos usar una muestra de puntos generada con una distribución no uniforme,
sólo si lo compensamos pesando más en la suma aquellos puntos que se encuentran en la
region donde generamos menos.

1.3 9.3 Simulaciones de Monte Carlo: cadenas de Markov y el algoritmo de Metropo-


lis.
• Llamamos simulaciones de Monte Carlo a aquellos programas de ordenador que utilizan
números aleatorios para simular el comportamiento aleatorio de variables físicas.

• Ejemplo de tales simulaciones son la desintegración radiactiva o el scattering de Rutherford.

• Aunque las simulaciones de Monte Carlo se usan en muchas ramas de la física, juegan un
papel central en la mecánica estadística, ya que la aleatoriedad es la parte esencial de este
campo.

• Por ello, en este sección nos vamos a centrar en estudiar las simulaciones de Monte Carlo en
física estadística.

38

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
1.3.1 9.3.1 El muestreo por importancia y la mecánica estadística.
• Uno de los problemas esenciales en física estadística es el de calcular el valor esperado o
medio de una cantidad de interés en un sistema físco en equilibrio térmico a temperatura T.

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Aunque no sabemos el estado exacto del sistema, sí sabemos que, a una temperatura T dada,
el sistema pasa por una sucesión de estados tal que la probabilidad de que en un momento
dado el sistema se encuentre en el estado Ei viene dada por

P( Ei , β) = e− β Ei Z ( β), Z ( β) = ∑ e−βE ,
i

siendo β = 1/k B T con k B la constante de Boltzmann y Z ( β) la función de partición canónica.

• Dada la probabilidad, el valor esperado de la cantidad X que toma el valor Xi en el estado


Ei viene dada por

⟨ X ⟩ = ∑ Xi P( Ei ).
i

• Aunque en algunos casos podremos realizar la suma de forma analítica, la mayoria de las
veces sólo se podrá hacer de forma numérica.

• Sin embargo, en muchas ocasiones no podemos simplemente evaluar la suma porque el


número de estados que intervienen es demasidado grande.

• Por ejemplo, hay 1023 moléculas en un mol de un gas, por lo que, si incluso asumimos que
cada molécula sólo tiene dos estados posibles (de hecho tienen decenas de ellos), el número
23
total de estados sería 210 que no se puede evaluar con ningun ordenador.

• La idea por tanto es enfocar el problema de la misma forma que hemos planteado la inte-
gración por Monte Carlo.

• El método del valor medio nos permite evaluar una integral sólo con sumar un conjunto de
puntos escogidos aleatoriamente en el dominio de integración.

• La idea ahora es hacer lo mismo con la suma, escoger un número aleatorio de términos y
sumarlos para obtener el resultado final. Por ejemplo dados N estados escogidos aleatoria-
mente y denotados con k = 1, · · · , N tendremos

∑kN=1 Xk P( Ek )
⟨X⟩ = ,
∑kN=1 P( Ek )
donde el denominador es esencial para normalizar la media ponderada, pues no estamos
cogiendo todos los estados que garantizan que

∑ P(Ei ) = 1.
i

• Desafortunadamente la ecuación de arriba no funciona en nuestro caso. La probabilidad de


Boltzmann esta exponencialmente suprimida para aquellos estados cuya energía Ei ≫ k B T,
lo cual ocurre para la mayoría de estados.

39

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• Esto implica que la mayoría de los estados que escogeremos contribuiran muy poco a la
suma que queremos obtener, o lo que es lo mismo, hay muy pocos estados que contribuyen
de forma significativa a la suma.

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• La forma de resolver este problema es clara: usar una distribución de números aleatorios no
uniforme; es decir, el muestreo por importancia.

• Hasta ahora hemos definido el muestreo por importancia como una forma de evitar pa-
tologías en funciones.
La consecuencia de ello es que uno debe escoger una muestra de números aleatorios con una
distribución no uniforme.

• En nuestro caso el objetivo es de hecho escoger una muestra no uniforme, de forma que po-
damos seleccionar correctamente los términos que debemos incluir en la suma para evaluar
el promedio de nuestro observable.

• Una vez más, dada cualquier función gi que depende del estado i, definimos la media pon-
derada como

∑ i ω i gi
⟨ g⟩ω = ,
∑ i ωi
siendo ωi cualquier conjunto de pesos que nosotros elijamos.

• Escogiendo gi = Xi P( Ei )/wi , es decir, escogiendo cada elemento de nuestra suma pero


dividido por el peso ωi , tenemos

Xi P( Ei ) ∑i ωi Xi P( Ei )/ωi ∑ X P( Ei ) ⟨X⟩
 
= = i i = ,
ωi ω ∑ i ωi ∑ i ωi ∑ i ωi

o lo que es lo mismo, el promedio de X vendrá dado por

Xi P( Ei )
 
⟨X⟩ =
ωi ∑ ωi .
ω i

• Una vez más, podemos evaluar la media ponderada escogiendo N estados aleatorios con
probabilidad

ωi
pi = ,
∑j ωj

de forma que nuestra estimación para la media ponderada sea

N
1
⟨ g⟩ω ≃
N ∑ gk ,
k =1

siendo gk el valor de g para el estado Ek .

40

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• Aplicando este resultado para el valor esperado de X, obtenemos

N
1 Xi P( Ei )
⟨X⟩ ≃
N ∑ ωi ∑ ωi ,
k =1 i

donde es fundamental darse cuenta que mientras que la primera suma sólo se realiza sobre
los N estados de nuestra muestra aleatoria, la segunda suma es sobre todos los estados
posibles. Por tanto, si es posible, es mejor calcular esta segunda suma analiticamente.

• La cuestión ahora es elegir los pesos ωi .

• Debemos elegirlos de forma que la mayoría de los estados escogidos aleatoriamente caigan
en la zona donde P( Ei ) es grande, y a la vez, de forma que la suma ∑i ωi se puede hacer de
forma analítica.

• Ambos requisitos los podemos satisfacer trivialmente si hacemos ωi = P( Ei ).

• En ese caso tendremos que que ∑i ωi = ∑i P( Ei ) = 1 por lo que

N
1
⟨X⟩ ≃
N ∑ Xi .
k =1

• Es decir, si escogemos los N estados aleatoriamente según las distribución de Bolzmann, en-
tonces sólo tenemos que tomar la media de X sobre todos ellos y obtener nuestro promedio.

• En otras palabras dejamos que el sistema vaya pasando por los N estados con probabilidad
P( Ei ), de forma que el valor medio de X no sea más que el promedio de los valores que ha
tomado en cada uno de ellos.

1.3.2 9.3.2 Cadenas de Markov.


• Hay un pequeño problema con respecto al algorimto anterior.

• Para obtener la muestra aleatoria de estados necesitamos calcular P( Ei ) que venia dada por

P( Ei , β) = e− β Ei Z ( β), Z ( β) = ∑ e−βE ,
i

y para ello tenemos que calcular la función de partición Z, que es una suma sobre todos los
estados del sistema.
Es el problema que de hecho queríamos evitar en primer lugar.

• Por suerte hay una forma de calcular la probabilidad de Boltzmann sin conocer la función
de partición. Es gracias a las llamadas cadenas de Markov.

• La idea esencial es que podemos generar estados uno detrás de otro, obteniendo por tanto
una sucesión que se denomina cadena de Markov.

• Para describir el proceso, asumamos que partimos de un estado inicial i, y que, en vez de ele-
gir de forma totalmente aleatoria el siguiente estado, lo obtenemos perturbando ligeramente
el estado i.

41

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Por ejemplo, en un gas, sería equivalente a cambiar una sólo de sus moléculas a un nuevo
nivel de energía.

• Para determinar cuan probable es ese nuevo estado, definimos un conjunto de transiciones

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
de probabilidad Tij , que definen la probabilidad de pasar del estado i al estado j.

• Si somos capaz de determinar de forma correcta este conjunto de probabilidades de tran-


sición, es decir, si conseguimos que la probabilidad de llegar en cualquier paso de nuestro
cadena al estado k sea la probabilidad de Boltzmann P( Ek ), entonces, al movernos sobre la
cadena de Markov, estaremos obteniendo exactamente la muestra de estados generados a
partir de la distribución de Boltzmann que estabamos buscando.

• El problema reside por tanto en elegir correctamente los valores de Tij .

• Puesto que dado un estado i siempre tenemos que acabar en cualquier otro estado, se cumple
que

∑ Tij = 1.
j

• Junto a este requisito, el punto clave para obtener Tij es imponer que

Tij P( Ej ) e− βEj /Z
= = − βE /Z = e− β(Ej −Ei ) ,
Tji P( Ei ) e i

es decir, que el cociente entre la probabilidad de ir de i → j y de j → i, sea exactamente el


cociente de las probabilidades de Boltzmann que determinan cuan probable es que el sistema
se encuentre en el estado j e i.

• Es importante darse cuenta que el valor de la función de partición se cancela en el cociente,


por lo que no la necesitamos para determinar el cociente.

• Supongamos ahora que conocemos las probabilidades de transición Tij que satisface las dos
condiciones anteriores, y asumamos ahora que, en un paso dado de la cadena de Markov, la
probabilidad de encontrarse en un estado i viene dada por la probabilidad de Boltzmann.

• Con todo ello, teniendo en cuenta las condiciones que ha de satisfacer Tij , la probabilidad de
acabar en el estado j sera

∑ Tij P(Ei ) = ∑ Tji P(Ej ) = P(Ej ) ∑ Tji = P(Ej ).


i i i

• Esto implica que si en un momento dado la probabilidad de estar en cualquier estado es la


probabilidad de Boltzmann, también tendremos la probabilidad de Boltmann en el siguiente
paso, o lo que es lo mismo, la distribución de Boltzmann es un punto fijo de la cadena de
Markov.

• Quedan sólo dos hipótesis por satisfacer:

1. Qué podemos llegar a un paso de la cadena de Markov donde la distribución de prob-


abilidad de acabar en cualquier estado es la de Boltzmann.

42

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
2. Que podemos encontrar un conjunto de probabilidades de transición que satisfacen las
condiciones impuestas.

• Vamos a explicar cómo podemos garantizar cada uno de estos dos puntos.

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Convergencia de una cadena de Markov hacía la distribución de Boltzmann.

• Supongamos que partimos de un estado inicial de nuestro sistema i, y de forma iterativa nos
movemos a cualquier otro estado con probabilidad Tij ,
donde, tal y como hemos especificado, la probabilidad de transición satisface

Tij P( Ej )
∑ Tij = 1, y
Tji
=
P( Ei )
,
j

donde P( Ei ) es la probabilidad de Boltzmann de encontrarse en el estado Ei .

• Definamos ahora como pi (t) la probabilidad de de que la cadena de Markov se encuentre en


el estado i en el paso t. La probabilidad de transitar al esado j en el siguiente paso t + 1 será

p j ( t + 1) = ∑ Tij pi (t),
i

que en notación matricial implica que

p(t + 1) = Tp(t)

donde p es el vector con elementos pi y T la matriz cuyo elemento ij es Tji .

• Como Tij es constante, el vector de probabilidad es multiplicado en cada paso por ella, por
lo que tras t pasos tenemos que

p ( t ) = T t p (0).

• Desconpongamos ahora el vector p(0) como una combinación lineal de los autovalores por
la derecha vk de Tt

p (0) = ∑ ck vk ,
k

e introduciendo esta descomposición en la probabilidad para el paso t, tenemos


 t
t λk
p(t) = T ∑ ck vk = ∑ ck λtk vk = λ1t ∑ ck vk ,
k k k
λ1

donde λk es el autovalor de vk y λ1 es el autovalor principal, es decir, el de mayor magnitud.

43

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• La cuestión ahora es estudiar que ocurre cuando dejamos evolucionar el tiempo, es decir
cuando t → ∞.
En ese caso,

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
p(t)
lim = c1 v1 ,
t→∞ λ1t

que implica que si dejamos evolucionar nuestro sistema el tiempo suficiente, acabará en el
estado correspondiente al autovalor principal.

• Sólo nos queda por tanto probar que la distribución de Boltzmann es un autovector de la
matriz de transición y que además corresponde al autovalor principal.

• La primera parte es fácil de probar, pues sabemos que

∑ Tji P(Ej ) = ∑ Tij P(Ej ) = P(Ei ) ∑ Tij = P(Ei ),


j j j

por tanto, llamando pi = P( Ei ) tenemos en forma matricial que

Tp = p,

es decir, la distribución de Boltzmann es un autovector de la matriz de transición con auto-


valor 1.

• Sólo nos queda por probar que es el autovector con el autovalor principal.

• Para ello, en primer lugar es conveniente notar que todas las componentes del autovector de
Boltzmann son mayores de cero P( Ei ) > 0.

• Por otro lado, debido a la propiedad

∑ Tij = 1,
j

podemos ver que el vector 1 = (1, 1, 1, · · · ) es un autovector por la izquierda de T con


autovalor 1.

• Eso implica que todos los autovectores por la derecha con autovalor ̸= 1 tienen que ser
ortogonales al vector 1, lo cual sólo es posible si algunas de sus componentes son negativas.

• Por tanto, si partimos de una punto inicial donde las componentes del vector de probabili-
dades p son no negativas, al ser Tij > 0, siempre tenderemos al autovector con el autovalor
principal cuyas componentes deben ser todas positivas.

• Sin embargo, el único autovector cuyas componentes son todas positivas es la distribución
de Boltzmann, que implica por tanto que empezando con cualquier probabilidad, nuestro
sistema siempre convergerá hacía la distribución de Boltzmann.

• Lo único que faltaría por probar es que sólo hay un autestado por la izquierda y derecha
asociado al autovalor 1. Lo cual se consigue si todos los estados del sistema son accesibles
(si el sistema es ergódico).

44

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Obteniendo la matriz de transición: el algoritmo de Metropolis.
• Para finalmente garantizar que podemos calcular el valor medio de nuestro estado X, sólo
nos queda encontrar encontrar el valor de Tij , las cuales deben satisfacer

Tij P( Ej )
∑ Tij = 1, y
Tji
=
P( Ei )
.
j

• Estas dos restriccione dejan muchas posibilidades para definir Tij , pero de forma mayoritaria
se usa el algoritmo de Metropolis.
• Para explicar como funciona, es importante hacer notar en primer lugar, que el sistema
puede pasar varias veces por el mismo estado, y que de hecho, puede hacerlo en dos pa-
sos consecutivos. Es decir, Tii puede ser no nulo.
• Teniendo esto en cuenta, el algorimto funciona de la siguiente forma.
• El punto de partida es un estado inicial cualquiera i, sobre el que aplicaremos una pequeña
modificación aleatoria, generando por tanto el estado j.
• Los posibles cambios posibles son lo que llamamos move set.
• Volviendo al ejemplo del gas, una posibilidad sería elegir aleatoriamente que molécula al-
terar y como variar su esta de energía, aumentandolo o disminuyendolo.
• Por último, aceptaremos o rechazaremos la transición a este estado definiendo la probabili-
dad

si Ej ≤ Ei ,

1
Pa =
e− β(Ej −Ei ) si Ej > Ei .

• Si la transicción se rechaza, entonces el sistema pertenece en el estado i durante un paso más.


Si la transición se rachaza, el sistema pasará al nuevo estado j.
• Dicho de otra forma, si la energía del nuevo estado j es menor que la del estado i la transición
siempre será aceptada. Por otro lado si el nuevo estado tiene más energía sólo permitiremos
la transición con la probabilidad de arriba.
• Veamos ahora que con este algoritmo nuestra probabilidad de transición satisface las condi-
ciones requeridas.
• En primer lugar la condición

∑ Tij = 1,
j

se satisface trivialmente puesto que dado un estado i siempre pasaremos a cualquier otro
estado, que puede ser el mismo estado i.
• Siguiendo este esquema, la probabilidad de pasar de un estado i a un estado j, será en primer
lugar la probabilidad de escoger aleatoriamente el estado j, la cual es 1/M con M el número
total de cambios posibles, multiplicada por la probabilidad de aceptar la transición si Ej >
Ei .

45

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Por ejemplo, si Ej > Ei tendremos

1 1
Tij = × e− β(Ej −Ei) , Tji = × 1,
M M

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
que satisface que

Tij e− β(Ej −Ei) /M


= = e− β(Ej −Ei) .
Tji 1/M

• Mientras que en el caso contrario, es decir, si Ej < Ei

1 1
Tij = × 1, Tji = × e− β(Ei −Ej) ,
M M
y su cociente

Tij 1/M
= − β(E −Ei) = e− β(Ej −Ei) .
Tji e j /M

• Así definidas, las probabilidades de transición satisfacen las condiciones necesarias.

• De esta forma el algoritmo de Metropolis implica los siguientes pasos:

1. Elegimos un estado de partida aleatorio.


2. Elegimos un movimiento aleatorio de forma uniforme entre un conjunto de estados
posibles (tales como cambiar una molécula de estado).
3. Calculamos el valor de la probabilidad de aceptación Pa .
4. Aceptamos el movimiento con probabilidad Pa , de tal manera que el estado cambiará a
otro estado o permanecerá en el estado inicial (en cualquier caso se cuenta en el cálculo
del promedio).
5. Medir/calcular el valor de la cantidad X que nos interesa en el estado actual y incluirla
en la suma de los elementos de la cadena de Markov.
6. Repetir desde el paso 2.

• Una vez hemos dado muchos pasos de Markov, dividimos el valor de la suma por el número
de pasos de la cadena y obtenemos ⟨ X ⟩.

• La forma más eficiente de implementar la probabilidad de aceptación es calcular el cambio


de energía entre los estados i y j, Ej − Ei , generar un número aleatorio z con probabilidad
uniforme entre 0 y 1, y aceptar la transición si z < e− β(Ej −Ei) .
Si Ej ≤ Ei la exponencial es mayor o igual que 1 y la transición siempre será aceptada.

• Es importante tener en cuenta la siguientes sutilizas

– Los pasos en los que rechazamos la transición deben contar como estados, incluso
cuando no hemos hecho ningún cambio.
– Para que la transición este bien definida, es esencial que el número M de transiciones
posibles para ir de i → j sea igual al de j → i.

46

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
– Es esencial asegurar que cualquier estado posible es accesible. Es lo mismo que de-
cir que el estado debe ser ergódico. Es una condición necesaria para asegurar que el
sistema converge a la distribución de Boltzmann.
– Aunque hemos probado que el sistema converge a la distribución de Boltzmann, no

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
hemos calculado cuanto tarda en converger a ella, o lo que es lo mismo a equilibrarse.
Aunque no hay una regla universal para calcular este tiempo, en general es bastante
fácil determinarlo.

Ejercicio 9.13: Simulación de Monte Carlo de un gas ideal.

• Los estados cuánticos de una partícula de masa m en una caja cúbica de longitud L viene
caracterizado por los enteros n x , ny , nz = 1, · · · , ∞, siendo su energía

π 2 h̄2  2 2 2

E(n x , ny , nz ) = n x + n y + n z .
2m2 L2
• Sea un gas ideal formado por N partículas definidas por sus energías cuánticas que no in-
teraccionan. La energía del sistema será por tanto la suma de las energías de cada una de las
partículas

(i ) (i ) (i )
E= ∑ E(n x , n y , n z ),
i

(i )
siendo n x,y,z el número cuántico correspondiente de la partícula i.

• Estimar la energía promedio de un gas ideal con N = 1000 partículas para k B T = 10 usando
las unidades m = h̄ = 1.

• En primer lugar el conjunto de estados posibles seran los que se obtienen de cambiar los
números cuánticos n x , ny o nz de un único átomo en ±1.

• En cada paso de la cadena de Markov escogeremos aleatoriamente una partícula, escogere-


mos aleatoriamente un número cuantico n x , ny o nz y aleatoriamente elegiremos un cambio,
+1 o 1 para el número cuántico.

• El cambio de la energía será, si pasamos de n x a n x + 1 será

π 2 h̄2
∆E = (2n x + 1),
2m2 L2
y si pasamos de n x a n x − 1

π 2 h̄2
∆E = (−2n x + 1),
2m2 L2
y analogamente para los otros números cuánticos.
(i ) (i ) (i )
• Partamos del estado inicial de menor energía, es decir n x = n x = n x = 1, ∀ i ∈ [0, N ] y
realicemos 250 000 pasos de Monte Carlo.

47

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
[25]: from random import random,randrange
from numpy import exp,pi
from numpy import ones
from matplotlib.pyplot import plot,xlabel,ylabel,show

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
# Constantes

T=10.0 # tempeatura
N=1000 # número de partículas
pasos=250000 # número de pasos

# Creamos un array 2-dimensional para almacenar los números cuánticos


n=ones([N,3],int)

# Bucle principal

eplot = []
E=3*N*pi*pi/2 # Energía total del estado inicial del gas

for k in range(pasos):

# Escogemos la partícula y el movimiento (número cuántico y +1 o -1)

i=randrange(N) # escogemos la partícula


j=randrange(3) # escogemos el número cuántico

# escogemos si aumentamos o disminuimos el nivel de eneria

if random()<0.5:
dn = 1 # Incremento del número cuantico
dE = (2*n[i,j]+1)*pi*pi/2 # Incremento de energía

else:

dn = -1 # Decremento del número cuantico


dE = (-2*n[i,j]+1)*pi*pi/2 # Decremento de energía

# Decidimos si se acepta el movimiento

if n[i,j]>1 or dn==1: # Si n es 1 dn sólo puede ser 1, pues 1 es␣


֒→ el menor nivel de energía.

if random()<exp(-dE/T):
n[i,j]+=dn
E+=dE

48

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
eplot.append(E)
[26]: # Hacemos la gráfica

plot(eplot)
ylabel("Energía")
xlabel("pasos")
show()

• El sistema parece alcanzar el equilibrio/estabilizarse tras 50000 pasos para al canzar un valor
de la energía total E = 25000.

• Podríamos cambiar la temperatura y calcular la energía total para diferentes valores de T.

Ejercicio 9.14: El modelo de Ising.


El modelo de Ising proporciona una descripción teórica del ferromagnetismo. La magneti-
zación de un material magnético es consecuencia de la combinación de muchos dipolos magnéti-
cos a lo largo de todo el material.
Si cada uno de estos dipolos apuntan en direcciones aleatorias, entonces la magnetización total
del sistema será practicamente nula. Sin embargo si la mayoria de ellos apuntan en una única
dirección, entonces el sistema adquiere una magnetización macroscópica.
El modelo de Ising describe este fenómeno en el caso de que cada uno de los dipolos del
material son consecuencia del spin de cada uno de sus átomos, los cuales se ordenan en un retículo
y apuntan sólo en dos direcciones, hacía arriba o hacía abajo. Por ejemplo en un retículo de dos
dimensiones

49

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
[27]: from IPython.display import Image,display
display(Image("spins.png",width=400))

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Matemáticamente los espines pueden representarse con la variable si = ±1 para cada punto
del retículo, donde +1 representa que el espín apunta hacía arriba y -1 cuando apunta hacía abajo.
El otro aspecto fundamental es que los dipolos interaccionan entre ellos de forma que puede
ser energéticamente favorable que se alineen en la misma dirección. La energía potencial mag-
nética debida a la interacción de dos dipolos i y j en el modelo de Ising viene dada por el producto
si s j , siendo la energía de la interacción − Jsi s j , siendo J una constante positiva.
El signo negativo asegura que la energía del sistema disminuye cuando los dipolos están
alineados, y es lo que define a los materiales ferromagnéticos. Los materiales ferromagnéticos
adquieren por tanto una magnetización si tienen la oportunidad para ello. Aquellos materiales
donde el signo de la interacción es positivo se llaman antiferromagnéticos, porque son sistemas
que tenderán a tener una magnetización total nula.

50

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
En el modelo de Ising se asume que los espines sólo interaccionan con sus vecinos más próxi-
mos, es decir con aquellos que se encuentran en elementos adyacentes del retículo. De esta forma,
la energía total del sistema es

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
E = − J ∑ si s j ,
⟨ij⟩

donde ⟨ij⟩ denota a suma sobre pares i, j que son adyacentes en el retículo. En un retículo
bidimensional, eso sígnifica que cada espín sólo interacciona con sus vecinos arriba, abajo, a la
izquierda y derecha, excepto que se encuentre en una de las paredes.
Escribir un programa para escribir una simulación de Monte Carlo usando una cadena de
Markov para el modelo de Ising en dos dimensiones usando un retículo de 20 × 20 espines. Para
ello:

1. Escribir una función que calcula la energía total del sistema.


2. Usar esa función para para hacer una simulación de Monte Carlo usando el algoritmo de
Metropolis, usando J = k B T = 1. Empezar la simulación asignando la dirección de cada uno
de los espines de forma aleatoria. Escoger entonces un espín aleatorio y cambiar la dirección
de su espín. Aplicar el algoritmo de Metroplis para decidir si ese cambio es aceptado o no.
Repetir el proceso durante un millón de pasos.
3. Representar la magnetización definda como M = ∑i si como función del tiempo durante el
millón de pasos de Monte Carlo. £Qué es lo que ocurre?.
4. Repetir el proceso desde cero varias veces, y comprobar el signo de la magnetización resul-
tante. £Qué es lo que esta pasando? £Por qué?.
5. Repetir el proceso aumentado la temperatura a k B T = 2, y k B T = 3. Analizar que ocurre.

[28]: # 1. Definimos nuestra función energía

from numpy import exp,empty,sum


from random import random,randrange
from matplotlib.pyplot import plot,show,xlabel,ylabel

# definimos las constantes del problema

L=20 # longitud de la caja


N=1000000 # número de pasos
J=1 # constante de interacción
T=1 # temperatura

# función para calcula la energía

def energia(s):
return -J*(sum(s[0:L-1,:]*s[1:L,:])+sum(s[:,0:L-1]*s[:,1:L]))
[29]: # 2. Realizamos la simulación de Monte Carlo usando el algoritmo de Metropolis

# construimos el estado inicial de forma aleatoria

51

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
s=empty([L,L],int)

for i in range(L):

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
for j in range(L):
if random()<0.5:
s[i,j]=+1
else:
s[i,j]=-1

E=energia(s) # energía inicial


M=sum(s) # magnetización inicial

# Loop principal

mp=[] # lista con el valor de manetización paso a paso

for k in range(N):
mp.append(M)

# guardamos la energía inicial


Ep=E
# elegimos aleatoriamente un espín que modificar

i=randrange(L)
j=randrange(L)
s[i,j]=-s[i,j]

E=energia(s)
deltaE=E-Ep

# decidimos si aceptamos o no la transicción.

if deltaE>0.0:
if random()>exp(-deltaE/T):
# la transición no es aceptada. Revertimos el espín.
s[i,j]=-s[i,j]
E=Ep

continue
# si no la trasición es aceptada
M=sum(s)
[30]: # 3. Representamos la magnetización.

plot(mp)
ylabel("Magnetización")

52

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
xlabel("Paso")
show()

• Aunque la magnetización empieza en 0, aumenta hasta 400=20*20, que es su valor máximo


rapidamente.
• El sistema se magnetiza de forma espontánea.

[31]: # 4. Repetimos la simulación.

# construimos el estado inicial de forma aleatoria

s=empty([L,L],int)

for i in range(L):
for j in range(L):
if random()<0.5:
s[i,j]=+1
else:
s[i,j]=-1

E=energia(s) # energía inicial


M=sum(s) # magnetización inicial

# Loop principal

53

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
mp=[] # lista con el valor de manetización paso a paso

for k in range(N):

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
mp.append(M)

# guardamos la energía inicial


Ep=E
# elegimos aleatoriamente un espín que modificar

i=randrange(L)
j=randrange(L)
s[i,j]=-s[i,j]

E=energia(s)
deltaE=E-Ep

# decidimos si aceptamos o no la transicción.

if deltaE>0.0:
if random()>exp(-deltaE/T):
# la transición no es aceptada. Revertimos el espín.
s[i,j]=-s[i,j]
E=Ep

continue
# si no la trasición es aceptada
M=sum(s)

plot(mp)
ylabel("Magnetización")
xlabel("Paso")
show()

54

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
• Esta vez la magnetización es negativa.
• El sistema es simétrico en energía para espines positivos y negativos. Alguna vez se magne-
tizará espontáneamente postivamente y otras negativamente.
• Que el sistema se magnetice de una forma o otra es lo que llamamos ruptura espontánea de
la simetría.
• Es el mismo fenómeno que permite generar masas a las partículas del modelo estándar de
partículas.

[32]: # 5. Aumentamos la Temperatura

T=2.

# construimos el estado inicial de forma aleatoria

s=empty([L,L],int)

for i in range(L):
for j in range(L):
if random()<0.5:
s[i,j]=+1
else:
s[i,j]=-1

E=energia(s) # energía inicial


M=sum(s) # magnetización inicial

55

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
# Loop principal

mp=[] # lista con el valor de manetización paso a paso

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
for k in range(N):
mp.append(M)

# guardamos la energía inicial


Ep=E
# elegimos aleatoriamente un espín que modificar

i=randrange(L)
j=randrange(L)
s[i,j]=-s[i,j]

E=energia(s)
deltaE=E-Ep

# decidimos si aceptamos o no la transicción.

if deltaE>0.0:
if random()>exp(-deltaE/T):
# la transición no es aceptada. Revertimos el espín.
s[i,j]=-s[i,j]
E=Ep

continue
# si no la trasición es aceptada
M=sum(s)

plot(mp)
ylabel("Magnetización")
xlabel("Paso")
show()

56

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
[33]: # 5. Aumentamos la Temperatura aún más

T=3.

# construimos el estado inicial de forma aleatoria

s=empty([L,L],int)

for i in range(L):
for j in range(L):
if random()<0.5:
s[i,j]=+1
else:
s[i,j]=-1

E=energia(s) # energía inicial


M=sum(s) # magnetización inicial

# Loop principal

mp=[] # lista con el valor de manetización paso a paso

for k in range(N):
mp.append(M)

57

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
# guardamos la energía inicial
Ep=E
# elegimos aleatoriamente un espín que modificar

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
i=randrange(L)
j=randrange(L)
s[i,j]=-s[i,j]

E=energia(s)
deltaE=E-Ep

# decidimos si aceptamos o no la transicción.

if deltaE>0.0:
if random()>exp(-deltaE/T):
# la transición no es aceptada. Revertimos el espín.
s[i,j]=-s[i,j]
E=Ep

continue
# si no la trasición es aceptada
M=sum(s)

plot(mp)
ylabel("Magnetización")
xlabel("Paso")
show()

58

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• Al aumentar la temperatura aumenta la probabilidad de que cada átomo cambie la direccio

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
del espín. El sistama va variando el valor de su magnetización paso a paso, generando una
magnetización media nula.

1.4 9.4 Máximos y mínimos: simulated annealing (teplado simulado).


• Uno de los mayores usos de los métodos de Monte Carlo en los últimos años es en la opti-
mización numérica.

• En el tema 6 vimos diferentes métodos que nos permiten encontrar mínimos o máximos de
una función. Sin embargo, estos métodos no nos dicen si ese mínimo es global o local.

• Sin embargo, en muchos casos esto no es suficiente. Por ejemplo si buscamos el estado fun-
damental de un estado físico estamos buscando el mínimo global del sistema. Es el mismo
caso si buscamos diseñar los parámetros de un automóvil para minimizar su consumo.

• Cuando queremos encontrar el mínimo global de una función f (el máximo sería equivalente
a buscar el mínimo de − f ), los métodos del tema 6, al menos por sí solos, no funcionan.

• La optimización global es uno de los problemas computacionales más complicados y en los


que más recuersos se invierte.

• Uno de los métodos más prometedores para este problema es el llamado simulated anneal-
ing (templado simulado), que fue propuesto en 1985 por Scott Kirkpatrick.

• Para explicarlo volvamos a la mecánica estadística e imaginemos un sistema en equilibrio a


la temperatura T.

• La probabilidad de que en algún momento nuestro sistema se encuentre en el estado i viene


dada por la probabilidad de Boltzmann

e− βEi
P( Ei ) =
Z
, con Z= ∑ e−βE ,
i

donde una vez más β = 1/k B T.

• Asumamos ahora que el sistema tiene un sólo estado fundamental y elijamos el sistema de
referencia de forma que Ei = 0 para el estado fundamental y Ei > 0 para el resto.

• Supongamos ahora que enfriamos nuestro sistema al cero absoluto. En el límite T → 0,


tenemos que β → ∞, por lo que exp (− βEi ) → 0 excepto para el estado fundamental donde
siempre se cumplira que exp (− βEi ) = 1.

• Por tanto en este límite Z=1 y la probabilidad de Boltzmann es



1 para Ei = 0,
P( Ei ) =
0 para Ei > 0.

59

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
• En otras palabras, implica que el sistema tiene que estar en el estado fundamental.

• Por consiguiente, si conseguimos enfriar el sistema hasta el cero absoluto sólo tenemos que

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
observar el estado en el que ha terminado.

• Esto sugiere una posible estrategia para encontrar el estado fundamental:

1. Simulamos nuestro sistema a una temperatura T usando el método de las cadenas de


Markov.
2. Reducimos la temperatura paso a paso, mientras vamos dejando evolucionar el sistema.
3. Llegamos a cero y observamos el estado en el que nuestro sistema ha termalizado.

• El aspecto interesante del templado simulado es que el mismo método se puede aplicar a
cualquier otra función, no sólo a un sistema cuyo estado fudamental queremos encontrar.

• De forma general, podemos coger cualquier función matemática f ( x, y, z, · · · ), y tratar las


variables como aquellas que nos permiten definir un “estado” del “sistema”, y la función
como su energía.

• Aplicando el mismo proceso que en física estadística y reduciendo la temperatura a cero,


podemos volver a obtener el “estado fundamental” del sistema, los valores de las variables
que minimizan el valor de la función.

• Para que el método funcione es necesario bajar la temperatura del sistema lentamente. Si
este es el caso, se puede probar que el sistema siempre encontrará el estado fundamental, o
lo que es lo mismo, el mínimo de la función.

• Por regla general, la temperatura inicial del sistema se debe tomar mayor que la variación
tipica en un paso de Monte Carlo, es decir β( Ei − Ej ) ≤ 1, de forma que Pa ≃ 1 para casi
todos los movimientos posibles, y el sistema se vuelva totalmente aleatorio sin importar cual
era su estado inicial.

• Tras ello uno empieza a enfriar el sistema, lo cual se suele hacer eligiendo la función de
enfriamiento

T = T0 e−t/τ ,

siendo T0 la temperatura inicial del sistema y τ una constante, que en general se suele coger
para optimizar el cociente precisión (τ grande) vs rapidez (τ pequeña).

Ejercicio 9.15: El problema del viajante.


Para entender el templado simulado vamos a resolver uno de los problemas de optimización
canónicos, el problema del viajante, que involucra encontrar el camino más corto que recorre toda
una serie de puntos en un mapa.
[34]: from IPython.display import Image,display
display(Image("salesman_problem.png",width=400))

60

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Es un problema importante porque pertenece a la clase de problemas NP, problemas cuyo
tiempo de resolución escala como un polinomio.
El problema se formula de la siguiente manera. Un vendedor tiene que recorrer N ciudades,
pudiendo viajar siempre en la linea recta que uno cualquier par de ciudades. Dada la localización
de las ciudades, el problema reside en encontrar el camino más corto (en términos de la distancia
recorrida), que le permite recorrer todas las ciudades empezando y acabando en la misma ciudad.
Para simplicar el problema asumamos que el vendedor se mueve en un espacio bidimensional,
y escojamos la posición de N = 25 ciudades de forma aleatoria en un espacio de longitud 1 por
cada lado. Numeremos las ciudades en el orden en las que el viajero las va a visitar, y denotemos
la posición de la ciudad i con el vector ri = ( xi , yi ), siendo r0 = r N , pues el viaje tiene que acabar
en el punto de partida.
De esta forma, la distancia recorrida por el viajante es
N −1
D= ∑ | r i +1 − r i | .
i =0

61

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Queremos minimizar esta cantidad sobre todo el posible orden de las ciudades usando el tem-
plado simulado. Para hacerlo, tenemos que definir en primer lugar los movimientos posibles
dentro de la cadena de Markov, que definimos como el intercambio del orden de dos ciudades.
Si el cambio disminuye la distancia total, entonces siempre lo aceptamos. Si no, lo aceptamos

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
con la probabilidad del algoritmo de Metropolis. En cada paso hay que actualizar la temperatura
siguiendo la función de enfriamineto exponencial.
Vamos a generar una animación que describa el proceso de la animación.
[1]: from numpy import sqrt,exp,empty
from random import random,randrange

# constantes del problema

N=25 # número de las particulas

Tmax=10 # temperatura inicial


Tmin=1e-3 # temperatura final
tau=1e4 # escala de enfriamiento

# función para calcular el módulo de un vector

def mag(x):
return sqrt(x[0]**2+x[1]**2)

# función para calcular la distancia total del viaje

def distancia():
s=0
for i in range(N):
s+=mag(r[i+1]-r[i])
return s

# escogemos la posicion de las N ciudades de forma aleatoria

r=empty([N+1,2],float)

for i in range(N):
r[i,0]=random()
r[i,1]=random()

r[N]=r[0]

# distancia inicial

D=distancia()
[2]: # preparamos la animación

62

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
from vpython import curve,rate,canvas,vector,sphere
scene = canvas(width=500, height=500,
center=vector(0.5,0.5,0))

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
<IPython.core.display.HTML object>

<IPython.core.display.Javascript object>

<IPython.core.display.HTML object>

<IPython.core.display.Javascript object>

[3]: R=0.02 # describimos cada ciudad por medio de una efera de radio R

listp=[]

for i in range(N):
sphere(pos=vector(r[i,0],r[i,1],0),radius=R)
listp.append(vector(r[i,0],r[i,1],0))

listp.append(vector(r[N,0],r[N,1],0))
l=curve(pos=listp,radius=R/4)

<IPython.core.display.Javascript object>

<IPython.core.display.Javascript object>

<IPython.core.display.Javascript object>

<IPython.core.display.Javascript object>

<IPython.core.display.Javascript object>

<IPython.core.display.Javascript object>

[4]: # loop principal

t=0 # tiempo de enfriamiento

63

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
T=Tmax # temperatura inicial

while T>Tmin:
t+=1

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
T=Tmax*exp(-t/tau) # enfriamos

if t%100==0: # cada 100 pasos actualizamos la animación y cambios␣


֒→ el orden de las ciudades
listp=[]
for i in range(N+1):
l.modify(i,pos=vector(r[i,0],r[i,1],0))
rate(25)

# escogemos dos ciudades para intercambiar. Nos aseguramos que son␣


֒→ diferentes.

i,j=randrange(1,N),randrange(1,N)
while i==j:
i,j=randrange(1,N),randrange(1,N)

# intercambiamos las ciudades

Dp=D # distancia antes de cambiar


r[i,0],r[j,0]=r[j,0],r[i,0]
r[i,1],r[j,1]=r[j,1],r[i,1]

D=distancia()
deltaD=D-Dp

# si el movimiento es recahzado las cambiamos otra vez

if random()>exp(-deltaD/T):
r[i,0],r[j,0]=r[j,0],r[i,0]
r[i,1],r[j,1]=r[j,1],r[i,1]
D=Dp
Ejercicio 9.16: Mínimo global de una función.
Considerar la función f ( x ) = x2 − cos 4πx, cuya representación es
[35]: from numpy import linspace,cos,pi
from matplotlib.pyplot import plot,show

x=linspace(-2,2,1000)
show(plot(x,x**2-cos(4*pi*x)))

64

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
El mínimo global es obviamente x=0.

1. Escribir un programa que usando el templado simulado lo confirme. Para ello, empezar en
x=2, y realizar pasos de Monte Carlo x → x + δ siendo δ un número aleatorio con generado
de una distribución gaussiana de media cero y desviación típica 1. Usar la función de enfri-
amineto exponencial y escoger tanto el valor de la temperatura inicial como del parámetro
τ que te permiten llegar al mínimo en un tiempo razonable.
2. Adaptar el código para encontrar el mínimo de la función

√ √
f ( x ) = cos x + cos 2x + cos 3x, con 0 < x < 50.
[36]: from numpy import cos,sin,sqrt,exp,log,pi
from random import random
from matplotlib.pyplot import plot,show

# definimos la función

def f(x):
return x*x-cos(4*pi*x)

# generamos dos números gaussianos

def gaussian():
r=sqrt(-2*log(1-random()))
theta=2*pi*random()
x=r*cos(theta)

65

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
y=r*sin(theta)

return x,y

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
Tmax=10
Tmin=1e-3
tau=1e4

T=Tmax
x=2
t=0

xpoints=[]

while T>Tmin:
xpoints.append(x)

dx,dy=gaussian()
xp=x+dx
df=f(xp)-f(x)

if df<=0:
x=xp
elif random()<exp(-df/T):
x=xp

t+=1
T=Tmax*exp(-t/tau)
[37]: plot(xpoints,"-")
show()

66

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
[38]: # Representamos la segunda función

def f(x):
return cos(x)+cos(sqrt(2)*x)+cos(sqrt(3)*x)

x=linspace(0,50,1000)
show(plot(x,f(x)))

67

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
El mínimo esta entorno a x=16.
[42]: # Volvemos a inicializar nuetros valores

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
T=Tmax
t=0
x=2

xpoints=[]

while T>Tmin:
xpoints.append(x)

dx,dy=gaussian()
xp=x+dx

if xp>=0.0 and xp<=50.0:


df=f(xp)-f(x)

if df<=0:
x=xp
elif random()<exp(-df/T):
x=xp

t+=1
T=Tmax*exp(-t/tau)
[43]: show(plot(xpoints,"-"))

68

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
Ejercicio 9.17: El problema de la cobertura mediante dímeros.
Los dímeros son polímeros formados por sólo dos monómeros. En su versión más sencilla
el problema de la cobertura de dímeros consiste en calcular cuantós dímeros, que ocupan dos
unidades espaciales, puden caber en una retícula bidimenisonal de tamaño L × L.
Es algo que se puede entender perfectamente mirando la siguiente figura:
[41]: from IPython.display import Image,display
display(Image("dimer.png",width=400))

En este caso la solución es trivial, el número máximo es obviamente L × L/2, pero en este
problema vamos a confirmar que este es el caso.

69

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
1. Escribir un programa que use el templado simulado en una retícula de 50 × 50 unidades. La
energía del sistema es en este caso menos el número de dimeros que caben en la retícula, que
se minimiza cuando el número de dímeros son máximos. Los movimientos de la cadena de
Markov son los siguientes:

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
i)- Elegir dos lugares adyacentes de la retícula de forma aleatoria.
ii)- Si ambos lugares están vacios, colocar un dímero.
iii)-Si ambos lugares están ocupados, eliminar el dímero que se encuentra en ellos con la
probabilidad inferida del algoritmo de Metropolis.
iv)- De otro forma, no hacer nada.
Representar el resultado mediante una animación.
2. Probar diferentes valores del pármetro τ para la función de enfriamiento exponencial. Como valor
inicial una opción razonable es τ = 10000 pasos.
Comprobar que cuando se disminuye τlassolucionesempiezanaserpeores.
[5]: from numpy import zeros,empty,exp
from random import random,randrange

# constantes del problema

L=50 # tamaño del retículo


Tmax=10 # temperatura inicial
Tmin=1e-3 # temperatura final
tau=1e5 # parámetro de enfriamiento

s=zeros([L,L],float) # array con nuestro retículo


d=0 # número de dímeros que hemos colocado (sin contar los␣
֒→que hemos eliminado)

n=0 # número de dímeros que se encuentran en el retículo


[6]: # preparamos la animación

from vpython import rate,canvas,vector,sphere,cylinder


scene = canvas(width=500, height=500,
center=vector((L-1)/2,(L-1)/2,0))

<IPython.core.display.HTML object>

<IPython.core.display.Javascript object>

[7]: dimer=dict() # dict es un diccionario


# nos permite almacenar información sobre las␣
֒→ variables a usar
# vamos a usarlo para almacenar cuando queremos
# que haya un cilindro uniendo nuestro dímeros

70

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
site=empty([L,L],sphere) # creamos un array de esferas, donde vamos a colocar␣
֒→nuestros dímeros

R=0.2 # radio de nuestras esferas

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.
for i in range(L):
for j in range(L):
site[i,j]=sphere(pos=vector(i,j,0),radius=2*R) # colocamos una␣
֒→esfera en cada punto del retículo

site[i,j].visible=False # al principio no␣


֒→dejamos que sea visible

[ ]: T=Tmax # temperatura inicial


t=0 # tiempo inicial

while T>Tmin:

# Enfriamos el sistema
t+=1
T=Tmax*exp(-t/tau)
rate(25)

# elegimos aleatoriamente si colocamos el dimero de forma vertical o␣


֒→ horizontal
# elegimos el punto en el que colocarlo

if random()<0.5: # lo colocamos en horizonal


i1=i2=randrange(L)
j1=randrange(L-1)
j2=j1+1
else:
i1=randrange(L-1)
i2=i1+1
j1=j2=randrange(L)

# realizamos el movimiento

if s[i1,j1]==s[i2,j2]: # si los dos puntos adyacentes están ambos␣


֒→ vacios o ambos con dímeros
if s[i1,j1]==0: # si encima estan vacíos.

# colocamos el dimero

d+=1 # aumentamos el número de dimeros en el␣


֒→ retículo
s[i1,j1]=s[i2,j2] # ocupamos el punto del retículo con el␣
֒→dímero que lo ocupa

71

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.
n+=1

# unimos los dos puntos que representan el dímero

Reservados todos los derechos. No se permite la explotación económica ni la transformación de esta obra. Queda permitida la impresión en su totalidad.

֒→ dimer[d]=cylinder(pos=vector(i1,j1,0),axis=vector(i2-i1,j2-j1,0),radius=R)

site[i1,j1].visible=True # dejamos ver la esfera en la posición␣


֒→del dímero

site[i2,j2].visible=True

# si la posición esta ocupada por un dímero

elif random()<exp(-1/tau): # probabilidad de metropolis, la energía␣


֒→aumenta en 1 si quitamos un dímero
ind=s[i1,j1]
s[i1,j2]=s[i2,j2]=0 # eliminamos el dímero que estaba
n-=1 # reducimos nuestro contador de dímeros␣
֒→en el retículo

dimer[ind].visible=False # eliminamos el cilindro que une los␣


֒→puntos del dímero

del dimer[ind]
site[i1,j1].visible=False
site[i2,j2].visible=False
Final del Tema 9.
Final de la asignatura de Física Computacional.

72

a64b0469ff35958ef4ab887a898bd50bdfbbe91a-5131391

Te has descargado este apunte gracias a la publicidad. También puedes eliminarla con 1 coin.

También podría gustarte