2012-04-13 15 views
9

Pythonで関数の最大値を見つけるにはどうすればよいですか?私はデリバティブ関数を一緒にハックしようとすると、そのゼロを見つけることができますが、numpy(または他のライブラリ)のメソッドは私のためにそれを行うことができますか?関数の最大値を見つける

+0

ゴールデンセクション検索をご覧ください。 http://en.wikipedia.org/wiki/Golden_section_search – wberry

+0

@EMSこれは一般的に私が行うことですが、私は常にそうではありません。あなたは人々にいくつかの時間を与える必要があります:P –

+0

申し訳ありませんが、私はpersnicketyを聞くことを意味しませんでした。多くは受け入れられないので、私は一般的にその特定の質問に答えたことを忘れる前に〜1日後のようなリマインダーノートを書く。 – ely

答えて

15

scipy.optimize.fminは、機能のネガティブに使用できます。

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

しかし、ここでは数値解析の問題に本当に注意する必要があることに注意してください。誰かが「私がライブラリでこれをどうやって解決できますか?」と言うと、間違ったエラーが出ることがよくあります。 *あなたが本当にライブラリ関数が何をしているのか理解していることを確認してください。たとえあなたが長い間数値作業を行っていたとしてもそうです。私は最近、 'scipy.stats'で[類似の問題](http://stackoverflow.com/questions/10038543/tracking-down-the-assumptions-made-by-scipys-ttest-ind-function)に苦しんでいました。 – ely

+0

無関係の質問には申し訳ありませんが、ラムダ式にゼロがあるのはなぜですか? – user1700890

+1

ゼロは 'lambda'の一部ではありません。 'lambda 'は、カンマ区切りの値のシーケンスを返すことによって暗黙的に' tuple'を返すことはできません。通常のPython関数ができる方法です。この場合、コンマは 'scipy.optimize.fmin'の引数リストの一部です。したがって、最初の引数は' lambda x:-f(x) 'で、2番目の引数はすべて' 0'です。 – ely

1

SymPyを試すことができます。 symPyは派生物を象徴的に提供し、ゼロを見つけることができるかもしれません。

5

あなたの機能が解析的に解決できる場合は、SymPyを試してみてください。上記のEMSの例を使用します。もちろん

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] 

、あなたはまだ1がマキシマイザーはなく、私がscipy.optimize.minimize_scalarscipy.optimize.minimizeはあなたにアクセス権を与える今の好適な方法、あると思います

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

の最小化であることを確認する必要があります技術の範囲、例えばパラメータを持つ関数の0と1

0

最大値の間になければならない単一変数関数の

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

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) 
関連する問題