2016-11-02 23 views
1

私は同じ階乗を何度も何度も計算するコードを最適化しています。呼び出しはいくつかの異なる関数からのものですので、関数の引数としてあらかじめ計算された階乗を配列に渡すことを避けたかったのですが、これが最も速い方法だと思います。matlabで階乗の使用を最適化

グローバル変数を使用する方が効果的ですが、グローバル変数の読み込みがファクタルアルの計算とほぼ同じくらい長くかかるので、それほど高速ではありません。

function [ facn ] = cfactorial(n) 

global facs 

if n > 170 
    facn = Inf; 
elseif n == 0 
    facn = 1; 
else 
    facn = facs(n); 
end 

私はまた永続的に設定しようとしましたが、あまり速くはありません。

function [ facn ] = cfactorial(n) 

persistent facs 

if isempty(facs) 
    load('facs.mat') 
    facs = faccs; 
end 

if n > 170 
    facn = Inf; 
elseif n == 0 
    facn = 1; 
else 
    facn = facs(n); 
end 

どちらの場合も、 "persistent facs"という行が表示されます。 「グローバルなfacs」はプロファイラでほとんどの時間を費やします。

これを行う別の方法はありますか?変数をロードせずにグローバルに利用できるようなものを定義できますか?

+0

をそこからそれらを入手しますか? – mpaskov

+0

それは私がやることです、私はすべての機能の間で配列を共有する効率的な方法を探しています。今のところ、私はその配列を渡す余分な引数を追加しましたが、それは私が避けたかったものです。私はまだ私が知らないよりエレガントで効率的な方法があれば、ほとんど興味があります。 – kili

+0

組み込みのガンマ関数はどうですか? –

答えて

3

可能な限り関数を呼び出したり、if..elseを使用したりしないでください。ベクトル化はより良いアプローチです。あなたはこのよう階乗行列を作ることができます :

f_ns = factorials(min(ns, 171) + 1) ; 
を:

factorials = [1 cumprod(1:170) Inf]; 

あなたはn sの値と階乗5回呼び出す必要があるとしますので、怒鳴るよう階乗を得ることができます

ns = [3 0 56 23 456]; 

です

次に、f_nsの値で計算を続けます。

あなたがf_nsを事前に計算することができない場合は、階乗のみとめ計算を必要とする関数内でインライン関数facnを作成することとfacn複数回呼び出す:あなたはすべての値の配列を事前に計算いけないのはなぜ

function myfunction 
    factorials = [1 cumprod(1:170) Inf]; 
    facn [email protected](n) factorials(min(n, 171) + 1) ; 
    facn(3); 
    facn(0); 
    facn(456); 
end 
+0

if..elseをf_ns = factorials(min(ns、171)+ 1)に置き換えます。良いアイデアのように思える。私は[外部関数](http://massey.dur.ac.uk/jdp/code.html#angmom)を使用していますが、ネストされた関数呼び出しがたくさんあります。使用したい場合はベクトル化するのが難しいですそれら。たぶん私はそれを最適化するためにそれらを書くだろう – kili

関連する問題