多項係数を計算したい:
満たされているところn=n0+n1+n2
この演算子の Matlab 実装は、関数で簡単に実行できます。
function N = nchooseks(k1,k2,k3)
N = factorial(k1+k2+k3)/(factorial(k1)*factorial(k2)*factorial(k3));
end
ただし、インデックスが 170 より大きい場合、階乗は無限になりNaN
、場合によっては生成され180!/(175! 3! 2!) -> Inf/Inf-> NaN
ます。
他の投稿では、 CとPythonのこのオーバーフローの問題を解決しました。
- Cの場合:「すべての階乗からリストを作成し、リスト内のすべての数字の素因数分解を見つけ、数字が完全に削減されるまで、一番上のすべての数字を一番下の数字でキャンセルできます" .
- Python の場合: 「factorial(n) = gamma(n+1) という事実を利用し、ガンマ関数の対数を使用し、乗算の代わりに加算を使用し、除算の代わりに減算を使用します」 .
最初の解決策は非常に遅いように思われるため、2 番目のオプションを試しました。
function N = nchooseks(k1,k2,k3)
N = 10^(log_gamma(k1+k2+k3)-(log_gamma(k1)+log_gamma(k2)+log_gamma(k3)));
end
function y = log_gamma(x), y = log10(gamma(x+1)); end
元の実装と log_gamma の実装を次のコードと比較します。
% Calculate
N=100; err = zeros(N,N,N);
for n1=1:N,
for n2=1:N,
for n3=1:N,
N1 = factorial(n1+n2+n3)/(factorial(n1)*factorial(n2)*factorial(n3));
N2 = 10^(log10(gamma(n1+n2+n3+1))-(log10(gamma(n1+1))+log10(gamma(n2+1))+log10(gamma(n3+1))));
err(n1,n2,n3) = abs(N1-N2);
end
end
end
% Plot histogram of errors
err_ = err(~isnan(err));
[nelements,centers] = hist(err_(:),1e2);
figure; bar(centers,nelements./numel(err_(:)));
ただし、次のヒストグラムに示すように、一部のケースでは結果がわずかに異なります。
したがって、私の実装が正しいと仮定する必要がありますか、それとも数値エラーが数の相違を正当化しないでしょうか?