Numpy除以零。为什么?

时间:2015-04-21 13:51:28

标签: python numpy

import pygame
import random
import math
import numpy as np
import matplotlib.pyplot as plt
fx = np.zeros([11])
fy = np.zeros([11])
x = np.zeros([11])
y = np.zeros([11])
x[0] = 11
y[0] = 1
sigma = 1.01
e = 1.1
dt = 0.1
def LJ(x,y):
    for i in range(1,10):
        for j in range(1,10):
            rx = (x[i]-x[j])
            ry = (y[i]-y[j])
            fx[i] = 24*e*(((2/rx)*sigma/rx**12)-((1/rx)*sigma/rx**6))
            fy[i] = 24*e*(((2/ry)*sigma/ry**12)-((1/ry)*sigma/ry**6))
    print fx, fy

为什么我仍然会收到错误 RuntimeWarning: divide by zero encountered in double_scalars

RuntimeWarning: invalid value encountered in double_scalars

我得到的结果是

[  0.  nan  nan  nan  nan  nan  nan  nan  nan  nan   0.] [  0.  nan  nan  nan  nan  nan  nan  nan  nan  nan   0.]

我试图修改起始x和y,但这没有效果。

2 个答案:

答案 0 :(得分:4)

在此代码中:

def LJ(x,y):
    for i in range(1,10):
        for j in range(1,10):
            ...

如果i == j,您正在将粒子与自身进行比较。尝试跳过for循环的迭代,如下所示:

def LJ(x,y):
    for i in range(1,10):
        for j in range(1,10):
            if i == j:
                continue
            rx = (x[i]-x[j])
            ry = (y[i]-y[j])
            fx[i] = 24*e*(((2/rx)*sigma/rx**12)-((1/rx)*sigma/rx**6))
            fy[i] = 24*e*(((2/ry)*sigma/ry**12)-((1/ry)*sigma/ry**6))

此外,您需要为x和y列表输入实际值,因为它们目前都是0。根据该等式,位于完全相同位置的两个粒子施加无限大的力,因此在该场景中除以0是准确的。

答案 1 :(得分:2)

你应该坚持物理学。潜在的功能是,从你的力量公式重建,

LJ(r) = 4*e*(  (sigma/r)**12 - (sigma/r)**6 )

对于任何潜在的,对应于潜力的力

F = - LJ'(r)*(rx/r, ry/r)

因此,计算组合交互力的过程应该类似于

def LJ(x,y):
    for i in range(x.size):
        for j in range(x.size):
            rx = (x[i]-x[j])
            ry = (y[i]-y[j])

            r = sqrt(rx*rx+ry*ry+1e-12)
            f = 24*e/r*( 2*(sigma/r)**12 - (sigma/r)**6 )

            fx[i] += f*(rx/r)
            fy[i] += f*(ry/r)
    print fx, fy

条件是在程序的调用下,力数组被初始化,或者为零或仅为重力。

在计算距离时添加术语eps**2用于避免零距离,从而在力计算中避免无限或非常大的值。这个epsilon eps当然应该小于粒子的典型距离。场景的维度,这里sigma=1.01是一个典型的距离,因此eps=1e-6对它来说很小。