diff --git a/src/multiwinner/methods/exhaustive/psi.h b/src/multiwinner/methods/exhaustive/psi.h index 3d89bcf..48eea80 100644 --- a/src/multiwinner/methods/exhaustive/psi.h +++ b/src/multiwinner/methods/exhaustive/psi.h @@ -53,7 +53,7 @@ double digamma(double x) { // Check the input. if (x <= 0.0) { - throw std::invalid_argument("digamma: x < 0 is not supported"); + throw std::invalid_argument("digamma: x <= 0 is not supported"); } // Initialize. @@ -99,6 +99,12 @@ double psi_voting_eval::evaluate(combo::it & start, combo::it & end, norm_rating_sum += this_ballot.get_norm_score(*pos); } + // digamma(0) = infinity. HACK to deal with this without having + // to bring in infinities. + if (delta + norm_rating_sum == 0) { + return 1e9 * this_ballot.weight; + } + return digamma(delta + norm_rating_sum) * this_ballot.weight; } diff --git a/src/multiwinner/methods/exhaustive/scored_method.h b/src/multiwinner/methods/exhaustive/scored_method.h index 592fe53..dac548f 100644 --- a/src/multiwinner/methods/exhaustive/scored_method.h +++ b/src/multiwinner/methods/exhaustive/scored_method.h @@ -15,6 +15,10 @@ class scored_ballot { std::vector scores; // #voters by #cands double get_norm_score(size_t candidate) const { + assert(min <= max); + assert(scores[candidate] >= min); + assert(scores[candidate] <= max); + return renorm(min, max, scores[candidate], 0.0, 1.0); } diff --git a/src/multiwinner/methods/qpq.h b/src/multiwinner/methods/qpq.h index 8d676d1..c3a9222 100644 --- a/src/multiwinner/methods/qpq.h +++ b/src/multiwinner/methods/qpq.h @@ -1,10 +1,13 @@ #pragma once #include "methods.h" -//#include "../tiebreaker.cc" #include #include +// KNOWN BUG: Does not handle negative scores well. I have no idea why, +// since this is a ranked method. Use multiwinner_spatial with Euclidean +// distance and no noise to reproduce. + class QPQ : public multiwinner_method { private: ordering::const_iterator ballot_contribution(