RuntimeWarning: nilai tidak valid ditemukan dalam pembagian


96

Saya harus membuat program menggunakan metode Euler untuk model "bola di musim semi"

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

Saya terus mendapatkan kesalahan ini:

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

Saya tidak bisa memahaminya, apa yang salah dengan kodenya?


cetak apa yang terjadi di setiap item yang lebih kecil di baris kode tersebut. Itulah satu-satunya cara untuk men-debugnya.
CppLearner

2
Anda memiliki nans untuk rr, yang membuang kesalahan itu. Masalah dengan rrberasal dari r[i,:]mana yang sama, dalam beberapa kasus, dengan array([ nan, nan]). Seperti yang disebutkan @CppLearner, cara terbaik untuk men-debug (atau menulis) kode adalah dengan menguji setiap bagian yang lebih kecil sebelum menerapkan.
cosmosis

Jawaban:


161

Saya pikir kode Anda mencoba untuk "bagi dengan nol" atau "bagi dengan NaN". Jika Anda menyadarinya dan tidak ingin hal itu mengganggu Anda, maka Anda dapat mencoba:

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

Untuk lebih jelasnya lihat:


76
Ini dapat berguna untuk digunakan with NP.errstate(divide='ignore',invalid='ignore'):jika Anda ingin menyembunyikan peringatan untuk satu blok kode.
GWW

8
Mengapa seseorang ingin mengabaikan pembagian dengan nol atau NaN?
x kuadrat

7
@xsquared Ketika Anda sendiri menangani nilai dengan benar, setelah pembagian, dan Anda mendistribusikan kode Anda ke pengguna (atau lelah melihat peringatan). with np.errstate(...)memungkinkan Anda melakukan ini dengan aman hanya untuk kasus yang ditangani.
reve_etrange

2
@reve_etrange Yang saya temukan jauh lebih dapat diterima daripada umumnya mengabaikan membagi dengan nol.
x kuadrat

1
lebih baik untuk mengatur ini sebelum baris yang menyebabkan kesalahan kemudian reset setelah baris ke keadaan normal 'warn'dengan perintahnp.seterr(divide='warn', invalid='warn')
Mohammad ElNesr

15

Pengindeksan Python dimulai dari 0 (bukan 1), jadi tugas Anda "r [1 ,:] = r0" mendefinisikan elemen kedua (yaitu indeks 1) dari r dan meninggalkan elemen pertama (indeks 0) sebagai sepasang nol. Nilai pertama i di perulangan for Anda adalah 0, jadi rr mendapatkan akar kuadrat dari hasil perkalian titik dari entri pertama di r dengan dirinya sendiri (yaitu 0), dan pembagian dengan r di baris berikutnya menghasilkan kesalahan.


10

Untuk mencegah pembagian dengan nol Anda dapat melakukan pra-inisialisasi keluaran 'keluar' di mana kesalahan div0 terjadi, misalnya np.wheretidak memotongnya karena garis lengkap dievaluasi terlepas dari kondisinya.

contoh dengan pra-inisialisasi:

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

Anda membagi rryang mungkin menjadi 0,0. Periksa apakah rrnol dan lakukan sesuatu yang masuk akal selain menggunakannya di penyebut.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.