Utility functions

Generators

radbm.utils.generators.sorted_merge(*gens, key=<function <lambda>>)

Given n generators that yield in increasing order, this method build a new generator that yield all the generators in increasing order.

Parameters:
  • *gens (sequence of generators) – All generator must yield in increasing order.
  • key (function (optional)) – Used to customize the sort order. Same as the built-in sorted. (default: identity)
Yields:
  • k (int) – The index of the generator that yielded this value
  • v (object) – The current minimal value of all generators.
radbm.utils.generators.smallest_subset_sums(values, yield_sums=False, yield_stats=False)

Generator that yields the subset’s index for a set of values in increasing order of their sum. The values must be all positive.

Parameters:
  • values (numpy.ndarray (ndim: 1)) – The set values from which to take the subsets
  • yield_sums (bool (optional)) – Whether to provide the sum of each subset.
  • yield_stats (bool (optional)) – Whether to provide statistic about the search. If True, the function will also yield the number of swap, the number of comparison and the size of the heap used to generate the subsets. (default: False)
Yields:
  • subset (list of int) – Subset of index of the values in increasing order of their sum.
  • sum (float (if yield_sums is True)) – The sum of the yielded subset.
  • swap_count (int (if yield_stats is True)) – The number of swap done to maintain the heap while generating this subset.
  • comp_count (int (if yield_stats is True)) – The number of comparison done to maintain the heap while generating this subset.
  • heap_size (int (if yield_stats is True)) – The current size of the heap (before adding the children of the yielded subset).
radbm.utils.generators.likeliest_multi_bernoulli_outcomes(log_probs0, log_probs1, yield_log_probs=False, yield_stats=False)

Generator that yields the outcomes of a Multi-Bernoulli in decreasing order of probability. This work by reducing to the problem of generating the subset of a set in increasing order of their sum.

Notes

