Skip to content

Commit

Permalink
added readme, some doc and cleaned up gem- and rakefile
Browse files Browse the repository at this point in the history
  • Loading branch information
larskuhnt committed Apr 27, 2010
1 parent 010b933 commit 7febe24
Show file tree
Hide file tree
Showing 14 changed files with 139 additions and 179 deletions.
22 changes: 3 additions & 19 deletions .gitignore
@@ -1,21 +1,5 @@
## MAC OS
.DS_Store

## TEXTMATE
*.tmproj
tmtags

## EMACS
*~
\#*
.\#*

## VIM
*.swp

## PROJECT::GENERAL
coverage
rdoc
pkg

## PROJECT::SPECIFIC
doc
.yardoc
*.gem
Empty file removed CHANGELOG
Empty file.
8 changes: 8 additions & 0 deletions Gemfile
@@ -0,0 +1,8 @@
source :gemcutter

gem 'rake', '>= 0.8.7'
gem 'rspec', '>= 1.3.0'
gem 'rcov', '>= 0.9.8'
gem 'yard', '>= 0.5.4'
gem 'yard-rspec', '>= 0.1.0'
gem 'bluecloth', '>= 2.0.5'
4 changes: 4 additions & 0 deletions HISTORY.md
@@ -0,0 +1,4 @@
v0.1.0
------

* Initial release of the trueskill gem
2 changes: 1 addition & 1 deletion LICENSE
@@ -1,4 +1,4 @@
Copyright (c) 2009 Lars Kuhnt
Copyright (c) 2010 Lars Kuhnt

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Expand Down
66 changes: 66 additions & 0 deletions README.md
@@ -0,0 +1,66 @@
trueskill
=========

trueskill is a rating-system for games with an arbitrary number of teams and players developed by Microsoft Research. It is based on the Glicko rating system and solves some major flaws of the ELO system.

Usage
-----

Example:

require 'rubygems'
require 'saulabs/trueskill'

include Saulabs::TrueSkill

# team 1 has just one player with a mean skill of 27.1, a skill-deviation of 2.13
# and an play activity of 100 %
team1 = [Rating.new(27.1, 2.13, 1.0)]

# team 2 has two players
team2 = [Rating.new(22.0, 0.98, 0.8), Rating.new(31.1, 5.33, 0.9)]

# team 1 finished first and team 2 second
graph = FactorGraph.new([team1, team2], [1,2])

# update the Ratings
graph.update_skills

Installation
------------

To install the TrueSkill gem, simply run

[sudo] gem install trueskill

Add the following to your script:

require 'saulabs/trueskill'

Known issues
------------

* The calculation of the ranking probability is not yet implemented

Plans
-----

*

Note on Patches/Pull Requests
-----------------------------

* Fork the project.
* Make your feature addition or bug fix.
* Add tests for it. This is important so I don't break it in a
future version unintentionally.
* Commit, do not mess with rakefile, version, or history.
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
* Send me a pull request. Bonus points for topic branches.

Copyright
---------

