@@ -146,13 +146,13 @@
- Sample
+ Hare
Sample method:
- Stratify (LR)
- Stratify (floor)
+ Stratify
+
By order
- Every n-th ballot
+ Cincinnati
diff --git a/html/index.js b/html/index.js
index b9a3087..5c5c7ce 100644
--- a/html/index.js
+++ b/html/index.js
@@ -671,7 +671,7 @@ function changePreset() {
document.getElementById('chkBulkExclusion').checked = false;
document.getElementById('chkDeferSurpluses').checked = false;
document.getElementById('chkImmediateElect').checked = true;
- document.getElementById('selSample').value = 'nth_ballot';
+ document.getElementById('selSample').value = 'cincinnati';
document.getElementById('chkSamplePerBallot').checked = true;
document.getElementById('txtMinThreshold').value = '49';
document.getElementById('selNumbers').value = 'rational';
@@ -680,7 +680,7 @@ function changePreset() {
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('selSumTransfers').value = 'by_value';
- document.getElementById('selMethod').value = 'cincinnati';
+ document.getElementById('selMethod').value = 'hare';
document.getElementById('selPapers').value = 'transferable';
document.getElementById('selExclusion').value = 'single_stage';
document.getElementById('selTies').value = 'backwards,random';
@@ -692,7 +692,7 @@ function changePreset() {
document.getElementById('chkBulkExclusion').checked = false;
document.getElementById('chkDeferSurpluses').checked = true;
document.getElementById('chkImmediateElect').checked = true;
- document.getElementById('selSample').value = 'stratify_lr';
+ document.getElementById('selSample').value = 'stratify';
document.getElementById('chkSamplePerBallot').checked = false;
document.getElementById('txtMinThreshold').value = '0';
document.getElementById('selNumbers').value = 'rational';
diff --git a/src/cli/stv.rs b/src/cli/stv.rs
index 3769a82..0f7312a 100644
--- a/src/cli/stv.rs
+++ b/src/cli/stv.rs
@@ -113,8 +113,8 @@ pub struct SubcmdOptions {
#[clap(help_heading=Some("STV VARIANTS"), long, value_name="seed")]
random_seed: Option,
- /// Method of surplus distributions
- #[clap(help_heading=Some("STV VARIANTS"), short='s', long, possible_values=&["wig", "uig", "eg", "meek", "cincinnati", "hare"], default_value="wig", value_name="method")]
+ /// Method of surplus distributions [default: wig] [possible values: wig, uig, eg, meek, ihare, hare]
+ #[clap(help_heading=Some("STV VARIANTS"), short='s', long, possible_values=&["wig", "uig", "eg", "meek", "ihare", "hare", "eh"], default_value="wig", value_name="method", hide_possible_values=true, hide_default_value=true)]
surplus: String,
/// (Gregory STV) Order to distribute surpluses
@@ -133,11 +133,11 @@ pub struct SubcmdOptions {
#[clap(help_heading=Some("STV VARIANTS"), long)]
meek_nz_exclusion: bool,
- /// (Cincinnati/Hare) Method of drawing a sample
- #[clap(help_heading=Some("STV VARIANTS"), long, possible_values=&["stratify_lr", "stratify_floor", "by_order", "nth_ballot"], default_value="stratify_lr", value_name="method")]
+ /// (Hare) Method of drawing a sample [default: stratify] [possible values: stratify, by_order, cincinnati]
+ #[clap(help_heading=Some("STV VARIANTS"), long, possible_values=&["stratify", "stratify_lr", "by_order", "cincinnati", "nth_ballot"], default_value="stratify", value_name="method", hide_possible_values=true, hide_default_value=true)]
sample: String,
- /// (Cincinnati/Hare) Sample-based methods: Check for candidate election after each individual ballot paper transfer
+ /// (Hare) Sample-based methods: Check for candidate election after each individual ballot paper transfer
#[clap(help_heading=Some("STV VARIANTS"), long)]
sample_per_ballot: bool,
diff --git a/src/stv/gregory/mod.rs b/src/stv/gregory/mod.rs
index b5b850e..77eb782 100644
--- a/src/stv/gregory/mod.rs
+++ b/src/stv/gregory/mod.rs
@@ -158,7 +158,7 @@ where
match opts.surplus {
SurplusMethod::WIG | SurplusMethod::UIG | SurplusMethod::EG => { distribute_surplus(state, &opts, elected_candidate); }
- SurplusMethod::Cincinnati | SurplusMethod::Hare => { sample::distribute_surplus(state, &opts, elected_candidate)?; }
+ SurplusMethod::IHare | SurplusMethod::Hare => { sample::distribute_surplus(state, &opts, elected_candidate)?; }
_ => unreachable!()
}
diff --git a/src/stv/mod.rs b/src/stv/mod.rs
index 6c48cc3..ddc387b 100644
--- a/src/stv/mod.rs
+++ b/src/stv/mod.rs
@@ -111,11 +111,11 @@ pub struct STVOptions {
#[builder(default="false")]
pub meek_nz_exclusion: bool,
- /// (Cincinnati/Hare) Method of drawing a sample
+ /// (Hare) Method of drawing a sample
#[builder(default="SampleMethod::StratifyLR")]
pub sample: SampleMethod,
- /// (Cincinnati/Hare) Sample-based methods: Check for candidate election after each individual ballot paper transfer
+ /// (Hare) Sample-based methods: Check for candidate election after each individual ballot paper transfer
#[builder(default="false")]
pub sample_per_ballot: bool,
@@ -169,7 +169,7 @@ impl STVOptions {
pub fn describe(&self) -> String {
let mut flags = Vec::new();
let n_str = N::describe_opt(); if !n_str.is_empty() { flags.push(N::describe_opt()) };
- if self.surplus != SurplusMethod::Cincinnati && self.surplus != SurplusMethod::Hare {
+ if self.surplus != SurplusMethod::IHare && self.surplus != SurplusMethod::Hare {
if let Some(dps) = self.round_surplus_fractions { flags.push(format!("--round-surplus-fractions {}", dps)); }
if let Some(dps) = self.round_values { flags.push(format!("--round-values {}", dps)); }
if let Some(dps) = self.round_votes { flags.push(format!("--round-votes {}", dps)); }
@@ -191,8 +191,8 @@ impl STVOptions {
if self.exclusion != ExclusionMethod::SingleStage { flags.push(self.exclusion.describe()); }
}
if self.surplus == SurplusMethod::Meek && self.meek_nz_exclusion { flags.push("--meek-nz-exclusion".to_string()); }
- if (self.surplus == SurplusMethod::Cincinnati || self.surplus == SurplusMethod::Hare) && self.sample != SampleMethod::StratifyLR { flags.push(self.sample.describe()); }
- if (self.surplus == SurplusMethod::Cincinnati || self.surplus == SurplusMethod::Hare) && self.sample_per_ballot { flags.push("--sample-per-ballot".to_string()); }
+ if (self.surplus == SurplusMethod::IHare || self.surplus == SurplusMethod::Hare) && self.sample != SampleMethod::StratifyLR { flags.push(self.sample.describe()); }
+ if (self.surplus == SurplusMethod::IHare || self.surplus == SurplusMethod::Hare) && self.sample_per_ballot { flags.push("--sample-per-ballot".to_string()); }
if !self.early_bulk_elect { flags.push("--no-early-bulk-elect".to_string()); }
if self.bulk_exclude { flags.push("--bulk-exclude".to_string()); }
if self.defer_surpluses { flags.push("--defer-surpluses".to_string()); }
@@ -216,11 +216,11 @@ impl STVOptions {
if self.transferable_only { return Err(STVError::InvalidOptions("--surplus meek is incompatible with --transferable-only")); }
if self.exclusion != ExclusionMethod::SingleStage { return Err(STVError::InvalidOptions("--surplus meek requires --exclusion single_stage")); }
}
- if self.surplus == SurplusMethod::Cincinnati || self.surplus == SurplusMethod::Hare {
- if self.round_quota != Some(0) { return Err(STVError::InvalidOptions("--surplus cincinnati and --surplus hare require --round-quota 0")); }
- if !self.normalise_ballots { return Err(STVError::InvalidOptions("--surplus cincinnati and --surplus hare require --normalise-ballots")); }
+ if self.surplus == SurplusMethod::IHare || self.surplus == SurplusMethod::Hare {
+ if self.round_quota != Some(0) { return Err(STVError::InvalidOptions("--surplus ihare and --surplus hare require --round-quota 0")); }
+ if !self.normalise_ballots { return Err(STVError::InvalidOptions("--surplus ihare and --surplus hare require --normalise-ballots")); }
if self.sample == SampleMethod::StratifyLR && self.sample_per_ballot { return Err(STVError::InvalidOptions("--sample stratify_lr is incompatible with --sample-per-ballot")); }
- if self.sample == SampleMethod::StratifyFloor && self.sample_per_ballot { return Err(STVError::InvalidOptions("--sample stratify_floor is incompatible with --sample-per-ballot")); }
+ //if self.sample == SampleMethod::StratifyFloor && self.sample_per_ballot { return Err(STVError::InvalidOptions("--sample stratify_floor is incompatible with --sample-per-ballot")); }
if self.sample == SampleMethod::StratifyLR && self.round_surplus_fractions.is_some() { return Err(STVError::InvalidOptions("--sample stratify_lr is incompatible with --round-surplus-fractions")); }
if self.sample_per_ballot && !self.immediate_elect { return Err(STVError::InvalidOptions("--sample-per-ballot is incompatible with --no-immediate-elect")); }
}
@@ -386,9 +386,9 @@ pub enum SurplusMethod {
EG,
/// Meek method
Meek,
- /// Cincinnati method (inclusive random subset)
- Cincinnati,
- /// Hare method (exclusive random subset)
+ /// Inclusive Hare method (random subset)
+ IHare,
+ /// (Exclusive) Hare method (random subset)
Hare,
}
@@ -400,7 +400,7 @@ impl SurplusMethod {
SurplusMethod::UIG => "--surplus uig",
SurplusMethod::EG => "--surplus eg",
SurplusMethod::Meek => "--surplus meek",
- SurplusMethod::Cincinnati => "--surplus cincinnati",
+ SurplusMethod::IHare => "--surplus ihare",
SurplusMethod::Hare => "--surplus hare",
}.to_string()
}
@@ -422,8 +422,8 @@ impl> From for SurplusMethod {
"uig" => SurplusMethod::UIG,
"eg" => SurplusMethod::EG,
"meek" => SurplusMethod::Meek,
- "cincinnati" => SurplusMethod::Cincinnati,
- "hare" => SurplusMethod::Hare,
+ "ihare" | "ih" | "cincinnati" => SurplusMethod::IHare, // Inclusive Hare method used to be erroneously referred to as "Cincinnati" method - accept for backwards compatibility
+ "hare" | "eh" => SurplusMethod::Hare,
_ => panic!("Invalid --surplus"),
}
}
@@ -510,22 +510,22 @@ impl> From for ExclusionMethod {
pub enum SampleMethod {
/// Stratify the ballots into parcels according to next available preference and transfer the last ballots from each parcel; round fractions according to largest remainders
StratifyLR,
- /// Stratify the ballots into parcels according to next available preference and transfer the last ballots from each parcel; disregard fractions
- StratifyFloor,
+ // Stratify the ballots into parcels according to next available preference and transfer the last ballots from each parcel; disregard fractions
+ //StratifyFloor,
/// Transfer the last ballots
ByOrder,
/// Transfer every n-th ballot, Cincinnati style
- NthBallot,
+ Cincinnati,
}
impl SampleMethod {
/// Convert to CLI argument representation
fn describe(self) -> String {
match self {
- SampleMethod::StratifyLR => "--sample stratify_lr",
- SampleMethod::StratifyFloor => "--sample stratify_floor",
+ SampleMethod::StratifyLR => "--sample stratify",
+ //SampleMethod::StratifyFloor => "--sample stratify_floor",
SampleMethod::ByOrder => "--sample by_order",
- SampleMethod::NthBallot => "--sample nth_ballot",
+ SampleMethod::Cincinnati => "--sample cincinnati",
}.to_string()
}
}
@@ -533,10 +533,10 @@ impl SampleMethod {
impl> From for SampleMethod {
fn from(s: S) -> Self {
match s.as_ref() {
- "stratify_lr" => SampleMethod::StratifyLR,
- "stratify_floor" => SampleMethod::StratifyFloor,
+ "stratify" | "stratify_lr" => SampleMethod::StratifyLR,
+ //"stratify_floor" => SampleMethod::StratifyFloor,
"by_order" => SampleMethod::ByOrder,
- "nth_ballot" => SampleMethod::NthBallot,
+ "cincinnati" | "nth_ballot" => SampleMethod::Cincinnati,
_ => panic!("Invalid --sample-method"),
}
}
@@ -780,7 +780,7 @@ where
for<'r> &'r N: ops::Mul<&'r N, Output=N>,
{
match opts.surplus {
- SurplusMethod::WIG | SurplusMethod::UIG | SurplusMethod::EG | SurplusMethod::Cincinnati | SurplusMethod::Hare => {
+ SurplusMethod::WIG | SurplusMethod::UIG | SurplusMethod::EG | SurplusMethod::IHare | SurplusMethod::Hare => {
gregory::distribute_first_preferences(state, opts);
}
SurplusMethod::Meek => {
@@ -1227,7 +1227,7 @@ where
for<'r> &'r N: ops::Neg,
{
match opts.surplus {
- SurplusMethod::WIG | SurplusMethod::UIG | SurplusMethod::EG | SurplusMethod::Cincinnati | SurplusMethod::Hare => {
+ SurplusMethod::WIG | SurplusMethod::UIG | SurplusMethod::EG | SurplusMethod::IHare | SurplusMethod::Hare => {
return gregory::distribute_surpluses(state, opts);
}
SurplusMethod::Meek => {
@@ -1558,7 +1558,7 @@ where
SurplusMethod::Meek => {
meek::exclude_candidates(state, opts, excluded_candidates);
}
- SurplusMethod::Cincinnati | SurplusMethod::Hare => {
+ SurplusMethod::IHare | SurplusMethod::Hare => {
sample::exclude_candidates(state, opts, excluded_candidates)?;
}
}
diff --git a/src/stv/sample.rs b/src/stv/sample.rs
index 26eff6c..3abdaad 100644
--- a/src/stv/sample.rs
+++ b/src/stv/sample.rs
@@ -60,7 +60,7 @@ where
let mut votes;
match opts.surplus {
- SurplusMethod::Cincinnati => {
+ SurplusMethod::IHare => {
// Inclusive
votes = count_card.concat_parcels();
}
@@ -73,7 +73,7 @@ where
}
match opts.sample {
- SampleMethod::StratifyLR | SampleMethod::StratifyFloor => {
+ SampleMethod::StratifyLR /*| SampleMethod::StratifyFloor*/ => {
// Stratified by next available preference (round fractions according to largest remainders)
let result = super::next_preferences(state, votes);
@@ -122,7 +122,7 @@ where
let mut candidate_transfers;
let remainder;
match surplus_fraction {
- Some(ref f) => {
+ Some(_) => {
match opts.sample {
SampleMethod::StratifyLR => {
// Incompatible with --round-surplus-fractions
@@ -130,7 +130,7 @@ where
candidate_transfers.floor_mut(0);
remainder = (&entry.num_ballots * &surplus) % surplus_denom.as_ref().unwrap();
}
- SampleMethod::StratifyFloor => {
+ /*SampleMethod::StratifyFloor => {
match opts.round_surplus_fractions {
Some(_) => {
candidate_transfers = &entry.num_ballots * f;
@@ -141,7 +141,7 @@ where
}
candidate_transfers.floor_mut(0);
remainder = N::new();
- }
+ }*/
_ => unreachable!()
}
}
@@ -166,7 +166,7 @@ where
exhausted_transfers.floor_mut(0);
remainder = (&result.exhausted.num_ballots * &surplus) % surplus_denom.as_ref().unwrap();
}
- SampleMethod::StratifyFloor => {
+ /*SampleMethod::StratifyFloor => {
match opts.round_surplus_fractions {
Some(_) => {
exhausted_transfers = &result.exhausted.num_ballots * surplus_fraction.as_ref().unwrap();
@@ -177,7 +177,7 @@ where
}
exhausted_transfers.floor_mut(0);
remainder = N::new();
- }
+ }*/
_ => unreachable!()
}
@@ -314,7 +314,7 @@ where
}
}
}
- SampleMethod::NthBallot => {
+ SampleMethod::Cincinnati => {
// Every nth-ballot (Cincinnati-style)
// Calculate skip value
diff --git a/tests/tests_impl/cambridge.rs b/tests/tests_impl/cambridge.rs
index eb30b37..2f6fd9a 100644
--- a/tests/tests_impl/cambridge.rs
+++ b/tests/tests_impl/cambridge.rs
@@ -26,15 +26,15 @@ fn cambridge_cc03_rational() {
.round_quota(Some(0))
.normalise_ballots(true)
.quota_criterion(stv::QuotaCriterion::GreaterOrEqual)
- .surplus(stv::SurplusMethod::Cincinnati)
+ .surplus(stv::SurplusMethod::Hare)
.transferable_only(true)
- .sample(stv::SampleMethod::NthBallot)
+ .sample(stv::SampleMethod::Cincinnati)
.sample_per_ballot(true)
.early_bulk_elect(false)
.min_threshold("49".to_string())
.build().unwrap();
- assert_eq!(stv_opts.describe::(), "--round-quota 0 --normalise-ballots --quota-criterion geq --surplus cincinnati --transferable-only --sample nth_ballot --sample-per-ballot --no-early-bulk-elect --min-threshold 49");
+ assert_eq!(stv_opts.describe::(), "--round-quota 0 --normalise-ballots --quota-criterion geq --surplus hare --transferable-only --sample cincinnati --sample-per-ballot --no-early-bulk-elect --min-threshold 49");
utils::read_validate_election::("tests/data/CambCC2003.csv", "tests/data/CambCC2003.blt", stv_opts, None, &["exhausted"]);
}