malachite_base/num/arithmetic/factorial.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::num::arithmetic::traits::{
10 CheckedDoubleFactorial, CheckedFactorial, CheckedMultifactorial, CheckedSubfactorial,
11 DoubleFactorial, Factorial, Multifactorial, Parity, Subfactorial,
12};
13use crate::num::basic::integers::USIZE_IS_U32;
14use crate::num::basic::unsigneds::PrimitiveUnsigned;
15use crate::num::conversion::traits::WrappingFrom;
16
17pub_test! {checked_multifactorial_naive<T: PrimitiveUnsigned>(n: u64, m: u64) -> Option<T> {
18 assert_ne!(m, 0);
19 let mut f = T::ONE;
20 let mut n = T::try_from(n).ok()?;
21 let m = T::saturating_from(m);
22 while n != T::ZERO {
23 f = f.checked_mul(n)?;
24 n.saturating_sub_assign(m);
25 }
26 Some(f)
27}}
28
29const FACTORIALS_U8: [u8; 6] = [1, 1, 2, 6, 24, 120];
30const FACTORIALS_U16: [u16; 9] = [1, 1, 2, 6, 24, 120, 720, 5040, 40320];
31const FACTORIALS_U32: [u32; 13] =
32 [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600];
33const FACTORIALS_U64: [u64; 21] = [
34 1,
35 1,
36 2,
37 6,
38 24,
39 120,
40 720,
41 5040,
42 40320,
43 362880,
44 3628800,
45 39916800,
46 479001600,
47 6227020800,
48 87178291200,
49 1307674368000,
50 20922789888000,
51 355687428096000,
52 6402373705728000,
53 121645100408832000,
54 2432902008176640000,
55];
56const FACTORIALS_U128: [u128; 35] = [
57 1,
58 1,
59 2,
60 6,
61 24,
62 120,
63 720,
64 5040,
65 40320,
66 362880,
67 3628800,
68 39916800,
69 479001600,
70 6227020800,
71 87178291200,
72 1307674368000,
73 20922789888000,
74 355687428096000,
75 6402373705728000,
76 121645100408832000,
77 2432902008176640000,
78 51090942171709440000,
79 1124000727777607680000,
80 25852016738884976640000,
81 620448401733239439360000,
82 15511210043330985984000000,
83 403291461126605635584000000,
84 10888869450418352160768000000,
85 304888344611713860501504000000,
86 8841761993739701954543616000000,
87 265252859812191058636308480000000,
88 8222838654177922817725562880000000,
89 263130836933693530167218012160000000,
90 8683317618811886495518194401280000000,
91 295232799039604140847618609643520000000,
92];
93
94const ODD_DOUBLE_FACTORIALS_U8: [u8; 4] = [1, 3, 15, 105];
95const ODD_DOUBLE_FACTORIALS_U16: [u16; 6] = [1, 3, 15, 105, 945, 10395];
96const ODD_DOUBLE_FACTORIALS_U32: [u32; 10] =
97 [1, 3, 15, 105, 945, 10395, 135135, 2027025, 34459425, 654729075];
98const ODD_DOUBLE_FACTORIALS_U64: [u64; 17] = [
99 1,
100 3,
101 15,
102 105,
103 945,
104 10395,
105 135135,
106 2027025,
107 34459425,
108 654729075,
109 13749310575,
110 316234143225,
111 7905853580625,
112 213458046676875,
113 6190283353629375,
114 191898783962510625,
115 6332659870762850625,
116];
117const ODD_DOUBLE_FACTORIALS_U128: [u128; 28] = [
118 1,
119 3,
120 15,
121 105,
122 945,
123 10395,
124 135135,
125 2027025,
126 34459425,
127 654729075,
128 13749310575,
129 316234143225,
130 7905853580625,
131 213458046676875,
132 6190283353629375,
133 191898783962510625,
134 6332659870762850625,
135 221643095476699771875,
136 8200794532637891559375,
137 319830986772877770815625,
138 13113070457687988603440625,
139 563862029680583509947946875,
140 25373791335626257947657609375,
141 1192568192774434123539907640625,
142 58435841445947272053455474390625,
143 2980227913743310874726229193921875,
144 157952079428395476360490147277859375,
145 8687364368561751199826958100282265625,
146];
147
148const SUBFACTORIALS_U8: [u8; 6] = [1, 0, 1, 2, 9, 44];
149const SUBFACTORIALS_U16: [u16; 9] = [1, 0, 1, 2, 9, 44, 265, 1854, 14833];
150const SUBFACTORIALS_U32: [u32; 14] =
151 [1, 0, 1, 2, 9, 44, 265, 1854, 14833, 133496, 1334961, 14684570, 176214841, 2290792932];
152const SUBFACTORIALS_U64: [u64; 21] = [
153 1,
154 0,
155 1,
156 2,
157 9,
158 44,
159 265,
160 1854,
161 14833,
162 133496,
163 1334961,
164 14684570,
165 176214841,
166 2290792932,
167 32071101049,
168 481066515734,
169 7697064251745,
170 130850092279664,
171 2355301661033953,
172 44750731559645106,
173 895014631192902121,
174];
175const SUBFACTORIALS_U128: [u128; 35] = [
176 1,
177 0,
178 1,
179 2,
180 9,
181 44,
182 265,
183 1854,
184 14833,
185 133496,
186 1334961,
187 14684570,
188 176214841,
189 2290792932,
190 32071101049,
191 481066515734,
192 7697064251745,
193 130850092279664,
194 2355301661033953,
195 44750731559645106,
196 895014631192902121,
197 18795307255050944540,
198 413496759611120779881,
199 9510425471055777937262,
200 228250211305338670494289,
201 5706255282633466762357224,
202 148362637348470135821287825,
203 4005791208408693667174771274,
204 112162153835443422680893595673,
205 3252702461227859257745914274516,
206 97581073836835777732377428235481,
207 3025013288941909109703700275299910,
208 96800425246141091510518408809597121,
209 3194414033122656019847107490716704992,
210 108610077126170304674801654684367969729,
211];
212
213macro_rules! impl_factorials_a {
214 ($t:ident, $fs:ident, $odfs:ident, $sfs:ident, $df_limit:expr) => {
215 impl CheckedFactorial for $t {
216 /// Computes the factorial of a number.
217 ///
218 /// If the input is too large, the function returns `None`.
219 ///
220 /// $$
221 /// f(n) = \\begin{cases}
222 /// \operatorname{Some}(n!) & \text{if} \\quad n! < 2^W, \\\\
223 /// \operatorname{None} & \text{if} \\quad n! \geq 2^W,
224 /// \\end{cases}
225 /// $$
226 /// where $W$ is `Self::WIDTH`.
227 ///
228 /// $n! = O(\sqrt{n}(n/e)^n)$.
229 ///
230 /// # Worst-case complexity
231 /// Constant time and additional memory.
232 ///
233 /// # Examples
234 /// See [here](super::factorial#checked_factorial).
235 #[inline]
236 fn checked_factorial(n: u64) -> Option<$t> {
237 $fs.get(usize::try_from(n).ok()?).copied()
238 }
239 }
240
241 impl CheckedDoubleFactorial for $t {
242 /// Computes the double factorial of a number.
243 ///
244 /// If the input is too large, the function returns `None`.
245 ///
246 /// $$
247 /// f(n) = \\begin{cases}
248 /// \operatorname{Some}(n!!) & \text{if} \\quad n!! < 2^W, \\\\
249 /// \operatorname{None} & \text{if} \\quad n!! \geq 2^W,
250 /// \\end{cases}
251 /// $$
252 /// where $W$ is `Self::WIDTH`.
253 ///
254 /// $n!! = O(\sqrt{n}(n/e)^{n/2})$.
255 ///
256 /// # Worst-case complexity
257 /// Constant time and additional memory.
258 ///
259 /// # Examples
260 /// See [here](super::factorial#checked_double_factorial).
261 #[inline]
262 fn checked_double_factorial(n: u64) -> Option<$t> {
263 if n > $df_limit {
264 None
265 } else if n.odd() {
266 $odfs.get(usize::try_from(n >> 1).ok()?).copied()
267 } else {
268 let half = n >> 1;
269 $fs.get(usize::try_from(half).ok()?).map(|&f| f << half)
270 }
271 }
272 }
273
274 impl CheckedSubfactorial for $t {
275 /// Computes the subfactorial of a number.
276 ///
277 /// The subfactorial of $n$ counts the number of derangements of a set of size $n$; a
278 /// derangement is a permutation with no fixed points.
279 ///
280 /// If the input is too large, the function returns `None`.
281 ///
282 /// $$
283 /// f(n) = \\begin{cases}
284 /// \operatorname{Some}(!n) & \text{if} \\quad !n < 2^W, \\\\
285 /// \operatorname{None} & \text{if} \\quad !n \geq 2^W,
286 /// \\end{cases}
287 /// $$
288 /// where $W$ is `Self::WIDTH`.
289 ///
290 /// $!n = O(n!) = O(\sqrt{n}(n/e)^n)$.
291 ///
292 /// # Worst-case complexity
293 /// Constant time and additional memory.
294 ///
295 /// # Examples
296 /// See [here](super::factorial#checked_subfactorial).
297 #[inline]
298 fn checked_subfactorial(n: u64) -> Option<$t> {
299 $sfs.get(usize::try_from(n).ok()?).copied()
300 }
301 }
302 };
303}
304impl_factorials_a!(
305 u8,
306 FACTORIALS_U8,
307 ODD_DOUBLE_FACTORIALS_U8,
308 SUBFACTORIALS_U8,
309 7
310);
311impl_factorials_a!(
312 u16,
313 FACTORIALS_U16,
314 ODD_DOUBLE_FACTORIALS_U16,
315 SUBFACTORIALS_U16,
316 12
317);
318impl_factorials_a!(
319 u32,
320 FACTORIALS_U32,
321 ODD_DOUBLE_FACTORIALS_U32,
322 SUBFACTORIALS_U32,
323 20
324);
325impl_factorials_a!(
326 u64,
327 FACTORIALS_U64,
328 ODD_DOUBLE_FACTORIALS_U64,
329 SUBFACTORIALS_U64,
330 33
331);
332impl_factorials_a!(
333 u128,
334 FACTORIALS_U128,
335 ODD_DOUBLE_FACTORIALS_U128,
336 SUBFACTORIALS_U128,
337 56
338);
339
340impl CheckedFactorial for usize {
341 /// Computes the factorial of a [`usize`].
342 ///
343 /// If the input is too large, the function returns `None`.
344 ///
345 /// $$
346 /// f(n) = \\begin{cases}
347 /// \operatorname{Some}(n!) & \text{if} \\quad n! < 2^W, \\\\
348 /// \operatorname{None} & \text{if} \\quad n! \geq 2^W,
349 /// \\end{cases}
350 /// $$
351 /// where $W$ is `usize::WIDTH`.
352 ///
353 /// $n! = O(\sqrt{n}(n/e)^n)$.
354 ///
355 /// # Worst-case complexity
356 /// Constant time and additional memory.
357 ///
358 /// # Examples
359 /// See [here](super::factorial#checked_factorial).
360 #[inline]
361 fn checked_factorial(n: u64) -> Option<usize> {
362 FACTORIALS_U64
363 .get(usize::try_from(n).ok()?)
364 .and_then(|&f| usize::try_from(f).ok())
365 }
366}
367
368impl CheckedSubfactorial for usize {
369 /// Computes the subfactorial of a [`usize`].
370 ///
371 /// The subfactorial of $n$ counts the number of derangements of a set of size $n$; a
372 /// derangement is a permutation with no fixed points.
373 ///
374 /// If the input is too large, the function returns `None`.
375 ///
376 /// $$
377 /// f(n) = \\begin{cases}
378 /// \operatorname{Some}(!n) & \text{if} \\quad !n < 2^W, \\\\
379 /// \operatorname{None} & \text{if} \\quad !n \geq 2^W,
380 /// \\end{cases}
381 /// $$
382 /// where $W$ is `usize::WIDTH`.
383 ///
384 /// $!n = O(n!) = O(\sqrt{n}(n/e)^n)$.
385 ///
386 /// # Worst-case complexity
387 /// Constant time and additional memory.
388 ///
389 /// # Examples
390 /// See [here](super::factorial#checked_subfactorial).
391 #[inline]
392 fn checked_subfactorial(n: u64) -> Option<usize> {
393 SUBFACTORIALS_U64
394 .get(usize::try_from(n).ok()?)
395 .and_then(|&f| usize::try_from(f).ok())
396 }
397}
398
399impl CheckedDoubleFactorial for usize {
400 /// Computes the double factorial of a [`usize`].
401 ///
402 /// If the input is too large, the function returns `None`.
403 ///
404 /// $$
405 /// f(n) = \\begin{cases}
406 /// \operatorname{Some}(n!!) & \text{if} \\quad n!! < 2^W, \\\\
407 /// \operatorname{None} & \text{if} \\quad n!! \geq 2^W,
408 /// \\end{cases}
409 /// $$
410 /// where $W$ is `usize::WIDTH`.
411 ///
412 /// $n!! = O(\sqrt{n}(n/e)^{n/2})$.
413 ///
414 /// # Worst-case complexity
415 /// Constant time and additional memory.
416 ///
417 /// # Examples
418 /// See [here](super::factorial#checked_double_factorial).
419 #[inline]
420 fn checked_double_factorial(n: u64) -> Option<usize> {
421 if USIZE_IS_U32 {
422 u32::checked_double_factorial(n).map(usize::wrapping_from)
423 } else {
424 u64::checked_double_factorial(n).map(usize::wrapping_from)
425 }
426 }
427}
428
429macro_rules! impl_factorials_b {
430 ($t:ident) => {
431 impl Factorial for $t {
432 /// Computes the factorial of a number.
433 ///
434 /// If the input is too large, the function panics. For a function that returns `None`
435 /// instead, try [`checked_factorial`](CheckedFactorial::checked_factorial).
436 ///
437 /// $$
438 /// f(n) = n! = 1 \times 2 \times 3 \times \cdots \times n.
439 /// $$
440 ///
441 /// $n! = O(\sqrt{n}(n/e)^n)$.
442 ///
443 /// # Worst-case complexity
444 /// Constant time and additional memory.
445 ///
446 /// # Panics
447 /// Panics if the output is too large to be represented.
448 ///
449 /// # Examples
450 /// See [here](super::factorial#factorial).
451 #[inline]
452 fn factorial(n: u64) -> $t {
453 $t::checked_factorial(n).unwrap()
454 }
455 }
456
457 impl DoubleFactorial for $t {
458 /// Computes the double factorial of a number.
459 ///
460 /// If the input is too large, the function panics. For a function that returns `None`
461 /// instead, try
462 /// [`checked_double_factorial`](CheckedDoubleFactorial::checked_double_factorial).
463 ///
464 /// $$
465 /// f(n) = n!! = n \times (n - 2) \times (n - 4) \times \cdots \times i,
466 /// $$
467 /// where $i$ is 1 if $n$ is odd and $2$ if $n$ is even.
468 ///
469 /// $n!! = O(\sqrt{n}(n/e)^{n/2})$.
470 ///
471 /// # Worst-case complexity
472 /// Constant time and additional memory.
473 ///
474 /// # Panics
475 /// Panics if the output is too large to be represented.
476 ///
477 /// # Examples
478 /// See [here](super::factorial#double_factorial).
479 #[inline]
480 fn double_factorial(n: u64) -> $t {
481 $t::checked_double_factorial(n).unwrap()
482 }
483 }
484
485 impl Multifactorial for $t {
486 /// Computes a multifactorial of a number.
487 ///
488 /// If the input is too large, the function panics. For a function that returns `None`
489 /// instead, try
490 /// [`checked_multifactorial`](CheckedMultifactorial::checked_multifactorial).
491 ///
492 /// $$
493 /// f(n, m) = n!^{(m)} = n \times (n - m) \times (n - 2m) \times \cdots \times i.
494 /// $$
495 /// If $n$ is divisible by $m$, then $i$ is $m$; otherwise, $i$ is the remainder when
496 /// $n$ is divided by $m$.
497 ///
498 /// $n!^{(m)} = O(\sqrt{n}(n/e)^{n/m})$.
499 ///
500 /// # Worst-case complexity
501 /// Constant time and additional memory.
502 ///
503 /// # Panics
504 /// Panics if the output is too large to be represented.
505 ///
506 /// # Examples
507 /// See [here](super::factorial#multifactorial).
508 #[inline]
509 fn multifactorial(n: u64, m: u64) -> $t {
510 $t::checked_multifactorial(n, m).unwrap()
511 }
512 }
513
514 impl CheckedMultifactorial for $t {
515 /// Computes a multifactorial of a number.
516 ///
517 /// If the input is too large, the function returns `None`.
518 ///
519 /// $$
520 /// f(n, m) = \\begin{cases}
521 /// \operatorname{Some}(n!^{(m)}) & \text{if} \\quad n!^{(m)} < 2^W, \\\\
522 /// \operatorname{None} & \text{if} \\quad n!^{(m)} \geq 2^W,
523 /// \\end{cases}
524 /// $$
525 /// where $W$ is `Self::WIDTH`.
526 ///
527 /// $n!^{(m)} = O(\sqrt{n}(n/e)^{n/m})$.
528 ///
529 /// # Worst-case complexity
530 /// Constant time and additional memory.
531 ///
532 /// # Examples
533 /// See [here](super::factorial#checked_multifactorial).
534 #[inline]
535 fn checked_multifactorial(n: u64, m: u64) -> Option<$t> {
536 assert_ne!(m, 0);
537 if m == 1 {
538 $t::checked_factorial(n)
539 } else if m == 2 {
540 $t::checked_double_factorial(n)
541 } else {
542 checked_multifactorial_naive(n, m)
543 }
544 }
545 }
546
547 impl Subfactorial for $t {
548 /// Computes the subfactorial of a number.
549 ///
550 /// The subfactorial of $n$ counts the number of derangements of a set of size $n$; a
551 /// derangement is a permutation with no fixed points.
552 ///
553 /// If the input is too large, the function panics. For a function that returns `None`
554 /// instead, try [`checked_subfactorial`](CheckedSubfactorial::checked_subfactorial).
555 ///
556 /// $$
557 /// f(n) = \\ !n = \lfloor n!/e \rfloor.
558 /// $$
559 ///
560 /// $!n = O(n!) = O(\sqrt{n}(n/e)^n)$.
561 ///
562 /// # Worst-case complexity
563 /// Constant time and additional memory.
564 ///
565 /// # Panics
566 /// Panics if the output is too large to be represented.
567 ///
568 /// # Examples
569 /// See [here](super::factorial#subfactorial).
570 #[inline]
571 fn subfactorial(n: u64) -> $t {
572 $t::checked_subfactorial(n).unwrap()
573 }
574 }
575 };
576}
577apply_to_unsigneds!(impl_factorials_b);