Karim Belabas on Sun, 27 Nov 2022 10:59:47 +0100
|
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: binomial() challenge (+thanks)
|
- To: "Ruud H.G. van Tol" <ruud.vantol@booking.com>
- Subject: Re: binomial() challenge (+thanks)
- From: Karim Belabas <Karim.Belabas@math.u-bordeaux.fr>
- Date: Sun, 27 Nov 2022 10:58:41 +0100
- Arc-authentication-results: i=1; smail; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; d=math.u-bordeaux.fr; s=openarc; t=1669543120; c=relaxed/relaxed; bh=hFFQSRenfOXx8oZIFrJxX+RD6hkWWYRAKOb1cYE4B+k=; h=DKIM-Signature:Date:From:To:Cc:Subject:Message-ID: Mail-Followup-To:References:MIME-Version:Content-Type: Content-Disposition:Content-Transfer-Encoding:In-Reply-To; b=twPpGm/ccn650I3GSNZ13dQIV+EIpcLIdNsnRekuQe8O4mvqaVXjmj5eQgYgF4IQoUNmnj+0WTA19mKUveWZgO2YXp1MiCmOdJm+74X9XqnlaDiHKLMmVgo9HSMJJFRz4aAk0SdHxcaNGQ4kfjqzm09qC4+pX7CHcGtfbqCwBONMziDv35wBrA1C85EfyyrG6JrMVIm8/tdztxoadegUuwM8ON4JXB+q/zeM4bvEz76uZMrL+HyAwAzQYGAZxhcWU9XwunYq2AkhR+X3Gne8Vo0yRFtu/w5PmRrmaX20Lj0rMyEK85Et+1bZvBBefMthLJmqvtCAZASJn4xU6maBZzmtIveBDv4ul9TL85pk10k0VfjFupw2ZMm9C5zzRFihSw8ysF4N+ps24VFTjEFpQ3sRYjI+45JAQ7LrXY8VaDLeUUOUVOaG73WpfNXzb+XX9XnoIpwOSgreFvIywZAA0ZUZhmLELSnnR0UapH4V3zoL30cZIEpwpwBubMxE7tzpEfY33QbQFuLB0jDFD7rol53K9iyr5Hg1cqT7ItVNCrTeW915yfF9V+7kqq0iu4bkkWXS5osgJntk1A6ufFtPMfiB9E85GrRjqrmLptYGjb657506Qf6195EqR5hu1qHXm+xkrFi/YTVs+XwWijvsWVZVfC+a2vNpboMVja7ikLk=
- Arc-seal: i=1; a=rsa-sha256; d=math.u-bordeaux.fr; s=openarc; t=1669543120; cv=none; b=hA02jQ/jn/en46PBDgBYWaAe5h5xZXNwCUn9JbXmS/Fku1ZNH73MwYrxikf4MsibL84hrEIi1ZcXQF++LJ0CEbjvOCyg6Zk39lMNMkRU3PpAzk9D7qDFWWbDNxjsnIJ+r7NdfEPGRevOruvHcbFpciaTk2vN6cd3c9nnU0+bH4ROCiYM2UdEgc91T/KB9Q5m2ByeQ+9k0QeiDr1BLr7DQOQRmpGjtJfnM//Oz8iHm73ngSvMuoszzDmpScH/VVPh9qJJEph72C6oFoMgKna3BVisHtqZZ9LtjLfllcM4LgmM1+x3+VIEMvgIuo/0U6DY33dK4neYnqxdi05RmkPyahnkopkZau2KrDi65RWn29SQWenbrP7X+R5F9NPYXXGz7Xg2exMWaatflPn/gEX8Ghk45CPHmn3jVwTXSwVnepE1GOzkjRZcZrtYYu5TY3VIbYd6uIQYuG1dJNj0Wl/QtZloW//VCPZMyb0q1VdKviUc4cCsNg9mmsx8lf6zmgKjgNTN0GuhmhGWZSMI8BaQxmvbhLCzXKtA7xsKShIpc1FV0qTKAzqY3EOifNTxzFaku57iXejBpejxcj6SGox+7fu8KecBZyEhZsptAZ5ZmRROWSJ1kIf/GvJG3c6nUnP3RfDjFikKnHb86u26/Fm1u7hFBi6l6eNOO02ZggXaD64=
- Authentication-results: smail; dmarc=none header.from=math.u-bordeaux.fr
- Authentication-results: smail; arc=none
- Cc: pari-users@pari.math.u-bordeaux.fr
- Delivery-date: Sun, 27 Nov 2022 10:59:47 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=math.u-bordeaux.fr; s=2022; t=1669543120; bh=hFFQSRenfOXx8oZIFrJxX+RD6hkWWYRAKOb1cYE4B+k=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=D5Al/B80ZYokUpIrPl9KifZ4hYJV66TnAupQGksuJNO8ap9AeFcxNmDlZ3YJWS1Gw obDNa1A+LThzfumiH7mtvmuz+dfjkKT8WdYhs3YBB9gPZOjovmT+cvcNv4A8n377R1 dhE25YwKYfC/w9JhrSFgzJa9GjBTj/0Fguc1k8+kPMgDWoY4qVE8rJbkt7vAZQ6UA8 NNkg2nXbju07VTnXOBZQYFLQWQF7C+TIBL5KqT8URmNb9L4ZAOFKWTU5YPFU6VpBWv /pycyvOKbc+Iclg8+oNS/BnOdU6yqLSBZyMcZrcjAziXyLR4Ott7kBxTcrG99TR6dU joSnTbjl0BSYhGIOtXRC1VtcLAwPNPZ199XsAAckpk1aKvah4Uz2EWYJNo9hi6hppq W5fXJDNfYG9uBsCAgdTP7rXIwg0OfyuZDLxB++rhbk+54wrSpBvO5pgA7OpRr7wgHT KT1ld83/9R20fk9O7f6r2IAz1QvZWUYUtHx+YfyuRqzSy7+YQJWXkVkXjjG6kj1Z/E sX0/Z/mi02tG5u88P7td7Fd8vOKYAeyAUydICLEi87isPNwhGpxZkGohKOLQzQ/03B Hvx+UhG735uGlMfO8wBI9DoW/NXEcqMNoQjAYswy7Q4CniSPUI283PyBrzq4+mHqoU D8PH9w/yaKjCafKWuWsLG0V0=
- In-reply-to: <d539899a-8938-387b-0b14-b1f79dd380c7@booking.com>
- Mail-followup-to: "Ruud H.G. van Tol" <ruud.vantol@booking.com>, pari-users@pari.math.u-bordeaux.fr
- References: <d539899a-8938-387b-0b14-b1f79dd380c7@booking.com>
* Ruud H.G. van Tol [2022-11-26 13:17]:
> PARI binomial() challenge:
>
> binom_1(n,k) = gamma(n+1) / gamma(k+1) / gamma(n-k+1)
> binom_2(n,k) = exp(lngamma(n+1) - lngamma(k+1) - lngamma(n-k+1))
[...]
> ? 1.0* binomial(10^40,43)
> %16 = 1.6552108677421951886982956337138493958 E1667
>
> ? 1.0* binom_2(10^40,43)
> %17 = 7.416480782428988905 E1778
This is expected of course: since n is huge and k small, we have n+1 ~ n-k+1
and the subtraction lngamma(n+1) - lngamma(n-k+1) suffers from massive
cancellation.
(10:44) gp > n=10^40;k=43
%1 = 43
(10:44) gp > lngamma(n+1) - lngamma(n-k+1)
%2 = 4096.000000000000000
But in fact
(10:44) gp > \p100
realprecision = 115 significant digits (100 digits displayed)
(10:44) gp > lngamma(n+1) - lngamma(n-k+1)
%3 = 3960.446359949758576510945302[...]
So binom_2() is a terrible idea without complicated counter-measures. On the
other hand, binom_1() is fine since divisions do not cause cancellation.
Actually, gamma(n+1) / (gamma(k+1) * gamma(n-k+1)) would be just as stable
and marginally faster (you may use factorial(), as Bill suggested).
> So it looks to me, that always using binomial(), so never even
> consider using an alternative, is simply the right way.
Not quite. :-)
binomial(n,k) is exact, so very wasteful if only a floating point
approximation is required. The underlying algorithm (when n fits into an
unsigned long) actually computes the factorisation of the result using
Lucas's formula for the valuation at each prime. This is then expanded
as an exact (and possibly huge!) integer.
It's not straightforward for a user to re-implement this in GP but it's
easy to adapt the C code so as to return the binomial in factored form
or expand it as a floating point number. Both would be massively more
efficient than binomial(). Lacking applications, I won't do it, but I'm
dropping the comment here in case anybody is interested.
Cheers,
K.B.
--
Karim Belabas / U. Bordeaux, vice-président en charge du Numérique
Institut de Mathématiques de Bordeaux UMR 5251 - (+33) 05 40 00 29 77
http://www.math.u-bordeaux.fr/~kbelabas/
`