diff --git a/docs/options.md b/docs/options.md
index d32881d..8b9eda1 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -102,7 +102,7 @@ Random sample methods are also supported, but also not recommended:
* *Hare (exclusive sample)*: During surplus transfers, a subset of the ballot papers received in the last transfer, equal in size to the surplus, is examined.
* *Inclusive Hare (sample)*: During surplus transfers, a subset of the elected candidate's ballot papers, equal in size to the surplus, is examined.
-The use of a random sample method requires *Normalise ballots* to be enabled, and will usually be used with a *Quota criterion* set to *>=*.
+A random sample method will usually be used with a *Quota criterion* set to *>=*.
### Papers to examine in surplus transfer (--transferable-only/--subtract-nontransferable)
@@ -219,14 +219,6 @@ This dropdown allows you to select how numbers (vote totals, etc.) are represent
* *Rational* (default): Numbers are represented exactly as fractions, resulting in the elimination of rounding error, but increasing computational complexity when the number of surplus transfers is very large.
* *Float (64-bit)*: Numbers are represented as native 64-bit floating-point numbers. This is fast, but not recommended as unexpectedly large rounding errors may be introduced in some circumstances.
-### Normalise ballots (--normalise-ballots)
-
-In the BLT file format, each set of preferences can have a specified weight – this is typically used to indicate multiple voters who had the same preferences.
-
-When ballots are not normalised (default), a set of preferences with weight *n* > 1 is represented as a single ballot with value *n*. This is known as [list-packed ballots](http://www.votingmatters.org.uk/ISSUE21/I21P1.pdf).
-
-When ballots are normalised, a set of preferences with weight *n* > 1 is instead converted to *n* ballots each with value 1.
-
## Count optimisations
### Early bulk election (--no-early-bulk-elect)
diff --git a/html/index.html b/html/index.html
index d26c216..685cef3 100644
--- a/html/index.html
+++ b/html/index.html
@@ -233,10 +233,6 @@
-
-
- Normalise ballots
-
Count optimisations:
diff --git a/html/index.js b/html/index.js
index cd8a296..9df3b30 100644
--- a/html/index.js
+++ b/html/index.js
@@ -146,7 +146,6 @@ async function clickCount() {
document.getElementById('chkRoundQuota').checked ? parseInt(document.getElementById('txtRoundQuota').value) : null,
document.getElementById('selSumTransfers').value,
document.getElementById('txtMeekSurplusTolerance').value,
- document.getElementById('chkNormaliseBallots').checked,
document.getElementById('selQuota').value,
document.getElementById('selQuotaCriterion').value,
document.getElementById('selQuotaMode').value,
@@ -189,7 +188,6 @@ async function clickCount() {
'optsStr': optsStr,
'numbers': document.getElementById('selNumbers').value,
'decimals': document.getElementById('txtDP').value,
- 'normaliseBallots': document.getElementById('chkNormaliseBallots').checked,
'reportStyle': document.getElementById('selReport').value,
});
}
diff --git a/html/presets.js b/html/presets.js
index fdb311c..00f85b1 100644
--- a/html/presets.js
+++ b/html/presets.js
@@ -27,7 +27,6 @@ function changePreset() {
document.getElementById('txtMinThreshold').value = '0';
document.getElementById('selNumbers').value = 'rational';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = false;
document.getElementById('chkRoundVotes').checked = false;
document.getElementById('chkRoundSFs').checked = false;
@@ -50,7 +49,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '5';
document.getElementById('txtPPDP').value = '5';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('chkRoundVotes').checked = false;
@@ -76,7 +74,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '5';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = false;
document.getElementById('chkRoundVotes').checked = false;
document.getElementById('chkRoundSFs').checked = false;
@@ -101,7 +98,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '12';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '9';
document.getElementById('chkRoundVotes').checked = true;
@@ -130,7 +126,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '12';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '9';
document.getElementById('chkRoundVotes').checked = true;
@@ -157,7 +152,6 @@ function changePreset() {
document.getElementById('txtMinThreshold').value = '0';
document.getElementById('selNumbers').value = 'rational';
document.getElementById('txtPPDP').value = '0';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('chkRoundVotes').checked = true;
@@ -181,7 +175,6 @@ function changePreset() {
document.getElementById('txtMinThreshold').value = '0';
document.getElementById('selNumbers').value = 'rational';
document.getElementById('txtPPDP').value = '0';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('chkRoundVotes').checked = true;
@@ -205,7 +198,6 @@ function changePreset() {
document.getElementById('txtMinThreshold').value = '0';
document.getElementById('selNumbers').value = 'rational';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('chkRoundVotes').checked = true;
@@ -229,7 +221,6 @@ function changePreset() {
document.getElementById('txtMinThreshold').value = '0';
document.getElementById('selNumbers').value = 'rational';
document.getElementById('txtPPDP').value = '0';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('chkRoundVotes').checked = true;
@@ -254,7 +245,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '4';
document.getElementById('txtPPDP').value = '4';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('chkRoundVotes').checked = false;
@@ -280,7 +270,6 @@ function changePreset() {
document.getElementById('txtMinThreshold').value = '49';
document.getElementById('selNumbers').value = 'rational';
document.getElementById('txtPPDP').value = '0';
- document.getElementById('chkNormaliseBallots').checked = true;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('selSumTransfers').value = 'single_step';
@@ -301,7 +290,6 @@ function changePreset() {
document.getElementById('txtMinThreshold').value = '0';
document.getElementById('selNumbers').value = 'rational';
document.getElementById('txtPPDP').value = '0';
- document.getElementById('chkNormaliseBallots').checked = true;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('selSumTransfers').value = 'single_step';
@@ -322,7 +310,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '5';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '0';
document.getElementById('chkRoundVotes').checked = false;
@@ -346,7 +333,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '6';
document.getElementById('txtPPDP').value = '3';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '3';
document.getElementById('chkRoundVotes').checked = true;
@@ -373,7 +359,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '5';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '2';
document.getElementById('chkRoundVotes').checked = true;
@@ -400,7 +385,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '5';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '2';
document.getElementById('chkRoundVotes').checked = true;
@@ -427,7 +411,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '5';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '2';
document.getElementById('chkRoundVotes').checked = true;
@@ -454,7 +437,6 @@ function changePreset() {
document.getElementById('selNumbers').value = 'fixed';
document.getElementById('txtDP').value = '5';
document.getElementById('txtPPDP').value = '2';
- document.getElementById('chkNormaliseBallots').checked = false;
document.getElementById('chkRoundQuota').checked = true;
document.getElementById('txtRoundQuota').value = '2';
document.getElementById('chkRoundVotes').checked = true;
diff --git a/src/cli/stv.rs b/src/cli/stv.rs
index fef4708..6edbe5d 100644
--- a/src/cli/stv.rs
+++ b/src/cli/stv.rs
@@ -56,10 +56,6 @@ pub struct SubcmdOptions {
#[clap(help_heading=Some("NUMBERS"), long, default_value="5", value_name="dps")]
decimals: usize,
- /// Convert ballots with value >1 to multiple ballots of value 1
- #[clap(help_heading=Some("NUMBERS"), long)]
- normalise_ballots: bool,
-
// -----------------------
// -- Rounding settings --
@@ -294,7 +290,6 @@ where
cmd_opts.round_quota,
cmd_opts.round_subtransfers.into(),
cmd_opts.meek_surplus_tolerance,
- cmd_opts.normalise_ballots,
cmd_opts.quota.into(),
cmd_opts.quota_criterion.into(),
cmd_opts.quota_mode.into(),
diff --git a/src/stv/mod.rs b/src/stv/mod.rs
index 3058734..57b32e5 100644
--- a/src/stv/mod.rs
+++ b/src/stv/mod.rs
@@ -71,10 +71,6 @@ pub struct STVOptions {
#[builder(default=r#"String::from("0.001%")"#)]
pub meek_surplus_tolerance: String,
- /// Convert ballots with value >1 to multiple ballots of value 1 (used only for [STVOptions::describe])
- #[builder(default="false")]
- pub normalise_ballots: bool,
-
/// Quota type
#[builder(default="QuotaType::Droop")]
pub quota: QuotaType,
@@ -181,7 +177,6 @@ impl STVOptions {
if let Some(dps) = self.round_quota { flags.push(format!("--round-quota {}", dps)); }
if self.surplus != SurplusMethod::Meek && self.round_subtransfers != RoundSubtransfersMode::SingleStep { flags.push(self.round_subtransfers.describe()); }
if self.surplus == SurplusMethod::Meek && self.meek_surplus_tolerance != "0.001%" { flags.push(format!("--meek-surplus-tolerance {}", self.meek_surplus_tolerance)); }
- if self.normalise_ballots { flags.push("--normalise-ballots".to_string()); }
if self.quota != QuotaType::Droop { flags.push(self.quota.describe()); }
if self.quota_criterion != QuotaCriterion::Greater { flags.push(self.quota_criterion.describe()); }
if self.quota_mode != QuotaMode::Static { flags.push(self.quota_mode.describe()); }
@@ -224,7 +219,6 @@ impl STVOptions {
}
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 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_per_ballot && !self.immediate_elect { return Err(STVError::InvalidOptions("--sample-per-ballot is incompatible with --no-immediate-elect")); }
@@ -623,8 +617,8 @@ impl fmt::Display for STVError {
/// Preprocess the given election
pub fn preprocess_election(election: &mut Election, opts: &STVOptions) {
- // Normalise ballots if requested
- if opts.normalise_ballots {
+ // Normalise ballots if required
+ if opts.surplus == SurplusMethod::IHare || opts.surplus == SurplusMethod::Hare {
election.normalise_ballots();
}
diff --git a/src/stv/wasm.rs b/src/stv/wasm.rs
index 4488e4c..04f8e76 100644
--- a/src/stv/wasm.rs
+++ b/src/stv/wasm.rs
@@ -246,7 +246,6 @@ impl STVOptions {
round_quota: Option,
round_subtransfers: &str,
meek_surplus_tolerance: String,
- normalise_ballots: bool,
quota: &str,
quota_criterion: &str,
quota_mode: &str,
@@ -275,7 +274,6 @@ impl STVOptions {
round_quota,
round_subtransfers.into(),
meek_surplus_tolerance,
- normalise_ballots,
quota.into(),
quota_criterion.into(),
quota_mode.into(),
diff --git a/tests/tests_impl/cambridge.rs b/tests/tests_impl/cambridge.rs
index 2f6fd9a..9a0131b 100644
--- a/tests/tests_impl/cambridge.rs
+++ b/tests/tests_impl/cambridge.rs
@@ -24,7 +24,6 @@ use opentally::stv;
fn cambridge_cc03_rational() {
let stv_opts = stv::STVOptionsBuilder::default()
.round_quota(Some(0))
- .normalise_ballots(true)
.quota_criterion(stv::QuotaCriterion::GreaterOrEqual)
.surplus(stv::SurplusMethod::Hare)
.transferable_only(true)
@@ -34,7 +33,7 @@ fn cambridge_cc03_rational() {
.min_threshold("49".to_string())
.build().unwrap();
- 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");
+ assert_eq!(stv_opts.describe::(), "--round-quota 0 --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"]);
}
diff --git a/tests/tests_impl/dail.rs b/tests/tests_impl/dail.rs
index 901d3e2..41fbb41 100644
--- a/tests/tests_impl/dail.rs
+++ b/tests/tests_impl/dail.rs
@@ -25,7 +25,6 @@ use opentally::ties::TieStrategy;
fn dublin_north_2002_rational() {
let stv_opts = stv::STVOptionsBuilder::default()
.round_quota(Some(0))
- .normalise_ballots(true)
.quota_criterion(stv::QuotaCriterion::GreaterOrEqual)
.surplus(stv::SurplusMethod::Hare)
.surplus_order(stv::SurplusOrder::ByOrder)
@@ -33,7 +32,7 @@ fn dublin_north_2002_rational() {
.defer_surpluses(true)
.build().unwrap();
- assert_eq!(stv_opts.describe::(), "--round-quota 0 --normalise-ballots --quota-criterion geq --surplus hare --surplus-order by_order --transferable-only --defer-surpluses");
+ assert_eq!(stv_opts.describe::(), "--round-quota 0 --quota-criterion geq --surplus hare --surplus-order by_order --transferable-only --defer-surpluses");
utils::read_validate_election::("tests/data/DublinNorthSorted.csv", "tests/data/DublinNorthSorted.blt", stv_opts, None, &["exhausted"]);
}
@@ -42,7 +41,6 @@ fn dublin_north_2002_rational() {
fn grey_fitzgerald_rational() {
let stv_opts = stv::STVOptionsBuilder::default()
.round_quota(Some(0))
- .normalise_ballots(true)
.quota_criterion(stv::QuotaCriterion::GreaterOrEqual)
.ties(vec![TieStrategy::Forwards])
.surplus(stv::SurplusMethod::Hare)
@@ -52,7 +50,7 @@ fn grey_fitzgerald_rational() {
.defer_surpluses(true)
.build().unwrap();
- assert_eq!(stv_opts.describe::(), "--round-quota 0 --normalise-ballots --quota-criterion geq --ties forwards --surplus hare --transferable-only --bulk-exclude --defer-surpluses");
+ assert_eq!(stv_opts.describe::(), "--round-quota 0 --quota-criterion geq --ties forwards --surplus hare --transferable-only --bulk-exclude --defer-surpluses");
utils::read_validate_election::("tests/data/grey_fitzgerald.csv", "tests/data/grey_fitzgerald.blt", stv_opts, None, &["exhausted"]);
}