总之,我的代码有完全相同的参数,但有三种不同的方法:
-
为具有三个实例/属性的粒子SP列表定义一个类.(约1分钟)
-
将SP定义为array.(约1分钟)
-
将SP定义为数组并使用Numba(大约5秒)
考虑第一种情况:
n=1000
mu=np.random.uniform(0,1,n)
r=[sqrt(-2*log(1-i)) for i in mu]
eta=np.random.uniform(0,1,n)
theta=2*pi*eta;
cuz=[cos(i) for i in theta]
suz=[sin(i) for i in theta]
Zinitial=[a*b for a,b in zip(r,cuz)];
Pinitial=[a*b for a,b in zip(r,suz)];
class Particle:
def __init__(self, pos, mom, spin):
self.pos = pos
self.mom = mom
self.spin = spin
SP = sorted([Particle(pos = i, mom = j, spin = choice([1, 0])) for i,j in zip(Zinitial,Pinitial)],key=lambda x:x.pos)
Upi=[];
Downi=[];
count_plot=[];
for j in range(len(SP)):
if SP[j].spin == 1:
Upi.append(SP[j].pos)
else:
Downi.append(SP[j].pos)
Zavgi=sum(Zinitial)/len(Zinitial)
Zreli=sum(Upi)/len(Upi)-sum(Downi)/len(Downi)
"Observables"
Zavg=[Zavgi];
Zrelm=[Zreli];
T_plot=[0];
"Time"
iter=10**(4);
dt=1/(2*n);
alf=sqrt(n);
"Dynamics"
counter=0;
sum1,sum2=0,0;
for i in range(1,iter+1):
t=i*dt;
T_plot.append(t)
Z=[];
Up=[];
Down=[];
c,s=cos(t),sin(t);
c1,s1=cos(t-dt),sin(t-dt);
for j in range(n-1):
collchk=((c*(SP[j].pos)+s*(SP[j].mom))-(c*(SP[j+1].pos)+s*(SP[j+1].mom)))*(c1*(SP[j].pos)+s1*(SP[j].mom)-(c1*(SP[j+1].pos)+s1*(SP[j+1].mom)));
prel=((c*(SP[j].mom)-s*(SP[j].pos))-(c*(SP[j+1].mom)-s*(SP[j+1].pos)))/2;
rcoeff=1/(1+(prel*alf)**2);
rand_value=random();
if collchk<0:
SP[j], SP[j+1]=SP[j+1],SP[j];
if rcoeff>rand_value:
counter=counter+1
SP[j].spin,SP[j+1].spin=SP[j+1].spin,SP[j].spin;
if SP[j].spin == 1:
Up.append(c*(SP[j].pos)+s*(SP[j].mom))
else:
Down.append(c*(SP[j].pos)+s*(SP[j].mom))
Z.append(c*(SP[j].pos)+s*(SP[j].mom))
Zrel=sum(Up[0:])/len(Up) - sum(Down[0:])/len(Down);
Zrelm.append(Zrel)
Zm=sum(Z)/len(Z)
Zavg.append(Zm)
print("Rate of collision per particle = ",counter/(n*(dt*iter)))
OUTPUT是:
第二种情况:
n=1000
mu=np.random.uniform(0,1,n)
r=np.array([sqrt(-2*log(1-i)) for i in mu])
eta=np.random.uniform(0,1,n)
theta=2*pi*eta;
cuz=np.array([cos(i) for i in theta])
suz=np.array([sin(i) for i in theta])
Zinitial=np.multiply(r,cuz);
Pinitial=np.multiply(r,suz);
SP = np.array(sorted(np.array([ np.array([i,j,choice([1,0])]) for i, j in zip(Zinitial, Pinitial)]),
key=lambda x: x[0]))
Upi=[];
Downi=[];
count_plot=[];
for j in range(len(SP)):
if SP[j][2] == 1:
Upi.append(SP[j][0])
else:
Downi.append(SP[j][0])
Zavgi=sum(Zinitial)/len(Zinitial)
Zreli=sum(Upi)/len(Upi)-sum(Downi)/len(Downi)
"Observables"
Zavg=[Zavgi];
Zrelm=[Zreli];
T_plot=[0];
"Time"
iter=10**(4);
dt=1/(2*n);
alf=sqrt(n);
"Dynamics"
counter=0;
sum1,sum2=0,0;
for i in range(1,iter+1):
t=i*dt;
T_plot.append(t)
Z=[];
Up=[];
Down=[];
c,s=cos(t),sin(t);
c1,s1=cos(t-dt),sin(t-dt);
for j in range(n-1):
collchk=((c*(SP[j][0])+s*(SP[j][1]))-(c*(SP[j+1][0])+s*(SP[j+1][1])))*(c1*(SP[j][0])+s1*(SP[j][1])-(c1*(SP[j+1][0])+s1*(SP[j+1][1])));
prel=((c*(SP[j][1])-s*(SP[j][0]))-(c*(SP[j+1][1])-s*(SP[j+1][0])))/2;
rcoeff=1/(1+(prel*alf)**2);
rand_value=random();
if collchk<0:
SP[j], SP[j+1]=SP[j+1],SP[j];
if rcoeff>rand_value:
counter=counter+1
SP[j][2],SP[j+1][2]=SP[j+1][2],SP[j][2];
if SP[j][2] == 1:
Up.append(c*(SP[j][0])+s*(SP[j][1]))
else:
Down.append(c*(SP[j][0])+s*(SP[j][1]))
Z.append(c*(SP[j][0])+s*(SP[j][1]))
Zrel=sum(Up[0:])/len(Up) - sum(Down[0:])/len(Down);
Zrelm.append(Zrel)
Zm=sum(Z)/len(Z)
Zavg.append(Zm)
print("Rate of collision per particle = ",counter/(n*(dt*iter)))
OUTPUT是:
每个粒子的碰撞率=0.0134
最快的麻木病例;
import numpy as np
import matplotlib.pyplot as plt
import random
from math import *
from random import *
from numba import jit
"Dynamics"
@jit(nopython=True)
def f(SP, Zavgi, Zreli, alf, dt, n):
"Time"
counter = 0;
Zavg = np.array([Zavgi]);
Zrelm = np.array([Zreli]);
T_plot = np.array([0]);
for i in range(1, iter + 1):
t = i * dt;
np.append(T_plot,t)
Z = [];
Up = [];
Down = [];
c, s = cos(t), sin(t);
c1, s1 = cos(t - dt), sin(t - dt);
for j in range(n - 1):
collchk = ((c * (SP[j][0]) + s * (SP[j][1])) - (c * (SP[j + 1][0]) + s * (SP[j + 1][1]))) * (
c1 * (SP[j][0]) + s1 * (SP[j][1]) - (c1 * (SP[j + 1][0]) + s1 * (SP[j + 1][1])));
prel = ((c * (SP[j][1]) - s * (SP[j][0])) - (c * (SP[j + 1][1]) - s * (SP[j + 1][0]))) / 2;
rcoeff = 1 / (1 + (prel * alf) ** 2);
rand_value = random();
if collchk < 0:
SP[j], SP[j + 1] = SP[j + 1], SP[j];
if rcoeff > rand_value:
counter = counter + 1
SP[j][2], SP[j + 1][2] = SP[j + 1][2], SP[j][2];
if SP[j][2] == 1:
Up.append(c * (SP[j][0]) + s * (SP[j][1]))
else:
Down.append(c * (SP[j][0]) + s * (SP[j][1]))
Z.append(c * (SP[j][0]) + s * (SP[j][1]))
Zrel = np.sum(np.array(Up)) / len(Up) - np.sum(np.array(Down)) / len(Down);
Zrelm = np.append(Zrelm, Zrel)
Zm = np.sum(np.array(Z)) / len(Z)
Zavg = np.append(Zavg, Zm)
return Zavg, Zrelm, counter, T_plot
if __name__ == '__main__':
n = 1000
mu = np.random.uniform(0, 1, n)
r = [sqrt(-2 * log(1 - i)) for i in mu]
eta = np.random.uniform(0, 1, n)
theta = 2 * pi * eta;
cuz = [cos(i) for i in theta]
suz = [sin(i) for i in theta]
Zinitial = [a * b for a, b in zip(r, cuz)];
Pinitial = [a * b for a, b in zip(r, suz)];
iter = 10 ** (4);
dt = 1 / (2 * n);
alf = sqrt(n);
SP = np.array(sorted(np.array([ np.array([i,j,choice([1,0])]) for i, j in zip(Zinitial, Pinitial)]),
key=lambda x: x[0]))
Upi = [];
Downi = [];
count_plot = [];
for j in range(len(SP)):
if SP[j][2] == 1:
Upi.append(SP[j][0])
else:
Downi.append(SP[j][0])
Zavgi = np.sum(Zinitial) / len(Zinitial)
Zreli = np.sum(Upi) / len(Upi) - np.sum(Downi) / len(Downi)
Zavg, Zrelm, counter, T_plot = f(SP, Zavgi, Zreli, alf, dt, n)
print("rate= ", counter/(n*(iter*dt)))
OUTPUT人:
费率=0.00814
可以看出,即使参数相同,这三种情况下的速率也不同.
由于参数相同,我希望三种不同的方法可以给出非常接近的速率.
为什么会这样?
100
我通过简单地运行代码缩短了代码的时间.由于这个原因,我还删除了在如此短的时间尺度下看起来非常奇怪的图表.我想强调的是,这个问题似乎有两个方面,但又是相关的:许多次运行的速率相差一个数量级,而数组情况(有和没有Numba)的图形似乎比类情况更不稳定(这在长时间运行中变得非常突出).