RuntimeWarning: พบค่าที่ไม่ถูกต้องในการหาร


96

ฉันต้องทำโปรแกรมโดยใช้วิธีของออยเลอร์สำหรับโมเดล "ball in a spring"

from pylab import*
from math import*
m=0.1
Lo=1
tt=30
k=200
t=20
g=9.81
dt=0.01
n=int((ceil(t/dt)))
km=k/m
r0=[-5,5*sqrt(3)]
v0=[-5,5*sqrt(3)]
a=zeros((n,2))
r=zeros((n,2))
v=zeros((n,2))
t=zeros((n,2))
r[1,:]=r0
v[1,:]=v0
for i in range(n-1):
    rr=dot(r[i,:],r[i,:])**0.5
    a=-g+km*cos(tt)*(rr-L0)*r[i,:]/rr
    v[i+1,:]=v[i,:]+a*dt
    r[i+1,:]=r[i,:]+v[i+1,:]*dt
    t[i+1]=t[i]+dt

    #print norm(r[i,:])

plot(r[:,0],r[:,1])
xlim(-100,100)
ylim(-100,100)
xlabel('x [m]')
ylabel('y [m]')

show()

ฉันได้รับข้อผิดพลาดนี้เรื่อย ๆ :

a=-g+km*cos(tt)*(rr-L0)*r[i,:]/rr
RuntimeWarning: invalid value encountered in divide

ฉันคิดไม่ออกว่ารหัสผิดอะไร


พิมพ์สิ่งที่เกิดขึ้นในแต่ละรายการขนาดเล็กในบรรทัดรหัสนั้น นั่นเป็นวิธีเดียวที่จะแก้ไขข้อบกพร่องได้
CppLearner

2
คุณมีnanสำหรับrrซึ่งทำให้เกิดข้อผิดพลาดนั้น ปัญหากับการrrอยู่ในที่เกิดจากซึ่งเท่ากับในบางกรณีเพื่อr[i,:] array([ nan, nan])ดังที่ @CppLearner กล่าวไว้วิธีที่ดีที่สุดในการดีบัก (หรือเขียน) โค้ดคือการทดสอบส่วนย่อย ๆ ก่อนที่จะใช้งาน
cosmosis

คำตอบ:


161

ฉันคิดว่าโค้ดของคุณพยายาม "หารด้วยศูนย์" หรือ "หารด้วย NaN" หากคุณตระหนักถึงเรื่องนี้และไม่ต้องการให้มันรบกวนคุณคุณสามารถลอง:

import numpy as np
np.seterr(divide='ignore', invalid='ignore')

ดูรายละเอียดเพิ่มเติมได้ที่:


76
จะมีประโยชน์ในการใช้งานwith NP.errstate(divide='ignore',invalid='ignore'):หากคุณต้องการระงับคำเตือนสำหรับบล็อกโค้ด
GWW

8
ทำไมเราถึงอยากละเว้นการหารด้วยศูนย์หรือ NaN?
x กำลังสอง

7
@xsquared เมื่อคุณจัดการค่าได้อย่างถูกต้องด้วยตัวเองหลังจากการหารและคุณกำลังแจกจ่ายรหัสของคุณให้กับผู้ใช้ (หรือเบื่อที่จะเห็นคำเตือน) with np.errstate(...)ช่วยให้คุณทำสิ่งนี้ได้อย่างปลอดภัยสำหรับเคสที่จัดการเท่านั้น
reve_etrange

2
@reve_etrange ฉันพบว่าเป็นที่ยอมรับได้มากกว่าการละเว้นการหารด้วยศูนย์โดยทั่วไป
x กำลังสอง

1
จะเป็นการดีกว่าที่จะตั้งค่านี้ก่อนบรรทัดที่ทำให้เกิดข้อผิดพลาดจากนั้นรีเซ็ตหลังจากบรรทัดเข้าสู่สถานะปกติของ'warn'คำสั่งnp.seterr(divide='warn', invalid='warn')
Mohammad ElNesr

15

การจัดทำดัชนี Python เริ่มต้นที่ 0 (แทนที่จะเป็น 1) ดังนั้นการกำหนด "r [1 ,:] = r0" ของคุณจะกำหนดองค์ประกอบที่สอง (เช่นดัชนี 1) ของ r และปล่อยให้องค์ประกอบแรก (ดัชนี 0) เป็นศูนย์คู่ ค่าแรกของ i ในสำหรับลูปของคุณคือ 0 ดังนั้น rr จึงได้รากที่สองของผลิตภัณฑ์ดอทของรายการแรกใน r ด้วยตัวมันเอง (ซึ่งก็คือ 0) และการหารด้วย rr ในบรรทัดต่อมาจะทำให้เกิดข้อผิดพลาด


10

เพื่อป้องกันการหารด้วยศูนย์คุณสามารถเริ่มต้นเอาต์พุต 'out' ล่วงหน้าได้เมื่อเกิดข้อผิดพลาด div0 เช่น np.whereห้ามตัดเนื่องจากเส้นที่สมบูรณ์ได้รับการประเมินโดยไม่คำนึงถึงเงื่อนไข

ตัวอย่างที่มีการเตรียมใช้งานล่วงหน้า:

a = np.arange(10).reshape(2,5)
a[1,3] = 0
print(a)    #[[0 1 2 3 4], [5 6 7 0 9]]
a[0]/a[1]   # errors at 3/0
out = np.ones( (5) )  #preinit
np.divide(a[0],a[1], out=out, where=a[1]!=0) #only divide nonzeros else 1

4

คุณกำลังหารด้วยrrซึ่งอาจเป็น 0.0 ตรวจสอบว่าrrเป็นศูนย์หรือไม่และทำสิ่งที่สมเหตุสมผลนอกเหนือจากการใช้ในตัวส่วน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.