2017-10-13 5 views
0

私は、Pythonの別の関数から変数を返す関数を書こうとしています。Excelソルバーのようなものです。Pythonを使って変数を返します。

私の例を簡略化するために、関数にいくつかの変数をとり、価格を計算します。実際の値(a、b、c、d、x)をこの関数に渡して数値を返すようにします。

def calc_price(a,b,c,d,x): 
    value = a+b*c-d + x 
    return value 

今、私は目標価格aとbとcとdを与えられました。変数xは未知数だけですので、変数xを解くことができます。 calc_priceと同じ変数にtarget_priceという変数を追加する関数にこれを組み込みたいと思います。

def solve(target_price, a,b,c,d): 
    #this function takes in values for target_price, a,b,c,d 
    #and should do something like this: 
    target_price = calc_price(a,b,c,d,x) 
    solve for x <---------this is the part I'm not sure how to do 
    return x 

私はループによって値xを解くバックアップするには、以下のように機能を作成したが、それは大規模なデータセットを計算するので、私は、より効率的なソリューションを探している中で、非効率的です。

def solve(target_price,a,b,c,d): 
    x = 0.01 
    while x < 1: 
     if abs(target_price - calc_price(a,b,c,d,x)) < 0.001: 
      return x 
     x += 0.001 

ありがとうございます!

+1

[scipy.optimize.minimize_scalar](https://docs.scipy.org/doc/scipy-0.19.1/reference/generated /scipy.optimize.minimize_scalar.html)。それは金の基準になります(数値的方法では、他の世界のコンピュータ代数システムを参照する必要はありません)。それがあまりにも重いコード/ lib依存関係の場合:root-findingとcoを参照してください。 – sascha

+1

@サシャ、「ゴールデン」の標準を意味していません:-) https://docs.scipy.org/doc/scipy-0.19.1/reference/optimize.minimize_scalar-golden.html –

+0

かなりいいスチュアート。しかし、私はブレントを使用しています(少なくとも、誰かが私のためにそれを実装していれば): – sascha

答えて

0

これはデモを検討してください(あなたの仕事はまだわかりません)。scipy's docsを必ず読んで、これらのメソッドが提供する基本的な保証について学んでください。

root-findingに基づく手法がより適切であると主張することができます(ここでは関数を最小限に抑えているため、残余関数のabs構造)が、ここではブラケットを使用する必要はありません。間隔。

コード:

import numpy as np 
from scipy.optimize import minimize_scalar 
np.random.seed(0) 

""" Utils """ 
def calc_price(x, a, b, c, d): 
    value = a+b*c-d + x 
    return value 

def calc_price_res(x, target, a, b, c, d): 
    value = a+b*c-d + x 
    return abs(value - target) # we are looking for f(x) == 0 

""" Create fake-data (typically the job of OP!) """ 
a, b, c, d, x = np.random.random(size=5) 
fake_target = calc_price(x, a, b, c, d) 

print('a, b, c, d: ', a, b, c, d) 
print('real x: ', x) 
print('target: ', fake_target) 
print('noisy obj (just to be sure): ', calc_price_res(x, fake_target, a, b, c, d)) 

""" Solve """ 
res = minimize_scalar(calc_price_res, args=(fake_target, a, b, c, d)) 

print('optimized x: ', res.x) 
print('optimized fun: ', res.fun) 

出力:

a, b, c, d: 0.548813503927 0.715189366372 0.602763376072 0.544883182997 
real x: 0.423654799339 
target: 0.858675077275 
noisy obj (just to be sure): 0.0 
optimized x: 0.423654796297 
optimized fun: 3.04165614917e-09 
+1

これは私が探していたものです。私はどのように他の変数を渡すかはわかりませんでしたが、この例では非常に明確でした!このminim_scalar関数も、私の元の関数よりもはるかに高速です。 – jingz

関連する問題