用Python编写的Friends of Friends算法需要使用Fortran 90/95
我正在尝试为“朋友的朋友”算法编写自己的代码。该算法作用于一组3d数据点,并返回数据集中的“光晕”数量。每个光环都是一组点,其距离小于程序的唯一参数链接长度b 算法描述: FOF算法有一个单独的自由参数,称为链接长度。相隔距离小于或等于链接长度的任何两个粒子称为“朋友”。FOF组由一组粒子定义,其中集合中的每个粒子通过朋友网络连接到集合中的每个其他粒子 设置FOF组计数器j=1用Python编写的Friends of Friends算法需要使用Fortran 90/95,python,fortran,finder,halo,Python,Fortran,Finder,Halo,我正在尝试为“朋友的朋友”算法编写自己的代码。该算法作用于一组3d数据点,并返回数据集中的“光晕”数量。每个光环都是一组点,其距离小于程序的唯一参数链接长度b 算法描述: FOF算法有一个单独的自由参数,称为链接长度。相隔距离小于或等于链接长度的任何两个粒子称为“朋友”。FOF组由一组粒子定义,其中集合中的每个粒子通过朋友网络连接到集合中的每个其他粒子 设置FOF组计数器j=1 对于尚未与任何组关联的每个粒子n: 将n指定给组j,初始化组j的新成员列表mlist,并将粒子n作为第一个条目 递归
- 对于尚未与任何组关联的每个粒子n:
- 将n指定给组j,初始化组j的新成员列表mlist,并将粒子n作为第一个条目
- 递归地,对于mlist中的每个新粒子p:
- 查找距离小于或等于链接长度的p的邻居,将尚未分配给组j的添加到mlist
- 记录j组的mlist,设置j=j+1
import random
from random import *
import math
from math import *
import numpy
from numpy import *
import time
points = 1000
halos=[0,100.,150.]
x=[]
y=[]
z=[]
id=[]
for i in arange(0,points,1):
x.append(halos[0]+random())
y.append(halos[0]+random())
z.append(halos[0]+random())
id.append(i)
for i in arange(points,points*2,1):
x.append(halos[1]+random())
y.append(halos[1]+random())
z.append(halos[1]+random())
id.append(i)
for i in arange(points*2,points*3,1):
x.append(halos[2]+random())
y.append(halos[2]+random())
z.append(halos[2]+random())
id.append(i)
然后我对FOF算法进行编码:
x=array(x)
y=array(y)
z=array(z)
id=array(id)
t0 = time.time()
id_grp=[]
groups=zeros((len(x),1)).tolist()
particles=id
b=1 # linking length
while len(particles)>0:
index = particles[0]
# remove the particle from the particles list
particles.remove(index)
groups[index]=[index]
print "#N ", index
dx=x-x[index]
dy=y-y[index]
dz=z-z[index]
dr=sqrt(dx**2.+dy**2.+dz**2.)
id_to_look = where(dr<b)[0].tolist()
id_to_look.remove(index)
nlist = id_to_look
# remove all the neighbors from the particles list
for i in nlist:
if (i in particles):
particles.remove(i)
print "--> neighbors", nlist
groups[index]=groups[index]+nlist
new_nlist = nlist
while len(new_nlist)>0:
index_n = new_nlist[0]
new_nlist.remove(index_n)
print "----> neigh", index_n
dx=x-x[index_n]
dy=y-y[index_n]
dz=z-z[index_n]
dr=sqrt(dx**2.+dy**2.+dz**2.)
id_to_look = where(dr<b)[0].tolist()
id_to_look = list(set(id_to_look) & set(particles))
nlist = id_to_look
if (len(nlist)==0):
print "No new neighbors found"
else:
groups[index]=groups[index]+nlist
new_nlist=new_nlist+nlist
print "------> neigh-neigh", new_nlist
for k in nlist:
particles.remove(k)
我认为,如果你开始学习Fortran时希望得到的代码比你当前的实现更快,那你就不明智了。最终可能是这样,但我认为最好在考虑用另一种语言(特别是外语)实现之前,尽可能快地完成Python实现 我写的是Fortran,我个人认为它的性能在Python上很受欢迎,但了解这些东西的人提供了令人信服的论据,Python+SciPy+Numpy如果精心设计,可以在许多科学/工程程序的计算内核中与Fortran相媲美。不要忘记,直到计算机上的所有内核都运行红热时,您才优化Python 因此: 第一,用Python实现一个有效的实现 第二,尽快实施
如果(大写字母,因为它是一个大的‘IF’),代码仍然不够快,将它翻译成编译语言的成本/收益是有利的,那么考虑将哪种编译语言翻译成。如果你在FORTRAN被广泛使用的领域,那么学习FORTRAN,但它是一种利基语言,它可能会受益于你的职业更多地学习C++或它的一个亲戚。 编辑(太长,无法放入注释框)
为什么在你的问题上误导我们?你说你唯一熟悉的语言是Python,现在你说你懂Fortran。我想你一定觉得不舒服。而且,从您的评论来看,您真正需要的帮助似乎是加快Python实现的速度;他提出了一些建议。考虑到这一点,然后并行化。我认为,如果你开始学习Fortran,希望得到的代码比当前的实现更快,那是不明智的。最终可能是这样,但我认为最好在考虑用另一种语言(特别是外语)实现之前,尽可能快地完成Python实现 我写的是Fortran,我个人认为它的性能在Python上很受欢迎,但了解这些东西的人提供了令人信服的论据,Python+SciPy+Numpy如果精心设计,可以在许多科学/工程程序的计算内核中与Fortran相媲美。不要忘记,直到计算机上的所有内核都运行红热时,您才优化Python 因此: 第一,用Python实现一个有效的实现 第二,尽快实施
如果(大写字母,因为它是一个大的‘IF’),代码仍然不够快,将它翻译成编译语言的成本/收益是有利的,那么考虑将哪种编译语言翻译成。如果你在FORTRAN被广泛使用的领域,那么学习FORTRAN,但它是一种利基语言,它可能会受益于你的职业更多地学习C++或它的一个亲戚。 编辑(太长,无法放入注释框)
为什么在你的问题上误导我们?你说你唯一熟悉的语言是Python,现在你说你懂Fortran。我想你一定觉得不舒服。而且,从您的评论来看,您真正需要的帮助似乎是加快Python实现的速度;他提出了一些建议。考虑到这一点,然后并行化。指向更高效算法的指针。如果我没弄错的话,你是在将一个点与其他点进行比较,看看是否有比链接长度更近的点。对于大量的点,有更快的方法找到近邻——空间索引和KD树,但毫无疑问,还有其他方法也适用于您。指向更高效算法的指针。如果我没弄错的话,你是在将一个点与其他点进行比较,看看是否有比链接长度更近的点。对于大量的点,有更快的方法找到近邻——空间索引和KD树,但毫无疑问,还有其他方法也适用于您。如果您有一个现代图形卡,您可以使用
def select(test,list):
selected = []
for item in list:
if test(item) == True:
selected.append(item)
return selected
groups=select(lambda x: sum(x)>0.,groups)
# sorting groups
groups.sort(lambda x,y: cmp(len(x),len(y)))
groups.reverse()
print time.time() - t0, "seconds"
mass=x
for i in arange(0,len(groups),1):
total_mass=sum([mass[j] for j in groups[i]])
x_cm = sum([mass[j]*x[j] for j in groups[i]])/total_mass
y_cm = sum([mass[j]*y[j] for j in groups[i]])/total_mass
z_cm = sum([mass[j]*z[j] for j in groups[i]])/total_mass
dummy_x_cm = [x[j]-x_cm for j in groups[i]]
dummy_y_cm = [y[j]-y_cm for j in groups[i]]
dummy_z_cm = [z[j]-z_cm for j in groups[i]]
dummy_x_cm = array(dummy_x_cm)
dummy_y_cm = array(dummy_y_cm)
dummy_z_cm = array(dummy_z_cm)
dr = max(sqrt(dummy_x_cm**2.+dummy_y_cm**2.+dummy_z_cm**2.))
dummy_x_cm = max(dummy_x_cm)
dummy_y_cm = max(dummy_y_cm)
dummy_z_cm = max(dummy_z_cm)
print i, len(groups[i]), x_cm, y_cm, z_cm,dummy_x_cm,dummy_y_cm,dummy_z_cm