did some renaming of main dirs (apps, libs, etc.)
This commit is contained in:
commit
63f8b0a13c
14 files changed
+4047
No files matched your search
+351
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2004 Stephen Waits
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty. In
|
||||
no event will the authors be held liable for any damages arising from the use
|
||||
of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim
|
||||
that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "glicko2.h"
|
||||
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
|
||||
class Glicko2_impl
|
||||
{
|
||||
public:
|
||||
|
||||
// constructors
|
||||
Glicko2_impl();
|
||||
Glicko2_impl(const Glicko2_impl& rhs);
|
||||
|
||||
// copy assignment
|
||||
Glicko2_impl& operator=(const Glicko2_impl& rhs);
|
||||
|
||||
// destructor
|
||||
virtual ~Glicko2_impl();
|
||||
|
||||
// system constants
|
||||
static const double dvolatility;
|
||||
|
||||
// rating data
|
||||
double rating;
|
||||
double deviation;
|
||||
double volatility;
|
||||
|
||||
// result data (copy of each opponent and results, 0.0, 0.5, or 1.0)
|
||||
std::vector<Glicko2> opponents;
|
||||
std::vector<double> results;
|
||||
|
||||
// utility functions
|
||||
double g(const double& deviation);
|
||||
double E(const double& rating, const double& rating_opponent, const double& deviation_opponent);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const double Glicko2_impl::dvolatility = 0.3; // should be [0.3,1.2]
|
||||
|
||||
|
||||
|
||||
Glicko2_impl::Glicko2_impl() :
|
||||
rating(0.0),
|
||||
deviation(0.0),
|
||||
volatility(0.0),
|
||||
opponents(),
|
||||
results()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
Glicko2_impl::Glicko2_impl(const Glicko2_impl& rhs) :
|
||||
rating(rhs.rating),
|
||||
deviation(rhs.deviation),
|
||||
volatility(rhs.volatility),
|
||||
opponents(rhs.opponents),
|
||||
results(rhs.results)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
Glicko2_impl& Glicko2_impl::operator=(const Glicko2_impl& rhs)
|
||||
{
|
||||
if ( this == &rhs )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
rating = rhs.rating;
|
||||
deviation = rhs.deviation;
|
||||
volatility = rhs.volatility;
|
||||
opponents = rhs.opponents;
|
||||
results = rhs.results;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Glicko2_impl::~Glicko2_impl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
double Glicko2_impl::g(const double& deviation)
|
||||
{
|
||||
#define PI_SQUARED (9.86960440108935861883)
|
||||
return 1.0 / (sqrt(1.0 + 3.0 * deviation * deviation / PI_SQUARED));
|
||||
}
|
||||
|
||||
|
||||
|
||||
double Glicko2_impl::E(const double& rating, const double& rating_opponent, const double& deviation_opponent)
|
||||
{
|
||||
return 1.0 / (1.0 + exp(-g(deviation_opponent)*(rating - rating_opponent)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Glicko2::Glicko2() :
|
||||
pimpl(0)
|
||||
{
|
||||
pimpl = new Glicko2_impl();
|
||||
|
||||
SetRating(1500.0);
|
||||
SetDeviation(350.0);
|
||||
SetVolatility(0.06);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Glicko2::Glicko2(const Glicko2& rhs) :
|
||||
pimpl(0)
|
||||
{
|
||||
pimpl = new Glicko2_impl(*(rhs.pimpl));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Glicko2::Glicko2(double rating, double deviation, double volatility) :
|
||||
pimpl(0)
|
||||
{
|
||||
pimpl = new Glicko2_impl;
|
||||
|
||||
SetRating(rating);
|
||||
SetDeviation(deviation);
|
||||
SetVolatility(volatility);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Glicko2& Glicko2::operator=(const Glicko2& rhs)
|
||||
{
|
||||
if ( this == &rhs )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
*pimpl = *rhs.pimpl;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Glicko2::~Glicko2()
|
||||
{
|
||||
delete pimpl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Glicko2::operator< (const Glicko2& rhs)
|
||||
{
|
||||
return pimpl->rating < rhs.pimpl->rating;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double Glicko2::GetRating() const
|
||||
{
|
||||
return pimpl->rating * 173.7178 + 1500.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double Glicko2::GetDeviation() const
|
||||
{
|
||||
return pimpl->deviation * 173.7178;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double Glicko2::GetVolatility() const
|
||||
{
|
||||
return pimpl->volatility;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Glicko2::SetRating(double rating)
|
||||
{
|
||||
pimpl->rating = (rating - 1500.0) / 173.7178;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Glicko2::SetDeviation(double deviation)
|
||||
{
|
||||
pimpl->deviation = deviation / 173.7178;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Glicko2::SetVolatility(double volatility)
|
||||
{
|
||||
pimpl->volatility = volatility;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Glicko2::ClearResults()
|
||||
{
|
||||
pimpl->opponents.clear();
|
||||
pimpl->results.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Glicko2::AddResult(const Glicko2& opponent, RESULT result)
|
||||
{
|
||||
pimpl->opponents.push_back(opponent);
|
||||
|
||||
switch ( result )
|
||||
{
|
||||
case WIN:
|
||||
pimpl->results.push_back(1.0);
|
||||
break;
|
||||
|
||||
case LOSS:
|
||||
pimpl->results.push_back(0.0);
|
||||
break;
|
||||
|
||||
case DRAW:
|
||||
pimpl->results.push_back(0.5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Glicko2::AddWin(const Glicko2& opponent)
|
||||
{
|
||||
AddResult(opponent,WIN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Glicko2::AddLoss(const Glicko2& opponent)
|
||||
{
|
||||
AddResult(opponent,LOSS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Glicko2::AddDraw(const Glicko2& opponent)
|
||||
{
|
||||
AddResult(opponent,DRAW);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Glicko2::Update()
|
||||
{
|
||||
// bail if no opponents set
|
||||
if ( pimpl->opponents.size() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// compute variance
|
||||
double variance = 0.0;
|
||||
for ( unsigned int i=0;i<pimpl->opponents.size();i++ )
|
||||
{
|
||||
double g_i = pimpl->g(pimpl->opponents[i].pimpl->deviation);
|
||||
double E_i = pimpl->E(pimpl->rating,pimpl->opponents[i].pimpl->rating,pimpl->opponents[i].pimpl->deviation);
|
||||
variance += g_i * g_i * E_i * (1.0 - E_i);
|
||||
}
|
||||
variance = 1.0 / variance;
|
||||
|
||||
// compute delta
|
||||
double delta = 0.0;
|
||||
for ( unsigned int i=0;i<pimpl->opponents.size();i++ )
|
||||
{
|
||||
delta += pimpl->g(pimpl->opponents[i].pimpl->deviation) * (pimpl->results[i] - pimpl->E(pimpl->rating,pimpl->opponents[i].pimpl->rating,pimpl->opponents[i].pimpl->deviation));
|
||||
}
|
||||
delta *= variance;
|
||||
|
||||
// determine new volatility
|
||||
double new_volatility = 0.0;
|
||||
double a = log(pimpl->volatility*pimpl->volatility);
|
||||
double x = 0.0;
|
||||
double x_new = a;
|
||||
while ( abs(x - x_new) > 0.0000001 )
|
||||
{
|
||||
x = x_new;
|
||||
double d = pimpl->deviation*pimpl->deviation + variance + exp(x);
|
||||
double h1 = -(x - a)/(Glicko2_impl::dvolatility*Glicko2_impl::dvolatility) - 0.5*exp(x)/d + 0.5*exp(x)*(delta/d)*(delta/d);
|
||||
double h2 = -1.0/(Glicko2_impl::dvolatility*Glicko2_impl::dvolatility) - 0.5*exp(x)*(pimpl->deviation*pimpl->deviation+variance)/(d*d) + 0.5*(delta*delta)*exp(x)*((pimpl->deviation*pimpl->deviation) + variance - exp(x))/(d*d*d);
|
||||
x_new = x - h1/h2;
|
||||
}
|
||||
new_volatility = exp(x_new / 2.0);
|
||||
|
||||
// update the rating deviation to the new pre-rating period value
|
||||
double pre_deviation = sqrt( pimpl->deviation*pimpl->deviation + new_volatility*new_volatility );
|
||||
|
||||
// update the rating and deviation
|
||||
double new_deviation = 1.0 / (sqrt( 1.0/(pre_deviation*pre_deviation) + 1.0 / variance));
|
||||
double new_rating = 0.0;
|
||||
for ( unsigned int i=0;i<pimpl->opponents.size();i++ )
|
||||
{
|
||||
new_rating += pimpl->g(pimpl->opponents[i].pimpl->deviation) * (pimpl->results[i] - pimpl->E(pimpl->rating,pimpl->opponents[i].pimpl->rating,pimpl->opponents[i].pimpl->deviation));
|
||||
}
|
||||
new_rating = new_rating * new_deviation * new_deviation;
|
||||
new_rating += pimpl->rating;
|
||||
|
||||
// copy new values
|
||||
pimpl->rating = new_rating;
|
||||
pimpl->deviation = new_deviation;
|
||||
pimpl->volatility = new_volatility;
|
||||
|
||||
// wipe our result lists
|
||||
ClearResults();
|
||||
}
|
||||
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2004 Stephen Waits
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty. In
|
||||
no event will the authors be held liable for any damages arising from the use
|
||||
of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim
|
||||
that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __glicko2_h__
|
||||
#define __glicko2_h__
|
||||
|
||||
|
||||
|
||||
class Glicko2_impl;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Glicko-2 Rating calculator class.
|
||||
*
|
||||
* This class implements the Glicko-2 rating system algorithm written by
|
||||
* Professor Mark E. Glickman. All rating inputs and outputs are Glicko ratings,
|
||||
* but internally everything is converted to and considered Glicko-2 ratings.
|
||||
*
|
||||
* Glicko-2 is an improvement on the original Glicko, which was, in turn, an
|
||||
* improvement on the ELO system.
|
||||
*
|
||||
* The Glicko-2 system is specified on http://www.glicko.com/
|
||||
*/
|
||||
class Glicko2
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration of possible results.
|
||||
*/
|
||||
enum RESULT
|
||||
{
|
||||
/**
|
||||
* A win result, internally 1.0.
|
||||
*/
|
||||
WIN,
|
||||
|
||||
/**
|
||||
* A loss result, internally 0.0.
|
||||
*/
|
||||
LOSS,
|
||||
|
||||
/**
|
||||
* A draw result, internally 0.5.
|
||||
*/
|
||||
DRAW
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor. Initializes to a rating of 1500, a rating deviation
|
||||
* of 350, and a volatility of 0.06.
|
||||
*/
|
||||
Glicko2();
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
* @param rhs Object to copy.
|
||||
*/
|
||||
Glicko2(const Glicko2& rhs);
|
||||
|
||||
/**
|
||||
* Constructor with rating, rating deviation, and volatility specified.
|
||||
*
|
||||
* @param rating Initial rating.
|
||||
* @param deviation Initial rating deviation.
|
||||
* @param volatility Initial volatility.
|
||||
*/
|
||||
Glicko2(double rating, double deviation, double volatility);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Copy assignment operator.
|
||||
*
|
||||
* @param rhs Object to copy.
|
||||
*
|
||||
* @return Reference to self after copy assignment.
|
||||
*/
|
||||
Glicko2& operator=(const Glicko2& rhs);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Glicko2();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Less than comparison operator.
|
||||
*
|
||||
* @param rhs Object to compare against.
|
||||
*
|
||||
* @return true if this object's rating is less than rhs's rating; false otherwise.
|
||||
*/
|
||||
bool operator< (const Glicko2& rhs);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the current rating. This rating is a Glicko rating, not a Glicko2 rating.
|
||||
* For details, please see http://www.glicko.com/
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
double GetRating() const;
|
||||
|
||||
/**
|
||||
* Get the current rating deviation. This is a Glicko rating deviation, not a
|
||||
* Glicko-2 RD. For details, please see http://www.glicko.com/
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
double GetDeviation() const;
|
||||
|
||||
/**
|
||||
* Get the current rating volatility.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
double GetVolatility() const;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set Glicko rating. Internally this is converted to a Glicko2 rating.
|
||||
* For details, please see http://www.glicko.com/
|
||||
*
|
||||
* @param rating Rating.
|
||||
*/
|
||||
void SetRating(double rating);
|
||||
|
||||
/**
|
||||
* Set Glicko rating deviation. Internally this is converted to a Glicko-2 RD.
|
||||
* For details, please see http://www.glicko.com/
|
||||
*
|
||||
* @param deviation Rating deviation.
|
||||
*/
|
||||
void SetDeviation(double deviation);
|
||||
|
||||
/**
|
||||
* Set rating volatility.
|
||||
*
|
||||
* @param volatility Rating volatility.
|
||||
*/
|
||||
void SetVolatility(double volatility);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clear all results previously added via AddResult(), AddWin(), AddLoss(),
|
||||
* and/or AddDraw(). This method is called automatically whenever Update()
|
||||
* is called.
|
||||
*/
|
||||
void ClearResults();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a result to this rating. Note that no calculation is performed until
|
||||
* Update() is called.
|
||||
*
|
||||
* @param opponent Other player in contest.
|
||||
* @param result WIN, LOSS, or DRAW; from the point of view of this player.
|
||||
*/
|
||||
void AddResult(const Glicko2& opponent, RESULT result);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a win result to this rating. Note that no calculation is performed until
|
||||
* Update() is called.
|
||||
*
|
||||
* @param opponent Other (losing) player in contest.
|
||||
*/
|
||||
void AddWin(const Glicko2& opponent);
|
||||
|
||||
/**
|
||||
* Add a loss result to this rating. Note that no calculation is performed until
|
||||
* Update() is called.
|
||||
*
|
||||
* @param opponent Other (winning) player in contest.
|
||||
*/
|
||||
void AddLoss(const Glicko2& opponent);
|
||||
|
||||
/**
|
||||
* Add a draw result to this rating. Note that no calculation is performed until
|
||||
* Update() is called.
|
||||
*
|
||||
* @param opponent Other (drawing) player in contest.
|
||||
*/
|
||||
void AddDraw(const Glicko2& opponent);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Update rating based on current results list, and clear results.
|
||||
*/
|
||||
void Update();
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Private Implementation.
|
||||
*/
|
||||
Glicko2_impl* pimpl;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // __glicko2_h__
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "glicko2.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Glicko-2 Example
|
||||
// calculation from http://www.glicko.com/glicko2.doc/example.html
|
||||
|
||||
Glicko2 A(1500.0, 200.0, 0.06);
|
||||
Glicko2 B(1400.0, 30.0, 0.06);
|
||||
Glicko2 C(1550.0, 100.0, 0.06);
|
||||
Glicko2 D(1700.0, 300.0, 0.06);
|
||||
|
||||
A.AddWin(B);
|
||||
A.AddLoss(C);
|
||||
A.AddResult(D,Glicko2::LOSS); // alternative way to add a result
|
||||
|
||||
A.Update();
|
||||
|
||||
printf("rating = %f, RD = %f\n", A.GetRating(), A.GetDeviation());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user