- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
分子模拟中的能量计算本质上充满了“for”循环。传统上,每个原子/分子的坐标存储在数组中。数组的矢量化相当简单,但结构很适合编码。将分子视为单独的对象,每个对象都有自己的坐标和其他属性,就簿记而言非常方便且清晰得多。
我的问题是,当我使用对象数组时,我无法弄清楚如何矢量化计算......似乎无法避免 for 循环。我是否有必要使用数组才能利用 numpy 并对我的代码进行矢量化?
这是一个利用数组(代码第 121 行)的 Python 示例,并显示了快速(numpy)和慢速(“正常”)Python 能量计算。
https://github.com/Allen-Tildesley/examples/blob/master/python_examples/mc_lj_module.py
使用 numpy 加速方法计算速度要快得多,因为它是矢量化的。
如果我不使用数组,而是使用对象数组(每个对象都有自己的坐标),我将如何矢量化能量计算?这似乎需要使用较慢的 for 循环。
import numpy as np
import time
class Mol:
num = 0
def __init__(self, r):
Mol.num += 1
self.r = np.empty((3),dtype=np.float_)
self.r[0] = r[0]
self.r[1] = r[1]
self.r[2] = r[2]
""" Alot more useful things go in here in practice"""
################################################
# #
# Main Program #
# #
################################################
L = 5.0 # Length of simulation box (arbitrary)
r_cut_box_sq = L/2 # arbitrary cutoff - required
mol_list=[]
nmol = 1000 # number of molecules
part = 1 # arbitrary molecule to interact with rest of molecules
""" make 1000 molecules (1 atom per molecule), give random coordinates """
for i in range(nmol):
r = np.random.rand(3) * L
mol_list.append( Mol( r ) )
energy = 0.0
start = time.time()
################################################
# #
# Slow but functioning loop #
# #
################################################
for i in range(nmol):
if i == part:
continue
rij = mol_list[part].r - mol_list[i].r
rij = rij - np.rint(rij/L)*L # apply periodic boundary conditions
rij_sq = np.sum(rij**2) # Squared separations
in_range = rij_sq < r_cut_box_sq
sr2 = np.where ( in_range, 1.0 / rij_sq, 0.0 )
sr6 = sr2 ** 3
sr12 = sr6 ** 2
energy += sr12 - sr6
end = time.time()
print('slow: ', end-start)
print('energy: ', energy)
start = time.time()
################################################
# #
# Failed vectorization attempt #
# #
################################################
""" The next line is my problem, how do I vectorize this so I can avoid the for loop all together?
Leads to error AttributeError: 'list' object has no attribute 'r' """
""" I also must add in that part cannot interact with itself in mol_list"""
rij = mol_list[part].r - mol_list[:].r
rij = rij - np.rint(rij/L)*L # apply periodic boundary conditions
rij_sq = np.sum(rij**2)
in_range = rij_sq < r_cut_box_sq
sr2 = np.where ( in_range, 1.0 / rij_sq, 0.0 )
sr6 = sr2 ** 3
sr12 = sr6 ** 2
energy = sr12 - sr6
energy = sum(energy)
end = time.time()
print('faster??: ', end-start)
print('energy: ', energy)
如果在能量计算中,有必要循环每个分子中的每个原子,其中每个原子现在每个分子超过 1 个原子,并且并非所有分子都具有相同数量的原子,因此任何可能的解决方案都会受到影响吗?用于分子与分子相互作用的双 for 循环,而不是当前使用的简单的配对相互作用。
最佳答案
利用 itertools 库可能是前进的方向。假设您将一对分子的能量计算包装在一个函数中:
def calc_pairwise_energy((mol_a,mol_b)):
# function takes a 2 item tuple of molecules
# energy calculating code here
return pairwise_energy
然后你可以使用 itertools.combinations 来获取所有分子对和 python 内置的列表推导式(下面最后一行 [ ] 内的代码):
from itertools import combinations
pairs = combinations(mol_list,2)
energy = sum( [calc_pairwise_energy(pair) for pair in pairs] )
我回到这个答案是因为我意识到我没有正确回答你的问题。根据我已经发布的内容,成对能量计算函数如下所示(我对您的代码进行了一些优化):
def calc_pairwise_energy(molecules):
rij = molecules[0].r - molecules[1].r
rij = rij - np.rint(rij/L)*L
rij_sq = np.sum(rij**2) # Squared separations
if rij_sq < r_cut_box_sq:
return (rij_sq ** -6) - (rij_sq ** - 3)
else:
return 0.0
在一次调用中执行所有成对计算的矢量化实现可能如下所示:
def calc_all_energies(molecules):
energy = 0
for i in range(len(molecules)-1):
mol_a = molecules[i]
other_mols = molecules[i+1:]
coords = np.array([mol.r for mol in other_mols])
rijs = coords - mol_a.r
# np.apply_along_axis replaced as per @hpaulj's comment (see below)
#rijs = np.apply_along_axis(lambda x: x - np.rint(x/L)*L,0,rijs)
rijs = rijs - np.rint(rijs/L)*L
rijs_sq = np.sum(rijs**2,axis=1)
rijs_in_range= rijs_sq[rijs_sq < r_cut_box_sq]
energy += sum(rijs_in_range ** -6 - rijs_in_range ** -3)
return energy
这要快得多,但这里仍然有很多需要优化的地方。
关于python - 在 python 中构建对象列表以进行矢量化 : Can a list of structures(objects) be vectorized, 或者需要显式数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51679898/
我是 CAN 协议(protocol)的新手,正在阅读 Robert Bosch 的 CAN 规范 ver2.0 B 部分。我无法理解第 63 页上的以下几行 ”注意:启动/唤醒:如果在启动期间只有一
我用 C 写了一些代码来读取 CAN 总线数据。当我读取 11 位 CAN ID 时一切正常。一旦我尝试读取 29 位 ID,它就会错误地显示 ID。 示例: 接收29位ID的消息: 0x01F0A0
如果这看起来与另一个问题相似或者看起来已经得到回答,我提前道歉。我觉得它非常详细,足以证明自己的问题。 我正在尝试寻找一个虚拟的 CAN 总线模拟器(或一些可以轻松制作模拟器的方法),它只会生成 CA
我的问题涉及 GNU 的品牌。 如果您有一系列命令可用作多个目标的配方,则 canned recipe派上用场了。我可能看起来像这样: define run-foo # Here comes a #
您好,我是一名学习canopen的学生。Canopen中的COB-ID和CAN标识符有什么关系?我在CIA主页上看到COB-ID不是CAN ID,但我不明白。 例如,如果 PDO 通过 CAN 总线传
我知道一个显性确认位是由另一个节点传输的消息的接收器发送的。 我无法理解的是,接收方是在接收到整个消息后发送单个显性位,还是接收者发送相同的消息,其中 ACK 位字段为显性? 或者是接收器在发送器传输
我是 CAN 协议(protocol)的新手,我正在尝试通过 Linux 的 SocketCAN 使用它。然而,我对可用的 2 种不同的 CAN 套接字(RAW 和广播管理器 (BCM))感到困惑。
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
我正在尝试制作一个在 Windows 下运行并与 ELM327 设备通信的软件。我创建了第一个版本,然后我进入了我的 SMART ForTwo (SMART 451) 车辆,我设法连接了仪表盘(发送
我知道在 CAN Controller 中,如果错误计数达到某个阈值(比如 255),就会发生总线关闭,这意味着特定的 CAN 节点将从 CAN 网络中关闭。所以根本不会有任何交流。但是,如果上述情况
我正在使用 ELM327,我希望能够设置要发送的 CAN 消息的 header 和数据部分。我看到有一个代码用于设置消息的标题 SH xxyyzz 但是我很难找出如何设置数据部分并控制何时发送消息。
我想做的是: 将数据插入具有两列的表中,并在同一 PHP 页面中显示更新的值。我能够获取数据并显示它,但无法插入任何数据。请指导我。 文件名为 mypage.php 到目前为止我的代码:
(这个问题是关于 Android 11 的) 我想将崩溃日志打印到其他应用程序可以读取的文件中(具体来说,我希望能够导航到该文件并使用"file"应用程序查看数据)。 我看过很多关于这个问题的答案,但
这会产生“ fatal error :无法解开Optional.None”,我似乎不明白为什么 var motionManager = CMMotionManager() motionManager.
在 Java 中,我经常遇到带有后缀 -able 的接口(interface),例如可序列化、可迭代等。这表明实现这些接口(interface)的对象具有可以对其执行某些操作的特性,例如该对象可以被序
我正在阅读 CanJS API 文档并遇到 can.Construct.extend http://canjs.com/docs/can.Construct.extend.html .我知道 can.
我正在使用 C 语言在 STM32F1xx 上进行开发,直到现在我都在尝试使用“CANopenNode-master”实现 CANopen 堆栈,并且我正在使用 2 个中断。 第一个是用于处理 SYN
我一直在使用 SocketCAN,尤其是 Virtual CAN vcan。但是,到目前为止,我从未使用过 CAN FD(灵活数据速率)。 好吧,我今天早上用 can-utils 试了一下: cans
我正在运行一个带有两个 CAN channel 的程序(使用 TowerTech CAN Cape TT3201)。 两个 channel 是 can0 (500k) 和 can1 (125k)。 c
存储由序列字符组成的字符串的 %s 格式说明符可以存储整数序列吗?如果是的话..你能解释一下吗? 最佳答案 无论如何,数字都是用字符表示的,所以是的,您可以使用 "%s" 说明符读取数字并将其存储在
我是一名优秀的程序员,十分优秀!