2012-05-09 8 views
1

私は、MATLABを使用してかなり醜い積分を計算しようとしています。私が問題を抱えているのは、非常に大きな数字(> 10^300)に非常に小さな数字(< 10^-300)を乗算する部分です。 MATLABは、0〜0.0005の範囲内でなければならないのに、このために 'inf'を返します。これは私が持っているものである 多数の小さな数値での乗算

besselFunction = @(u)besseli(qb,2*sqrt(lambda*(theta + mu)).*u); 
    exponentFuncion = @(u)exp(-u.*(lambda + theta + mu)); 

QB = 5は、ラムダ= 12、シータ= 10、ムー= 3そして、私が見つけたいが、Uのすべての実数値に対して

besselFunction(u)*exponentFunction(u) 

ある

。問題は、u> 28のときはいつでも 'inf'として評価されるということです。私は聞いたことがあり、MATLAB関数 'vpa'を使用しようとしましたが、関数を使用したいときにはうまく動作しないようです...

この時点で、どんなヒントもありがとうございます!

答えて

5

私は対数を使用します。

x = Bessel function of uy = x*exp(-u)(あなたの方程式よりも簡単ですが、それに似ています)。 log(v*w) = log(v) + log(w)以来

、その後、log(y) = log(x) + log(exp(-u))

これはこれは、より良い数値的に振る舞うことになる

log(y) = log(x) - u 

に簡素化します。

もう1つのキーはになりません。は、大量になり、ログを取得するために数学関数に渡すベッセル関数を評価します。自分自身でBessel関数の対数を直接返す方がよいでしょう。 AbramowitzとStegunのような参考文献を見て試してみてください。

+0

これは実際にそれを行う最もスマートな方法です!ありがとう!私の必要性のために、より大きい数字を扱うことができる象徴的なエンジンを使用するのに十分であった。これは私のやり方です: besselFunction = @(u)besseli(qb、2 * sqrt(lambda *(theta + mu))。* sym(u)); exponentFuncion = @(u)exp(-sym(u)。*(lambda + theta + mu)); Then besselFunction(u)* exponentFunction(u) は記号値を返します。倍精度表現が必要な場合はdouble()を使用できます。 – Groot

0

統合を行う場合は、代わりにGauss–Laguerre quadratureを使用することを検討してください。基本的な考え方は、形式exp(-x)*f(x)の方程式の場合、0からinfまでの積分はsum(w(X).*f(X))と近似できます。ここで、Xの値はラゲール多項式の零点であり、W(X)の値は特定の重みです(ウィキペディアの記事を参照)。非常に高度なシンプソンのルールのような並べ替え。あなたの方程式はすでにexp(-x)の部分を持っているので、特に適しています。

多項式の根を見つけるには、MATLAB CentralにLaguerrePolyという関数があります。そこから重みを計算するのは簡単です。