From 29f97b8337c8d471a3eb058c1174a40dbf55410e Mon Sep 17 00:00:00 2001 From: Simon Rey Date: Thu, 8 Feb 2024 18:20:09 +0100 Subject: [PATCH] Docs for composition --- docs-source/source/quickstart.rst | 49 +++++++++++++++++++++ docs-source/source/reference/core/index.rst | 3 ++ prefsampling/core/__init__.py | 11 +++++ prefsampling/core/composition.py | 2 +- tests/test_samplers/test_all_samplers.py | 7 +++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/docs-source/source/quickstart.rst b/docs-source/source/quickstart.rst index 0ccb5d7..e9f3e9d 100644 --- a/docs-source/source/quickstart.rst +++ b/docs-source/source/quickstart.rst @@ -145,3 +145,52 @@ Approval Samplers - | :code:`p` | :code:`phi` - :code:`noise_type` (defaults to :py:const:`~prefsampling.approval.NoiseType.HAMMING`) + + +Composition of Samplers +~~~~~~~~~~~~~~~~~~~~~~~ + +It is often useful to be able to compose samplers, to define mixture for instance. The functions +:py:func:`~prefsampling.core.mixture` and :py:func:`~prefsampling.core.concatenation` can do that. + +The mixture uses different samplers, each being use with a given probability. + +.. code-block:: python + + from prefsampling.core import mixture + from prefsampling.ordinal import single_peaked_conitzer, single_peaked_walsh, norm_mallows + + # We create a mixture for 100 voters and 10 candidates of the single-peaked samplers using the + # Conitzer one with probability 0.6 and the Walsh one with probability 0.4 + mixture( + 100, # num_voters + 10, # num_candidates + [single_peaked_conitzer, single_peaked_walsh], # list of samplers + [0.6, 0.4], # weights of the samplers + [{}, {}] # parameters of the samplers + ) + + # We create a mixture for 100 voters and 10 candidates of different Mallows' models + mixture( + 100, # num_voters + 10, # num_candidates + [norm_mallows, norm_mallows, norm_mallows], # list of samplers + [4, 10, 3], # weights of the samplers + [{"norm_phi": 0.4}, {"norm_phi": 0.9}, {"norm_phi": 0.23}] # parameters of the samplers + ) + +The concatenation simply concatenates the votes returned by different samplers. + +.. code-block:: python + + from prefsampling.core import concatenation + from prefsampling.ordinal import single_peaked_conitzer, single_peaked_walsh + + # We create a concatenation for 100 voters and 10 candidates. 60 votes are sampled from the + # single_peaked_conitzer sampler and 40 votes from the single_peaked_walsh sampler. + concatenation( + [60, 40], # num_voters per sampler + 10, # num_candidates + [single_peaked_conitzer, single_peaked_walsh], # list of samplers + [{}, {}] # parameters of the samplers + ) \ No newline at end of file diff --git a/docs-source/source/reference/core/index.rst b/docs-source/source/reference/core/index.rst index 4421d1c..8c28882 100644 --- a/docs-source/source/reference/core/index.rst +++ b/docs-source/source/reference/core/index.rst @@ -1,5 +1,8 @@ Core ==== +.. automodule:: prefsampling.core.composition + :members: + .. automodule:: prefsampling.core.euclidean :members: diff --git a/prefsampling/core/__init__.py b/prefsampling/core/__init__.py index e69de29..c2f1d65 100644 --- a/prefsampling/core/__init__.py +++ b/prefsampling/core/__init__.py @@ -0,0 +1,11 @@ +""" +Core functions that are not specific to any ballot format. +""" + +from prefsampling.core.composition import mixture, concatenation + + +__all__ = [ + "mixture", + "concatenation" +] \ No newline at end of file diff --git a/prefsampling/core/composition.py b/prefsampling/core/composition.py index 2ca2a22..8a5abc7 100644 --- a/prefsampling/core/composition.py +++ b/prefsampling/core/composition.py @@ -55,7 +55,7 @@ def mixture( rng = np.random.default_rng(seed) - weights = np.array(weights) + weights = np.array(weights, dtype=float) weights /= weights.sum() num_samplers = len(samplers) samples = rng.choice(range(num_samplers), size=num_voters, replace=True, p=weights) diff --git a/tests/test_samplers/test_all_samplers.py b/tests/test_samplers/test_all_samplers.py index b5d3ca0..08df9dc 100644 --- a/tests/test_samplers/test_all_samplers.py +++ b/tests/test_samplers/test_all_samplers.py @@ -152,6 +152,13 @@ [approval_identity, approval_full, approval_urn_partylist], [0.5, 0.2, 0.3], [{"p": 0.4}, {}, {"alpha": 0.1, "parties": 3}] + ), + lambda num_voters, num_candidates, seed=None: mixture( + num_voters, + num_candidates, + [ordinal_norm_mallows, ordinal_norm_mallows, ordinal_norm_mallows], + [4, 10, 3], + [{"norm_phi": 0.4}, {"norm_phi": 0.9}, {"norm_phi": 0.23}] ) ]