我想要计算多项式系数:
在满足条件 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情况:"利用阶乘(n) = gamma(n+1)这个事实,使用伽玛函数的对数,使用加法而不是乘法,使用减法而不是除法"。
第一个解决方案似乎非常慢,因此我尝试了第二个选项:
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_(:)));
然而,对于某些情况,结果略有不同,如下直方图所示。 因此,我应该假设我的实现是正确的,还是数值误差不足以证明数字发散?
gammaln
。 - Luis Mendo