Skip to content

Commit

Permalink
Special handling of comb for python 3.7
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon-Rey committed Feb 21, 2024
1 parent 40f67bf commit 9349864
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 5 deletions.
5 changes: 3 additions & 2 deletions prefsampling/approval/noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import numpy as np

from prefsampling.inputvalidators import validate_num_voters_candidates
from prefsampling.utils import comb


class NoiseType(Enum):
Expand Down Expand Up @@ -91,9 +92,9 @@ def noise(

# Prepare buckets
for x in range(len(A) + 1):
num_options_in = math.comb(len(A), x)
num_options_in = comb(len(A), x)
for y in range(len(B) + 1):
num_options_out = math.comb(len(B), y)
num_options_out = comb(len(B), y)

if noise_type == NoiseType.HAMMING:
factor = phi ** (len(A) - x + y)
Expand Down
3 changes: 2 additions & 1 deletion prefsampling/ordinal/groupseparable.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from prefsampling.tree.caterpillar import caterpillar_tree
from prefsampling.tree.balanced import balanced_tree
from prefsampling.inputvalidators import validate_num_voters_candidates
from prefsampling.utils import comb


class TreeSampler(Enum):
Expand Down Expand Up @@ -161,7 +162,7 @@ def _number_group_separable_profiles(m: int, r: int, n: int) -> float:
of internal nodes `r` based on the formula from `Karpov (2019)
<https://link.springer.com/article/10.1007/s10726-019-09621-w>`_
"""
return math.comb(m - 1, r) * math.comb(m - 1 + r, m) * (2 ** (n - 1) - 1) ** (r - 1)
return comb(m - 1, r) * comb(m - 1 + r, m) * (2 ** (n - 1) - 1) ** (r - 1)


def _sample_a_vote(node, reverse=False):
Expand Down
5 changes: 3 additions & 2 deletions prefsampling/tree/schroeder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from prefsampling.inputvalidators import validate_int
from prefsampling.tree.node import Node
from prefsampling.utils import comb


def validate_num_leaves_nodes(num_leaves: int, num_internal_nodes: int | None):
Expand Down Expand Up @@ -52,8 +53,8 @@ def _random_num_internal_nodes(num_leaves: int, rng: np.random.Generator) -> int

def _num_schroeder_tree(num_internal_nodes, num_leaves):
return (
math.comb(num_leaves - 1, num_internal_nodes)
* math.comb(num_leaves - 1 + num_internal_nodes, num_leaves)
comb(num_leaves - 1, num_internal_nodes)
* comb(num_leaves - 1 + num_internal_nodes, num_leaves)
/ (num_leaves - 1)
)

Expand Down
27 changes: 27 additions & 0 deletions prefsampling/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import math


def comb(n: int, k: int):
"""
Function to compute the binomial coefficient. It uses math.comb if available (i.e., if Python >=
3.8), otherwise computes it by hand.
Parameters
----------
n
k
Returns
-------
"""
if hasattr(math, "comb"):
return math.comb(n, k)
return _comb(n, k)


def _comb(n, k):
try:
return math.factorial(n) // math.factorial(k) // math.factorial(n - k)
except ValueError:
return 0

0 comments on commit 9349864

Please sign in to comment.