2012-04-13 20 views
9

Come trovo il massimo di una funzione in Python? Potrei provare a hackerare una funzione derivata e trovare lo zero di quello, ma c'è un metodo in numpy (o altra libreria) che può farlo per me?Trovare il massimo di una funzione

+0

Cerca nella sezione aurea. http://en.wikipedia.org/wiki/Golden_section_search – wberry

+0

@EMS è generalmente quello che faccio, ma non sono sempre su SO. Devi dare un po 'di tempo alle persone: P –

+0

Scusa, non volevo sembrare perspicace. Molte cose non sono accettate, quindi in genere scrivo un promemoria come ~ 1 giorno dopo, prima di dimenticare che ho persino risposto a quella domanda specifica. – ely

risposta

15

È possibile utilizzare scipy.optimize.fmin sul negativo della propria funzione.

def f(x): return -2 * x**2 + 4 * x 
max_x = scipy.optimize.fmin(lambda x: -f(x), 0) 
# array([ 1.]) 
+7

Ma tieni presente che devi davvero prestare attenzione ai problemi di analisi numerica qui. Spesso è una bandiera rossa di errore imminente quando qualcuno dice "come può una biblioteca risolvere questo per me?" Assicurati che * tu * capisca veramente cosa sta facendo la funzione della libreria. Questo è vero anche se hai fatto lavori numerici per molto tempo. Recentemente ho sofferto di un [problema simile] (http://stackoverflow.com/questions/10038543/tracking-down-the-assumptions-made-by-scipys-ttest-ind-function) con 'scipy.stats'. – ely

+0

Mi dispiace per la domanda non correlata, ma perché c'è zero nell'espressione lambda? – user1700890

+1

Lo zero non fa parte del 'lambda'. Un 'lambda' non può restituire implicitamente una' tupla' restituendo una sequenza di valori separati da virgole, come può fare una normale funzione Python. In questo caso, la virgola fa parte dell'elenco degli argomenti a 'scipy.optimize.fmin', quindi l'intero primo argomento è' lambda x: -f (x) 'e l'intero secondo argomento è' 0'. – ely

1

Si potrebbe provare SymPy. SymPy potrebbe essere in grado di fornire la derivata simbolicamente, trovare i suoi zeri e così via.

5

Se la funzione è risolvibile in modo analitico, provare SymPy. Userò l'esempio di EMS sopra.

In [1]: from sympy import * 
In [2]: x = Symbol('x', real=True) 

In [3]: f = -2 * x**2 + 4*x 

In [4]: fprime = f.diff(x) 
In [5]: fprime 
Out[5]: -4*x + 4 

In [6]: solve(fprime, x) # solve fprime = 0 with respect to x 
Out[6]: [1] 

Naturalmente, sarà ancora bisogno di controllare che 1 è un Maximizer e non un punto di minimo di f

In [7]: f.diff(x).diff(x) < 0 
Out[7]: True 
1

Penso scipy.optimize.minimize_scalar e scipy.optimize.minimize sono i modi preferiti ora, che vi darà l'accesso alla gamma di tecniche, ad es

solution = scipy.optimize.minimize_scalar(lambda x: -f(x), bounds=[0,1], method='bounded') 

per una singola funzione variabile che deve essere compreso tra 0 e 1.

0

massimo di una funzione con parametri.

import scipy.optimize as opt 

def get_function_max(f, *args): 
    """ 
    >>> round(get_function_max(lambda x, *a: 3.0-2.0*(x**2)), 2) 
    3.0 

    >>> round(get_function_max(lambda x, *a: 3.0-2.0*(x**2)-2.0*x), 2) 
    3.5 

    >>> round(get_function_max(lambda x, *a: a[0]-a[1]*(x**2)-a[1]*x, 3.0, 2.0), 2) 
    3.5 
    """ 
    def func(x, *arg): 
     return -f(x, *arg) 
    return f(opt.fmin(func, 0, args=args, disp=False)[0], *args) 
Problemi correlati