ValueError: błąd domeny matematycznej

102

Właśnie testowałem przykład z Numerical Methods in Engineering w Pythonie .

from numpy import zeros, array
from math import sin, log
from newtonRaphson2 import *

def f(x):
    f = zeros(len(x))
    f[0] = sin(x[0]) + x[1]**2 + log(x[2]) - 7.0
    f[1] = 3.0*x[0] + 2.0**x[1] - x[2]**3 + 1.0
    f[2] = x[0] + x[1] + x[2] -5.0
    return f

x = array([1.0, 1.0, 1.0])
print newtonRaphson2(f,x)

Po uruchomieniu pokazuje następujący błąd:

File "example NR2method.py", line 8, in f
    f[0] = sin(x[0]) + x[1]**2 + log(x[2]) - 7.0
ValueError: math domain error

Zawęziłem to do dziennika, ponieważ kiedy usuwam dziennik i dodam inną funkcję, działa. Zakładam, że jest to spowodowane jakąś ingerencją w podstawę, nie wiem, jak to zrobić. Czy ktoś może zaproponować rozwiązanie?

ramanunni.pm
źródło

Odpowiedzi:

131

Twój kod składa się logz liczby mniejszej lub równej zero. Jest to matematycznie niezdefiniowane, więc logfunkcja Pythona zgłasza wyjątek. Oto przykład:

>>> from math import log
>>> log(-1)
Traceback (most recent call last):
  File "<pyshell#59>", line 1, in <module>
    log(-1)
ValueError: math domain error

Nie wiedząc, co newtonRaphson2robi twoja funkcja, nie jestem pewien, czy mogę zgadnąć, skąd pochodzi nieprawidłowa x[2]wartość, ale mam nadzieję, że poprowadzi cię to na właściwą ścieżkę.

Blckknght
źródło
Nie rozumiem, jak to robi logarytm ujemny, ponieważ definicja definiuje zestaw równań, to znaczy x [0], x [1] i x [2] to zmienne x, y i z, których używa Newton Raphson . Do rozwiązania potrzebuje tego zestawu równań.
ramanunni.pm
1
Również, jak mówię x [2] = 1.0, kiedy zdefiniuję x w powyższym kodzie, log (1) = 0, przynajmniej tak myślę, może się mylę .. Ale dzięki za pomoc ..
ramanunni .pm
1
dodaj a print xna początku swojej funkcji f . Zobaczysz, jak narzędzie do rozwiązywania równań kolejno próbuje różnych wartości x, co prowadzi do błędu.
mtadd
3
W moich przypadkach problem polegał na tym, że argument nie był ujemny, ale dokładnie równy 0, co prowadzi do tego samego wyjątku (co może być zaskakujące dla osób z tłem JS, gdzie Math.log (0) to po prostu -Infinity)
qbolec
1

Próbujesz obliczyć logarytm czegoś, co nie jest dodatnie.

Logarytmy obliczają podstawę po otrzymaniu liczby i potęgi, do której została podniesiona. log(0)oznacza, że ​​coś podniesionego do potęgi 2jest 0. Wykładnik nigdy nie może dać znaku 0*, co oznacza, że log(0)nie ma odpowiedzi, dlatego rzucamath domain error

* Uwaga: 0^0może skutkować 0, ale może również skutkować w 1tym samym czasie. Ten problem jest mocno dyskutowany.

Eric Xue
źródło
1

Możesz także użyć math.log1p.

Według oficjalnej dokumentacji :

math.log1p (x)

Zwróć logarytm naturalny z 1 + x (podstawa e). Wynik jest obliczany w sposób, który jest dokładny dla x bliskich zeru.

Możesz przekonwertować z powrotem na pierwotną wartość, używając math.expm1której zwraca epodniesioną do potęgi x minus 1.

Catalina Chircu
źródło
0

otrzymujesz błąd domeny matematycznej z jednego z powodów: albo próbujesz użyć liczby ujemnej wewnątrz funkcji dziennika, albo wartości zerowej.

Fizyka 3067
źródło