Bell numbers
#include <flint/arith.h>Set the result to the Bell number . The default version uses a table for (64-bit), the Bell triangle in fixed-size multiword arithmetic for , Dobiński's formula for and the multimodular algorithm above.
The dobinski version computes and for and returns , an exact form of Dobiński's formula [Dob1877] without floating-point arithmetic. Powers of even are obtained from those of odd by shifts.
The multi_mod version computes modulo primes of bits with the sum used by arith_bell_number_nmod, in Montgomery arithmetic and with powers for composite obtained as products from a divisor table, and combines the residues by Chinese remaindering. The number of primes is determined by arith_bell_number_size. The primes are processed in parallel with the threads set by flint_set_num_threads.
Set to . The recursive version uses the Bell triangle (Aitken's array), with additions of numbers of bits; the multi_mod version computes the vector modulo word-size primes with arith_bell_number_nmod_vec and combines them by Chinese remaindering, in . The default version uses the recursive algorithm for .
Returns modulo the modulus of mod, which can be any integer .
Small are read from the table, and the moduli 2 and 3 use the periods 3 and 13 of the sequence. If is less than the modulus and is invertible, the function evaluates
with the factorials scaled by so that the main loop only multiplies, the powers of composite numbers sieved from those of their factors, and the sum accumulated in three words; this costs multiplications and memory. Otherwise it computes with arith_bell_number_nmod_vec (and throws if ).
Set to modulo the modulus of mod.
The recursive version uses the Bell triangle, with additions. The ogf version expands the ordinary generating function
truncated to length , with the partial sums computed by binary splitting as a fraction and one power series division, in . The series version computes as a power series and multiplies by factorials, in ; it requires to be invertible modulo the modulus and returns 0 (with unspecified) if it is not, 1 on success. The recursive and ogf versions work for any modulus. The default version uses the recursive algorithm for , the series version if the modulus is at least and it succeeds, the recursive algorithm for where is the bit size of the modulus, and the ogf version otherwise.
Returns such that , from de Bruijn's asymptotic expansion of [deB1958] with a margin. The bound is verified for but not proved in general; an earlier version used the weaker bound of [BerTas2010].
The Bell number is the number of partitions of a set of elements: In terms of Stirling numbers of the second kind, , and the exponential generating function is [Comtet1974]. The numbers grow slightly slower than : , 6403 bits for .
The module computes an isolated (arith_bell_number), the vector (arith_bell_number_vec), and the same modulo a word-size integer (arith_bell_number_nmod, arith_bell_number_nmod_vec), which is much cheaper when only the residue is needed.
Isolated values#
arith_bell_number reads from a table for (64-bit), runs the Bell triangle in fixed-size arrays of up to three words for , uses Dobiński's formula
for , in an exact form without floating-point arithmetic (arith_bell_number_dobinski), and the multimodular algorithm above (arith_bell_number_multi_mod). The latter computes modulo primes of bits with the identity
which needs multiplications modulo per prime, and combines the residues by Chinese remaindering; the primes are processed in parallel by the threads of flint_set_num_threads. About primes are needed, so the residues cost bit operations.
Vectors#
The Bell triangle (Aitken's array) computes with additions: each row starts with the last entry of the previous row, and each further entry is the sum of its left neighbour and the entry above it; the rows start with the Bell numbers. Over this costs bit operations and is used for ; for longer vectors arith_bell_number_vec_multi_mod computes the vector modulo word-size primes and reconstructs each entry with only as many primes as it needs.
Modulo , arith_bell_number_nmod_vec chooses between three methods: the triangle ( operations, any , used for ), the power series ( operations, requires to be invertible modulo , so in particular for prime ), and the ordinary generating function
summed by binary splitting ( operations, any ).
Example#
The program prints the first Bell numbers, the size of , and checks arith_bell_number_nmod against the residue of the exact value for the prime (where the series method applies) and for the modulus (where it does not).
#include <flint/flint.h>
#include <flint/fmpz.h>
#include <flint/fmpz_vec.h>
#include <flint/nmod.h>
#include <flint/arith.h>
int main(void)
{
fmpz * b;
fmpz_t B;
nmod_t mod;
slong i;
b = _fmpz_vec_init(10);
arith_bell_number_vec(b, 10);
flint_printf("B_0..B_9:");
for (i = 0; i < 10; i++)
{
flint_printf(" ");
fmpz_print(b + i);
}
flint_printf("\n");
fmpz_init(B);
arith_bell_number(B, 1000);
flint_printf("B_1000 has %wu bits\n", fmpz_bits(B));
nmod_init(&mod, 1000000007);
flint_printf("mod 10^9+7: %wu %wu\n",
arith_bell_number_nmod(1000, mod), fmpz_fdiv_ui(B, mod.n));
nmod_init(&mod, 1024);
flint_printf("mod 1024: %wu %wu\n",
arith_bell_number_nmod(1000, mod), fmpz_fdiv_ui(B, mod.n));
fmpz_clear(B);
_fmpz_vec_clear(b, 10);
return 0;
}B_0..B_9: 1 1 2 5 15 52 203 877 4140 21147 B_1000 has 6403 bits mod 10^9+7: 465231251 465231251 mod 1024: 443 443
References#
- [Dob1877] G. Dobiński, "Summirung der Reihe für ", Archiv der Mathematik und Physik 61 (1877), 333–336.
- [deB1958] N. G. de Bruijn, Asymptotic Methods in Analysis, North-Holland, 1958 (§6.2: Bell numbers).
- [BerTas2010] D. Berend and T. Tassa : Improved bounds on Bell numbers and on moments of sums of random variables, Probability and Mathematical Statistics vol. 30 (2010) 185–205
- [Comtet1974] L. Comtet, Advanced Combinatorics: The Art of Finite and Infinite Expansions, D. Reidel, 1974.
The FLINT team, “Bell numbers (arith.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/arith/bell.html (generated 2026-11-02).
@misc{flint-doc-arith-bell,
author = {{The FLINT team}},
title = {{Bell numbers (arith.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/arith/bell.html},
note = {Generated 2026-11-02}
}