© 2010 Lars Kuhnt (<http://saulabs.net>).

See LICENSE for details.
17 changes: 0 additions & 17 deletions README.rdoc

This file was deleted.

50 changes: 14 additions & 36 deletions Rakefile
@@ -1,46 +1,24 @@
require 'rubygems'
require 'rake'
require 'bundler'

begin
require 'jeweler'
Jeweler::Tasks.new do |gem|
gem.name = "trueskill"
gem.summary = %Q{A ruby library for the trueskill rating system}
gem.description = %Q{A ruby library for the trueskill rating system}
gem.email = "lars.kuhnt@gmail.com"
gem.homepage = "http://github.com/saulabs/trueskill"
gem.authors = ["Lars Kuhnt"]
gem.add_development_dependency "rspec", ">= 1.2.9"
gem.add_dependency('narray', '>= 0.5.9.7')
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
end
Jeweler::GemcutterTasks.new
rescue LoadError
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
end
Bundler.setup
Bundler.require

require 'spec/rake/spectask'
Spec::Rake::SpecTask.new(:spec) do |spec|
spec.libs << 'lib' << 'spec'
spec.spec_files = FileList['spec/**/*_spec.rb']
end

Spec::Rake::SpecTask.new(:rcov) do |spec|
spec.libs << 'lib' << 'spec'
spec.pattern = 'spec/**/*_spec.rb'
spec.rcov = true
end

task :spec => :check_dependencies

desc 'Default: run specs.'
task :default => :spec

require 'rake/rdoctask'
Rake::RDocTask.new do |rdoc|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
desc 'Run the specs'
Spec::Rake::SpecTask.new(:spec) do |t|
t.rcov_opts << '--exclude "gems/*,spec/*"'
t.rcov = true
t.rcov_dir = 'doc/coverage'
t.spec_files = FileList['spec/**/*_spec.rb']
end

rdoc.rdoc_dir = 'rdoc'
rdoc.title = "trueskill #{version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('lib/**/*.rb')
YARD::Rake::YardocTask.new(:doc) do |t|
t.files = ['lib/**/*.rb', 'HISTORY.md']
t.options = ['--no-private', '--title', 'trueskill Documentation', '--readme', 'README.md']
end
1 change: 0 additions & 1 deletion VERSION

This file was deleted.

24 changes: 13 additions & 11 deletions lib/saulabs/gauss/distribution.rb
@@ -1,10 +1,13 @@
module Saulabs
module Gauss

# Implementation of a gaussian distribution
#
class Distribution

SQRT2 = Math.sqrt(2).freeze
INV_SQRT_2PI = (1 / Math.sqrt(2 * Math::PI)).freeze
LOG_SQRT_2PI = Math.log(Math.sqrt(2 * Math::PI)).freeze
@@sqrt2 = Math.sqrt(2).freeze
@@inv_sqrt_2pi = (1 / Math.sqrt(2 * Math::PI)).freeze
@@log_sqrt_2pi = Math.log(Math.sqrt(2 * Math::PI)).freeze

# gaussian normal distribution values
attr_accessor :mean, :deviation, :variance, :precision, :precision_mean
Expand All @@ -22,8 +25,7 @@ def initialize(mean = 0.0, deviation = 0.0)
class << self

def standard
@@standard ||= Distribution.new(0.0, 1.0)
@@standard
Distribution.new(0.0, 1.0)
end

def with_deviation(mean, deviation)
Expand All @@ -46,40 +48,40 @@ def log_product_normalization(x, y)
return 0.0 if x.precision == 0.0 || y.precision == 0.0
variance_sum = x.variance + y.variance
mean_diff = x.mean - y.mean
-LOG_SQRT_2PI - (Math.log(variance_sum) / 2.0) - (mean_diff**2 / (2.0 * variance_sum))
-@@log_sqrt_2pi - (Math.log(variance_sum) / 2.0) - (mean_diff**2 / (2.0 * variance_sum))
end

def log_ratio_normalization(x, y)
return 0.0 if x.precision == 0.0 || y.precision == 0.0
variance_diff = y.variance - x.variance
return 0.0 if variance_diff == 0.0
mean_diff = x.mean - y.mean
Math.log(y.variance) + LOG_SQRT_2PI - (Math.log(variance_diff) / 2.0) + (mean_diff**2 / (2.0 * variance_diff))
Math.log(y.variance) + @@log_sqrt_2pi - (Math.log(variance_diff) / 2.0) + (mean_diff**2 / (2.0 * variance_diff))
end

# Computes the cummulative Gaussian distribution at a specified point of interest
def cumulative_distribution_function(x)
0.5 * (1 + Math.erf(x / SQRT2))
0.5 * (1 + Math.erf(x / @@sqrt2))
end
alias_method :cdf, :cumulative_distribution_function

# Computes the Gaussian density at a specified point of interest
def probability_density_function(x)
INV_SQRT_2PI * Math.exp(-0.5 * (x**2))
@@inv_sqrt_2pi * Math.exp(-0.5 * (x**2))
end
alias_method :pdf, :probability_density_function

# The inverse of the cummulative Gaussian distribution function
def quantile_function(x)
-SQRT2 * Math.erfc(2.0 * x)
-@@sqrt2 * Math.erfc(2.0 * x)
end
alias_method :inv_cdf, :quantile_function

end

def value_at(x)
exp = -(x - @mean)**2.0 / (2.0 * @variance)
(1.0/@deviation) * INV_SQRT_2PI * Math.exp(exp)
(1.0/@deviation) * @@inv_sqrt_2pi * Math.exp(exp)
end

# copy values from other distribution
Expand Down
2 changes: 1 addition & 1 deletion lib/saulabs/trueskill/factor_graph.rb
Expand Up @@ -5,7 +5,7 @@ class FactorGraph

attr_reader :teams, :beta, :beta_squared, :draw_probability, :epsilon, :layers

# teams: 2 dimensional array of ratings
# @param teams (Array) 2 dimensional array of ratings
def initialize(teams, ranks, options = {})
@teams = teams
@ranks = ranks
Expand Down
7 changes: 7 additions & 0 deletions spec/saulabs/trueskill_spec.rb
@@ -0,0 +1,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'

describe Saulabs::TrueSkill do



end
3 changes: 3 additions & 0 deletions spec/spec.opts
@@ -1 +1,4 @@
--color
--format specdoc
--loadby mtime
--reverse

0 comments on commit 7febe24

Please sign in to comment.