Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Análisis Aplicado II
Simulación Monte Carlo
Objetivos
1. Revisión de conceptos de probabilidad.
Introducción
Algunos procesos en fı́sica son aleatorios, como el decaimiento radiactivo. Se cree que es funda-
mentalmente imposible predecir cuando un átomo radiactivo va decaer. La mecánica cuántica
nos da la probabilidad de decaimiento por unidad de tiempo, pero el momento exacto del de-
caimiento es aleatorio y no puede calcularse.
1
program aleatorio1
do i=1,5
x=rand()
print*,i,x
end do
subroutine percolacion(enrejado,L,p)
implicit none
integer::L,enrejado(1:L,1:L)
real::p
do j=1,L
do i=1,L
R=rand()
if (R.lt. p) enrejado(i,j)=1
enddo
enddo
return
end subroutine percolacion
Variables aleatorias
En muchas ocasiones, no podemos predecir el resultado de un experimento con absoluta cer-
teza, aquı́ podemos entender la palabra experimento en un sentido amplio, podemos contar el
número de electrones emitidos por una sustancia que emite radiación beta en un intervalo de
tiempo dado, medir el espin de un electron, el tiempo que le toma a un autobus viajar de San
Pedro Sula a Tegucigalpa.
Podemos denotar por E el set de posibles resultados del experimento. Para la sustancia que emi-
te radiación β, E = {0, 1, 2, ..., }, las posibles medidas en el espin del electrón E = {−~/2, ~/2}.
2
En los casos anteriores, no hay una forma a priori de conocer los posibles resultados, aqui aban-
donamos el punto de vista determinı́stico y adoptamos una descripción probabilistica
La asignación de un número al resultado de un experimento es llamado una variable aleatoria.
El siguiente paso es asignar probabilidades a los posibles resultados del experimento, o lo que
es equivalente los diferentes valores de la variable aleatoria.
La asignación de probabilidades a eventos debe seguir algunas leyes fisicas (como en el caso de
la sustancia radiactiva, la ley de Boltzmann de distribución de energı́as, o los postulados de la
mecánica cuántica)
Para una variable discreta que toma valores x ∈ {x1 , x2 , x3 , ..., }, asignamos a cada valor xi su
probabilidad pi = P (x = xi ), tal que sigue las siguientes dos condiciones, llamadas no negati-
vidad y normalización, son satisfechas:
pi ≥ 0, ∀i (1)
X
pi = 1 (2)
i
Para una variable continua, se asignan probabilidades a la variable aleatoria en intervalo finito
[a, b] como.
Z x
P (x) = f (x)dx (3)
−∞
f (x) ≥ 0 (4)
Z ∞
f (x)dx = 1 (5)
−∞
Como una variable aleatoria x asigna a cada número real x(ξ) al resultado de un experimento
ξ, es posible usar una función real G(x) para definir una nueva variable aleatoria Ĝ como
Ĝ(ξ) = G(x(ξ)). Podemos definir el promedio o valor esperado como
Z ∞
E[Ĝ] = f (x)G(x)dx (6)
−∞
3
Ejemplo: Distribución de puntos aleatorios distribuidos uniformemente dentro de una elipse.
Considere el problema de generación de números aleatorios dentro la elipse:
x2 y 2
+ =1
16 4
Una forma de lograrlo es generar números aleatorios en el rectángulo −4 ≤ x ≤ 4, −2 ≤ y ≤ 2
y descartar los que no se encuentran en la elipse.
El siguiente programa en Fortran 90 logra lo anterior.
program elipse
implicit none
integer::npt,i,j,n
real::u,v,x,y
print*,’Cuantos puntos, desea generar,npt: ’
read*,npt
print*,’Cuantos puntos quiere dentro de la elipse,n:’
read*,n
open(unit=6,file=’elipse.dat’)
do i=1,npt
u=8*rand()-4
v=4*rand()-2
if ((u**2+4*v**2)<=16.0) then
x=u
y=v
write(6,*)x,y
j=j+1
if (n==j) stop
endif
enddo
close(6)
end program elipse
El programa genera un archivo de datos que se llama elipse.dat, los datos contenidos en el
archivo son graficados con el programa GNUPLOT, la siguiente gráfica muestra el resultado.
4
iniciamos con una muestra de 1000 átomos de Talio. Simulemos el decaimiento de estos átomos
con el paso del tiempo, imitando la aleatoridad del proceso usando números aleatorios .
program decaimiento
implicit none
real::tau,p,h,t,tmax,decai
integer::npb,ntl,i
print*,’Ingrese el numero inicial de atomos de Talio’
read*,ntl
tau=3.053*60 !constante de tiempo.
npb=0 !numero inicial de atomos de plomo
h=1.0 !tamanio del paso, en segundos.
tmax=1000.0
p=1-2**(-h/tau)
open(unit=6,file=’decai.dat’)
t=0
do while(t<=tmax)
decai=0
do i=1,ntl
if (rand()<p) decai=decai+1
end do
ntl=ntl-decai
npb=npb+decai
write(6,*)t,ntl,npb
t=t+h
if (ntl<=0) stop
end do
close(6)
end program decaimiento
5
El programa genera un archivo de datos que le llame decai, usando GNUPLOT capturamos
esos datos y obtenemos la siguiente gráfica.
k I
'
N A
kA
I' (10)
N
Ya que hemos medido k y conocemos A y N , podemos evaluar la expresión (1) y obtener de
forma aproximada el valor de la integral.
El método de Monte Carlo es especialmente útil para evaluar funciones que tienen un compor-
tamiento patológico e integrales multidimensionales, consideremos la siguiente integral:
Z 2
2 1
I= sen dx (11)
0 x (2 − x)
Si graficamos la función que se esta integrando, vemos que tiene un comportamiento complejo
en la región de integración.
6
El programa en Fortran 90, que calcula la integral es el siguiente:
program integracion_mc
implicit none
real::x,y,f,r,A,error
integer::i,n,m
A=2.0
! se utiliza la tecnica, acierto-fallo
m=0
print*,’Cuantos puntos desea utilizar,n: ’
read*,n
do i=1,n
x=2*rand()
y=rand()
if (y<=f(x)) m=m+1
end do
r=real(m)/real(n)*2
error=sqrt(r*(A-r)/n)
print*,’===========================================================’
print*,’Integracion monte carlo con tecnica de acierto y fallo’
print*,’===========================================================’
print*,’El valor aproximado de la integral es:’,r
print*,’El error estadistico es:’,error
print*,’===========================================================’
end program integracion_mc
function f(x)
implicit none
real::x,f
f=(sin(1/(x*(2.0-x))))**2
end function
La principal desventaja del método de Monte Carlo es que no da una respuesta muy precisa.
Investiguemos que tan preciso es el método. La probabilidad de que un punto aleatorio acierte
7
en el área bajo la curva es p = I/A y la probabilidad que este fuera es q = 1−p. La probabilidad
que k de nuestros puntos acierten y que los restantes N − k fallen es pk (1 − p)N −k . Pero hay
N
k
formas de escoger los k puntos de N total, ası́ la probabilidad P (k) de obtener k puntos
bajo la curva es
N k
P (k) = p (1 − p)N −k (12)
k
la cual es llamada distribución binomial. La varianza de esta distribución es:
2 I I
σ = N p (1 − p) = N 1− (13)
A A
Tomando la raı́z cuadrada de la varianza obtenemos la desviación estándar, la cual es una forma
de estimar la variación o error de k, y el error de la integral misma.
√ A
p
I (A − I)
σ= σ 2 = √ (14)
N N
En otras palabras el error varı́a con N como N −1/2
Técnica del valor medio
Queremos evaluar la integral
Z b
I= f (x) dx (15)
a
I = (b − a) hf i (17)
Si logramos estimar hf i entonces podemos estimar I. Una forma simple de estimar hf i es
evaluar f (x)
P en N puntos x1 ,x2 ,...,xN escogidos aleatoriamente entre a y b y calculamos
hf i ' N −1 N i=1 f (xi ). Entonces.
N
b−aX
I' f (xi ) (18)
N i=1
Esta es la fórmula fundamental para el método del valor medio.
Que tan preciso es este método? Se puede demostrar que el error en este caso es
√
var f
σ = (b − a) √ (19)
N
El siguiente programa implementa el método del valor medio
program integral_mc1
implicit none
real(8)::integral,a,b,r,s
integer::n
a=0.0
b=2.0
8
n=100000
call promedio(a,b,n,r,s)
print*,’============================================================’
print*,’Integral de f(x) con ’
print*,’Limite inferior, a: ’,a
print*,’Limite superior, b: ’,b
print*,’La integral es igual a:’, r
print*,’El error estadistico es: ’, s
print*,’============================================================’
end program integral_mc1
subroutine promedio(a,b,n,r,s)
implicit none
real(8)::a,b,f,r,s,x
integer::i,n
r=0.0
s=0.0
do i=1,n
x=a+(b-a)*rand()
f=(sin(1./(x*(2.-x))))**2
r=r+f
s=s+f*f
enddo
r=r/float(n)
s=sqrt((s/float(n)-r*r)/float(n))
r=(b-a)*r
s=(b-a)*s
f (x)
g (x) =
w (x)
en la ecuación (13), tenemos
Rb Rb
f (x) a
w (x) f (x) /w (x) dx f (x) dx I
= Rb = R ab = Rb (22)
w (x) w w (x) dx w (x) dx w (x) dx
a a a
9
Z b
f (x)
I= w (x) dx (23)
w (x) w a
Como vamos a calcular el promedio ponderado? Para hacer esto, definimos una función de
densidad de probabilidad
w (x)
p (x) = R b (24)
a
w (x) dx
Tomamos una muestra de N puntos aleatorios xi no uniformes con esta densidad. Esto es la
probabilidad de generar un valor entre x y x + dx estará dada por p (x) dx.
Considerando todo lo anterior, obtenemos el siguiente resultado [2].
N
1 X f (x) b
Z
I' w (x) dx (25)
N i=1 w (x) a
Esta es la fórmula fundamental del muestreo por importancia. Esta es una generalización del
método del valor medio, si escogemos w (x) = 1, obtenemos la ecuación (11).
1
x−1/2
Z
dx
0 ex + 1
x−1/2 1
p (x) = R 1 = √
x−1/2 dx 2 x
0
program integral_mc3
implicit none
real(8)::integral,a,b,r,s
integer::n
a=0.0
b=1.0
n=10000
call promedio(n,r,s)
print*,’============================================================’
print*,’Integral de f(x) con muestreo por importancia ’
print*,’Limite inferior, a: ’,a
print*,’Limite superior, b: ’,b
print*,’La integral es igual a:’, r
print*,’El error estadistico es: ’,s
print*,’============================================================’
end program integral_mc3
subroutine promedio(n,r,s)
implicit none
real(8)::a,b,g,r,s,x,wi,var_g
10
integer::i,n
r=0.0
s=0.0
wi=2.0 ! funcion de peso integrada de 0 a 1
do i=1,n
x=rand()**2
g=1.0/(exp(x)+1.0)
r=r+g
s=s+g*g
enddo
var_g=s/float(n)-(r/float(n))**2
s=sqrt(var_g/float(n))*wi
r=r*wi/float(n) ! integral con MC
end subroutine promedio
program mc_volumen
implicit none
real(8)::volumen,vol_exa,x,y,pi,suma,z,error
integer::i,n
pi=4.0*atan(1.0)
!calculo del volumen de un solido:
!Thomas, seccion 15.4, ejercicio 32
print*,’Cuantos puntos va utilizar’
read*,n
suma=0
do i = 1,n
x=4*rand()-2.0; y=4*rand()-2.0
suma=suma+z(x,y)
end do
volumen=(pi*4*suma)/real(n)
vol_exa=12*pi
print*,’================================================================================
print*,’El volumen aproximado es:’,volumen
error=(abs(volumen-vol_exa)/vol_exa)*100.0
print*,’El volumen exacto es:’,vol_exa
print*,’El error porcentual en el calculo del volumen es:’,error
print*,’================================================================================
end program mc_volumen
function z(x,y)
implicit none
real(8)::x,y,z
z=3.0-x
end function
program hiper_volumen
11
! calculo del volumen de una esfera
! en cuatro dimensiones
! Calculo de Steward
print*,’Cuantos puntos desea utilizar:’
read*,n
m=0
PI = 4.0*ATAN(1.0)
print*,’Ingrese el radio de la hiperesfera:’
read*,r
do i=1,n
x=2*r*rand()-r
y=2*r*rand()-r
z=2*r*rand()-r
w=2*r*rand()-r
if (x*x+y*y+z*z+w*w<=r*r) m=m+1
end do
volumen=(real(m)/real(n))*(2*r)**4
vol_exacto=((PI**2)*r**4)/2.0
print*,’El volumen exacto es:’,vol_exacto
print*,’El volumen aproximado de la esfera es:’,volumen
end program hiper_volumen
Muestreo Metropolis
El ensamble canónico es una construcción teórica que nos permite desarrollar un enfoque es-
tadı́stico conveniente para calcular variables termodinámicas a partir del estudio de átomos.
Imagine un grupo de sistemas con un volumen fijo V y un número de partı́culas, N , que estan
conectados unos con otros. El intercambio de energı́a es permitido de un sistema a otro sistema.
Sin embargo, ya que los sistemas son cerrados, no cruza materia en las fronteras. Asumimos
tambien que el volumen de los sistemas es constante. Si permitimos que pase un tiempo sufi-
cientemente grande y asumimos que todos los sistemas estan en contacto térmico, se va alcanzar
una temperatuta finita de equilibrio en el ensamble.
Las cantidades que podemos calcular del ensamble canónico son promedios y de ahi se despren-
de una interpretación simple. Los promedios calculados corresponden a los promedios que uno
mide experimentalmente, si consideramos una muestra suficientemente grande de tales sistemas
en el ensamble. El ensamble canónico es conocido también como ensamble (9N, V, T ). Existen
otros ensambles, por ejemplo el microcanónico o (N, V, E), el ensamble isotermico isobárico
(N, P, T ) y el ensamble gran canónico .
El concepto central para el desarrollo teórico de la mecanica estadı́stica es la función de parti-
ción. La herramienta fundamental para el enfoque numérico en estos casos, es el muestreo por
importancia.
La hipótesis básica de la mecánica estadı́stica de la mecánica estadı́stica es que la probabilidad
de emcontrar un sistema mecanico en un punto en la vecindad del espacio de fases (p, q) con
una energı́a H(p, q), decrece exponencialmente, asi como la energı́a de los estados crece. Para
un ensamble de sistemas contiene una partı́cula moviendose en una dimension, la probabilidad
de encontrarla entre (p, q) y (p + dp, q + dq) se postula como
12
Z ∞ Z
Q= dp dq exp {−βH(p, q)} (27)
−∞ V
Note que si conocemos la función de partición ası́ como β, podemos calcular expresiones analı́ti-
cas para el promedio de la energia
1 ∂Q ∂Ln Q
hHi = − =− (29)
Q ∂β ∂β
Queremos calcular la energı́a para el ensamble
R∞
dx dq H(x, p) exp(−H(x, p)/kB T )
E = −∞R ∞ (30)
−∞
dx dp exp(−H(x, p)/kB T )
El Hamiltoniano es
n
X 1 2
H(x, p) = p + V (x) (31)
i=1
2mi i
la integración sobre los momentos, se puede realizar de forma analı́tica, con lo cual se obtiene
3kB T
E= n + Vp (32)
2
donde el potencial promedio es
R∞ N
−∞
dx V (x) exp(−V (x)/kB T ) 1 X
Vp = R∞ ≈ V (xi ) (33)
−∞
dx exp(−V (x)/kB T ) N i=1
evaluemos con el potencial cuártico
3 4α − 4 3 6α
V (x) = x4 + x − x2 + 1 (34)
2α + 1 2α + 1 2α + 1
La idea de la técnica de rechazo es muy similar a la idea de evaluar el área de un cı́rculo,
suponga que queremos dibujar números distribuidos de acuerdo a.
e−V (x)/kB T
f (x) = R ∞ (35)
−∞
dxe−V (x)/kB T
2. Cambiar x a
1
xn = x + ∆ ξ1 − (36)
2
3. Calcular
13
4. Compare q y ξ2 , si ξ2 < q se acepta xn , caso contrario rechazar xn La implementacion es
la siguiente
program metropolis
implicit none
real(8)::temp,dx,gama,x,sumav,xt
real(8)::q,vt,v,xr2,xr1
integer::nm,nre,m
gama=0.9
temp=1.0
nm=100000
dx=3.5
! unidades en kelvin V/kT=VT
x=1.0
nre=0
sumav=0.0
call pot(gama,x,v)
do m=1,2*nm
xr1=rand()
xr2=rand()
! se realiza un movimiento metropolis
xt=x+dx*(xr1-0.5)
call pot(gama,xt,vt)
q=exp(-vt/temp)/exp(-v/temp)
if (xr2 .lt. q) then
x=xt ! se acepta el movimiento
v=vt
else
nre=nre+1 ! se rechaza el movimiento
end if
! se sigue la pista de los caminantes y se acumula para promediar la energia
if (m .gt. nm) then
sumav=sumav+v
end if
end do
print*,’=========================================================’
print*,’Potencial promedio:’,sumav/float(nm),’Kelvin’
print*,
print*,’Porcentaje de rechazos: ’,100.0*float(nre)/float(2*nm)
print*,’==========================================================’
end program metropolis
! potencial cuartico:
!propuesto por Frantz y colaboradores, J. Chem. Phys 93, 2769 (1990)
subroutine pot(gama,x,v)
implicit none
real(8)::gama,alfa,t1,t2,t3,v,dv,d2v,x
integer::k
alfa=0.0
do k=1,20
alfa=(gama*(2.0*alfa+1)/(alfa+2))**(1./3.)
end do
14
t1=3./(2.0*alfa+1.0)
t2=(4.0*alfa-4.0)/(2.0*alfa+1.0)
t3=-6.0*alfa/(2.0*alfa+1.0)
v=t1*x**4+t2*x**3+t3*x**2
! dv=4.0*t1*x**3+3.0*t2*x**2+2.0*t3*x
!d2v=12.0*t1*x**2+6.0*t2*x+2.0*t3
end subroutine pot
donde
1
β= (39)
kB T
donde kB es la constante de Boltzmann. Las integrales resultantes se pueden realizar de
forma exacta
∞ ∞
Z Z r
1 2 1 2 2π m 2π
dp dx exp −β p + kx = =
−∞ −∞ 2m 2 β k βω
∂hHi k2 T 2
=− B − hV 2 i + hV i2 (43)
∂β 2
kB hV 2 i − hV i2
CV = + (44)
2 kB T 2
El siguiente programa calcula la energı́a promedio y el calor especifico para el oscilador
armónico usando el algoritmo de Metropolis.
program oscilador_clasico
implicit none
integer::mw,m,kt,i,nre
real(8)::temp,prom1,prom2,xi,deltax,xim1,xr2,vxi
real(8)::p,xr1,u,cv,pr,e_exacta,vxim1,cv_exacta
write(6,1010)
15
mw=10000
m=10000
temp=0.02
deltax=1.0
do kt=1,81
nre=0
prom1=0.0
prom2=0.0
xim1=0.0
xi=0.0
! calculamos el potencial en x=0
call pot(xim1,vxim1)
do i=1,mw+m
xr1=rand()
xr2=rand()
! se calcula la nueva posicion
xi=xim1+deltax*(xr1-0.5)
call pot(xi,vxi)
! se calcula el factor de probabilidad
p=exp(-(vxi-vxim1)/temp)
if (xr2 .lt. p) then
xim1=xi
vxim1=vxi
else
nre=nre+1 ! numero de rechazos
xi=xim1
vxi=vxim1
end if
if (i.gt. mw) then
! se calculan los promedios
prom1=prom1+vxi/float(m)
prom2=prom2+vxi*vxi/float(m)
end if
end do
! se calcula la energia total y calor especifico
u=0.5*temp+prom1
cv=0.5+(prom2-prom1*prom1)/(temp*temp)
! se calcula el porcentaje de rechazos
pr=100.0*float(nre)/float(m+mw)
e_exacta=temp
cv_exacta=1.0
write(6,1000)u,e_exacta,cv,cv_exacta,pr
temp=temp+0.04
deltax=deltax+0.3
enddo
1000 format(6f12.4)
1010 format(’ <H>(K) T(K) Cv/kB valor exacto %rechazos’)
end program oscilador_clasico
subroutine pot(x,v)
implicit none
16
real(8)::x,v
v=0.5*x*x
return
end subroutine pot
Consideremos ahora el caso cuántico, la función de partición se suma sobre todos los
niveles cuánticos de energı́a
∞
X
Q= exp(−βEn ) (45)
n=0
∞
X 1
Q= exp −β~ω n + (46)
n=0
2
La función de partición puede ser escrita como una serie geométrica
1
X ∞ exp − β~ω
1 n 2
Q = exp − β~ω [exp(−β~ω)] = (47)
2 n=0
1 − exp(−β~ω)
U y CV se calculan con las ecuaciones (41) y (42). Para la implementación computacional
se generan números aleatorios con la distribución de probabilidad normalizada, con la
técnica de rechazo
exp(−βEn )
p(n) = P∞ (48)
n=0 exp(−βEn )
Para la simulación usamos unidades reducidas
kB T hEn i Cv
T∗ = , hEn∗ i = , Cv∗ = (49)
~ω ~ω kB
Las expresiones finales en términos de estas unidades reducidas
1
exp − ∗
∗ 1 T Cv h(En∗ )2 i − hEn∗ i2
hEn i = + , = (50)
2 1 kB (T ∗ )2
1 − exp − ∗
T
A continuación la implementación en gfortran
program oscilador_cuantico
implicit none
real(8)::suma1,suma2,et,temp,dT,pr,cv,e_exacta
real(8)::p,det,en,em1,cv_exacta,xr1,xr2
integer::i,nre,nw,nmc,nt,kt,nmax,n
write(6,1010)
nw=100000
nmc=100000
temp=0.02
dT=0.04
do kt=1,10 !ciclo sobre todas las temperaturas
nmax=max(1,int(temp*27.631021-0.5))
n=0
en=0.5
17
suma1=0.0
suma2=0.0
nre=0
do i=1,nw+nmc
xr1=rand()
xr2=rand()
nt=int(nmax*xr1) ! se hace un movimiento
et=float(nt)+0.5
det=(et-en)/temp
p=dexp(-det)
if (xr2 .lt. p) then
en=et ! se acepta
n=nt
else
nre=nre+1 !se rechaza
end if
if (i .gt. nw) then
suma1=suma1+en/float(nmc) ! se recolecta la data
suma2=suma2+en*en/float(nmc)
end if
enddo
cv=(suma2-suma1*suma1)/(temp*temp)
em1=dexp(-1.0/temp)
e_exacta=0.5+em1/(1.0-em1) ! la energia exacta
! calor especifico exacto
cv_exacta=(em1/((1.0-em1)*(1.0-em1)))/(temp*temp)
pr=100.0*float(nre)/(nmc+nw)
write(6,1000)temp,suma1,e_exacta,cv,cv_exacta,pr
temp=temp+dT
Evaluación
a) Explicar e implementar caminata aleatoria fija en gfortran para resolver los ejercicios
4.10 y 4.12 del libro de Sadiku, Monte Carlo Method for electromagnetics
18