RuntimeWarning: gặp phải giá trị không hợp lệ khi chia


96

Tôi phải tạo một chương trình sử dụng phương pháp của Euler cho mô hình "quả bóng trong lò xo"

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()

Tôi cứ bị lỗi này:

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

Tôi không thể tìm ra, có gì sai với mã không?


in những gì đang xảy ra trong từng mục nhỏ hơn trong dòng mã đó. Đó là cách duy nhất để gỡ lỗi nó.
CppLearner 13/02/13

2
Bạn có nans cho rr, đang ném lỗi đó. Vấn đề rrlà bắt nguồn từ r[i,:]việc bình đẳng, trong một số trường hợp, với array([ nan, nan]). Như @CppLearner đã đề cập, cách tốt nhất để gỡ lỗi (hoặc viết) mã là kiểm tra từng phần nhỏ hơn trước khi triển khai.
cosmosis

Câu trả lời:


160

Tôi nghĩ rằng mã của bạn đang cố gắng "chia cho không" hoặc "chia cho NaN". Nếu bạn nhận thức được điều đó và không muốn nó làm phiền bạn, thì bạn có thể thử:

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

Để biết thêm chi tiết xem:


76
Nó có thể hữu ích để sử dụng with NP.errstate(divide='ignore',invalid='ignore'):nếu bạn muốn loại bỏ các cảnh báo cho một khối mã.
GWW

8
Tại sao người ta muốn bỏ qua số chia cho 0 hoặc NaN?
x bình phương vào

7
@xsquared Khi bạn đã tự xử lý chính xác giá trị, sau khi phân chia và bạn đang phân phối mã của mình cho người dùng (hoặc mệt mỏi khi thấy cảnh báo). with np.errstate(...)cho phép bạn làm điều này một cách an toàn chỉ đối với trường hợp đã xử lý.
Reve_etrange

2
@reve_etrange Điều đó tôi thấy dễ chấp nhận hơn nhiều so với việc bỏ qua các phép chia cho 0.
x bình phương vào

1
nó là tốt hơn để thiết lập này trước khi dòng gây ra lỗi sau đó thiết lập lại sau khi dòng trạng thái bình thường của 'warn'bằng lệnhnp.seterr(divide='warn', invalid='warn')
Mohammad ElNesr

15

Lập chỉ mục Python bắt đầu từ 0 (thay vì 1), do đó, phép gán của bạn "r [1 ,:] = r0" xác định phần tử thứ hai (tức là chỉ số 1) của r và để phần tử đầu tiên (chỉ số 0) là một cặp số không. Giá trị đầu tiên của i trong vòng lặp for của bạn là 0, vì vậy rr lấy căn bậc hai của tích số chấm của mục nhập đầu tiên trong r với chính nó (là 0) và phép chia cho rr ở dòng tiếp theo sẽ tạo ra lỗi.


10

Để ngăn phép chia cho 0, bạn có thể khởi tạo trước đầu ra 'out' khi lỗi div0 xảy ra, ví dụ: np.wherekhông cắt nó vì dòng hoàn chỉnh được đánh giá bất kể điều kiện.

ví dụ với khởi tạo trước:

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

Bạn đang chia cho số rrđó có thể là 0,0. Kiểm tra xem rrcó bằng không và làm điều gì đó hợp lý ngoài việc sử dụng nó ở mẫu số.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.