Update nomenclature for van der Craats (‘Wright’) STV

master
RunasSudo 3 months ago
parent cb1cc5fb72
commit 254c04b574
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
  1. 4
      docs/options.md
  2. 2
      docs/validation.md
  3. 4
      html/index.html
  4. 2
      html/main.css
  5. 4
      html/presets.js
  6. 4
      src/cli/stv.rs
  7. 4
      src/stv/gregory/mod.rs
  8. 4
      src/stv/mod.rs
  9. 9
      src/stv/options.rs
  10. 6
      src/stv/wasm.rs
  11. 4
      tests/tests_impl/csm.rs

@ -19,7 +19,7 @@ The preset dropdown allows you to choose from a hardcoded list of preloaded STV
| Minneapolis STV | Rules from chapter 167 of the [*Minneapolis Code of Ordinances*](https://library.municode.com/mn/minneapolis/codes/code_of_ordinances?nodeId=COOR_TIT8.5EL_CH167MUELRUCO), using the weighted inclusive Gregory method. | [E6] | ✓ |
| Cambridge STV | Rules in force in Cambridge, Massachusetts, using random sample transfers. These rules are derived from the [former chapter 54A of the Massachusetts General Laws](https://www.cambridgema.gov/-/media/Files/electioncommission/massachusettsgenerallawschapter54a.pdf), but have by regulation been modified to incorporate the procedures set out in Article IX of the former [1938 Charter of the City of Cincinnati](https://catalog.hathitrust.org/Record/001754258). See also [here](https://web.archive.org/web/20081118104049/http://www.fairvote.org/media/1993countmanual.pdf). | | ✓ |
| Dáil Éireann STV | Rules from the [*Electoral Act 1992* (Ireland)](http://www.irishstatutebook.ie/eli/1992/act/23/enacted/en/print), using stratified random sample transfers. | [E4] [E7] | ✓ |
| [Wright STV](https://www.aph.gov.au/Parliamentary_Business/Committees/House_of_Representatives_Committees?url=em/elect07/subs/sub051.1.pdf) | Rules proposed by Anthony van der Craats designed for computer counting, involving reset and re-iteration of the count after each candidate exclusion. | | ✓ |
| [van der Craats (‘Wright’) STV](https://www.aph.gov.au/Parliamentary_Business/Committees/House_of_Representatives_Committees?url=em/elect07/subs/sub051.1.pdf) | Rules proposed by Anthony van der Craats designed for computer counting, involving reset and re-iteration of the count after each candidate exclusion. | | ✓ |
| [PRSA 1977](https://www.prsa.org.au/rule1977.htm) | Simple rules designed for hand counting, using the exclusive Gregory method, with counting performed in thousandths of a vote. | | ✓ |
| [ERS97](https://www.electoral-reform.org.uk/latest-news-and-research/publications/how-to-conduct-an-election-by-the-single-transferable-vote-3rd-edition/) | More complex rules designed for hand counting, using the exclusive Gregory method. | [E8] [E9] | ✓ |
| • ERS76 | Former rules from the 1976 2nd edition. | [E8] [E9] [E10] | ✓ |
@ -119,7 +119,7 @@ When *Surplus method* is set to a Gregory method, this option controls how candi
* *By value*: When excluding candidate(s), transfer their ballots in descending order of accumulated transfer value. Each transfer of all ballots of a certain transfer value forms a separate stage, i.e. if a transfer allows another candidate to meet the quota, no further ballots are transferred to that candidate.
* *By source*: When excluding candidate(s), transfer their ballots according to the candidate from which those ballots were received, in the order the transferring candidates were elected or excluded. Each transfer of all ballots received from a certain candidate forms a separate stage.
* *By parcel (by order)*: When excluding a candidate, transfer their ballot ballots one parcel at a time, in the order each was received. Each parcel forms a separate stage. This option cannot be combined with bulk exclusion.
* *Wright method (re-iterate)*: When excluding candidate(s), reset the count from the distribution of first preferences, disregarding the excluded candidates.
* *Reset and re-iterate*: When excluding candidate(s), reset the count from the distribution of first preferences, disregarding the excluded candidates.
### (Meek) NZ-style exclusion (--meek-nz-exclusion)

@ -16,7 +16,7 @@ STV-counting software is frequently validated empirically by comparing the resul
| Minneapolis STV | [2013 Minneapolis Parks & Recreation Commissioner At Large election](https://vote.minneapolismn.gov/results-data/election-results/2013/park-board-at-large/) | Results sheet (official) | ✓ |
| Cambridge STV | [2003 Cambridge City Council election](https://web.archive.org/web/20070204083508/http://stv.sourceforge.net/) | OpenSTV 1.7, [ChoicePlus Pro 2.1](https://www.votingsolutions.com/cpdetail.htm) (official) | ✓ |
| Dáil Éireann STV | [2002 Dublin North election](https://electionsireland.org/counts.cfm?election=2002&cons=96) | Results sheet (official) | ✓ |
| Wright STV | [EVE Online CSM 15 election](https://www.eveonline.com/news/view/meet-the-new-council) | [ccp-wright-stv](https://github.com/ccpgames/ccp-wright-stv) (official) | ✓ |
| van der Craats (‘Wright’) STV | [EVE Online CSM 15 election](https://www.eveonline.com/news/view/meet-the-new-council) | [ccp-wright-stv](https://github.com/ccpgames/ccp-wright-stv) (official) | ✓ |
| PRSA 1977 | [*Proportional Representation Manual*](https://www.prsa.org.au/publicat.htm#p2) [example 1](https://www.prsa.org.au/utopiatc.pdf) | [Model result](https://www.prsa.org.au/example1.pdf) (official) | ✓ |
| PRSA 1977 | 40 elections from [stvdb](https://gitlab.com/RunasSudo/stvdb) | [count.nl (RunasSudo version)](https://gitlab.com/RunasSudo/prsa_count) | ✓ |
| ERS97 | [Reverse engineered ballots for the ERS97 model election](https://yingtongli.me/blog/2021/01/04/ers97.html) | [Model result](https://www.electoral-reform.org.uk/latest-news-and-research/publications/how-to-conduct-an-election-by-the-single-transferable-vote-3rd-edition/#sub-section-24) (official) | ✓ |

@ -59,7 +59,7 @@
</optgroup>
<optgroup label="Computer-count">
<option value="meek06">Meek STV (2006)</option>
<option value="wright">Wright STV</option>
<option value="vdc">van der Craats (‘Wright’) STV</option>
</optgroup>
</select>
</label>
@ -136,7 +136,7 @@
<option value="by_value">By value</option>
<option value="by_source">By source</option>
<option value="parcels_by_order">By parcel (by order)</option>
<option value="wright">Wright method (re-iterate)</option>
<option value="reset_and_reiterate">Reset and re-iterate</option>
</select>
</label>
<label>

@ -138,7 +138,7 @@ table.transfers tr:first-child td, table.transfers tr:nth-last-child(2) td, tabl
border-bottom: 1px solid #76858c;
}
.blw {
/* Used to separate counts in Wright STV */
/* Used to separate counts in van der Craats (‘Wright’) STV */
border-left: 2px solid #76858c;
}

@ -298,7 +298,7 @@ function changePreset() {
document.getElementById('selPapers').value = 'transferable';
document.getElementById('selExclusion').value = 'single_stage';
document.getElementById('selTies').value = 'forwards,random';
} else if (document.getElementById('selPreset').value === 'wright') {
} else if (document.getElementById('selPreset').value === 'vdc') {
document.getElementById('selQuotaCriterion').value = 'geq';
document.getElementById('selQuota').value = 'droop';
document.getElementById('selQuotaMode').value = 'static';
@ -319,7 +319,7 @@ function changePreset() {
document.getElementById('selSurplus').value = 'by_size';
document.getElementById('selMethod').value = 'wig';
document.getElementById('selPapers').value = 'both';
document.getElementById('selExclusion').value = 'wright';
document.getElementById('selExclusion').value = 'reset_and_reiterate';
document.getElementById('selTies').value = 'random';
} else if (document.getElementById('selPreset').value === 'prsa77') {
document.getElementById('selQuotaCriterion').value = 'geq';

@ -125,8 +125,8 @@ pub struct SubcmdOptions {
#[clap(help_heading=Some("STV VARIANTS"), long)]
subtract_nontransferable: bool,
/// (Gregory STV) Method of exclusions
#[clap(help_heading=Some("STV VARIANTS"), long, possible_values=&["single_stage", "by_value", "by_source", "parcels_by_order", "wright"], default_value="single_stage", value_name="method")]
/// (Gregory STV) Method of exclusions [default: single_stage] [possible values: single_stage, by_value, by_source, parcels_by_order, reset_and_reiterate]
#[clap(help_heading=Some("STV VARIANTS"), long, possible_values=&["single_stage", "by_value", "by_source", "parcels_by_order", "wright", "reset_and_reiterate"], default_value="single_stage", value_name="method", hide_possible_values=true, hide_default_value=true)]
exclusion: String,
/// (Meek STV) NZ Meek STV behaviour: Iterate keep values one round before candidate exclusion

@ -684,8 +684,8 @@ where
state.loss_fraction.transfer(&-checksum);
}
/// Perform one stage of a candidate exclusion according to the Wright method
pub fn wright_exclude_candidates<'a, N: Number>(state: &mut CountState<'a, N>, opts: &STVOptions, excluded_candidates: Vec<&'a Candidate>)
/// Exclude a candidate and reset the count from first preferences
pub fn exclude_candidates_and_reset<'a, N: Number>(state: &mut CountState<'a, N>, opts: &STVOptions, excluded_candidates: Vec<&'a Candidate>)
where
for<'r> &'r N: ops::Sub<&'r N, Output=N>,
for<'r> &'r N: ops::Mul<&'r N, Output=N>,

@ -1051,8 +1051,8 @@ where
// Exclusion in parts compatible only with Gregory method
gregory::exclude_candidates(state, opts, excluded_candidates, complete_type);
}
ExclusionMethod::Wright => {
gregory::wright_exclude_candidates(state, opts, excluded_candidates);
ExclusionMethod::ResetAndReiterate => {
gregory::exclude_candidates_and_reset(state, opts, excluded_candidates);
}
}

@ -520,8 +520,8 @@ pub enum ExclusionMethod {
BySource,
/// Transfer the ballot papers of an excluded candidate parcel by parcel in the order received
ParcelsByOrder,
/// Wright method (re-iterate)
Wright,
/// Reset count and re-iterate from count of first preferences
ResetAndReiterate,
}
impl ExclusionMethod {
@ -532,7 +532,7 @@ impl ExclusionMethod {
ExclusionMethod::ByValue => "--exclusion by_value",
ExclusionMethod::BySource => "--exclusion by_source",
ExclusionMethod::ParcelsByOrder => "--exclusion parcels_by_order",
ExclusionMethod::Wright => "--exclusion wright",
ExclusionMethod::ResetAndReiterate => "--exclusion reset_and_reiterate",
}.to_string()
}
}
@ -544,7 +544,8 @@ impl<S: AsRef<str>> From<S> for ExclusionMethod {
"by_value" => ExclusionMethod::ByValue,
"by_source" => ExclusionMethod::BySource,
"parcels_by_order" => ExclusionMethod::ParcelsByOrder,
"wright" => ExclusionMethod::Wright,
"reset_and_reiterate" => ExclusionMethod::ResetAndReiterate,
"wright" => ExclusionMethod::ResetAndReiterate,
_ => panic!("Invalid --exclusion"),
}
}

@ -385,10 +385,10 @@ pub fn init_results_table<N: Number>(election: &Election<N>, opts: &stv::STVOpti
pub fn update_results_table<N: Number>(stage_num: usize, state: &CountState<N>, opts: &stv::STVOptions, report_style: &str) -> Array {
let result = Array::new();
// Insert borders to left of new exclusions in Wright STV
// Insert borders to left of new exclusions if reset-and-reiterate method applied
let classes_o; // Outer version
let classes_i; // Inner version
if (opts.exclusion == stv::ExclusionMethod::Wright && matches!(state.title, StageKind::ExclusionOf(_))) || matches!(state.title, StageKind::Rollback) {
if (opts.exclusion == stv::ExclusionMethod::ResetAndReiterate && matches!(state.title, StageKind::ExclusionOf(_))) || matches!(state.title, StageKind::Rollback) {
classes_o = r#" class="blw""#;
classes_i = r#"blw "#;
} else {
@ -400,7 +400,7 @@ pub fn update_results_table<N: Number>(stage_num: usize, state: &CountState<N>,
let hide_xfers_trsp;
if let StageKind::FirstPreferences = state.title {
hide_xfers_trsp = true;
} else if opts.exclusion == stv::ExclusionMethod::Wright && matches!(state.title, StageKind::ExclusionOf(_)) {
} else if opts.exclusion == stv::ExclusionMethod::ResetAndReiterate && matches!(state.title, StageKind::ExclusionOf(_)) {
hide_xfers_trsp = true;
} else if let StageKind::Rollback = state.title {
hide_xfers_trsp = true;

@ -25,12 +25,12 @@ fn csm15_float64() {
let stv_opts = stv::STVOptionsBuilder::default()
.round_quota(Some(0))
.quota_criterion(stv::QuotaCriterion::GreaterOrEqual)
.exclusion(stv::ExclusionMethod::Wright)
.exclusion(stv::ExclusionMethod::ResetAndReiterate)
.early_bulk_elect(false)
.bulk_exclude(true)
.build().unwrap();
assert_eq!(stv_opts.describe::<NativeFloat64>(), "--numbers float64 --round-quota 0 --quota-criterion geq --exclusion wright --no-early-bulk-elect --bulk-exclude");
assert_eq!(stv_opts.describe::<NativeFloat64>(), "--numbers float64 --round-quota 0 --quota-criterion geq --exclusion reset_and_reiterate --no-early-bulk-elect --bulk-exclude");
utils::read_validate_election::<NativeFloat64>("tests/data/CSM15.csv", "tests/data/CSM15.blt", stv_opts, Some(6), &["quota"]);
}

Loading…
Cancel
Save