diff --git a/.clang-tidy b/.clang-tidy index 3d82e1db07..8990525420 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,7 @@ --- Checks: | -*, + clang-diagnostic-*, bugprone-reserved-identifier, modernize-*, -modernize-use-trailing-return-type, @@ -14,42 +15,15 @@ Checks: | WarningsAsErrors: '*' HeaderFilterRegex: '.*' FormatStyle: none -User: arbiter CheckOptions: - - key: llvm-else-after-return.WarnOnConditionVariables - value: 'false' - key: modernize-loop-convert.MinConfidence value: reasonable - key: modernize-replace-auto-ptr.IncludeStyle value: llvm - - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons - value: 'false' - - key: google-readability-namespace-comments.ShortNamespaceLines - value: '10' - - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField - value: 'false' - - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic - value: 'true' - - key: cert-dcl16-c.NewSuffixes - value: 'L;LL;LU;LLU' - - key: google-readability-braces-around-statements.ShortStatementLines - value: '1' - - key: modernize-pass-by-value.IncludeStyle - value: llvm - - key: google-readability-namespace-comments.SpacesBeforeComments - value: '2' - key: modernize-loop-convert.MaxCopySize value: '16' - - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors - value: 'true' - key: modernize-use-nullptr.NullMacros value: 'NULL' - - key: llvm-qualified-auto.AddConstToQualified - value: 'false' - key: modernize-loop-convert.NamingStyle value: CamelCase - - key: llvm-else-after-return.WarnOnUnfixable - value: 'false' - - key: google-readability-function-size.StatementThreshold - value: '800' ... diff --git a/Makefile.am b/Makefile.am index d87d99916f..1e984d47e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -349,7 +349,7 @@ endif # Define VERSION for all C++ compilations and set include paths AM_CPPFLAGS = -I$(top_srcdir)/src -DVERSION=\"$(VERSION)\" -AM_CXXFLAGS = ${LLVM_CXXFLAGS} +AM_CXXFLAGS = ${LLVM_CXXFLAGS} -Wall -Wsign-compare -Wunreachable-code ## Convenience libraries ## @@ -480,6 +480,4 @@ msw-msi: light -ext WixUIExtension gambit.wixobj clang-tidy: - clang-tidy ${top_srcdir}/src/core/*.cc -- --std=c++20 -I ${top_srcdir}/src -DVERSION=\"$(VERSION)\" - clang-tidy ${top_srcdir}/src/games/*.cc ${top_srcdir}/src/games/*/*.cc -- --std=c++20 -I ${top_srcdir}/src -DVERSION=\"$(VERSION)\" - clang-tidy ${top_srcdir}/src/solvers/*/*.cc -- --std=c++20 -I ${top_srcdir}/src -DVERSION=\"$(VERSION)\" + clang-tidy ${top_srcdir}/src/core/*.cc ${top_srcdir}/src/games/*.cc ${top_srcdir}/src/games/*/*.cc ${top_srcdir}/src/solvers/*/*.cc -- --std=c++20 -I ${top_srcdir}/src -DVERSION=\"$(VERSION)\" -Wall -Wsign-compare -Wunreachable-code -Wextra-semi -Wdouble-promotion diff --git a/src/core/function.cc b/src/core/function.cc index 60fb0fefe7..12b2fc3c2e 100644 --- a/src/core/function.cc +++ b/src/core/function.cc @@ -78,85 +78,87 @@ void ConjugatePRMinimizer::AlphaXPlusY(double alpha, const Vector &x, Ve // These routines are drawn from comparably-named ones in // multimin/directional_minimize.c in GSL. -void ConjugatePRMinimizer::TakeStep(const Vector &x, const Vector &p, double step, - double lambda, Vector &x1, Vector &dx) +void ConjugatePRMinimizer::TakeStep(const Vector &p_x, const Vector &p_p, + double p_step, double p_lambda, Vector &p_x1, + Vector &p_dx) { - dx = 0.0; - AlphaXPlusY(-step * lambda, p, dx); - x1 = x; - AlphaXPlusY(1.0, dx, x1); + p_dx = 0.0; + AlphaXPlusY(-p_step * p_lambda, p_p, p_dx); + p_x1 = p_x; + AlphaXPlusY(1.0, p_dx, p_x1); } -void ConjugatePRMinimizer::IntermediatePoint(const Function &fdf, const Vector &x, - const Vector &p, double lambda, double pg, - double stepa, double stepc, double fa, double fc, - Vector &x1, Vector &dx, - Vector &gradient, double &step, double &f) +void ConjugatePRMinimizer::IntermediatePoint(const Function &p_fdf, const Vector &p_x, + const Vector &p_p, double p_lambda, + double p_pg, double p_stepa, double p_stepc, + double p_fa, double p_fc, Vector &p_x1, + Vector &p_dx, Vector &p_gradient, + double &p_step, double &p_f) { double stepb, fb; trial: - const double u = fabs(pg * lambda * stepc); - if ((fc - fa) + u == 0) { + const double u = fabs(p_pg * p_lambda * p_stepc); + if ((p_fc - p_fa) + u == 0) { // TLT: Added this check 2002/08/31 due to floating point exceptions // under MSW. Not really sure how to handle this correctly. throw FunctionMinimizerError(); } - stepb = 0.5 * stepc * u / ((fc - fa) + u); + stepb = 0.5 * p_stepc * u / ((p_fc - p_fa) + u); - TakeStep(x, p, stepb, lambda, x1, dx); + TakeStep(p_x, p_p, stepb, p_lambda, p_x1, p_dx); - fb = fdf.Value(x1); + fb = p_fdf.Value(p_x1); - if (fb >= fa && stepb > 0.0) { + if (fb >= p_fa && stepb > 0.0) { /* downhill step failed, reduce step-size and try again */ - fc = fb; - stepc = stepb; + p_fc = fb; + p_stepc = stepb; goto trial; } - step = stepb; - f = fb; - fdf.Gradient(x1, gradient); + p_step = stepb; + p_f = fb; + p_fdf.Gradient(p_x1, p_gradient); } -void ConjugatePRMinimizer::Minimize(const Function &fdf, const Vector &x, - const Vector &p, double lambda, double stepa, - double stepb, double stepc, double fa, double fb, double fc, - double tol, Vector &x1, Vector &dx1, - Vector &x2, Vector &dx2, - Vector &gradient, double &step, double &f, - double &gnorm) +void ConjugatePRMinimizer::Minimize(const Function &p_fdf, const Vector &p_x, + const Vector &p_p, double p_lambda, double p_stepa, + double p_stepb, double p_stepc, double p_fa, double p_fb, + double p_fc, double p_tol, Vector &p_x1, + Vector &p_dx1, Vector &p_x2, + Vector &p_dx2, Vector &p_gradient, + double &p_step, double &p_f, double &p_gnorm) { /* Starting at (x0, f0) move along the direction p to find a minimum f(x0 - lambda * p), returning the new point x1 = x0-lambda*p, f1=f(x1) and g1 = grad(f) at x1. */ - double u = stepb; - double v = stepa; - double w = stepc; - double fu = fb; - double fv = fa; - double fw = fc; + double u = p_stepb; + double v = p_stepa; + double w = p_stepc; + double fu = p_fb; + double fv = p_fa; + double fw = p_fc; double old2 = fabs(w - v); double old1 = fabs(v - u); double stepm, fm, pg, gnorm1; - double iter = 0; + double num_trials = 0; - x2 = x1; - dx2 = dx1; + p_x2 = p_x1; + p_dx2 = p_dx1; - f = fb; - step = stepb; - gnorm = std::sqrt(gradient.NormSquared()); + p_f = p_fb; + p_step = p_stepb; + p_gnorm = std::sqrt(p_gradient.NormSquared()); mid_trial: - iter++; + num_trials++; - if (iter > 10) { + if (num_trials > 10) { return; /* MAX ITERATIONS */ } @@ -171,24 +173,24 @@ void ConjugatePRMinimizer::Minimize(const Function &fdf, const Vector &x du = e1 / e2; } - if (du > 0 && du < (stepc - stepb) && fabs(du) < 0.5 * old2) { + if (du > 0 && du < (p_stepc - p_stepb) && fabs(du) < 0.5 * old2) { stepm = u + du; } - else if (du < 0 && du > (stepa - stepb) && fabs(du) < 0.5 * old2) { + else if (du < 0 && du > (p_stepa - p_stepb) && fabs(du) < 0.5 * old2) { stepm = u + du; } - else if ((stepc - stepb) > (stepb - stepa)) { - stepm = 0.38 * (stepc - stepb) + stepb; + else if ((p_stepc - p_stepb) > (p_stepb - p_stepa)) { + stepm = 0.38 * (p_stepc - p_stepb) + p_stepb; } else { - stepm = stepb - 0.38 * (stepb - stepa); + stepm = p_stepb - 0.38 * (p_stepb - p_stepa); } - TakeStep(x, p, stepm, lambda, x1, dx1); + TakeStep(p_x, p_p, stepm, p_lambda, p_x1, p_dx1); - fm = fdf.Value(x1); + fm = p_fdf.Value(p_x1); - if (fm > fb) { + if (fm > p_fb) { if (fm < fv) { w = v; v = stepm; @@ -200,17 +202,17 @@ void ConjugatePRMinimizer::Minimize(const Function &fdf, const Vector &x fw = fm; } - if (stepm < stepb) { - stepa = stepm; - fa = fm; + if (stepm < p_stepb) { + p_stepa = stepm; + p_fa = fm; } else { - stepc = stepm; - fc = fm; + p_stepc = stepm; + p_fc = fm; } goto mid_trial; } - else if (fm <= fb) { + else if (fm <= p_fb) { old2 = old1; old1 = fabs(u - stepm); w = v; @@ -220,36 +222,36 @@ void ConjugatePRMinimizer::Minimize(const Function &fdf, const Vector &x fv = fu; fu = fm; - x2 = x1; - dx2 = dx1; + p_x2 = p_x1; + p_dx2 = p_dx1; - fdf.Gradient(x1, gradient); - pg = p * gradient; - gnorm1 = std::sqrt(gradient.NormSquared()); + p_fdf.Gradient(p_x1, p_gradient); + pg = p_p * p_gradient; + gnorm1 = std::sqrt(p_gradient.NormSquared()); - f = fm; - step = stepm; - gnorm = gnorm1; + p_f = fm; + p_step = stepm; + p_gnorm = gnorm1; if (gnorm1 == 0.0) { return; } - if (fabs(pg * lambda / gnorm1) < tol) { + if (fabs(pg * p_lambda / gnorm1) < p_tol) { return; /* SUCCESS */ } - if (stepm < stepb) { - stepc = stepb; - fc = fb; - stepb = stepm; - fb = fm; + if (stepm < p_stepb) { + p_stepc = p_stepb; + p_fc = p_fb; + p_stepb = stepm; + p_fb = fm; } else { - stepa = stepb; - fa = fb; - stepb = stepm; - fb = fm; + p_stepa = p_stepb; + p_fa = p_fb; + p_stepb = stepm; + p_fb = fm; } goto mid_trial; } diff --git a/src/core/function.h b/src/core/function.h index f80b7c664d..86eb8a55b6 100644 --- a/src/core/function.h +++ b/src/core/function.h @@ -91,17 +91,18 @@ class ConjugatePRMinimizer : public FunctionMinimizer { Vector g0; void AlphaXPlusY(double alpha, const Vector &x, Vector &y); - void TakeStep(const Vector &x, const Vector &p, double step, double lambda, - Vector &x1, Vector &dx); - void IntermediatePoint(const Function &fdf, const Vector &x, const Vector &p, - double lambda, double pg, double stepa, double stepc, double fa, - double fc, Vector &x1, Vector &dx, - Vector &gradient, double &step, double &f); - void Minimize(const Function &fdf, const Vector &x, const Vector &p, - double lambda, double stepa, double stepb, double stepc, double fa, double fb, - double fc, double tol, Vector &x1, Vector &dx1, Vector &x2, - Vector &dx2, Vector &gradient, double &step, double &f, - double &gnorm); + void TakeStep(const Vector &p_x, const Vector &p_p, double p_step, + double p_lambda, Vector &p_x1, Vector &p_dx); + void IntermediatePoint(const Function &p_fdf, const Vector &p_x, + const Vector &p_p, double p_lambda, double p_pg, double p_stepa, + double p_stepc, double p_fa, double p_fc, Vector &p_x1, + Vector &p_dx, Vector &p_gradient, double &p_step, + double &p_f); + void Minimize(const Function &p_fdf, const Vector &p_x, const Vector &p_p, + double p_lambda, double p_stepa, double p_stepb, double p_stepc, double p_fa, + double p_fb, double p_fc, double p_tol, Vector &p_x1, + Vector &p_dx1, Vector &p_x2, Vector &p_dx2, + Vector &p_gradient, double &p_step, double &p_f, double &p_gnorm); }; } // end namespace Gambit diff --git a/src/core/integer.cc b/src/core/integer.cc index d11b126d1e..dfcb6108d8 100644 --- a/src/core/integer.cc +++ b/src/core/integer.cc @@ -175,10 +175,14 @@ static IntegerRep *Inew(int newlen) allocsiz <<= 1; // find a power of 2 } allocsiz -= MALLOC_MIN_OVERHEAD; - // assert((unsigned long) allocsiz < MAX_INTREP_SIZE * sizeof(short)); + + const unsigned int repSize = (allocsiz - sizeof(IntegerRep) + sizeof(short)) / sizeof(short); + if (repSize > std::numeric_limits::max()) { + throw std::overflow_error("Integer: requested precision too large"); + } auto *rep = reinterpret_cast(new char[allocsiz]); - rep->sz = (allocsiz - sizeof(IntegerRep) + sizeof(short)) / sizeof(short); + rep->sz = static_cast(repSize); return rep; } diff --git a/src/core/integer.h b/src/core/integer.h index 1ca2cdf5e4..dec2d802eb 100644 --- a/src/core/integer.h +++ b/src/core/integer.h @@ -209,8 +209,8 @@ class Integer { // coercion & conversion - int fits_in_long() const { return Iislong(rep); } - int fits_in_double() const { return Iisdouble(rep); } + bool fits_in_long() const { return Iislong(rep); } + bool fits_in_double() const { return Iisdouble(rep); } long as_long() const { return Itolong(rep); } double as_double() const { return Itodouble(rep); } diff --git a/src/core/rational.cc b/src/core/rational.cc index 7472d2539f..1e440765f2 100644 --- a/src/core/rational.cc +++ b/src/core/rational.cc @@ -27,7 +27,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. #include #include -#include +#include #include #include "util.h" @@ -160,7 +160,7 @@ Rational::Rational(double x) : num(0), den(1) mantissa *= width; mantissa = modf(mantissa, &intpart); num <<= shift; - num += (long)intpart; + num += static_cast(intpart); exponent -= shift; } if (exponent > 0) { @@ -306,7 +306,7 @@ std::istream &operator>>(std::istream &f, Rational &y) } while (ch >= '0' && ch <= '9') { num *= 10; - num += (int)(ch - '0'); + num += (ch - '0'); f.get(ch); if (f.eof() || f.bad()) { ch = ' '; @@ -321,7 +321,7 @@ std::istream &operator>>(std::istream &f, Rational &y) } while (ch >= '0' && ch <= '9') { denom *= 10; - denom += (int)(ch - '0'); + denom += (ch - '0'); f.get(ch); if (f.eof() || f.bad()) { ch = ' '; @@ -337,7 +337,7 @@ std::istream &operator>>(std::istream &f, Rational &y) while (ch >= '0' && ch <= '9') { denom *= 10; num *= 10; - num += (int)(ch - '0'); + num += (ch - '0'); f.get(ch); if (f.eof() || f.bad()) { ch = ' '; @@ -366,14 +366,18 @@ bool Rational::OK() const return v; } -int Rational::fits_in_float() const +bool Rational::fits_in_float() const { - return Rational(FLT_MIN) <= *this && *this <= Rational(FLT_MAX); + // NOLINTBEGIN(clang-diagnostic-double-promotion) + return Rational(std::numeric_limits::min()) <= *this && + *this <= Rational(std::numeric_limits::max()); + // NOLINTEND(clang-diagnostic-double-promotion) } -int Rational::fits_in_double() const +bool Rational::fits_in_double() const { - return Rational(DBL_MIN) <= *this && *this <= Rational(DBL_MAX); + return Rational(std::numeric_limits::min()) <= *this && + *this <= Rational(std::numeric_limits::max()); } // @@ -527,7 +531,7 @@ template <> Rational lexical_cast(const std::string &f) while (ch >= '0' && ch <= '9' && index <= length) { num *= 10; - num += (int)(ch - '0'); + num += (ch - '0'); ch = f[index++]; } @@ -536,7 +540,7 @@ template <> Rational lexical_cast(const std::string &f) ch = f[index++]; while (ch >= '0' && ch <= '9' && index <= length) { denom *= 10; - denom += (int)(ch - '0'); + denom += (ch - '0'); ch = f[index++]; } } @@ -546,7 +550,7 @@ template <> Rational lexical_cast(const std::string &f) while (ch >= '0' && ch <= '9' && index <= length) { denom *= 10; num *= 10; - num += (int)(ch - '0'); + num += (ch - '0'); ch = f[index++]; } @@ -560,7 +564,7 @@ template <> Rational lexical_cast(const std::string &f) } while (ch >= '0' && ch <= '9' && index <= length) { exponent *= 10; - exponent += (int)(ch - '0'); + exponent += (ch - '0'); ch = f[index++]; } if (exponent * expsign > 0) { @@ -587,7 +591,7 @@ template <> Rational lexical_cast(const std::string &f) } while (ch >= '0' && ch <= '9' && index <= length) { exponent *= 10; - exponent += (int)(ch - '0'); + exponent += (ch - '0'); ch = f[index++]; } if (exponent * expsign > 0) { diff --git a/src/core/rational.h b/src/core/rational.h index 0ed9e5b5c4..21f76ca43e 100644 --- a/src/core/rational.h +++ b/src/core/rational.h @@ -103,8 +103,8 @@ class Rational { friend std::istream &operator>>(std::istream &s, Rational &y); friend std::ostream &operator<<(std::ostream &s, const Rational &y); - int fits_in_float() const; - int fits_in_double() const; + bool fits_in_float() const; + bool fits_in_double() const; // procedural versions of operators diff --git a/src/games/agg/agg.cc b/src/games/agg/agg.cc index c99e507c9e..de0801fb90 100644 --- a/src/games/agg/agg.cc +++ b/src/games/agg/agg.cc @@ -22,7 +22,6 @@ // #include -#include #include #include #include "games/agg/gray.h" @@ -219,7 +218,7 @@ std::shared_ptr AGG::makeAGG(istream &in) throw std::runtime_error("Error in game file: expected integer for type of function node #" + std::to_string(i)); } - projTypes[i] = make_proj_func((TypeEnum)pt, in, S, P); + projTypes[i] = make_proj_func(static_cast(pt), in, S, P); } vector>> projS; @@ -331,7 +330,9 @@ void AGG::setProjections(vector>> &projS, } else if (neighb[Node][k] >= S) { const projtype f = projTypes[neighb[Node][k] - S]; - assert(f); + if (!f) { + throw ValueException("AGG: encountered a null projection function"); + } const pair::iterator, multiset::iterator> p = an[neighb[Node][k] - S].equal_range(AS[i][j]); multiset blah(p.first, p.second); @@ -446,7 +447,9 @@ template void AGG::doProjection(int Node, int i, Rational *s); template V AGG::getPurePayoff(int player, const std::vector &s) const { - assert(player >= 0 && player < numPlayers); + if (player < 0 || player >= numPlayers) { + throw ValueException("AGG::getPurePayoff: player index out of range"); + } const int Node = actionSets[player][s[player]]; const int keylen = neighbors[Node].size(); Config pureprofile(projection[Node][0][s[0]]); @@ -634,7 +637,9 @@ template Rational AGG::payoffInnerProd(int node, template V AGG::getMixedPayoff(int player, const StrategyProfile &s) { V result(0); - assert(player >= 0 && player < numPlayers); + if (player < 0 || player >= numPlayers) { + throw ValueException("AGG::getMixedPayoff: player index out of range"); + } for (int act = 0; act < actions[player]; ++act) { if (s[act + firstAction(player)] > V(0)) { result += s[act + firstAction(player)] * getV(player, act, s); @@ -645,7 +650,9 @@ template V AGG::getMixedPayoff(int player, const StrategyProfile &s void AGG::getPayoffVector(std::vector &dest, int player, const StrategyProfile &s) { - assert(player >= 0 && player < numPlayers); + if (player < 0 || player >= numPlayers) { + throw ValueException("AGG::getPayoffVector: player index out of range"); + } for (int act = 0; act < actions[player]; ++act) { dest[act] = getV(player, act, s); } @@ -673,7 +680,7 @@ double AGG::getSymMixedPayoff(StrategyProfile &s) } for (int node = 0; node < numActionNodes; ++node) { - if (s[node] > (double)0.0) { + if (s[node] > 0.0) { result += s[node] * getSymMixedPayoff(node, s); } } @@ -696,7 +703,9 @@ double AGG::getSymMixedPayoff(int node, StrategyProfile &s) if (!isPure[node]) { // then compute EU using trie_map::power() doProjection(node, 0, s); - assert(numPlayers > 1); + if (numPlayers <= 1) { + throw ValueException("AGG::getSymMixedPayoff: requires more than one player"); + } // ConfigDistribution *dest; // m_state.projectedStrat[node][0].power(numPlayers-1, dest, m_state.Pr, // numNei,projFunctions[node]); @@ -715,12 +724,12 @@ double AGG::getSymMixedPayoff(int node, StrategyProfile &s) if (neighbors[node][i] == node) { self = i; } - if (s[neighbors[node][i]] > (double)0) { + if (s[neighbors[node][i]] > 0) { support.push_back(i); null_prob -= s[neighbors[node][i]]; } } - if (numNei < numActionNodes && null_prob > (double)0) { + if (numNei < numActionNodes && null_prob > 0) { support.push_back(-1); } @@ -752,8 +761,10 @@ double AGG::getSymMixedPayoff(int node, StrategyProfile &s) // update prob const double i_prob = (support.at(gc.i) != -1) ? s[neighbors[node][support[gc.i]]] : null_prob; const double d_prob = (support.at(gc.d) != -1) ? s[neighbors[node][support[gc.d]]] : null_prob; - assert(i_prob > (double)0 && d_prob > (double)0); - prob *= ((double)(gc.get().at(gc.d) + 1)) * i_prob / (double)(gc.get().at(gc.i)) / d_prob; + if (i_prob <= 0 || d_prob <= 0) { + throw ValueException("AGG::getSymMixedPayoff: probabilities must be positive"); + } + prob *= (gc.get().at(gc.d) + 1) * i_prob / gc.get().at(gc.i) / d_prob; } // end while @@ -769,7 +780,9 @@ void AGG::getSymConfigProb(int plClass, StrategyProfile &s, int ownPlCla { const int node = uniqueActionSets.at(ownPlClass).at(act); int numPl = playerClasses.at(plClass).size(); - assert(numPl > 0); + if (numPl <= 0) { + throw ValueException("AGG::getSymConfigProb: player class must be non-empty"); + } if (plClass == ownPlClass) { numPl--; @@ -785,7 +798,7 @@ void AGG::getSymConfigProb(int plClass, StrategyProfile &s, int ownPlCla m_state.projectedStrat[node][player].reset(); if (numPl > 0) { for (int j = 0; j < actions[player]; j++) { - if (s[j] > (double)0.0) { + if (s[j] > 0.0) { m_state.projectedStrat[node][player] += make_pair(projection[node][player][j], s[j]); } } @@ -833,12 +846,12 @@ void AGG::getSymConfigProb(int plClass, StrategyProfile &s, int ownPlCla } const int a = node2Action.at(neighbors[node][i]).at(p); - if (a >= 0 && s[a] > (double)0) { + if (a >= 0 && s[a] > 0) { support.push_back(i); null_prob -= s[a]; } } - if (null_prob > (double)0) { + if (null_prob > 0) { support.push_back(-1); } @@ -879,8 +892,10 @@ void AGG::getSymConfigProb(int plClass, StrategyProfile &s, int ownPlCla (support.at(gc.i) != -1) ? s[node2Action[neighbors[node][support[gc.i]]][p]] : null_prob; const double d_prob = (support.at(gc.d) != -1) ? s[node2Action[neighbors[node][support[gc.d]]][p]] : null_prob; - assert(i_prob > (double)0 && d_prob > (double)0); - prob *= ((double)(gc.get().at(gc.d) + 1)) * i_prob / (double)(gc.get().at(gc.i)) / d_prob; + if (i_prob <= 0 || d_prob <= 0) { + throw ValueException("AGG::getSymConfigProb: probabilities must be positive"); + } + prob *= (gc.get().at(gc.d) + 1) * i_prob / gc.get().at(gc.i) / d_prob; } // end while } @@ -889,8 +904,8 @@ double AGG::getKSymMixedPayoff(int playerClass, vector> { double result = 0.0; - for (int act = 0; act < (int)uniqueActionSets[playerClass].size(); act++) { - if (s[playerClass][act] > (double)0.0) { + for (int act = 0; act < static_cast(uniqueActionSets[playerClass].size()); act++) { + if (s[playerClass][act] > 0.0) { result += s[playerClass][act] * getKSymMixedPayoff(playerClass, act, s); } @@ -902,8 +917,8 @@ double AGG::getKSymMixedPayoff(int playerClass, StrategyProfile &s) { double result = 0.0; - for (int act = 0; act < (int)uniqueActionSets[playerClass].size(); act++) { - if (s[firstKSymAction(playerClass) + act] > (double)0.0) { + for (int act = 0; act < static_cast(uniqueActionSets[playerClass].size()); act++) { + if (s[firstKSymAction(playerClass) + act] > 0.0) { result += s[firstKSymAction(playerClass) + act] * getKSymMixedPayoff(s, playerClass, act); } @@ -991,7 +1006,9 @@ void AGG::makeMAPPINGpayoff(std::istream &in, PayoffTable &pay, ExactPayoffTable } c = in.get(); - assert(in.good()); + if (!in.good()) { + throw std::runtime_error("ERROR: unexpected end of input while reading configuration"); + } if (c != AGG::LBRACKET) { throw std::runtime_error("ERROR: " + std::to_string(AGG::LBRACKET) + " expected. Instead, got " + std::to_string(c)); @@ -1010,7 +1027,9 @@ void AGG::makeMAPPINGpayoff(std::istream &in, PayoffTable &pay, ExactPayoffTable in >> ws; c = in.get(); // get right bracket - assert(in.good()); + if (!in.good()) { + throw std::runtime_error("ERROR: unexpected end of input while reading configuration"); + } if (c != AGG::RBRACKET) { throw std::runtime_error("ERROR: " + std::to_string(AGG::RBRACKET) + @@ -1059,7 +1078,9 @@ void AGG::makeMAPPINGpayoff(std::istream &in, PayoffTable &pay, ExactPayoffTable template V AGG::getMaxPayoff() const { - assert(numActionNodes > 0); + if (numActionNodes <= 0) { + throw ValueException("AGG::getMaxPayoff: game has no action nodes"); + } if constexpr (std::is_same_v) { Rational result = static_cast(exactPayoffs[0].begin()->second); for (int i = 0; i < numActionNodes; i++) { @@ -1082,7 +1103,9 @@ template V AGG::getMaxPayoff() const template V AGG::getMinPayoff() const { - assert(numActionNodes > 0); + if (numActionNodes <= 0) { + throw ValueException("AGG::getMinPayoff: game has no action nodes"); + } if constexpr (std::is_same_v) { Rational result = static_cast(exactPayoffs[0].begin()->second); for (int i = 0; i < numActionNodes; i++) { diff --git a/src/games/agg/bagg.cc b/src/games/agg/bagg.cc index c938c4f668..88682c2f68 100644 --- a/src/games/agg/bagg.cc +++ b/src/games/agg/bagg.cc @@ -3,7 +3,6 @@ #include #include #include -#include #include #include "games/agg/bagg.h" @@ -209,7 +208,9 @@ template V BAGG::getMixedPayoff(int player, int tp, const StrategyProf void BAGG::getPayoffVector(std::vector &dest, int player, int tp, const StrategyProfile &s) { - assert(player >= 0 && player < getNumPlayers() && tp >= 0 && tp < getNumTypes(player)); + if (player < 0 || player >= getNumPlayers() || tp < 0 || tp >= getNumTypes(player)) { + throw ValueException("BAGG::getPayoffVector: player or type index out of range"); + } for (size_t act = 0; act < typeActionSets[player][tp].size(); ++act) { dest[act] = getV(player, tp, act, s); } diff --git a/src/games/agg/trie_map.h b/src/games/agg/trie_map.h index 495930e7e1..6d7c6386d0 100644 --- a/src/games/agg/trie_map.h +++ b/src/games/agg/trie_map.h @@ -50,7 +50,7 @@ template struct TrieNode { // constructor TrieNode(size_t branches, typename std::list, V>>::iterator v) - : children(branches, (TrieNode *)nullptr), val(v) + : children(branches, nullptr), val(v) { } @@ -60,7 +60,7 @@ template struct TrieNode { return children[i]; } else { - children.resize(i + 1, (TrieNode *)nullptr); + children.resize(i + 1, nullptr); return children[i]; } } @@ -162,7 +162,7 @@ template class trie_map { { size_t i = 0; TrieNode *ptr = root; - for (; i < k.size() && k[i] < (int)ptr->children.size() && ptr->children[k[i]]; + for (; i < k.size() && k[i] < static_cast(ptr->children.size()) && ptr->children[k[i]]; ptr = ptr->children[k[i++]]) { } @@ -189,11 +189,11 @@ template class trie_map { std::vector &f); // inner product - V inner_prod(trie_map &other, V init = (V)(0)) const; + V inner_prod(trie_map &other, V init = static_cast(0)) const; // first apply the action x, then inner prod V inner_prod(const std::vector &x, size_t keylen, std::vector &f, - trie_map &other, V init = (V)(0)) const; + trie_map &other, V init = static_cast(0)) const; // polynomial division trie_map &operator/=(const std::vector &denom); diff --git a/src/games/agg/trie_map.imp b/src/games/agg/trie_map.imp index a519b11244..df6d9418c7 100644 --- a/src/games/agg/trie_map.imp +++ b/src/games/agg/trie_map.imp @@ -40,7 +40,7 @@ trie_map::insert(const trie_map::value_type &x) // ind=x.first[i]; ind = *(p++); if (ind >= ptr->children.size()) { - ptr->children.resize(ind + 1, (TrieNode *)nullptr); + ptr->children.resize(ind + 1, nullptr); } if (ptr->children[ind] == nullptr) { ptr->children[ind] = new TrieNode(initBranches, data.end()); @@ -62,7 +62,7 @@ typename trie_map::iterator &trie_map::find(const trie_map::key_type &k { size_t i = 0; TrieNode *ptr = root; - for (; i < k.size() && k[i] < (int)ptr->children.size() && ptr->children[k[i]]; + for (; i < k.size() && k[i] < static_cast(ptr->children.size()) && ptr->children[k[i]]; ptr = ptr->children[k[i++]]) ; @@ -74,7 +74,7 @@ typename trie_map::iterator trie_map::findExact(const trie_map::key_typ { size_t i = 0; TrieNode *ptr = root; - for (; i < k.size() && k[i] < (int)ptr->children.size() && ptr->children[k[i]]; + for (; i < k.size() && k[i] < static_cast(ptr->children.size()) && ptr->children[k[i]]; ptr = ptr->children[k[i++]]) ; @@ -124,18 +124,16 @@ void trie_map::multiply(const trie_map &t1, const trie_map &t2, size_t static size_t i; static std::pair, V> v; const_iterator p1, p2; - // assert(this!=&t1 && this != &t2); v.first.resize(keylen); reset(); for (p1 = t1.begin(); p1 != t1.end(); ++p1) { - if ((*p1).second > (V)0) { + if ((*p1).second > static_cast(0)) { for (p2 = t2.begin(); p2 != t2.end(); ++p2) { - if ((*p2).second > (V)0) { - // assert((*p1).first.size()==keylen&& (*p2).first.size()==keylen); + if ((*p2).second > static_cast(0)) { for (i = 0; i < keylen; ++i) { v.first[i] = (*(f[i]))((*p1).first[i], (*p2).first[i]); } - v.second = (V)((*p1).second * (*p2).second); + v.second = (*p1).second * (*p2).second; (*this) += v; } } // end for(p2 @@ -150,7 +148,8 @@ void trie_map::multiply(const trie_map &other, size_t keylen, std::vector< static size_t i; if (&other == this) { - std::runtime_error("Error: (in-place) multiply: other should not be the same object as self"); + throw std::runtime_error( + "Error: (in-place) multiply: other should not be the same object as self"); } std::list::value_type> data2; data2 = data; @@ -161,21 +160,21 @@ void trie_map::multiply(const trie_map &other, size_t keylen, std::vector< TrieNode *ptr; for (p1 = data2.begin(); p1 != data2.end(); ++p1) { - if ((*p1).second > (V)0.0) { + if ((*p1).second > static_cast(0.0)) { for (auto p2 = other.begin(); p2 != other.end(); ++p2) { - if ((*p2).second > (V)0.0) { + if ((*p2).second > static_cast(0.0)) { ptr = root; for (i = 0; i < keylen; ++i) { v.first[i] = (*(f[i]))((*p1).first[i], (*p2).first[i]); - if (v.first[i] >= (int)ptr->children.size()) { - ptr->children.resize(v.first[i] + 1, (TrieNode *)nullptr); + if (v.first[i] >= static_cast(ptr->children.size())) { + ptr->children.resize(v.first[i] + 1, nullptr); } if (ptr->children[v.first[i]] == nullptr) { ptr->children[v.first[i]] = new TrieNode(initBranches, data.end()); } ptr = ptr->children[v.first[i]]; } - v.second = (V)((*p1).second * (*p2).second); + v.second = (*p1).second * (*p2).second; if (ptr->val != data.end()) { ptr->val->second += v.second; } @@ -195,19 +194,17 @@ void trie_map::square(trie_map &dest, size_t keylen, std::vector { static std::pair, V> v; v.first.resize(keylen); - // assert(this!=&dest); dest.reset(); for (auto p1 = begin(); p1 != end(); ++p1) { - if ((*p1).second > (V)0) { + if ((*p1).second > static_cast(0)) { for (auto p2 = p1; p2 != end(); ++p2) { - if ((*p2).second > (V)0) { - // assert((*p1).first.size()==keylen&& (*p2).first.size()==keylen); + if ((*p2).second > static_cast(0)) { for (size_t i = 0; i < keylen; ++i) { v.first[i] = (*(f[i]))((*p1).first[i], (*p2).first[i]); } - v.second = (V)((*p1).second * (*p2).second); + v.second = (*p1).second * (*p2).second; if (p1 != p2) { - v.second *= (V)2; + v.second *= static_cast(2); } dest += v; } @@ -225,16 +222,15 @@ template void trie_map::square(size_t keylen, std::vector data2 = data; reset(); for (p1 = data2.begin(); p1 != end(); ++p1) { - if ((*p1).second > (V)0) { + if ((*p1).second > static_cast(0)) { for (p2 = p1; p2 != data2.end(); ++p2) { - if ((*p2).second > (V)0) { - // assert((*p1).first.size()==keylen&& (*p2).first.size()==keylen); + if ((*p2).second > static_cast(0)) { for (size_t i = 0; i < keylen; ++i) { v.first[i] = (*(f[i]))((*p1).first[i], (*p2).first[i]); } - v.second = (V)((*p1).second * (*p2).second); + v.second = (*p1).second * (*p2).second; if (p1 != p2) { - v.second *= (V)2; + v.second *= static_cast(2); } (*this) += v; } @@ -247,7 +243,6 @@ template void trie_map::power(size_t p, trie_map &dest, trie_map &scratch, size_t keylen, std::vector &f) { - // assert(p>0 && this!=&dest ); if (p == 1) { dest = *this; return; @@ -271,10 +266,10 @@ template V trie_map::inner_prod(trie_map &other, V init /*= (V) { V result(init); for (auto p = begin(); p != end(); ++p) { - if ((*p).second > (V)0) { + if ((*p).second > static_cast(0)) { auto p2 = other.find((*p).first); if (p2 == other.end()) { - if (p->second > (V)THRESH) { + if (p->second > static_cast(THRESH)) { std::stringstream str; str << "inner_prod WARNING: discarding ["; copy(p->first.begin(), p->first.end(), std::ostream_iterator(str, " ")); @@ -299,9 +294,8 @@ V trie_map::inner_prod(const std::vector &x, size_t keylen, std::vector< static iterator p2; // V s(-1); for (auto p = begin(); p != end(); ++p) { - if ((*p).second > (V)0) { + if ((*p).second > static_cast(0)) { value_type y = *p; - // assert(y.first.size()==keylen); for (size_t i = 0; i < keylen; ++i) { y.first[i] = (*(f[i]))(y.first[i], x[i]); } @@ -330,7 +324,7 @@ template trie_map &trie_map::operator/=(const std::vector &de int piv = -1; for (size_t i = 0; i < denom.size(); ++i) { if (denom[i] > th) { - piv = (int)i; + piv = static_cast(i); break; } } @@ -368,14 +362,14 @@ void trie_map::div(const std::vector &denom, TrieNode *n, int current, return; } - for (i = 0; i < (int)(n->children.size()) - 1; i++) { + for (i = 0; i < static_cast(n->children.size()) - 1; i++) { n->children[i] = n->children[i + 1]; } n->children.pop_back(); typename trie_map::div_helper f(denom, pivot, data.end()); for (i = n->children.size() - 1; i >= 0; i--) { - if (i < (int)(n->children.size()) - 1 && n->children[i + 1]) { + if (i < static_cast(n->children.size()) - 1 && n->children[i + 1]) { // if(!n->children[i])n->children[i]=new TrieNode(initBranches, data.end()); typename trie_map::div_helper_mul g(denom, pivot, n->children[i], data.end()); in_order_subtree(g, n->children[i + 1]); @@ -411,11 +405,11 @@ template void trie_map::deleteNodes(TrieNode *n) template void trie_map::div_helper_mul::add(const std::vector &conf, V y) { const size_t keylen = conf.size(); - const double th(THRESH / (double)denom[pivot]); + const double th(THRESH / static_cast(denom[pivot])); // if (y<=th&&y>=-th) return; if (!dest) { - if ((double)y > th || (double)y < -th) { + if (static_cast(y) > th || static_cast(y) < -th) { std::stringstream str; str << "division (pivot=" << denom[pivot] << ") WARNING: discarding " << y; throw std::runtime_error(str.str()); @@ -425,7 +419,7 @@ template void trie_map::div_helper_mul::add(const std::vector TrieNode *ptr = dest; for (size_t i = pivot + 1; i < keylen; ++i) { if ((*ptr)[conf[i]] == nullptr) { - if ((double)y > th || (double)y < -th) { + if (static_cast(y) > th || static_cast(y) < -th) { std::stringstream str; str << "division (pivot=" << denom[pivot] << ") WARNING: discarding " << y; throw std::runtime_error(str.str()); @@ -435,15 +429,14 @@ template void trie_map::div_helper_mul::add(const std::vector ptr = (*ptr)[conf[i]]; } ptr->val->second += y; - // assert(ptr->val->second>-THRESH); - if ((double)ptr->val->second <= -th) { + if (static_cast(ptr->val->second) <= -th) { std::stringstream str; str << "division (pivot=" << denom[pivot] << ") WARNING: discarding " << ptr->val->second << std::endl; throw std::runtime_error(str.str()); } - if (ptr->val->second < (V)0) { - ptr->val->second = (V)0; + if (ptr->val->second < static_cast(0)) { + ptr->val->second = static_cast(0); } } @@ -453,11 +446,10 @@ template void trie_map::div_helper_mul::operator()(iterator p) return; } const size_t keylen = p->first.size(); - // assert(keylen==denom.size()); - V null_prob(((V)1) - denom[pivot]); + V null_prob(static_cast(1) - denom[pivot]); // V th(THRESH); for (size_t i = pivot + 1; i < keylen; ++i) { - if (denom[i] > (V)0) { + if (denom[i] > static_cast(0)) { p->first[i]++; add(p->first, -denom[i] * p->second); p->first[i]--; @@ -465,7 +457,7 @@ template void trie_map::div_helper_mul::operator()(iterator p) } } - if (null_prob > (V)0) { + if (null_prob > static_cast(0)) { add(p->first, -null_prob * p->second); } } diff --git a/src/games/behavspt.h b/src/games/behavspt.h index ce578d1ceb..155e6318ca 100644 --- a/src/games/behavspt.h +++ b/src/games/behavspt.h @@ -210,7 +210,7 @@ class BehaviorSupportProfile { GameRep::Players GetPlayers() const { return GetGame()->GetPlayers(); } template MixedBehaviorProfile ToMixedBehaviorProfile(const std::map &) const; - Infosets GetInfosets() const { return {this}; }; + Infosets GetInfosets() const { return {this}; } SequenceContingencies GetSequenceContingencies() const; std::shared_ptr> GetReachableInfosets() const; diff --git a/src/games/game.cc b/src/games/game.cc index 8621a9c6c4..a29e01882f 100644 --- a/src/games/game.cc +++ b/src/games/game.cc @@ -449,7 +449,6 @@ template void MixedStrategyProfile::ComputePayoffs() const for (const auto &strategy : strategies) { newCache.m_strategyValues[player][strategy] = *value_it; ++value_it; - ; } } else { @@ -460,7 +459,7 @@ template void MixedStrategyProfile::ComputePayoffs() const } newCache.m_valid = true; m_cache = std::move(newCache); -}; +} template T MixedStrategyProfile::GetLiapValue() const { diff --git a/src/games/gametree.cc b/src/games/gametree.cc index ffb2e15729..1662bac363 100644 --- a/src/games/gametree.cc +++ b/src/games/gametree.cc @@ -959,7 +959,7 @@ bool GameTreeRep::IsConstSum() const static void OnVisit(GameNode, int) {} }; - ConstSumCallback callback{this}; + ConstSumCallback callback{this, {}}; WalkDFS(Game(const_cast(this)->shared_from_this()), m_root, TraversalOrder::Postorder, callback); return callback.m_isConstSum; @@ -1000,7 +1000,7 @@ Rational GameTreeRep::AggregateSubtreePayoff(const GamePlayer &p_player, static void OnVisit(GameNode, int) {} }; - AggregatePayoffCallback callback{p_player, std::move(p_aggregator)}; + AggregatePayoffCallback callback{p_player, std::move(p_aggregator), {}}; WalkDFS(Game(const_cast(this)->shared_from_this()), m_root, TraversalOrder::Postorder, callback); @@ -1546,7 +1546,7 @@ const GameTreeRep::SubgameData &GameTreeRep::GetSubgameData() const SpanVisitor span_visitor{disc, hull}; WalkDFS(game, m_root, TraversalOrder::Postorder, span_visitor); - BridgeVisitor bridge_visitor{disc, hull, sd.m_subgamePostorder}; + BridgeVisitor bridge_visitor{disc, hull, sd.m_subgamePostorder, {}}; WalkDFS(game, m_root, TraversalOrder::Postorder, bridge_visitor); // Phase 3: Build subgame tree with subgame differences @@ -1599,8 +1599,8 @@ const GameTreeRep::SubgameData &GameTreeRep::GetSubgameData() const const std::unordered_set subgame_root_set(sd.m_subgamePostorder.begin(), sd.m_subgamePostorder.end()); - SubgameVisitor subgame_visitor{subgame_root_set, sd.m_subgameByRoot, - const_cast(this)}; + SubgameVisitor subgame_visitor{ + subgame_root_set, sd.m_subgameByRoot, const_cast(this), {}, {}}; WalkDFS(game, m_root, TraversalOrder::Preorder, subgame_visitor); return sd; }); diff --git a/src/games/writer.h b/src/games/writer.h index 2c7ffa5aab..7cb23f54ed 100644 --- a/src/games/writer.h +++ b/src/games/writer.h @@ -67,17 +67,6 @@ std::string FormatList(const C &p_container, T p_renderer, bool p_commas = false return s; } -/// -/// Abstract base class for objects that write games to various formats -/// -class GameWriter { -public: - /// - /// Convert the game to a string-based representation - /// - virtual std::string Write(const Game &) const = 0; -}; - /// /// Convert the game to HTML, selecting the row and column player. /// diff --git a/src/pygambit/gambit.pyx b/src/pygambit/gambit.pyx index ac1665248b..7a61fc3836 100644 --- a/src/pygambit/gambit.pyx +++ b/src/pygambit/gambit.pyx @@ -79,27 +79,6 @@ def _to_number(value: typing.Any) -> c_Number: return c_Number(_to_number_string(value).encode("ascii")) -@cython.cfunc -def _resolve_by_label(collection, label: str, scope: str, kind: str, kind_plural: str): - """Resolve a member of a game collection by its text label. - - Game collections are accessed by label, not by position. Lookup is by exact label match. - - Failure modes: - * an empty label raises ``ValueError``; - * a label matching no member raises ``KeyError``; - * a label matching more than one member raises ``ValueError``. - """ - if not label: - raise ValueError(f"{kind} label cannot be empty") - matches = [x for x in collection if x.label == label] - if not matches: - raise KeyError(f"{scope} has no {kind} with label '{label}'") - if len(matches) > 1: - raise ValueError(f"{scope} has multiple {kind_plural} with label '{label}'") - return matches[0] - - ProfileDType = float | Rational diff --git a/src/solvers/enummixed/enummixed.cc b/src/solvers/enummixed/enummixed.cc index 4e5e55f0ff..0f5b2671a8 100644 --- a/src/solvers/enummixed/enummixed.cc +++ b/src/solvers/enummixed/enummixed.cc @@ -124,8 +124,8 @@ EnumMixedStrategySolveDetailed(const Game &p_game, StrategyCallbackType p_onE // Construct vectors b1, b2 Vector b1(1, p_game->GetPlayer(1)->GetStrategies().size()); Vector b2(1, p_game->GetPlayer(2)->GetStrategies().size()); - b1 = (T)-1; - b2 = (T)-1; + b1 = static_cast(-1); + b2 = static_cast(-1); // enumerate vertices of A1 x + b1 <= 0 and A2 x + b2 <= 0 const auto poly1 = EnumerateVertices(A1, b1, p_cancel); diff --git a/src/solvers/gtracer/aggame.cc b/src/solvers/gtracer/aggame.cc index f567d63490..1b4269b794 100644 --- a/src/solvers/gtracer/aggame.cc +++ b/src/solvers/gtracer/aggame.cc @@ -76,7 +76,7 @@ void aggame::KSymPayoffMatrix(cmatrix &dest, const cvector &s, double fuzz) cons for (int cola = 0; cola < getNumKSymActions(colcls); ++cola) { dest(rowa + firstKSymAction(rowcls), cola + firstKSymAction(colcls)) = - (double)multiplier * aggPtr->getKSymMixedPayoff(sp, rowcls, rowa, colcls, cola); + multiplier * aggPtr->getKSymMixedPayoff(sp, rowcls, rowa, colcls, cola); } } } diff --git a/src/solvers/gtracer/cmatrix.cc b/src/solvers/gtracer/cmatrix.cc index 918ab4fd62..9b32820365 100644 --- a/src/solvers/gtracer/cmatrix.cc +++ b/src/solvers/gtracer/cmatrix.cc @@ -48,7 +48,7 @@ int cmatrix::LUdecomp(cmatrix &LU, std::vector &ix) const vv[i] = dum; } } - if (vv[i] == (double)0.0) { + if (vv[i] == 0.0) { delete[] vv; return 0; } diff --git a/src/solvers/gtracer/cmatrix.h b/src/solvers/gtracer/cmatrix.h index f43f725775..0ea48cac4d 100644 --- a/src/solvers/gtracer/cmatrix.h +++ b/src/solvers/gtracer/cmatrix.h @@ -30,6 +30,8 @@ #include #include +#include "core/util.h" + namespace Gambit::gametracer { class cvector { @@ -709,7 +711,9 @@ class cmatrix { void multiply(const cvector &source, cvector &dest) const { - // assert(n == source.m && m == dest.m); + if (n != source.m || m != dest.m) { + throw DimensionException(); + } int i, j, c = 0; for (i = 0; i < m; i++) { dest[i] = 0; diff --git a/src/solvers/gtracer/gnm.cc b/src/solvers/gtracer/gnm.cc index 93a0b76d1c..cef1d5efe6 100644 --- a/src/solvers/gtracer/gnm.cc +++ b/src/solvers/gtracer/gnm.cc @@ -27,7 +27,7 @@ namespace Gambit::gametracer { -const double BIGFLOAT = 3.0e+28F; +const double BIGFLOAT = 3.0e+28; // LNM runs the local Newton method on z to attempt to bring it closer to // the image of the graph of the equilibrium correspondence above the ray, @@ -44,7 +44,7 @@ double LNM(const gnmgame &game, cvector &z, const cvector &g, double det, cmatri for (k = 0; k < MaxLNM; k++) { // del = z - s - DG*s / (double)(numPlayers - 1) - g; DG.multiply(s, del); - del /= (double)(game.getNumPlayers() - 1); + del /= (game.getNumPlayers() - 1); del += g; del += s; del -= z; @@ -174,7 +174,7 @@ GNMResult GNM(gnmgame &A, cvector &g, int steps, double fuzz, int LNMFreq, int L A.payoffMatrix(DG, sigma, fuzz); DG.multiply(sigma, v); - v /= (double)(N - 1); + v /= (N - 1); // Scale g until the equilibrium sigma calculated above // is in fact the one unique equilibrium, and set lambda @@ -247,7 +247,7 @@ GNMResult GNM(gnmgame &A, cvector &g, int steps, double fuzz, int LNMFreq, int L // Calculate payoff cvector DG.multiply(sigma, v); - v /= (double)(N - 1); + v /= (N - 1); ym1 = g; ym1 *= lambda; v += ym1; @@ -386,7 +386,7 @@ GNMResult GNM(gnmgame &A, cvector &g, int steps, double fuzz, int LNMFreq, int L } // already at the support boundary DG.multiply(sigma, err); - err /= (double)(N - 1); + err /= (N - 1); g0 = g; g0 *= lambda; err += g0; @@ -401,7 +401,7 @@ GNMResult GNM(gnmgame &A, cvector &g, int steps, double fuzz, int LNMFreq, int L if (ee > threshold) { // if we've accumulated too much error, either if (wobble) { // wobble or quit. DG.multiply(sigma, ym1); - ym1 /= (double)(N - 1); + ym1 /= (N - 1); g = z; g -= sigma; g -= ym1; @@ -459,7 +459,7 @@ GNMResult GNM(gnmgame &A, cvector &g, int steps, double fuzz, int LNMFreq, int L if (N > 2 && wobble) { A.payoffMatrix(DG, sigma, fuzz); DG.multiply(sigma, ym1); - ym1 /= (double)(N - 1); + ym1 /= (N - 1); g = z; g -= sigma; g -= ym1; diff --git a/src/solvers/gtracer/gnmgame.cc b/src/solvers/gtracer/gnmgame.cc index 529d3de8a3..175852c0bd 100644 --- a/src/solvers/gtracer/gnmgame.cc +++ b/src/solvers/gtracer/gnmgame.cc @@ -95,7 +95,7 @@ void gnmgame::retract(cvector &dest, const cvector &z) const } sumz += y[i]; } - v = (sumz - 1) / (double)(i - firstAction(n)); + v = (sumz - 1) / (i - firstAction(n)); for (i = firstAction(n); i < lastAction(n); i++) { dest[i] = z[i] - v; if (dest[i] < 0.0) { diff --git a/src/solvers/gtracer/ipa.cc b/src/solvers/gtracer/ipa.cc index ed974a3642..5cc16cb6b3 100644 --- a/src/solvers/gtracer/ipa.cc +++ b/src/solvers/gtracer/ipa.cc @@ -78,7 +78,7 @@ int Pivot(cmatrix &T, int pr, int pc, std::vector &row, std::vector &c void LemkeHowson(const gnmgame &game, cvector &dest, cmatrix &T, std::vector &Im) { - const double BIGFLOAT = 3.0e+28F; + const double BIGFLOAT = 3.0e+28; const int numActions = game.getNumActions(), numPlayers = game.getNumPlayers(); double D = 1; const int cg = numActions + numPlayers; @@ -245,7 +245,7 @@ IPAResult IPA(const gnmgame &A, const cvector &g, cvector &zh, double alpha, dou for (unsigned int iter = 1; iter <= maxiter; iter++) { p_cancel.Check(); A.payoffMatrix(DG, sh, 0.0); - DG /= (double)(N - 1); // find the Jacobian of the approximating bimatrix game + DG /= (N - 1); // find the Jacobian of the approximating bimatrix game InitialiseLHTableau(T, A, DG, g); diff --git a/src/solvers/ipa/ipa.cc b/src/solvers/ipa/ipa.cc index 4583236a17..725d43a600 100644 --- a/src/solvers/ipa/ipa.cc +++ b/src/solvers/ipa/ipa.cc @@ -91,7 +91,8 @@ IPAStrategySolve(const MixedStrategyProfile &p_pert, .profile = profile, .iteration = p_iteration, .zDiff = p_zDiff, .sDiff = p_sDiff}); }; - IPAResult result{cvector(A->getNumActions()), IPATerminationReason::MaxIterationsReached, 0}; + IPAResult result{ + cvector(A->getNumActions()), IPATerminationReason::MaxIterationsReached, 0, 0, 0, 0.0}; for (int restart = 0; restart < MAX_RESTARTS; restart++) { p_cancel.Check(); result = IPA(*A, g, zh, ALPHA, EQERR, 100, onStep, p_cancel); diff --git a/src/solvers/lcp/nfglcp.cc b/src/solvers/lcp/nfglcp.cc index 874bd8150c..ab77ac3d8b 100644 --- a/src/solvers/lcp/nfglcp.cc +++ b/src/solvers/lcp/nfglcp.cc @@ -96,7 +96,7 @@ template Matrix Make_A2(const Game &p_game) template Vector Make_b1(const Game &p_game) { Vector b1(1, p_game->GetPlayer(1)->GetStrategies().size()); - b1 = -(T)1; + b1 = -static_cast(1); return b1; } @@ -105,7 +105,7 @@ template Vector Make_b2(const Game &p_game) Vector b2(p_game->GetPlayer(1)->GetStrategies().size() + 1, p_game->GetPlayer(1)->GetStrategies().size() + p_game->GetPlayer(2)->GetStrategies().size()); - b2 = -(T)1; + b2 = -static_cast(1); return b2; } @@ -175,14 +175,14 @@ NashLcpStrategySolver::OnBFS(const Game &p_game, linalg::LHTableau &p_tabl MixedStrategyProfile profile(p_game->NewMixedStrategyProfile(static_cast(0.0))); const int n1 = p_game->GetPlayer(1)->GetStrategies().size(); const int n2 = p_game->GetPlayer(2)->GetStrategies().size(); - T sum = (T)0; + T sum = static_cast(0); for (int j = 1; j <= n1; j++) { if (cbfs.count(j)) { sum += cbfs[j]; } } - if (sum == (T)0) { + if (sum == static_cast(0)) { // This is the trivial CBFS. return SearchResult::PruneBranch; } @@ -193,11 +193,11 @@ NashLcpStrategySolver::OnBFS(const Game &p_game, linalg::LHTableau &p_tabl profile[strategy] = cbfs[j] / sum; } else { - profile[strategy] = (T)0; + profile[strategy] = static_cast(0); } } - sum = (T)0; + sum = static_cast(0); for (int j = 1; j <= n2; j++) { if (cbfs.count(n1 + j)) { sum += cbfs[n1 + j]; @@ -210,7 +210,7 @@ NashLcpStrategySolver::OnBFS(const Game &p_game, linalg::LHTableau &p_tabl profile[strategy] = cbfs[n1 + j] / sum; } else { - profile[strategy] = (T)0; + profile[strategy] = static_cast(0); } } diff --git a/src/solvers/linalg/lptab.cc b/src/solvers/linalg/lptab.cc index e2444955c2..caae5b79ba 100644 --- a/src/solvers/linalg/lptab.cc +++ b/src/solvers/linalg/lptab.cc @@ -104,7 +104,7 @@ template <> Rational LPTableau::ComputeTotalCost() const GetBasisVector(sol); for (int i = tmpcol.front_index(); i <= tmpcol.back_index(); i++) { if (GetLabel(i) > 0) { - tmpcol[i] /= (Rational)Tableau::GetTotalDenominator(); + tmpcol[i] /= static_cast(Tableau::GetTotalDenominator()); } } @@ -118,7 +118,7 @@ template T LPTableau::ComputeRelativeCost(int col) const return m_unitCost[-col] - m_dual[-col]; } else { - this->GetColumn(col, (Vector &)tmpcol); + this->GetColumn(col, tmpcol); return m_cost[col] - m_dual * tmpcol; } } diff --git a/src/solvers/linalg/tableau.cc b/src/solvers/linalg/tableau.cc index ef4578b42c..893bc83537 100644 --- a/src/solvers/linalg/tableau.cc +++ b/src/solvers/linalg/tableau.cc @@ -195,9 +195,10 @@ Integer find_lcd(const Vector &vec) // Tableau::Tableau(const Matrix &A, const Vector &b) - : TableauBase(A, b), m_tableauData(A.MinRow(), A.MaxRow(), A.MinCol(), A.MaxCol()), + : TableauBase(A, b), m_nonbasicLabels(A.MinCol(), A.MaxCol()), + m_tableauData(A.MinRow(), A.MaxRow(), A.MinCol(), A.MaxCol()), m_scaledRHS(b.front_index(), b.back_index()), m_pivotDenominator(1), - m_scratchColumn(b.front_index(), b.back_index()), m_nonbasicLabels(A.MinCol(), A.MaxCol()) + m_scratchColumn(b.front_index(), b.back_index()) { for (int j = MinCol(); j <= MaxCol(); j++) { m_nonbasicLabels[j] = j; @@ -231,11 +232,10 @@ Tableau::Tableau(const Matrix &A, const Vector &b) Tableau::Tableau(const Matrix &A, const Array &art, const Vector &b) - : TableauBase(A, art, b), + : TableauBase(A, art, b), m_nonbasicLabels(A.MinCol(), A.MaxCol() + art.size()), m_tableauData(A.MinRow(), A.MaxRow(), A.MinCol(), A.MaxCol() + art.size()), m_scaledRHS(b.front_index(), b.back_index()), m_pivotDenominator(1), - m_scratchColumn(b.front_index(), b.back_index()), - m_nonbasicLabels(A.MinCol(), A.MaxCol() + art.size()) + m_scratchColumn(b.front_index(), b.back_index()) { for (int j = MinCol(); j <= MaxCol(); j++) { m_nonbasicLabels[j] = j; diff --git a/src/solvers/linalg/vertenum.cc b/src/solvers/linalg/vertenum.cc index 1ea967f797..90cd7faa47 100644 --- a/src/solvers/linalg/vertenum.cc +++ b/src/solvers/linalg/vertenum.cc @@ -125,10 +125,10 @@ VertexEnumerationResult EnumerateVertices(const Matrix &A, const Vector template std::list> VertexEnumerationResult::GetVertices() const { std::list> verts; - for (int i = 1; i <= vertices.size(); i++) { + for (int i = vertices.front_index(); i <= vertices.back_index(); i++) { Vector vert(numColumns); vert = T{0}; - for (int j = 1; j <= vert.size(); j++) { + for (int j = vert.front_index(); j <= vert.back_index(); j++) { if (vertices[i].count(j)) { vert[j] = -vertices[i][j]; } diff --git a/src/solvers/lp/lp.h b/src/solvers/lp/lp.h index db96a4f935..0e0bddffad 100644 --- a/src/solvers/lp/lp.h +++ b/src/solvers/lp/lp.h @@ -39,6 +39,6 @@ LpBehaviorSolve(const Game &p_game, BehaviorCallbackType p_onEquilibrium = NullBehaviorCallback, const CancelToken &p_cancel = CancelToken()); -}; // namespace Gambit::Nash +} // namespace Gambit::Nash #endif // GAMBIT_SOLVERS_LP_LP_H