Я хочу рассчитать полиномиальный коэффициент:
где это удовлетворено 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), используйте логарифм гамма-функции и используйте сложения вместо умножения, вычитания вместо деления".
Первое решение кажется очень медленным, поэтому я попробовал второй вариант:
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
напрямую. - person Luis Mendo   schedule 10.03.2014