2011-12-19 16 views
5

Po raz pierwszy używam funkcji optimize.fsolve dla scipy, aby znaleźć korzenie równania. Problem polega na tym, że niezależnie od liczby używanej jako wartość przypuszczenia/wartości szacunkowej, otrzymuję odpowiedź jako odpowiedź (z dokładnością do 8 miejsc po przecinku). Używając full_output = True, otrzymuję exitflag o wartości "1", co powinno oznaczać, że "Rozwiązanie jest konwergentne", co najlepiej zrozumiałe powinno oznaczać, że dane wyjściowe są rzeczywiście źródłem równania.fsolve zawsze zwraca wartość domyślną

Wiem, że istnieje skończona liczba odrębnych korzeni (które są oddalone od siebie), jak wtedy, gdy wykreślam równanie, które widzę. Ponadto, fsolve kończy się niepowodzeniem (daje znaki wyjścia błędu), kiedy wprowadzam punkt początkowy w zakres, który powinien zwracać niezdefiniowane wartości (dzielenie przez zero, pierwiastek kwadratowy z wartości ujemnej). Poza tym zawsze zwraca punkt początkowy jako root.

Testowałem fsolve z bardzo prostym równaniem i działało dobrze, więc wiem, że importuję wszystko, czego potrzebuję i powinno się poprawnie używać fsolve. Próbowałam też poradzić sobie z niektórymi argumentami wejściowymi, ale nie rozumiem ich bardzo dobrze i nic się nie zmieniło).

Poniżej znajduje się odpowiedni kod (E jest jedyną zmienną, wszystko ma wartość niezerową):

def func(E): 
    s = sqrt(c_sqr * (1 - E/V_0)) 
    f = s/tan(s) + sqrt(c_sqr - s**2) 
    return f 

guess = 3 
fsolve(func, guess) 

który właśnie wyprowadza „3” i mówi, choć "Rozwiązanie konwergentnych. najbliższe rozwiązania powinny wynosić około 2,8 i 4,7.

Czy ktoś ma pomysł, jak to naprawić i uzyskać poprawną odpowiedź (przy użyciu fsolve)?

+3

Być może jesteś po prostu bardzo dobrym zgadywaczem. –

+0

Jaka jest wartość dla 'V_0'? –

+3

Czy możesz podać wartości dla 'V_0' i' c_sqr'?Próbowałem wstawić 'c_sqr = 100' i' V_0 = 10', i to poprawnie łączy się z root 2.90496355. –

Odpowiedz

6

myślę równanie nie robi nie rób tego, co myślisz. Po pierwsze, kiedy próbuję, nie zwraca to domysłów; zwraca liczbę zamknij do zgadywania. Jest bardzo niestabilny i wydaje się być mylący fsolve. Na przykład:

>>> V_0 = 100 
>>> c_sqr = 3e8 ** 2 
>>> guess = 5 
>>> fsolve(func, guess) 
array([ 5.00000079]) 

To nie jest 5. Nie ma nawet 5 w precyzji maszyny. To również nie jest pierwiastkiem równania:

>>> func(5.00000079) 
2114979.3239706755 

Ale zachowanie równania jest dość nieprzewidywalny i tak:

>>> func(5.0000008) 
6821403.0196130127 
>>> func(5.0000006) 
-96874198.203683496 

Tak oczywiście nie jest przejście przez zero gdzieś tam. Powiedziałbym, że dobrze przyjrzyj się równaniu. Upewnij się, że podałeś argument w radianach, np. tan.

+2

dzięki, zapomniałem dodać argumentu tan w radianach. – scaevity

1

Czy próbowałeś zmienić swoją funkcję na coś naprawdę trywialnego? W ten sposób:

#!/usr/bin/python 
from scipy.optimize import fsolve 

def func(E): 
# s = sqrt(c_sqr * (1 - E/V_0)) 
# f = s/tan(s) + sqrt(c_sqr - s**2) 
    f = E**2 -3. 
    return f 

guess = 9 

sol=fsolve(func, guess) 
print sol, func(sol) 

Dla mnie powyższy kod zbiegnie się tam, gdzie powinien.

Również w podanym kodzie --- co to są c_str i V_0? Jeśli w istocie czynność zależy od więcej niż jednej zmiennej, a ty traktujesz ich wszystkich, ale jeden jako stałe parametry, a następnie użyć args argument fsolve coś takiego:

#!/usr/bin/python 
from scipy.optimize import fsolve 
from numpy import sqrt 

def func(E,V_0): 
    #s = sqrt(c_sqr * (1 - E/V_0)) 
    #f = s/tan(s) + sqrt(c_sqr - s**2) 
    f = E**2 -V_0 
    return f 

VV=4. 
guess = 9 
sol=fsolve(func, guess, args=(VV)) 

print sol, func(sol,VV) 
Powiązane problemy