2016-12-10 19 views
1

割り当ての場合、範囲関数F(X)は、aからbまでの範囲、[a,b]の範囲内にあります。aからbの範囲の関数の範囲を見つける

微積分を使用すると、これほど難しくありません。私はこれを基底とし、その部分を見つけ出し、次のようにコードの特定の部分に到達しました。

注:私はf = x**2をテスト用に使用しています。

問題がある
def integrate(a,b,tolerance_level): 
    firsttrapezoid = simpleIntegrate(a,b) 
    secondtrapezoid = simpleIntegrate(a,b/2) + simpleIntegrate(b/2,b) 
    error_range = abs(firsttrapezoid - secondtrapezoid) 
    if error_range < tolerance_level: 
     return secondtrapezoid 
    else: 
     return integrate(a, b/2, tolerance_level/2) + integrate(b/2, b, tolerance_level/2) 

def simpleIntegrate(a,b): 
    return (b-a)*(f(a)+f(b))/2 

def f(x): 
    f = x**2 
    return f 

result = integrate(0,5,0.0001) 

print(result) 

は、私は41前後の値を取得する必要がありますが、私が得る値は44

+0

[a、b]の間隔を2つの小さな間隔に分割する方法を確認します。中点の計算方法を具体的にチェックしてください。より明確な見方をするには:[0、5]の例から始めないでください。例題[1、5]から始めましょう。 – joanolo

+0

@joanolo私は与えられた入力例の1つであるので[0,5]を使用していましたが、試してみます。 – tokyolerd

+2

=>あなたの中点はわずか5/2です。しかし、あなたが[1、5]で作業するなら...あなたの中点は... – joanolo

答えて

1

周り(a+b)/2

def integrate(a, b, tolerance_level): 
    firsttrapezoid = simpleIntegrate(a, b) 
    secondtrapezoid = simpleIntegrate(a, (a + b)/2) + simpleIntegrate((a + b)/2, b) 
    error_range = abs(firsttrapezoid - secondtrapezoid) 
    if error_range <= tolerance_level: 
     return secondtrapezoid 
    else: 
     return integrate(a, (a + b)/2, tolerance_level/2) + integrate((a + b)/2, b, tolerance_level/2) 


def simpleIntegrate(a, b): 
    return (b - a) * (f(a) + f(b))/2 


def f(x): 
    f = x ** 2 
    return f 


def intf(x): 
    int_f = (x ** 3)/3 
    return int_f 


a = 0 
b = 5 
tolerance = 0.0001 
result = integrate(a, b, tolerance) 
exactly = intf(b) - intf(a) 
error = abs(exactly-result) 
print("aprox: {approx} exactly: {exactly} error:{error} max error:{max_error}" 
     .format(approx=result, exactly=exactly, error=error, max_error=tolerance)) 
であり、bの間の中間点に変更 b/2です

出力:

aprox: 41.66668653488159 exactly: 41.666666666666664 error:1.9868214927498684e-05 max error:0.0001 
0

@eyllanesc(だけでなく、@joanolo)がエラーを指摘しています中点計算では

他の二つの発言:

1)機能のグローバル名とfでハード配線が悪いデザインです。人が1つの計算の一部として2つ以上の関数を統合したい場合はどうなりますか?あなたのアプローチは、彼らが繰り返し不便かもしれないfを繰り返し定義するように強制するでしょう。代わりに、私はsimpleIntegrateに類似の変更、およびintegrateまたはsimpleIntegrateのいずれかが呼び出されるラインに作られた適切な調整を

def integrate(f, a, b, tolerance_level): 

def integrate(a, b, tolerance_level): 

を変更することをお勧めします。結果として得られる関数はより柔軟になります。とりわけ、関数を統合して無名関数として渡すことができます。

2)実装しているアルゴリズムは、大部分の積分では機能しますが、一部のアルゴリズムでは劇的に失敗します。私は上記のお勧めの調整を行った後、

>>> def f(x): return 150*x*(1-x)*(x+1)**2 
>>> integrate(f,-1,1,0.001) 
0.0 

しかし、その答えは、関数は、エンドポイントで中間点で同じ値をとるという理由だけで、関数が一定であるということにはならない40の周りでなければなりません実際にはこのアルゴリズムはそうであると仮定します。一方、あなたのアルゴリズムがほとんどの関数とほとんどの区間で動作するので、それを実装するように言われたらあまり心配しません。

+0

フィードバックのために本当にありがとう。 私の関数 "integrate()"は完全な信用を受け取るために再帰的であると言われましたが、私はこの代入のために数学モジュールを使用するはずがないと信じています – tokyolerd

+0

私はちょうど私が私は単純な積分を解くことだけを試みていると仮定します – tokyolerd

+0

数学のインポートはここにもそこにもありません。同じように動作する多項式を見つけることができました。あなたの 'integrate'は'(a、f(a)) '、'(m、f(m)) '、'(b、f(b)) 'がいつも 'simpleIntegrate'を返すという性質を持っています。共線(ここで 'm =(a + b)/ 2')。そのような関数が線形であると仮定していると思われます。そうである必要はありません。 –

関連する問題