我想计算多项式系数:
满意的地方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 的情况下:“利用阶乘(n)= gamma(n+1)这一事实,使用 gamma 函数的对数并使用加法而不是乘法,减法而不是除法”。
第一个解决方案似乎非常慢,所以我尝试了第二个选项:
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_(:)));
但是,某些情况下的结果略有不同,如下面的直方图所示。
因此,我应该假设我的实现是正确的还是数字错误不能证明数字分歧是合理的?