Bits probability must be in ]0,1[ (i.e. they cannot be zero or one)

Parameters:
  • log_probs0 (numpy.ndarray (ndim: 1)) – Log probabilities for bits to be zero.
  • log_probs1 (numpy.ndarray (ndim: 1)) – Log probabilities for bits to be one.
  • yield_log_probs (bool (optional)) – Whether to provide the log probabilities of each outcome.
  • yield_stats (bool (optional)) – Whether to provide statistic about the search. If True, the function will also yield the number of swap, the number of comparison and the size of the heap used to generate the outcomes. (default: False)
Yields:
  • outcome (numpy.ndarray (dtype: bool)) – The Multi-Bernoulli outcomes in decreasing order of prababilities.
  • log_prob (float (if yield_log_probs is True)) – The log probability of the yielded outcome.
  • swap_count (int (if yield_stats is True)) – The number of swap done to maintain the heap while generating this outcome.
  • comp_count (int (if yield_stats is True)) – The number of comparison done to maintain the heap while generating this outcome.
  • heap_size (int (if yield_stats is True)) – The current size of the heap (before adding the children of the yielded outcome).
Raises:

ValueError – If the probabilities of each bit to be one or zero does not sum to one.

Additional features for numpy

radbm.utils.numpy.function.dihedral4(x, transform='r0')
Parameters:
  • x (numpy.ndarray (ndim: >=2)) – The last 2 dims are interpreted as the y (height) and x (width) axes respectively. The y axis goes from up to bottom while the x axis goes from left to right (as in images).
  • transform (str (optional)) – Should be ‘r0’, ‘r1’, ‘r2’, ‘r3’, ‘sr0’, ‘sr1’, ‘sr2’, ‘sr3’. Where r is a 90 degree rotation and s is the vertical flip. The operations starts at the right e.g. ‘sr2’ means a rotation of 180 degree and then a vertical flip. (default: ‘r0’ the identity i.e. doing nothing)
radbm.utils.numpy.function.log_comb(n, k)

Numerically stable version of numpy.log(scipy.special.comb(n, k))

radbm.utils.numpy.function.numpy_log_sigmoid(x)

Computes -log(1 + exp(-x)) with numerical stability.

radbm.utils.numpy.function.softplus(x)

Numerically stable numpy.log(1 + numpy.exp(x))

radbm.utils.numpy.function.softplusinv(x)

Numerically stable numpy.log(numpy.exp(x) - 1)

Notes

The domain of this function is the strictly positive reals.

radbm.utils.numpy.logical.adjacency_list_to_matrix(adj_list, n=None)
Parameters:
  • adj_list (list of list of int) – j in adj_list[i] indicates a link from i to j.
  • n (int (optinal)) – The number of nodes (default: len(adj_list))
Returns:

adj_matrix – adj_matrix[i, j] is True iff there is a link from i to j.

Return type:

numpy.ndarray (shape: (len(adj), n), dtype: bool)

Notes

The maximal value in adj_list needs to be smaller than n.

radbm.utils.numpy.logical.isrepeat(x)
Parameters:x (numpy.ndarray (shape: (n, k))) –
Returns:z – z[i] is True iif x[i]’s elements are not unique
Return type:numpy.ndarray (shape: (n,), dtype: bool)

Notes

Uses vec_isrepeat if k < 64 and set_isrepeat otherwise.

radbm.utils.numpy.logical.issubset(x, y)
Parameters:
  • x (numpy.ndarray (shape: (n, l))) –
  • y (numpy.ndarray (shape: (n, k))) –
Returns:

z – z[i] is True iif x[i]’s elements are subset of y[i]’s elements.

Return type:

numpy.ndarray (shape: (n,), dtype: bool)

Notes

Uses vec_issubset if l < 128 and set_issubset otherwise.

radbm.utils.numpy.logical.issubset_product_with_set(x, y)
Parameters:
  • x (numpy.ndarray (shape: (n, k))) –
  • y (numpy.ndarray (shape: (n, l))) –
Returns:

issubset – j (int) is in issubset[i] (list) iif set(x[i]).issubset(y[j]).

Return type:

list of list of int

radbm.utils.numpy.logical.issubset_product_with_trie(x, y)
Parameters:
  • x (numpy.ndarray (shape: (n, k))) –
  • y (numpy.ndarray (shape: (n, l))) –
Returns:

issubset – j (int) is in issubset[i] (list) iif set(x[i]).issubset(y[j]).

Return type:

list of list of int

Notes

Instead of doing len(queries)*len(documents) comparisons, this algorithm build a trie containing the queries. This is faster whenever the queries are sparse.

radbm.utils.numpy.logical.set_isrepeat(x)
Parameters:x (numpy.ndarray (shape: (n, k))) –
Returns:z – z[i] is True iif x[i]’s elements are not unique
Return type:numpy.ndarray (shape: (n,), dtype: bool)

Notes

Works in O(n*k). A bit slower when many repeats.

radbm.utils.numpy.logical.set_issubset(x, y)
Parameters:
  • x (numpy.ndarray (shape: (n, l))) –
  • y (numpy.ndarray (shape: (n, k))) –
Returns:

z – z[i] is True iif x[i]’s elements are subset of y[i]’s elements.

Return type:

numpy.ndarray (shape: (n,), dtype: bool)

Notes

Works in O(n*(l+k)).

radbm.utils.numpy.logical.vec_isrepeat(x)
Parameters:x (numpy.ndarray (shape: (n, k))) –
Returns:z – z[i] is True iif x[i]’s elements are not unique
Return type:numpy.ndarray (shape: (n,), dtype: bool)

Notes

Vectorized implementation, works in O(n*k^2). Faster than set_isrepeat if k < 64 since no hashing overhead and maximize numpy usage (vs python loop).

radbm.utils.numpy.logical.vec_issubset(x, y)
Parameters:
  • x (numpy.ndarray (shape: (n, l))) –
  • y (numpy.ndarray (shape: (n, k))) –
Returns:

z – z[i] is True iif x[i]’s elements are subset of y[i]’s elements.

Return type:

numpy.ndarray (shape: (n,), dtype: bool)

Notes

Vectorized implementation, works in O(n*l*k). Faster than set_issubset for l < 128.

radbm.utils.numpy.random.fast_unique_randint(low, high, n, k, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/radbm/envs/develop/lib/python3.7/site-packages/numpy/random/__init__.py'>)

Similar to numpy.random.randint but where each rows have unique elements.

Parameters:
  • low (int) – Lowest (signed) integer to be drawn from the distribution.
  • high (int) – Largest (signed) integer to be drawn from the distribution.
  • n (int) – The (unsigned) number of rows (vectors) with unique elements.
  • k (int) – The (unsigned) size of each rows (vectors).
  • rng (numpy.random.generator.Generator (optional)) – The generator used for sampling. (default: np.random)
Returns:

samples – For all i<n, samples[i,j] == samples[i,k] iif j==k.

Return type:

np.ndarray (shape: (n, k), dtype: int)

Notes

The fastest unique_randint algorithm. Runs in O(n*k) memory and O(n*k) times. However this python implementation (without any vectorization) is quite slow.

radbm.utils.numpy.random.no_subset_unique_randint(low, high, n, l, x, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/radbm/envs/develop/lib/python3.7/site-packages/numpy/random/__init__.py'>)

Similar to numpy.random.randint but where each rows have unique elements. Also, not all elements generated will be in x.

Parameters:
  • low (int) – Lowest (signed) integer to be drawn from the distribution.
  • high (int) – Largest (signed) integer to be drawn from the distribution.
  • n (int) – The (unsigned) number of rows (vectors) with unique elements.
  • l (int) – The (unsigned) size of each rows (vectors).
  • x (numpy.ndarray (shape: (n, k))) – The no subset conditions. See the returned value for more information.
  • rng (numpy.random.generator.Generator (optional)) – The generator used for sampling. (default: np.random)
Returns:

samples – For all i<n, samples[i,j] == samples[i,k] iif j==k. Furthermore, there exists j s.t. samples[i, j] is not present in x[i].

Return type:

np.ndarray (shape: (n, k), dtype: int)

Notes

This implementation is recursive, consequently if the probability of accepting is to low then this will raise a RecursionError. There should be at least one integer inside np.arange(low, high) that is not in x[i] for all i.

radbm.utils.numpy.random.uniform_n_choose_k_by_enumeration(n, k, t, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/radbm/envs/develop/lib/python3.7/site-packages/numpy/random/__init__.py'>)
Parameters:
  • n (int) – The number of elements to choose from.
  • k (int) – The number of elements to choose without replacement.
  • t (int) – The number of distinct vectors of k elements.
  • rng (numpy.random.generator.Generator) – The random number generator used to sample the k-subsets. (default: numpy.random)
Returns:

samples – t unique vectors of k unique integers from 0,…,n-1

Return type:

numpy.ndarray (shape: (t, k))

Raises:

ValueError – When t > comb(n, k).

Notes

This algorithms works in O(comb(n, k)) as it enumerates all possible combination before sampling t from it without replacement.

radbm.utils.numpy.random.uniform_n_choose_k_by_rejection(n, k, t, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/radbm/envs/develop/lib/python3.7/site-packages/numpy/random/__init__.py'>)
Parameters:
  • n (int) – The number of elements to choose from.
  • k (int) – The number of elements to choose without replacement.
  • t (int) – The number of distinct vectors of k elements.
  • rng (numpy.random.generator.Generator) – The random number generator used to sample the k-subsets. (default: numpy.random)
Returns:

samples – t unique vectors of k unique integers from 0,…,n-1

Return type:

numpy.ndarray (shape: (t, k))

Raises:

ValueError – When t > comb(n, k).

Notes

This algorithms is faster than uniform_n_choose_k_by_enumeration whenever t << comb(n, k). Otherwise, uniform_n_choose_k_by_enumeration is preferable.

radbm.utils.numpy.random.unique_randint(low, high, n, k, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/radbm/envs/develop/lib/python3.7/site-packages/numpy/random/__init__.py'>)

Similar to numpy.random.randint but where each rows have unique elements.

Parameters:
  • low (int) – Lowest (signed) integer to be drawn from the distribution.
  • high (int) – Largest (signed) integer to be drawn from the distribution.
  • n (int) – The (unsigned) number of rows (vectors) with unique elements.
  • k (int) – The (unsigned) size of each rows (vectors).
  • rng (numpy.random.generator.Generator (optional)) – The generator used for sampling. (default: np.random)
Returns:

samples – For all i<n, samples[i,j] == samples[i,k] iif j==k.

Return type:

np.ndarray (shape: (n, k), dtype: int)

Notes

When the acceptance probability is fine, unique_randint_with_randint is used. Otherwise, if high-low < 500K then unique_randint_with_permutation is used. Otherwise, fast_unique_randint is used.

radbm.utils.numpy.random.unique_randint_with_permutation(low, high, n, k, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/radbm/envs/develop/lib/python3.7/site-packages/numpy/random/__init__.py'>)

Similar to numpy.random.randint but where each rows have unique elements.

Parameters:
  • low (int) – Lowest (signed) integer to be drawn from the distribution.
  • high (int) – Largest (signed) integer to be drawn from the distribution.
  • n (int) – The (unsigned) number of rows (vectors) with unique elements.
  • k (int) – The (unsigned) size of each rows (vectors).
  • rng (numpy.random.generator.Generator (optional)) – The generator used for sampling. (default: np.random)
Returns:

samples – For all i<n, samples[i,j] == samples[i,k] iif j==k.

Return type:

np.ndarray (shape: (n, k), dtype: int)

Notes

This implementation uses rng.permutation. The memory and time usage are in O(n*k + r) and O(r) respectively, with r = high-low.

radbm.utils.numpy.random.unique_randint_with_randint(low, high, n, k, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/radbm/envs/develop/lib/python3.7/site-packages/numpy/random/__init__.py'>)

Similar to numpy.random.randint but where each rows have unique elements.

Parameters:
  • low (int) – Lowest (signed) integer to be drawn from the distribution.
  • high (int) – Largest (signed) integer to be drawn from the distribution.
  • n (int) – The (unsigned) number of rows (vectors) with unique elements.
  • k (int) – The (unsigned) size of each rows (vectors).
  • rng (numpy.random.generator.Generator (optional)) – The generator used for sampling. (default: np.random)
Returns:

samples – For all i<n, samples[i,j] == samples[i,k] iif j==k.

Return type:

np.ndarray (shape: (n, k), dtype: int)

Notes

This implementation uses rng.randint with rejection sampling (i.e. reject when samples are not unique). This runs in O(n*k) memory and expected O(n*k) if k << high-low. This is way faster than shuffle/permutation if k << high-low because the probability of accepting is close to one. This probability can be computed using p = (np.arange(r-k+1, r+1)/r).prod() with r = high-low.

This implementation is recursive, consequently if p is to low (e.g. k is near high-low) then this will raise a RecursionError.

radbm.utils.numpy.random.unique_randint_with_shuffle(low, high, n, k, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/radbm/envs/develop/lib/python3.7/site-packages/numpy/random/__init__.py'>)

Similar to numpy.random.randint but where each rows have unique elements.

Parameters:
  • low (int) – Lowest (signed) integer to be drawn from the distribution.
  • high (int) – Largest (signed) integer to be drawn from the distribution.
  • n (int) – The (unsigned) number of rows (vectors) with unique elements.
  • k (int) – The (unsigned) size of each rows (vectors).
  • rng (numpy.random.generator.Generator (optional)) – The generator used for sampling. (default: np.random)
Returns:

samples – For all i<n, samples[i,j] == samples[i,k] iif j==k.

Return type:

np.ndarray (shape: (n, k), dtype: int)

Notes

This implementation uses rng.shuffle. The memory and time usage are in O(n*k + r) and O(r*k) respectively, with r = high-low. Because of the inplace shuffling this implementation is slightly faster than unique_randint_with_permutation however it takes more spaces.

Additional features for pytorch

radbm.utils.torch.multi_bernoulli.poisson_binomial.log_hamming_binomial(log_p10, log_p11, log_p20, log_p21)

Computes the log probabilities of each Hamming Binomial events, parameterized with p1 and p2.

Parameters:
  • log_p10 (torch.tensor (dtype=torch.float)) – The log probability of each bits to be zero of the first random vector. The Hamming Binomial is considered to be on the last dim. shape=(a1,a2,a3,…,am,n) where n is the number of bits for each vectors. a1,a2,a3,…,am are arbitrary but should be broadcastable with the other inputs.
  • log_p11 (torch.tensor (dtype=torch.float)) – The log probability of each bits to be one of the first random vector. The Hamming Binomial is considered to be on the last dim. shape=(a1,a2,a3,…,am,n) where n is the number of bits for each vectors. a1,a2,a3,…,am are arbitrary but should be broadcastable with the other inputs.
  • log_p20 (torch.tensor (dtype=torch.float)) – The log probability of each bits to be zero of the second random vector. The Hamming Binomial is considered to be on the last dim. shape=(a1,a2,a3,…,am,n) where n is the number of bits for each vectors. a1,a2,a3,…,am are arbitrary but should be broadcastable with the other inputs.
  • log_p21 (torch.tensor (dtype=torch.float)) – The log probability of each bits to be one of the second random vector. The Hamming Binomial is considered to be on the last dim. shape=(a1,a2,a3,…,am,n) where n is the number of bits for each vectors. a1,a2,a3,…,am are arbitrary but should be broadcastable with the other inputs.
Returns:

log_hb – The log probability of each Hamming Binomial events. shape=(a1,a2,a3,…,am,n+1). log_pb[i1,i2,i3,…,am,k] is the log probability that the hamming distance between the two random Multi-Bernoulli parameterized by log_p11.exp()[i1,i2,i3,…,am] and log_p21.exp()[i1,i2,i3,…,am] be k.

Return type:

torch.tensor (dtype=torch.float)

Notes

see log_poisson_binomial’s notes.

radbm.utils.torch.multi_bernoulli.poisson_binomial.log_poisson_binomial(log_q0, log_q1)

Computes the events log probabilities w.r.t. a batch of Poisson Binomial R.V. The computation is numerically stable.

Parameters:
  • log_q0 (torch.tensor (dtype=torch.float)) – The log probability of each bits to be zero. The Poisson Binomial is considered to be on the last dim. shape=(a1,a2,a3,…,am,n) where n is the number of bits for each Poisson Binomial. a1,a2,a3,…,am are arbitrary but should match with log_q1.
  • log_q1 (torch.tensor (dtype=torch.float)) – The log probability of each bits to be one. The Poisson Binomial is considered to be on the last dim. shape=(a1,a2,a3,…,am,n) where n is the number of bits for each Poisson Binomial. a1,a2,a3,…,am are arbitrary but should match with log_q0.
Returns:

log_pb – The log probability of each Poisson Binomial events. shape=(a1,a2,a3,…,am,n+1). log_pb[i1,i2,i3,…,am,k] is the log probability that the sum of the n Bernoulli with parameters log_q1.exp()[i1,i2,i3,…,am] gives k.

Return type:

torch.tensor(dtype=torch.float)

Notes

We should have (1-log_q0.exp()).log() = log_q1 in theory, hence the input of this function is over specified. But for numerical stability we need both log_q0 and log_q1 and it is not possible to compute log_q0 from log_q1 with numerical stability (and vice versa). This is why they are both required as input. Since in some cases, it is possible to compute log_q0 and log_q1 with numerical stability, i.e. log_q0 = log_sigmoid(-logits) and log_q1 = log_sigmoid(logits)

radbm.utils.torch.multi_bernoulli.log_arithmetic.multi_bernoulli_activated_equality(xz, yz, az)

Compute the bitwise log probability that two Multi-Bernoulli are equal or that a third Multi-Bernoulli is one.

Parameters:
  • xz (torch.tensor) – the logits (before sigmoid) of the first Multi-Bernoulli
  • yz (torch.tensor) – the logits (before sigmoid) of the second Multi-Bernoulli
  • az (torch.tensor) – the logits of the third Multi-Bernoulli which act as an activation of the equality.
Returns:

  • log_p0 (torch.tensor) – the bitwise log probability that the two Multi-Bernoulli are not equal and the third is zero.
  • log_p1 (torch.tensor) – the bitwise log probability that the two Multi-Bernoulli are equal or the third is one.

Notes

xz and yz need not to have the same shape, but they should be broadcastable.

radbm.utils.torch.multi_bernoulli.log_arithmetic.multi_bernoulli_activated_subset(xz, yz, az)

Compute the bitwise log probability that the first Multi-Bernoulli is lower are equal to the second or that a third Multi-Bernoulli is one.

Parameters:
  • xz (torch.tensor) – the logits (before sigmoid) of the first Multi-Bernoulli
  • yz (torch.tensor) – the logits (before sigmoid) of the second Multi-Bernoulli
  • az (torch.tensor) – the logits of the third Multi-Bernoulli which act as an activation of the “subset”.
Returns:

  • log_p0 (torch.tensor)
  • log_p1 (torch.tensor)

Notes

xz and yz need not to have the same shape, but they should be broadcastable.

radbm.utils.torch.multi_bernoulli.log_arithmetic.multi_bernoulli_equality(xz, yz)

Compute the bitwise log probability that two Multi-Bernoulli are equal.

Parameters:
  • xz (torch.tensor) – the logits (before sigmoid) of the first Multi-Bernoulli
  • yz (torch.tensor) – the logits (before sigmoid) of the second Multi-Bernoulli
Returns:

  • log_p0 (torch.tensor) – the bitwise log probability that the two Multi-Bernoulli are not equal
  • log_p1 (torch.tensor) – the bitwise log probability that the two Multi-Bernoulli are equal

Notes

xz and yz need not to have the same shape, but they should be broadcastable.

radbm.utils.torch.multi_bernoulli.log_arithmetic.multi_bernoulli_subset(xz, yz)

Compute the bitwise log probability that the first Multi-Bernoulli is lower are equal to the second.

Parameters:
  • xz (torch.tensor) – the logits (before sigmoid) of the first Multi-Bernoulli
  • yz (torch.tensor) – the logits (before sigmoid) of the second Multi-Bernoulli
Returns:

  • log_p0 (torch.tensor) – the bitwise log probability of not subset
  • log_p1 (torch.tensor) – the bitwise log probability of subset

Notes

xz and yz need not to have the same shape, but they should be broadcastable.

radbm.utils.torch.multi_bernoulli.log_arithmetic.torch_log_prob_any(log_q0, log_q1)

Similar to x.any() but for log probabilities (instead of booleans). The any is taken across the last dim.

Parameters:
  • log_q0 (torch.tensor (dtype=torch.float)) – The log probability of each bits to be zero. The any operation is over the last dim. shape=(a1,a2,a3,…,am,n) where n is the number of (independant) Bernoullis. a1,a2,a3,…,am are arbitrary but should match with log_q1.
  • log_q1 (torch.tensor (dtype=torch.float)) – The log probability of each bits to be one. The any operation is over the last dim. shape=(a1,a2,a3,…,am,n) where n is the number of (independant) Bernoullis. a1,a2,a3,…,am are arbitrary but should match with log_q1.
Returns:

  • log_nor (torch.tensor (dtype=torch.float))
  • log_or (torch.tensor (dtype=torch.float))

class radbm.utils.torch.multi_bernoulli.match.HammingMatch(dist)

Functional to compute the probability that two Multi-Bernoulli’s Hamming distance is below or equal to dist.

Parameters:dist (int (positive)) – The radius at which two binary vectors are considered to be “matching”. dist should be at most the number of bits.
hard_match(x, y)
Parameters:
  • x (torch.tensor (dtype: bool)) – The bits of the first set of Multi-Bernoulli. x.shape = (a1, a2, …, am, k) where k is the number of bits.
  • y (torch.tensor (dtype: bool)) – The bits of the first set of Multi-Bernoulli. y.shape = (b1, b2, …, bm, k) where k is the number of bits.
Returns:

match – Whether the two Multi-Bernoulli’s Hamming distance is below or equal to dist, shape = (c1, c2, …, cm).

Return type:

torch.tensor (dtype: bool)

Notes

(a1, a2, …, am, n) and (b1, b2, …, bm, n) should be broadcastable, where (c1, c2, …, cm, n) is their broadcasted shape.

soft_match(x, y)
Parameters:
  • x (torch.tensor (dtype: float)) – The logits (pre-sigmoid) of the bits of the first set of Multi-Bernoulli. x.shape = (a1, a2, …, am, k) where k is the number of bits.
  • y (torch.tensor (dtype: float)) – The logits (pre-sigmoid) of the bits of the first set of Multi-Bernoulli. y.shape = (b1, b2, …, bm, k) where k is the number of bits.
Returns:

  • log_probs_not_match (torch.tensor (dtype: float)) – The log probability that the two Multi-Bernoulli’s Hamming distance is above dist, shape = (c1, c2, …, cm).
  • log_probs_match (torch.tensor (dtype: float)) – The log probability that the two Multi-Bernoulli’s Hamming distance is below or equal to dist, shape = (c1, c2, …, cm).

Notes

(a1, a2, …, am, n) and (b1, b2, …, bm, n) should be broadcastable, where (c1, c2, …, cm, n) is their broadcasted shape.

class radbm.utils.torch.regularization.HuberLoss(maximum_slope, branching_point)

Functional for of Huber loss from which we can decide the final slope and the branching point between the quadratic and the linear branches. It is equivalent to the HuberLoss from the pytorch package (after multipling by a constant) but it allows the user to controls the derivative without the need of carefully choosing the right multipling factor.

Parameters:
  • maximum_slope (float) – The the maximum slope of the function, it is the slope of the linear branch.
  • branching_point (float) – Below this value, we use a quadratique equation otherwise a linear (affine to be exact) equation.

Probability and statistics

radbm.utils.stats.hypergeometric(N, K)

This function compute the pmf of the Hypergeometric(N, K, n) for each possible value of n (i.e. n in {0,1,2,…,N})

In the context where an urn with N marbles contains K white marbles, this function outputs an array P of shape (N+1,K+1) where P[i, j] correspond to the probabillity that with i samples without replacement we select j white marbles.

Parameters:
  • N (int) – The number of marbles in the urn
  • K (int) – The number of white marbles in the urn
Returns:

P – P[i, j] is the probability that with i samples without replacement we select j white marbles. P.shape is (N+1, K+1)

Return type:

numpy.ndarray

Notes

This is equivalent to np.array([scipy.stats.hypergeom(N, K, n).pmf(range(0,K+1)) for n in range(N+1)]) but faster, if only a row is needed (e.g. P[i]) than using scipy is faster.

This algorithm uses the following recursive formula P[i, j] = P[i-1, j]*(1-Q[i-1, j]) + P[i-1, j-1]*Q[i-1, j-1] with Q[i, j] = (K-j)/(N-i) the probability of sampling a white marble given that i marbles where sampled from which j were white

radbm.utils.stats.superdupergeometric(N, K)

This is the scenario where we have an urn with N marbles and K of them are white. We sample from the urn without replacement until we obtain k white marbles. The function gives the probability that we need n samples to obtain k white marbles.

Parameters:
  • N (int) – The number of marbles in the urn
  • K (int) – The number of white marbles in the urn
Returns:

SP – SP[i, j] is the probability that it requires i samples without replacement to select j white marbles. SP.shape is (N+1, K+1)

Return type:

numpy.ndarray

Notes

Probabibly related to the negative hypergeometric distribution

This uses the hypergeometric (hence the name) SP[i, j] = P[i-1, j-1]*Q[i-1, j-1] where P = hypergeometric(N, K) and with Q[i, j] = (K-j)/(N-i) the probability of sampling a white marble given that i marbles where sampled from which j were white

radbm.utils.stats.superdupergeometric_expectations(N, K)

This is the scenario where we have an urn with N marbles and K of them are white. We sample from the urn without replacement until we obtain k white marbles. The function gives the expected number of samples n requires to get k white marbles (for each k).

Parameters:
  • N (int) – The number of marbles in the urn
  • K (int) – The number of white marbles in the urn
Returns:

ESP – ESP[k] is the expected number of samples without replacement requires to get k white marbles. ESP.shape is (K+1,)

Return type:

numpy.ndarray

Notes

This is equivalent (but way faster) to (SP*np.arange(N+1)[:,None]).sum(axis=0) where SP = superdupergeometric(N, K)

Others

radbm.utils.Ramp(x0, x1, y0, y1)
Parameters:
  • x0 (float) – The input value where we start ramping
  • x1 (float) – The input value where we stop ramping
  • y0 (float) – The output value where the ramp starts
  • y1 (float) – The output value where the ramp stops
Returns:

ramp – The ramping function

Return type:

function float -> float

radbm.utils.identity(x)

The identity function.

Parameters:x (object) –
Returns:x – The given input.
Return type:object
radbm.utils.unique_list(it)

Create a list from an iterable with only unique element and where the order is preserved.

Parameters:
  • it (iterable) – Items should be hashable and comparable
  • Returns (list) – All items in the list is unique and the order of the iterable is preserved.
class radbm.utils.time.chronometer.Chronometer

A chronometer found time codes.

reset()

Resets the chronometer.

start()

Starts the chronometer.

stop()

Stops the chronometer.

time() : float

return the number of second on the chronometer.

radbm.utils.os.safe_load(path, map_location=None, n_attempts=5, verbose=False, stdout=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, stderr=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>)

Safely load an object using the possibly existing path/to/file/.tmp_<name>

Parameters:path (str) – the path where the object is saved
Returns:obj – the object loaded
Return type:object
radbm.utils.os.safe_save(obj, path, n_attempts=5, n_save_attempts=2, n_reload_attempts=2, verbose=False, stdout=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, stderr=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, pickle_protocol=2)

Safely saves obj in path by creating .tmp_<name> file before ovewriting an existing file then trying to read the file before removing .tmp_<name>

Parameters:
  • obj (object) – the object to be saved
  • path (str) – the path where to save obj
  • pickle_protocol (int (optional)) – The pickle protocol to uses. By default, the torch default_protocol is used.
Returns:

obj – the same obj received as input

Return type:

object

radbm.utils.gdrive.download.available_files()
Returns:files – The files available for download
Return type:list of str
radbm.utils.gdrive.download.download_file(file, path=None, verbose=False)

Download a file from Google Drive. This uses the gdown package. Warning, this function overwrite any existing file.

Parameters:
  • file (str) – The name of the file to download. Use available_files() to see which files are available for download.
  • path (str, optional (default=file)) – The path where to download the file. If the path does not exists it will be created. This should contain the filename.
  • verbose (bool, optional (default=False)) – If True output the download progress.
Returns:

path – The path where the file has been downloaded.

Return type:

str

radbm.utils.fetch.expend_paths(paths, subpaths)
Parameters:
  • dirs (list of str (directory path)) –
  • subpaths (list of str (sub-directory path)) –
radbm.utils.fetch.fetch_file(file, path=None, data_type=None, subdirs=None, download=True)

lookup on the machine for file otherwise download it.

Parameters:
  • file (str) – The name of the file to fetch
  • path (str, optional (default=None)) – The principal path to look for the file. If the find is not found, this function will attemp to download to path to this file.
  • data_type (str ('dataset' or 'model'), optional (default=None)) – Modifies the path to consider when looking for the file. If path is None and the file is not found, it will affect where to the file is downloaded, see get_directories_list for more information.
  • subdirs (list of str, optional (default=None)) – Additional sub-directories to lookup
  • download (bool) – A boolean to indicate if we want to download the file if not found on the machine
Returns:

paths_list – The list of path where to find the file

Return type:

list of str

radbm.utils.fetch.get_directories_list(path=None, data_type=None)

This function return the list of directory that is relevant for RADBM in order, it returns:

path $DATASETS_DIR if data_type==’dataset’ $MODELS_DIR if data_type==’model’ $PYTHONRADBM_DUMP/<data_type> $HOME/.radbm/<data_type> .

Parameters:
  • path (str, optional) – The path to look first, this is helpful when a user specifies a path to file or relevant directory
  • data_type (str, optional) – should be ‘dataset’ or ‘model’ this tell to lookup for environment variables specific to dataset or model
Returns:

dirs – The relevant directories in order

Return type:

list of str