From cb46631ff869a2125937772b9dda4b5029e490bb Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Thu, 18 Mar 2010 07:39:48 -0400 Subject: [PATCH 01/14] Initial version of Moserware.Skills TrueSkill calculator to go along with my Computing Your Skill blog post --- Skills.sln | 26 + Skills.suo | Bin 0 -> 64512 bytes Skills/Elo/DuellingEloCalculator.cs | 138 +++ Skills/Elo/EloRating.cs | 14 + Skills/Elo/FideEloCalculator.cs | 31 + Skills/Elo/FideKFactor.cs | 36 + Skills/Elo/GaussianEloCalculator.cs | 27 + Skills/Elo/GaussianKFactor.cs | 20 + Skills/Elo/KFactor.cs | 22 + Skills/Elo/TwoPlayerEloCalculator.cs | 79 ++ Skills/FactorGraphs/Factor.cs | 94 ++ Skills/FactorGraphs/FactorGraph.cs | 9 + Skills/FactorGraphs/FactorGraphLayer.cs | 108 ++ Skills/FactorGraphs/FactorList.cs | 47 + Skills/FactorGraphs/Message.cs | 30 + Skills/FactorGraphs/Schedule.cs | 105 ++ Skills/FactorGraphs/Variable.cs | 58 + Skills/FactorGraphs/VariableFactory.cs | 42 + Skills/GameInfo.cs | 49 + Skills/Guard.cs | 36 + Skills/ISupportPartialPlay.cs | 13 + Skills/ISupportPartialUpdate.cs | 10 + Skills/License.txt | 37 + Skills/Numerics/GaussianDistribution.cs | 240 +++++ Skills/Numerics/Matrix.cs | 520 +++++++++ Skills/Numerics/Range.cs | 49 + Skills/PairwiseComparison.cs | 15 + Skills/PartialPlay.cs | 26 + Skills/Player.cs | 129 +++ Skills/PlayersRange.cs | 22 + Skills/Properties/AssemblyInfo.cs | 45 + Skills/README.txt | 58 + Skills/RankSorter.cs | 76 ++ Skills/Rating.cs | 94 ++ Skills/SkillCalculator.cs | 93 ++ Skills/Skills.csproj | 116 ++ Skills/Skills.suo | Bin 0 -> 142336 bytes Skills/Team.cs | 90 ++ Skills/TeamsRange.cs | 22 + Skills/TrueSkill/DrawMargin.cs | 23 + .../FactorGraphTrueSkillCalculator.cs | 156 +++ Skills/TrueSkill/Factors/GaussianFactor.cs | 33 + .../Factors/GaussianGreaterThanFactor.cs | 75 ++ .../Factors/GaussianLikelihoodFactor.cs | 72 ++ .../TrueSkill/Factors/GaussianPriorFactor.cs | 39 + .../Factors/GaussianWeightedSumFactor.cs | 252 +++++ .../TrueSkill/Factors/GaussianWithinFactor.cs | 73 ++ .../IteratedTeamDifferencesInnerLayer.cs | 192 ++++ ...ayerPerformancesToTeamPerformancesLayer.cs | 68 ++ .../Layers/PlayerPriorValuesToSkillsLayer.cs | 63 ++ .../Layers/PlayerSkillsToPerformancesLayer.cs | 64 ++ .../Layers/TeamDifferencesComparisonLayer.cs | 38 + ...mancesToTeamPerformanceDifferencesLayer.cs | 43 + .../Layers/TrueSkillFactorGraphLayer.cs | 20 + Skills/TrueSkill/TrueSkillFactorGraph.cs | 119 +++ .../TruncatedGaussianCorrectionFunctions.cs | 188 ++++ .../TrueSkill/TwoPlayerTrueSkillCalculator.cs | 150 +++ .../TrueSkill/TwoTeamTrueSkillCalculator.cs | 173 +++ Skills/TrueSkillCalculator.cs | 45 + Skills/bin/Debug/Moserware.Skills.dll | Bin 0 -> 63488 bytes Skills/bin/Debug/Moserware.Skills.pdb | Bin 0 -> 247296 bytes UnitTests/Elo/DuellingEloTest.cs | 51 + UnitTests/Elo/EloAssert.cs | 37 + UnitTests/Elo/FideEloCalculatorTest.cs | 36 + UnitTests/Elo/GaussianEloCalculatorTest.cs | 26 + .../Numerics/GaussianDistributionTests.cs | 68 ++ UnitTests/Numerics/MatrixTests.cs | 186 ++++ UnitTests/Properties/AssemblyInfo.cs | 35 + UnitTests/README.txt | 23 + UnitTests/RankSorterTest.cs | 34 + UnitTests/TrueSkill/DrawMarginTest.cs | 27 + .../FactorGraphTrueSkillCalculatorTests.cs | 22 + .../TrueSkill/TrueSkillCalculatorTests.cs | 987 ++++++++++++++++++ .../TwoPlayerTrueSkillCalculatorTest.cs | 20 + .../TwoTeamTrueSkillCalculatorTest.cs | 19 + UnitTests/UnitTests.csproj | 80 ++ UnitTests/UnitTests.csproj.user | 9 + 77 files changed, 6172 insertions(+) create mode 100644 Skills.sln create mode 100644 Skills.suo create mode 100644 Skills/Elo/DuellingEloCalculator.cs create mode 100644 Skills/Elo/EloRating.cs create mode 100644 Skills/Elo/FideEloCalculator.cs create mode 100644 Skills/Elo/FideKFactor.cs create mode 100644 Skills/Elo/GaussianEloCalculator.cs create mode 100644 Skills/Elo/GaussianKFactor.cs create mode 100644 Skills/Elo/KFactor.cs create mode 100644 Skills/Elo/TwoPlayerEloCalculator.cs create mode 100644 Skills/FactorGraphs/Factor.cs create mode 100644 Skills/FactorGraphs/FactorGraph.cs create mode 100644 Skills/FactorGraphs/FactorGraphLayer.cs create mode 100644 Skills/FactorGraphs/FactorList.cs create mode 100644 Skills/FactorGraphs/Message.cs create mode 100644 Skills/FactorGraphs/Schedule.cs create mode 100644 Skills/FactorGraphs/Variable.cs create mode 100644 Skills/FactorGraphs/VariableFactory.cs create mode 100644 Skills/GameInfo.cs create mode 100644 Skills/Guard.cs create mode 100644 Skills/ISupportPartialPlay.cs create mode 100644 Skills/ISupportPartialUpdate.cs create mode 100644 Skills/License.txt create mode 100644 Skills/Numerics/GaussianDistribution.cs create mode 100644 Skills/Numerics/Matrix.cs create mode 100644 Skills/Numerics/Range.cs create mode 100644 Skills/PairwiseComparison.cs create mode 100644 Skills/PartialPlay.cs create mode 100644 Skills/Player.cs create mode 100644 Skills/PlayersRange.cs create mode 100644 Skills/Properties/AssemblyInfo.cs create mode 100644 Skills/README.txt create mode 100644 Skills/RankSorter.cs create mode 100644 Skills/Rating.cs create mode 100644 Skills/SkillCalculator.cs create mode 100644 Skills/Skills.csproj create mode 100644 Skills/Skills.suo create mode 100644 Skills/Team.cs create mode 100644 Skills/TeamsRange.cs create mode 100644 Skills/TrueSkill/DrawMargin.cs create mode 100644 Skills/TrueSkill/FactorGraphTrueSkillCalculator.cs create mode 100644 Skills/TrueSkill/Factors/GaussianFactor.cs create mode 100644 Skills/TrueSkill/Factors/GaussianGreaterThanFactor.cs create mode 100644 Skills/TrueSkill/Factors/GaussianLikelihoodFactor.cs create mode 100644 Skills/TrueSkill/Factors/GaussianPriorFactor.cs create mode 100644 Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs create mode 100644 Skills/TrueSkill/Factors/GaussianWithinFactor.cs create mode 100644 Skills/TrueSkill/Layers/IteratedTeamDifferencesInnerLayer.cs create mode 100644 Skills/TrueSkill/Layers/PlayerPerformancesToTeamPerformancesLayer.cs create mode 100644 Skills/TrueSkill/Layers/PlayerPriorValuesToSkillsLayer.cs create mode 100644 Skills/TrueSkill/Layers/PlayerSkillsToPerformancesLayer.cs create mode 100644 Skills/TrueSkill/Layers/TeamDifferencesComparisonLayer.cs create mode 100644 Skills/TrueSkill/Layers/TeamPerformancesToTeamPerformanceDifferencesLayer.cs create mode 100644 Skills/TrueSkill/Layers/TrueSkillFactorGraphLayer.cs create mode 100644 Skills/TrueSkill/TrueSkillFactorGraph.cs create mode 100644 Skills/TrueSkill/TruncatedGaussianCorrectionFunctions.cs create mode 100644 Skills/TrueSkill/TwoPlayerTrueSkillCalculator.cs create mode 100644 Skills/TrueSkill/TwoTeamTrueSkillCalculator.cs create mode 100644 Skills/TrueSkillCalculator.cs create mode 100644 Skills/bin/Debug/Moserware.Skills.dll create mode 100644 Skills/bin/Debug/Moserware.Skills.pdb create mode 100644 UnitTests/Elo/DuellingEloTest.cs create mode 100644 UnitTests/Elo/EloAssert.cs create mode 100644 UnitTests/Elo/FideEloCalculatorTest.cs create mode 100644 UnitTests/Elo/GaussianEloCalculatorTest.cs create mode 100644 UnitTests/Numerics/GaussianDistributionTests.cs create mode 100644 UnitTests/Numerics/MatrixTests.cs create mode 100644 UnitTests/Properties/AssemblyInfo.cs create mode 100644 UnitTests/README.txt create mode 100644 UnitTests/RankSorterTest.cs create mode 100644 UnitTests/TrueSkill/DrawMarginTest.cs create mode 100644 UnitTests/TrueSkill/FactorGraphTrueSkillCalculatorTests.cs create mode 100644 UnitTests/TrueSkill/TrueSkillCalculatorTests.cs create mode 100644 UnitTests/TrueSkill/TwoPlayerTrueSkillCalculatorTest.cs create mode 100644 UnitTests/TrueSkill/TwoTeamTrueSkillCalculatorTest.cs create mode 100644 UnitTests/UnitTests.csproj create mode 100644 UnitTests/UnitTests.csproj.user diff --git a/Skills.sln b/Skills.sln new file mode 100644 index 0000000..7e5e0f9 --- /dev/null +++ b/Skills.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skills", "Skills\Skills.csproj", "{15AD1345-984C-48ED-AF9A-2EAB44E5AA2B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{6F80946D-AC8B-4063-8588-96841C18BF0A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {15AD1345-984C-48ED-AF9A-2EAB44E5AA2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15AD1345-984C-48ED-AF9A-2EAB44E5AA2B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15AD1345-984C-48ED-AF9A-2EAB44E5AA2B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15AD1345-984C-48ED-AF9A-2EAB44E5AA2B}.Release|Any CPU.Build.0 = Release|Any CPU + {6F80946D-AC8B-4063-8588-96841C18BF0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F80946D-AC8B-4063-8588-96841C18BF0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F80946D-AC8B-4063-8588-96841C18BF0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F80946D-AC8B-4063-8588-96841C18BF0A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Skills.suo b/Skills.suo new file mode 100644 index 0000000000000000000000000000000000000000..e468e1956d38ed06a520638028bb9842ac359d0f GIT binary patch literal 64512 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 literal 0 HcmV?d00001 diff --git a/Skills/Elo/DuellingEloCalculator.cs b/Skills/Elo/DuellingEloCalculator.cs new file mode 100644 index 0000000..d135608 --- /dev/null +++ b/Skills/Elo/DuellingEloCalculator.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Moserware.Skills.Elo +{ + public class DuellingEloCalculator : SkillCalculator + { + private readonly TwoPlayerEloCalculator _TwoPlayerEloCalc; + + public DuellingEloCalculator(TwoPlayerEloCalculator twoPlayerEloCalculator) + : base(SupportedOptions.None, TeamsRange.AtLeast(2), PlayersRange.AtLeast(1)) + { + _TwoPlayerEloCalc = twoPlayerEloCalculator; + } + + public override IDictionary CalculateNewRatings(GameInfo gameInfo, IEnumerable> teams, params int[] teamRanks) + { + // On page 6 of the TrueSkill paper, the authors write: + // "When we had to process a team game or a game with more than two teams we used + // the so-called *duelling* heuristic: For each player, compute the Δ's in comparison + // to all other players based on the team outcome of the player and every other player and + // perform an update with the average of the Δ's." + // This implements that algorithm. + + ValidateTeamCountAndPlayersCountPerTeam(teams); + RankSorter.Sort(ref teams, ref teamRanks); + + var teamsList = teams.ToList(); + + var deltas = new Dictionary>(); + + for(int ixCurrentTeam = 0; ixCurrentTeam < teamsList.Count; ixCurrentTeam++) + { + for(int ixOtherTeam = 0; ixOtherTeam < teamsList.Count; ixOtherTeam++) + { + if(ixOtherTeam == ixCurrentTeam) + { + // Shouldn't duel against ourself ;) + continue; + } + + var currentTeam = teamsList[ixCurrentTeam]; + var otherTeam = teamsList[ixOtherTeam]; + + // Remember that bigger numbers mean worse rank (e.g. other-current is what we want) + var comparison = (PairwiseComparison) Math.Sign(teamRanks[ixOtherTeam] - teamRanks[ixCurrentTeam]); + + foreach(var currentTeamPlayerRatingPair in currentTeam) + { + foreach(var otherTeamPlayerRatingPair in otherTeam) + { + UpdateDuels(gameInfo, deltas, + currentTeamPlayerRatingPair.Key, currentTeamPlayerRatingPair.Value, + otherTeamPlayerRatingPair.Key, otherTeamPlayerRatingPair.Value, + comparison); + + } + } + } + } + + var result = new Dictionary(); + + foreach(var currentTeam in teamsList) + { + foreach(var currentTeamPlayerPair in currentTeam) + { + var currentPlayerAverageDuellingDelta = deltas[currentTeamPlayerPair.Key].Values.Average(); + result[currentTeamPlayerPair.Key] = new EloRating(currentTeamPlayerPair.Value.Mean + currentPlayerAverageDuellingDelta); + } + } + + return result; + } + + private void UpdateDuels(GameInfo gameInfo, + IDictionary> duels, + TPlayer player1, Rating player1Rating, + TPlayer player2, Rating player2Rating, + PairwiseComparison weakToStrongComparison) + { + + var duelOutcomes = _TwoPlayerEloCalc.CalculateNewRatings(gameInfo, + Teams.Concat( + new Team(player1, player1Rating), + new Team(player2, player2Rating)), + (weakToStrongComparison == PairwiseComparison.Win) ? new int[] { 1, 2 } + : (weakToStrongComparison == PairwiseComparison.Lose) ? new int[] { 2, 1 } + : new int[] { 1, 1}); + + + UpdateDuelInfo(duels, player1, player1Rating, duelOutcomes[player1], player2); + UpdateDuelInfo(duels, player2, player2Rating, duelOutcomes[player2], player1); + } + + private static void UpdateDuelInfo(IDictionary> duels, + TPlayer self, Rating selfBeforeRating, Rating selfAfterRating, + TPlayer opponent ) + { + IDictionary selfToOpponentDuelDeltas; + + if(!duels.TryGetValue(self, out selfToOpponentDuelDeltas)) + { + selfToOpponentDuelDeltas = new Dictionary(); + duels[self] = selfToOpponentDuelDeltas; + } + + selfToOpponentDuelDeltas[opponent] = selfAfterRating.Mean - selfBeforeRating.Mean; + } + + public override double CalculateMatchQuality(GameInfo gameInfo, IEnumerable> teams) + { + // HACK! Need a better algorithm, this is just to have something there and it isn't good + double minQuality = 1.0; + + var teamList = teams.ToList(); + + for(int ixCurrentTeam = 0; ixCurrentTeam < teamList.Count; ixCurrentTeam++) + { + EloRating currentTeamAverageRating = new EloRating(teamList[ixCurrentTeam].Values.Average(r => r.Mean)); + var currentTeam = new Team(new Player(ixCurrentTeam), currentTeamAverageRating); + + for(int ixOtherTeam = ixCurrentTeam + 1; ixOtherTeam < teamList.Count; ixOtherTeam++) + { + EloRating otherTeamAverageRating = new EloRating(teamList[ixOtherTeam].Values.Average(r => r.Mean)); + var otherTeam = new Team(new Player(ixOtherTeam), otherTeamAverageRating); + + minQuality = Math.Min(minQuality, + _TwoPlayerEloCalc.CalculateMatchQuality(gameInfo, + Teams.Concat(currentTeam, otherTeam))); + } + } + + return minQuality; + } + } +} \ No newline at end of file diff --git a/Skills/Elo/EloRating.cs b/Skills/Elo/EloRating.cs new file mode 100644 index 0000000..e408c43 --- /dev/null +++ b/Skills/Elo/EloRating.cs @@ -0,0 +1,14 @@ + +namespace Moserware.Skills.Elo +{ + /// + /// An Elo rating represented by a single number (mean). + /// + public class EloRating : Rating + { + public EloRating(double rating) + : base(rating, 0) + { + } + } +} diff --git a/Skills/Elo/FideEloCalculator.cs b/Skills/Elo/FideEloCalculator.cs new file mode 100644 index 0000000..cc3623e --- /dev/null +++ b/Skills/Elo/FideEloCalculator.cs @@ -0,0 +1,31 @@ +using System; + +namespace Moserware.Skills.Elo +{ + // Including ELO's scheme as a simple comparison. + // See http://en.wikipedia.org/wiki/Elo_rating_system#Theory + // for more details + public class FideEloCalculator : TwoPlayerEloCalculator + { + public FideEloCalculator() + : this(new FideKFactor()) + { + } + + public FideEloCalculator(FideKFactor kFactor) + : base(kFactor) + { + } + + protected override double GetPlayerWinProbability(GameInfo gameInfo, double playerRating, double opponentRating) + { + double ratingDifference = opponentRating - playerRating; + + return 1.0 + / + ( + 1.0 + Math.Pow(10.0, ratingDifference / (2 * gameInfo.Beta)) + ); + } + } +} \ No newline at end of file diff --git a/Skills/Elo/FideKFactor.cs b/Skills/Elo/FideKFactor.cs new file mode 100644 index 0000000..f3c16b2 --- /dev/null +++ b/Skills/Elo/FideKFactor.cs @@ -0,0 +1,36 @@ + +namespace Moserware.Skills.Elo +{ + // see http://ratings.fide.com/calculator_rtd.phtml for details + public class FideKFactor : KFactor + { + public FideKFactor() + { + } + + public override double GetValueForRating(double rating) + { + if (rating < 2400) + { + return 15; + } + + return 10; + } + + /// + /// Indicates someone who has played less than 30 games. + /// + public class Provisional : FideKFactor + { + public Provisional() + { + } + + public override double GetValueForRating(double rating) + { + return 25; + } + } + } +} diff --git a/Skills/Elo/GaussianEloCalculator.cs b/Skills/Elo/GaussianEloCalculator.cs new file mode 100644 index 0000000..9e9a012 --- /dev/null +++ b/Skills/Elo/GaussianEloCalculator.cs @@ -0,0 +1,27 @@ +using System; +using Moserware.Numerics; + +namespace Moserware.Skills.Elo +{ + public class GaussianEloCalculator : TwoPlayerEloCalculator + { + // From the paper + private static readonly KFactor StableKFactor = new KFactor(24); + + public GaussianEloCalculator() + : base(StableKFactor) + { + } + + protected override double GetPlayerWinProbability(GameInfo gameInfo, double playerRating, double opponentRating) + { + double ratingDifference = playerRating - opponentRating; + + // See equation 1.1 in the TrueSkill paper + return GaussianDistribution.CumulativeTo( + ratingDifference + / + (Math.Sqrt(2) * gameInfo.Beta)); + } + } +} diff --git a/Skills/Elo/GaussianKFactor.cs b/Skills/Elo/GaussianKFactor.cs new file mode 100644 index 0000000..f2fa62a --- /dev/null +++ b/Skills/Elo/GaussianKFactor.cs @@ -0,0 +1,20 @@ +using System; + +namespace Moserware.Skills.Elo +{ + public class GaussianKFactor : KFactor + { + // From paper + const double StableDynamicsKFactor = 24.0; + + public GaussianKFactor() + : base(StableDynamicsKFactor) + { + } + + public GaussianKFactor(GameInfo gameInfo, double latestGameWeightingFactor) + : base(latestGameWeightingFactor * gameInfo.Beta * Math.Sqrt(Math.PI)) + { + } + } +} diff --git a/Skills/Elo/KFactor.cs b/Skills/Elo/KFactor.cs new file mode 100644 index 0000000..c8be739 --- /dev/null +++ b/Skills/Elo/KFactor.cs @@ -0,0 +1,22 @@ + +namespace Moserware.Skills.Elo +{ + public class KFactor + { + private double _Value; + + protected KFactor() + { + } + + public KFactor(double exactKFactor) + { + _Value = exactKFactor; + } + + public virtual double GetValueForRating(double rating) + { + return _Value; + } + } +} diff --git a/Skills/Elo/TwoPlayerEloCalculator.cs b/Skills/Elo/TwoPlayerEloCalculator.cs new file mode 100644 index 0000000..943db47 --- /dev/null +++ b/Skills/Elo/TwoPlayerEloCalculator.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Moserware.Skills.Elo +{ + public abstract class TwoPlayerEloCalculator : SkillCalculator + { + protected readonly KFactor _KFactor; + + protected TwoPlayerEloCalculator(KFactor kFactor) + : base(SupportedOptions.None, TeamsRange.Exactly(2), PlayersRange.Exactly(1)) + { + _KFactor = kFactor; + } + + public override IDictionary CalculateNewRatings(GameInfo gameInfo, IEnumerable> teams, params int[] teamRanks) + { + ValidateTeamCountAndPlayersCountPerTeam(teams); + RankSorter.Sort(ref teams, ref teamRanks); + + var result = new Dictionary(); + bool isDraw = (teamRanks[0] == teamRanks[1]); + + var player1 = teams.First().First(); + var player2 = teams.Last().First(); + + var player1Rating = player1.Value.Mean; + var player2Rating = player2.Value.Mean; + + result[player1.Key] = CalculateNewRating(gameInfo, player1Rating, player2Rating, isDraw ? PairwiseComparison.Draw : PairwiseComparison.Win); + result[player2.Key] = CalculateNewRating(gameInfo, player2Rating, player1Rating, isDraw ? PairwiseComparison.Draw : PairwiseComparison.Lose); + + return result; + } + + protected virtual EloRating CalculateNewRating(GameInfo gameInfo, double selfRating, double opponentRating, PairwiseComparison selfToOpponentComparison) + { + double expectedProbability = GetPlayerWinProbability(gameInfo, selfRating, opponentRating); + double actualProbability = GetScoreFromComparison(selfToOpponentComparison); + double k = _KFactor.GetValueForRating(selfRating); + double ratingChange = k * (actualProbability - expectedProbability); + double newRating = selfRating + ratingChange; + + return new EloRating(newRating); + } + + private static double GetScoreFromComparison(PairwiseComparison comparison) + { + switch (comparison) + { + case PairwiseComparison.Win: + return 1; + case PairwiseComparison.Draw: + return 0.5; + case PairwiseComparison.Lose: + return 0; + default: + throw new NotSupportedException(); + } + } + + protected abstract double GetPlayerWinProbability(GameInfo gameInfo, double playerRating, double opponentRating); + + public override double CalculateMatchQuality(GameInfo gameInfo, IEnumerable> teams) + { + ValidateTeamCountAndPlayersCountPerTeam(teams); + double player1Rating = teams.First().First().Value.Mean; + double player2Rating = teams.Last().First().Value.Mean; + double ratingDifference = player1Rating - player2Rating; + + // The TrueSkill paper mentions that they used s1 - s2 (rating difference) to + // determine match quality. I convert that to a percentage as a delta from 50% + // using the cumulative density function of the specific curve being used + double deltaFrom50Percent = Math.Abs(GetPlayerWinProbability(gameInfo, player1Rating, player2Rating) - 0.5); + return (0.5 - deltaFrom50Percent) / 0.5; + } + } +} diff --git a/Skills/FactorGraphs/Factor.cs b/Skills/FactorGraphs/Factor.cs new file mode 100644 index 0000000..6e7caf2 --- /dev/null +++ b/Skills/FactorGraphs/Factor.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Moserware.Skills.FactorGraphs +{ + public abstract class Factor + { + private readonly List> _Messages = new List>(); + + private readonly Dictionary, Variable> _MessageToVariableBinding = + new Dictionary, Variable>(); + + private readonly string _Name; + private readonly List> _Variables = new List>(); + + protected Factor(string name) + { + _Name = "Factor[" + name + "]"; + } + + /// Returns the log-normalization constant of that factor + public virtual double LogNormalization + { + get { return 0; } + } + + /// Returns the number of messages that the factor has + public int NumberOfMessages + { + get { return _Messages.Count; } + } + + protected ReadOnlyCollection> Variables + { + get { return _Variables.AsReadOnly(); } + } + + protected ReadOnlyCollection> Messages + { + get { return _Messages.AsReadOnly(); } + } + + /// Update the message and marginal of the i-th variable that the factor is connected to + public virtual double UpdateMessage(int messageIndex) + { + Guard.ArgumentIsValidIndex(messageIndex, _Messages.Count, "messageIndex"); + return UpdateMessage(_Messages[messageIndex], _MessageToVariableBinding[_Messages[messageIndex]]); + } + + protected virtual double UpdateMessage(Message message, Variable variable) + { + throw new NotImplementedException(); + } + + /// Resets the marginal of the variables a factor is connected to + public virtual void ResetMarginals() + { + foreach (var currentVariable in _MessageToVariableBinding.Values) + { + currentVariable.ResetToPrior(); + } + } + + /// Sends the ith message to the marginal and returns the log-normalization constant + public virtual double SendMessage(int messageIndex) + { + Guard.ArgumentIsValidIndex(messageIndex, _Messages.Count, "messageIndex"); + + Message message = _Messages[messageIndex]; + Variable variable = _MessageToVariableBinding[message]; + return SendMessage(message, variable); + } + + protected abstract double SendMessage(Message message, Variable variable); + + public abstract Message CreateVariableToMessageBinding(Variable variable); + + protected Message CreateVariableToMessageBinding(Variable variable, Message message) + { + int index = _Messages.Count; + _Messages.Add(message); + _MessageToVariableBinding[message] = variable; + _Variables.Add(variable); + + return message; + } + + public override string ToString() + { + return _Name ?? base.ToString(); + } + } +} \ No newline at end of file diff --git a/Skills/FactorGraphs/FactorGraph.cs b/Skills/FactorGraphs/FactorGraph.cs new file mode 100644 index 0000000..a7e93c5 --- /dev/null +++ b/Skills/FactorGraphs/FactorGraph.cs @@ -0,0 +1,9 @@ +namespace Moserware.Skills.FactorGraphs +{ + public class FactorGraph + where TSelf : FactorGraph + where TVariable : Variable + { + public VariableFactory VariableFactory { get; protected set; } + } +} \ No newline at end of file diff --git a/Skills/FactorGraphs/FactorGraphLayer.cs b/Skills/FactorGraphs/FactorGraphLayer.cs new file mode 100644 index 0000000..fd76b5b --- /dev/null +++ b/Skills/FactorGraphs/FactorGraphLayer.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Moserware.Skills.FactorGraphs +{ + public abstract class FactorGraphLayerBase + { + public abstract IEnumerable> UntypedFactors { get; } + public abstract void BuildLayer(); + + public virtual Schedule CreatePriorSchedule() + { + return null; + } + + public virtual Schedule CreatePosteriorSchedule() + { + return null; + } + + // HACK + + public abstract void SetRawInputVariablesGroups(object value); + public abstract object GetRawOutputVariablesGroups(); + } + + public abstract class FactorGraphLayer + : FactorGraphLayerBase + where TParentGraph : FactorGraph + where TBaseVariable : Variable + where TInputVariable : TBaseVariable + where TFactor : Factor + where TOutputVariable : TBaseVariable + { + private readonly List _LocalFactors = new List(); + private readonly List> _OutputVariablesGroups = new List>(); + private IList> _InputVariablesGroups = new List>(); + + protected FactorGraphLayer(TParentGraph parentGraph) + { + ParentFactorGraph = parentGraph; + } + + protected IList> InputVariablesGroups + { + get { return _InputVariablesGroups; } + } + + // HACK + + public TParentGraph ParentFactorGraph { get; private set; } + + public IList> OutputVariablesGroups + { + get { return _OutputVariablesGroups; } + } + + public IList LocalFactors + { + get { return _LocalFactors; } + } + + public override IEnumerable> UntypedFactors + { + get { return _LocalFactors.Cast>(); } + } + + public override void SetRawInputVariablesGroups(object value) + { + var newList = value as IList>; + if (newList == null) + { + // TODO: message + throw new ArgumentException(); + } + + _InputVariablesGroups = newList; + } + + public override object GetRawOutputVariablesGroups() + { + return _OutputVariablesGroups; + } + + protected Schedule ScheduleSequence( + IEnumerable itemsToSequence, + string nameFormat, + params object[] args) + where TSchedule : Schedule + + { + string formattedName = String.Format(nameFormat, args); + return new ScheduleSequence(formattedName, itemsToSequence); + } + + protected void AddLayerFactor(TFactor factor) + { + _LocalFactors.Add(factor); + } + + // Helper utility + protected double Square(double x) + { + return x*x; + } + } +} \ No newline at end of file diff --git a/Skills/FactorGraphs/FactorList.cs b/Skills/FactorGraphs/FactorList.cs new file mode 100644 index 0000000..07540f7 --- /dev/null +++ b/Skills/FactorGraphs/FactorList.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Moserware.Skills.FactorGraphs +{ + /// + /// Helper class for computing the factor graph's normalization constant. + /// + public class FactorList + { + private readonly List> _List = new List>(); + + public double LogNormalization + { + get + { + _List.ForEach(f => f.ResetMarginals()); + + double sumLogZ = 0.0; + + for (int i = 0; i < _List.Count; i++) + { + Factor f = _List[i]; + for (int j = 0; j < f.NumberOfMessages; j++) + { + sumLogZ += f.SendMessage(j); + } + } + + double sumLogS = _List.Aggregate(0.0, (acc, fac) => acc + fac.LogNormalization); + + return sumLogZ + sumLogS; + } + } + + public int Count + { + get { return _List.Count; } + } + + public Factor AddFactor(Factor factor) + { + _List.Add(factor); + return factor; + } + } +} \ No newline at end of file diff --git a/Skills/FactorGraphs/Message.cs b/Skills/FactorGraphs/Message.cs new file mode 100644 index 0000000..85f8c90 --- /dev/null +++ b/Skills/FactorGraphs/Message.cs @@ -0,0 +1,30 @@ +using System; + +namespace Moserware.Skills.FactorGraphs +{ + public class Message + { + private readonly string _NameFormat; + private readonly object[] _NameFormatArgs; + + public Message() + : this(default(T), null, null) + { + } + + public Message(T value, string nameFormat, params object[] args) + + { + _NameFormat = nameFormat; + _NameFormatArgs = args; + Value = value; + } + + public T Value { get; set; } + + public override string ToString() + { + return (_NameFormat == null) ? base.ToString() : String.Format(_NameFormat, _NameFormatArgs); + } + } +} \ No newline at end of file diff --git a/Skills/FactorGraphs/Schedule.cs b/Skills/FactorGraphs/Schedule.cs new file mode 100644 index 0000000..ac9d15a --- /dev/null +++ b/Skills/FactorGraphs/Schedule.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; + +namespace Moserware.Skills.FactorGraphs +{ + public abstract class Schedule + { + private readonly string _Name; + + protected Schedule(string name) + { + _Name = name; + } + + public abstract double Visit(int depth, int maxDepth); + + public double Visit() + { + return Visit(-1, 0); + } + + public override string ToString() + { + return _Name; + } + } + + public class ScheduleStep : Schedule + { + private readonly Factor _Factor; + private readonly int _Index; + + public ScheduleStep(string name, Factor factor, int index) + : base(name) + { + _Factor = factor; + _Index = index; + } + + public override double Visit(int depth, int maxDepth) + { + double delta = _Factor.UpdateMessage(_Index); + return delta; + } + } + + // TODO: Remove + public class ScheduleSequence : ScheduleSequence> + { + public ScheduleSequence(string name, IEnumerable> schedules) + : base(name, schedules) + { + } + } + + public class ScheduleSequence : Schedule + where TSchedule : Schedule + { + private readonly IEnumerable _Schedules; + + public ScheduleSequence(string name, IEnumerable schedules) + : base(name) + { + _Schedules = schedules; + } + + public override double Visit(int depth, int maxDepth) + { + double maxDelta = 0; + + foreach (TSchedule currentSchedule in _Schedules) + { + maxDelta = Math.Max(currentSchedule.Visit(depth + 1, maxDepth), maxDelta); + } + + return maxDelta; + } + } + + public class ScheduleLoop : Schedule + { + private readonly double _MaxDelta; + private readonly Schedule _ScheduleToLoop; + + public ScheduleLoop(string name, Schedule scheduleToLoop, double maxDelta) + : base(name) + { + _ScheduleToLoop = scheduleToLoop; + _MaxDelta = maxDelta; + } + + public override double Visit(int depth, int maxDepth) + { + int totalIterations = 1; + double delta = _ScheduleToLoop.Visit(depth + 1, maxDepth); + while (delta > _MaxDelta) + { + delta = _ScheduleToLoop.Visit(depth + 1, maxDepth); + totalIterations++; + } + + return delta; + } + } +} \ No newline at end of file diff --git a/Skills/FactorGraphs/Variable.cs b/Skills/FactorGraphs/Variable.cs new file mode 100644 index 0000000..0ea1e40 --- /dev/null +++ b/Skills/FactorGraphs/Variable.cs @@ -0,0 +1,58 @@ +using System; + +namespace Moserware.Skills.FactorGraphs +{ + public class Variable + { + private readonly string _Name; + private readonly VariableFactory _ParentFactory; + private readonly TValue _Prior; + private int _ParentIndex; + + public Variable(string name, VariableFactory parentFactory, int parentIndex, TValue prior) + { + _Name = "Variable[" + name + "]"; + _ParentFactory = parentFactory; + _ParentIndex = parentIndex; + _Prior = prior; + ResetToPrior(); + } + + public virtual TValue Value { get; set; } + + public void ResetToPrior() + { + Value = _Prior; + } + + public override string ToString() + { + return _Name; + } + } + + public class DefaultVariable : Variable + { + public DefaultVariable() + : base("Default", null, 0, default(TValue)) + { + } + + public override TValue Value + { + get { return default(TValue); } + set { throw new NotSupportedException(); } + } + } + + public class KeyedVariable : Variable + { + public KeyedVariable(TKey key, string name, VariableFactory parentFactory, int parentIndex, TValue prior) + : base(name, parentFactory, parentIndex, prior) + { + Key = key; + } + + public TKey Key { get; private set; } + } +} \ No newline at end of file diff --git a/Skills/FactorGraphs/VariableFactory.cs b/Skills/FactorGraphs/VariableFactory.cs new file mode 100644 index 0000000..d6cb1d9 --- /dev/null +++ b/Skills/FactorGraphs/VariableFactory.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace Moserware.Skills.FactorGraphs +{ + public class VariableFactory + { + // using a Func to encourage fresh copies in case it's overwritten + private readonly List> _CreatedVariables = new List>(); + private readonly Func _VariablePriorInitializer; + + public VariableFactory(Func variablePriorInitializer) + { + _VariablePriorInitializer = variablePriorInitializer; + } + + public Variable CreateBasicVariable(string nameFormat, params object[] args) + { + var newVar = new Variable( + String.Format(nameFormat, args), + this, + _CreatedVariables.Count, + _VariablePriorInitializer()); + + _CreatedVariables.Add(newVar); + return newVar; + } + + public KeyedVariable CreateKeyedVariable(TKey key, string nameFormat, params object[] args) + { + var newVar = new KeyedVariable( + key, + String.Format(nameFormat, args), + this, + _CreatedVariables.Count, + _VariablePriorInitializer()); + + _CreatedVariables.Add(newVar); + return newVar; + } + } +} \ No newline at end of file diff --git a/Skills/GameInfo.cs b/Skills/GameInfo.cs new file mode 100644 index 0000000..cfdddc4 --- /dev/null +++ b/Skills/GameInfo.cs @@ -0,0 +1,49 @@ +namespace Moserware.Skills +{ + /// + /// Parameters about the game for calculating the TrueSkill. + /// + public class GameInfo + { + private const double DefaultBeta = DefaultInitialMean/6.0; + private const double DefaultDrawProbability = 0.10; + private const double DefaultDynamicsFactor = DefaultInitialMean/300.0; + private const double DefaultInitialMean = 25.0; + private const double DefaultInitialStandardDeviation = DefaultInitialMean/3.0; + + public GameInfo(double initialMean, double initialStandardDeviation, double beta, double dynamicFactor, + double drawProbability) + { + InitialMean = initialMean; + InitialStandardDeviation = initialStandardDeviation; + Beta = beta; + DynamicsFactor = dynamicFactor; + DrawProbability = drawProbability; + } + + public double InitialMean { get; set; } + public double InitialStandardDeviation { get; set; } + public double Beta { get; set; } + + public double DynamicsFactor { get; set; } + public double DrawProbability { get; set; } + + public Rating DefaultRating + { + get { return new Rating(InitialMean, InitialStandardDeviation); } + } + + public static GameInfo DefaultGameInfo + { + get + { + // We return a fresh copy since we have public setters that can mutate state + return new GameInfo(DefaultInitialMean, + DefaultInitialStandardDeviation, + DefaultBeta, + DefaultDynamicsFactor, + DefaultDrawProbability); + } + } + } +} \ No newline at end of file diff --git a/Skills/Guard.cs b/Skills/Guard.cs new file mode 100644 index 0000000..deda637 --- /dev/null +++ b/Skills/Guard.cs @@ -0,0 +1,36 @@ +using System; + +namespace Moserware.Skills +{ + /// + /// Verifies argument contracts. + /// + /// These are used until .NET 4.0 ships with Contracts. For more information, + /// see http://www.moserware.com/2008/01/borrowing-ideas-from-3-interesting.html + internal static class Guard + { + public static void ArgumentNotNull(object value, string parameterName) + { + if (value == null) + { + throw new ArgumentNullException(parameterName); + } + } + + public static void ArgumentIsValidIndex(int index, int count, string parameterName) + { + if ((index < 0) || (index >= count)) + { + throw new ArgumentOutOfRangeException(parameterName); + } + } + + public static void ArgumentInRangeInclusive(double value, double min, double max, string parameterName) + { + if ((value < min) || (value > max)) + { + throw new ArgumentOutOfRangeException(parameterName); + } + } + } +} \ No newline at end of file diff --git a/Skills/ISupportPartialPlay.cs b/Skills/ISupportPartialPlay.cs new file mode 100644 index 0000000..9b781a6 --- /dev/null +++ b/Skills/ISupportPartialPlay.cs @@ -0,0 +1,13 @@ +namespace Moserware.Skills +{ + /// + /// Indicates support for allowing partial play (where a player only plays a part of the time). + /// + public interface ISupportPartialPlay + { + /// + /// Indicates the percent of the time the player should be weighted where 0.0 indicates the player didn't play and 1.0 indicates the player played 100% of the time. + /// + double PartialPlayPercentage { get; } + } +} \ No newline at end of file diff --git a/Skills/ISupportPartialUpdate.cs b/Skills/ISupportPartialUpdate.cs new file mode 100644 index 0000000..f202c61 --- /dev/null +++ b/Skills/ISupportPartialUpdate.cs @@ -0,0 +1,10 @@ +namespace Moserware.Skills +{ + public interface ISupportPartialUpdate + { + /// + /// Indicated how much of a skill update a player should receive where 0.0 represents no update and 1.0 represents 100% of the update. + /// + double PartialUpdatePercentage { get; } + } +} \ No newline at end of file diff --git a/Skills/License.txt b/Skills/License.txt new file mode 100644 index 0000000..f6c1a69 --- /dev/null +++ b/Skills/License.txt @@ -0,0 +1,37 @@ +The core ideas used in this Moserware.Skills project were described in +"TrueSkill (TM): A Bayesian Skill Rating System" available at +http://research.microsoft.com/apps/pubs/default.aspx?id=67956 + +The authors of the above paper have asked for a link to that article +as attribution in derived works. + +Some concepts were based on sample F# code that was written by Ralf Herbrich +Copyright (c) 2007, 2008 Microsoft Research Ltd, available at +http://blogs.technet.com/apg/archive/2008/06/16/trueskill-in-f.aspx + +All the C# code in this Moserware.Skills project is +Copyright (c) 2010 Jeff Moser + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY JEFF MOSER ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JEFF MOSER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of Jeff Moser. \ No newline at end of file diff --git a/Skills/Numerics/GaussianDistribution.cs b/Skills/Numerics/GaussianDistribution.cs new file mode 100644 index 0000000..d303b1b --- /dev/null +++ b/Skills/Numerics/GaussianDistribution.cs @@ -0,0 +1,240 @@ +using System; + +namespace Moserware.Numerics +{ + public class GaussianDistribution + { + // Intentionally, we're not going to derive related things, but set them all at once + // to get around some NaN issues + + private GaussianDistribution() + { + } + + public GaussianDistribution(double mean, double standardDeviation) + { + Mean = mean; + StandardDeviation = standardDeviation; + Variance = Square(StandardDeviation); + Precision = 1.0/Variance; + PrecisionMean = Precision*Mean; + } + + public double Mean { get; private set; } + public double StandardDeviation { get; private set; } + + // Precision and PrecisionMean are used because they make multiplying and dividing simpler + // (the the accompanying math paper for more details) + + public double Precision { get; private set; } + + public double PrecisionMean { get; private set; } + + private double Variance { get; set; } + + public double NormalizationConstant + { + get + { + // Great derivation of this is at http://www.astro.psu.edu/~mce/A451_2/A451/downloads/notes0.pdf + return 1.0/(Math.Sqrt(2*Math.PI)*StandardDeviation); + } + } + + public GaussianDistribution Clone() + { + var result = new GaussianDistribution(); + result.Mean = Mean; + result.StandardDeviation = StandardDeviation; + result.Variance = Variance; + result.Precision = Precision; + result.PrecisionMean = PrecisionMean; + return result; + } + + public static GaussianDistribution FromPrecisionMean(double precisionMean, double precision) + { + var gaussianDistribution = new GaussianDistribution(); + gaussianDistribution.Precision = precision; + gaussianDistribution.PrecisionMean = precisionMean; + gaussianDistribution.Variance = 1.0/precision; + gaussianDistribution.StandardDeviation = Math.Sqrt(gaussianDistribution.Variance); + gaussianDistribution.Mean = gaussianDistribution.PrecisionMean/gaussianDistribution.Precision; + return gaussianDistribution; + } + + // Although we could use equations from // For details, see http://www.tina-vision.net/tina-knoppix/tina-memo/2003-003.pdf + // for multiplication, the precision mean ones are easier to write :) + public static GaussianDistribution operator *(GaussianDistribution left, GaussianDistribution right) + { + return FromPrecisionMean(left.PrecisionMean + right.PrecisionMean, left.Precision + right.Precision); + } + + /// Computes the absolute difference between two Gaussians + public static double AbsoluteDifference(GaussianDistribution left, GaussianDistribution right) + { + return Math.Max( + Math.Abs(left.PrecisionMean - right.PrecisionMean), + Math.Sqrt(Math.Abs(left.Precision - right.Precision))); + } + + /// Computes the absolute difference between two Gaussians + public static double operator -(GaussianDistribution left, GaussianDistribution right) + { + return AbsoluteDifference(left, right); + } + + public static double LogProductNormalization(GaussianDistribution left, GaussianDistribution right) + { + if ((left.Precision == 0) || (right.Precision == 0)) + { + return 0; + } + + double varianceSum = left.Variance + right.Variance; + double meanDifference = left.Mean - right.Mean; + + double logSqrt2Pi = Math.Log(Math.Sqrt(2*Math.PI)); + return -logSqrt2Pi - (Math.Log(varianceSum)/2.0) - (Square(meanDifference)/(2.0*varianceSum)); + } + + + public static GaussianDistribution operator /(GaussianDistribution numerator, GaussianDistribution denominator) + { + return FromPrecisionMean(numerator.PrecisionMean - denominator.PrecisionMean, + numerator.Precision - denominator.Precision); + } + + public static double LogRatioNormalization(GaussianDistribution numerator, GaussianDistribution denominator) + { + if ((numerator.Precision == 0) || (denominator.Precision == 0)) + { + return 0; + } + + double varianceDifference = denominator.Variance - numerator.Variance; + double meanDifference = numerator.Mean - denominator.Mean; + + double logSqrt2Pi = Math.Log(Math.Sqrt(2*Math.PI)); + + return Math.Log(denominator.Variance) + logSqrt2Pi - Math.Log(varianceDifference)/2.0 + + Square(meanDifference)/(2*varianceDifference); + } + + private static double Square(double x) + { + return x*x; + } + + public static double At(double x) + { + return At(x, 0, 1); + } + + public static double At(double x, double mean, double standardDeviation) + { + // See http://mathworld.wolfram.com/NormalDistribution.html + // 1 -(x-mean)^2 / (2*stdDev^2) + // P(x) = ------------------- * e + // stdDev * sqrt(2*pi) + + double multiplier = 1.0/(standardDeviation*Math.Sqrt(2*Math.PI)); + double expPart = Math.Exp((-1.0*Math.Pow(x - mean, 2.0))/(2*(standardDeviation*standardDeviation))); + double result = multiplier*expPart; + return result; + } + + public static double CumulativeTo(double x, double mean, double standardDeviation) + { + double invsqrt2 = -0.707106781186547524400844362104; + double result = ErrorFunctionCumulativeTo(invsqrt2*x); + return 0.5*result; + } + + public static double CumulativeTo(double x) + { + return CumulativeTo(x, 0, 1); + } + + private static double ErrorFunctionCumulativeTo(double x) + { + // Derived from page 265 of Numerical Recipes 3rd Edition + double z = Math.Abs(x); + + double t = 2.0/(2.0 + z); + double ty = 4*t - 2; + + double[] coefficients = { + -1.3026537197817094, 6.4196979235649026e-1, + 1.9476473204185836e-2, -9.561514786808631e-3, -9.46595344482036e-4, + 3.66839497852761e-4, 4.2523324806907e-5, -2.0278578112534e-5, + -1.624290004647e-6, 1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8, + 6.529054439e-9, 5.059343495e-9, -9.91364156e-10, -2.27365122e-10, + 9.6467911e-11, 2.394038e-12, -6.886027e-12, 8.94487e-13, 3.13092e-13, + -1.12708e-13, 3.81e-16, 7.106e-15, -1.523e-15, -9.4e-17, 1.21e-16, -2.8e-17 + }; + + int ncof = coefficients.Length; + double d = 0.0; + double dd = 0.0; + + + for (int j = ncof - 1; j > 0; j--) + { + double tmp = d; + d = ty*d - dd + coefficients[j]; + dd = tmp; + } + + double ans = t*Math.Exp(-z*z + 0.5*(coefficients[0] + ty*d) - dd); + return x >= 0.0 ? ans : (2.0 - ans); + } + + + private static double InverseErrorFunctionCumulativeTo(double p) + { + // From page 265 of numerical recipes + + if (p >= 2.0) + { + return -100; + } + if (p <= 0.0) + { + return 100; + } + + double pp = (p < 1.0) ? p : 2 - p; + double t = Math.Sqrt(-2*Math.Log(pp/2.0)); // Initial guess + double x = -0.70711*((2.30753 + t*0.27061)/(1.0 + t*(0.99229 + t*0.04481)) - t); + + for (int j = 0; j < 2; j++) + { + double err = ErrorFunctionCumulativeTo(x) - pp; + x += err/(1.12837916709551257*Math.Exp(-(x*x)) - x*err); // Halley + } + + return p < 1.0 ? x : -x; + } + + public static double InverseCumulativeTo(double x, double mean, double standardDeviation) + { + // From numerical recipes, page 320 + return mean - Math.Sqrt(2)*standardDeviation*InverseErrorFunctionCumulativeTo(2*x); + } + + public static double InverseCumulativeTo(double x) + { + return InverseCumulativeTo(x, 0, 1); + } + + + public override string ToString() + { + // Debug help + return String.Format("μ={0:0.0000}, σ={1:0.0000}", + Mean, + StandardDeviation); + } + } +} \ No newline at end of file diff --git a/Skills/Numerics/Matrix.cs b/Skills/Numerics/Matrix.cs new file mode 100644 index 0000000..926065e --- /dev/null +++ b/Skills/Numerics/Matrix.cs @@ -0,0 +1,520 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Moserware.Numerics +{ + /// + /// Represents an MxN matrix with double precision values. + /// + internal class Matrix + { + protected double[][] _MatrixRowValues; + // Note: some properties like Determinant, Inverse, etc are properties instead + // of methods to make the syntax look nicer even though this sort of goes against + // Framework Design Guidelines that properties should be "cheap" since it could take + // a long time to compute these properties if the matrices are "big." + + protected Matrix() + { + } + + public Matrix(int rows, int columns, params double[] allRowValues) + { + Rows = rows; + Columns = columns; + + _MatrixRowValues = new double[rows][]; + + int currentIndex = 0; + for (int currentRow = 0; currentRow < Rows; currentRow++) + { + _MatrixRowValues[currentRow] = new double[Columns]; + + for (int currentColumn = 0; currentColumn < Columns; currentColumn++) + { + if ((allRowValues != null) && (currentIndex < allRowValues.Length)) + { + _MatrixRowValues[currentRow][currentColumn] = allRowValues[currentIndex++]; + } + } + } + } + + public Matrix(double[][] rowValues) + { + if (!rowValues.All(row => row.Length == rowValues[0].Length)) + { + throw new ArgumentException("All rows must be the same length!"); + } + + Rows = rowValues.Length; + Columns = rowValues[0].Length; + _MatrixRowValues = rowValues; + } + + protected Matrix(int rows, int columns, double[][] matrixRowValues) + { + Rows = rows; + Columns = columns; + _MatrixRowValues = matrixRowValues; + } + + public Matrix(int rows, int columns, IEnumerable> columnValues) + : this(rows, columns) + { + int columnIndex = 0; + + foreach (var currentColumn in columnValues) + { + int rowIndex = 0; + foreach (double currentColumnValue in currentColumn) + { + _MatrixRowValues[rowIndex++][columnIndex] = currentColumnValue; + } + columnIndex++; + } + } + + public int Rows { get; protected set; } + public int Columns { get; protected set; } + + public double this[int row, int column] + { + get { return _MatrixRowValues[row][column]; } + } + + public Matrix Transpose + { + get + { + // Just flip everything + var transposeMatrix = new double[Columns][]; + for (int currentRowTransposeMatrix = 0; + currentRowTransposeMatrix < Columns; + currentRowTransposeMatrix++) + { + var transposeMatrixCurrentRowColumnValues = new double[Rows]; + transposeMatrix[currentRowTransposeMatrix] = transposeMatrixCurrentRowColumnValues; + + for (int currentColumnTransposeMatrix = 0; + currentColumnTransposeMatrix < Rows; + currentColumnTransposeMatrix++) + { + transposeMatrixCurrentRowColumnValues[currentColumnTransposeMatrix] = + _MatrixRowValues[currentColumnTransposeMatrix][currentRowTransposeMatrix]; + } + } + + return new Matrix(Columns, Rows, transposeMatrix); + } + } + + private bool IsSquare + { + get { return (Rows == Columns) && Rows > 0; } + } + + public double Determinant + { + get + { + // Basic argument checking + if (!IsSquare) + { + throw new NotSupportedException("Matrix must be square!"); + } + + if (Rows == 1) + { + // Really happy path :) + return _MatrixRowValues[0][0]; + } + + if (Rows == 2) + { + // Happy path! + // Given: + // | a b | + // | c d | + // The determinant is ad - bc + double a = _MatrixRowValues[0][0]; + double b = _MatrixRowValues[0][1]; + double c = _MatrixRowValues[1][0]; + double d = _MatrixRowValues[1][1]; + return a*d - b*c; + } + + // I use the Laplace expansion here since it's straightforward to implement. + // It's O(n^2) and my implementation is especially poor performing, but the + // core idea is there. Perhaps I should replace it with a better algorithm + // later. + // See http://en.wikipedia.org/wiki/Laplace_expansion for details + + double result = 0.0; + + // I expand along the first row + for (int currentColumn = 0; currentColumn < Columns; currentColumn++) + { + double firstRowColValue = _MatrixRowValues[0][currentColumn]; + double cofactor = GetCofactor(0, currentColumn); + double itemToAdd = firstRowColValue*cofactor; + result += itemToAdd; + } + + return result; + } + } + + public Matrix Adjugate + { + get + { + if (!IsSquare) + { + throw new ArgumentException("Matrix must be square!"); + } + + // See http://en.wikipedia.org/wiki/Adjugate_matrix + if (Rows == 2) + { + // Happy path! + // Adjugate of: + // | a b | + // | c d | + // is + // | d -b | + // | -c a | + + double a = _MatrixRowValues[0][0]; + double b = _MatrixRowValues[0][1]; + double c = _MatrixRowValues[1][0]; + double d = _MatrixRowValues[1][1]; + + return new SquareMatrix(d, -b, + -c, a); + } + + // The idea is that it's the transpose of the cofactors + var result = new double[Columns][]; + + for (int currentColumn = 0; currentColumn < Columns; currentColumn++) + { + result[currentColumn] = new double[Rows]; + + for (int currentRow = 0; currentRow < Rows; currentRow++) + { + result[currentColumn][currentRow] = GetCofactor(currentRow, currentColumn); + } + } + + return new Matrix(result); + } + } + + public Matrix Inverse + { + get + { + if ((Rows == 1) && (Columns == 1)) + { + return new SquareMatrix(1.0/_MatrixRowValues[0][0]); + } + + // Take the simple approach: + // http://en.wikipedia.org/wiki/Cramer%27s_rule#Finding_inverse_matrix + return (1.0/Determinant)*Adjugate; + } + } + + public static Matrix operator *(double scalarValue, Matrix matrix) + { + int rows = matrix.Rows; + int columns = matrix.Columns; + var newValues = new double[rows][]; + + for (int currentRow = 0; currentRow < rows; currentRow++) + { + var newRowColumnValues = new double[columns]; + newValues[currentRow] = newRowColumnValues; + + for (int currentColumn = 0; currentColumn < columns; currentColumn++) + { + newRowColumnValues[currentColumn] = scalarValue*matrix._MatrixRowValues[currentRow][currentColumn]; + } + } + + return new Matrix(rows, columns, newValues); + } + + public static Matrix operator +(Matrix left, Matrix right) + { + if ((left.Rows != right.Rows) || (left.Columns != right.Columns)) + { + throw new ArgumentException("Matrices must be of the same size"); + } + + // simple addition of each item + + var resultMatrix = new double[left.Rows][]; + + for (int currentRow = 0; currentRow < left.Rows; currentRow++) + { + var rowColumnValues = new double[right.Columns]; + resultMatrix[currentRow] = rowColumnValues; + for (int currentColumn = 0; currentColumn < right.Columns; currentColumn++) + { + rowColumnValues[currentColumn] = left._MatrixRowValues[currentRow][currentColumn] + + + right._MatrixRowValues[currentRow][currentColumn]; + } + } + + return new Matrix(left.Rows, right.Columns, resultMatrix); + } + + public static Matrix operator *(Matrix left, Matrix right) + { + // Just your standard matrix multiplication. + // See http://en.wikipedia.org/wiki/Matrix_multiplication for details + + if (left.Columns != right.Rows) + { + throw new ArgumentException("The width of the left matrix must match the height of the right matrix", + "right"); + } + + int resultRows = left.Rows; + int resultColumns = right.Columns; + + var resultMatrix = new double[resultRows][]; + + for (int currentRow = 0; currentRow < resultRows; currentRow++) + { + resultMatrix[currentRow] = new double[resultColumns]; + + for (int currentColumn = 0; currentColumn < resultColumns; currentColumn++) + { + double productValue = 0; + + for (int vectorIndex = 0; vectorIndex < left.Columns; vectorIndex++) + { + double leftValue = left._MatrixRowValues[currentRow][vectorIndex]; + double rightValue = right._MatrixRowValues[vectorIndex][currentColumn]; + double vectorIndexProduct = leftValue*rightValue; + productValue += vectorIndexProduct; + } + + resultMatrix[currentRow][currentColumn] = productValue; + } + } + + return new Matrix(resultRows, resultColumns, resultMatrix); + } + + private Matrix GetMinorMatrix(int rowToRemove, int columnToRemove) + { + // See http://en.wikipedia.org/wiki/Minor_(linear_algebra) + + // I'm going to use a horribly naïve algorithm... because I can :) + var result = new double[Rows - 1][]; + int resultRow = 0; + + for (int currentRow = 0; currentRow < Rows; currentRow++) + { + if (currentRow == rowToRemove) + { + continue; + } + + result[resultRow] = new double[Columns - 1]; + + int resultColumn = 0; + + for (int currentColumn = 0; currentColumn < Columns; currentColumn++) + { + if (currentColumn == columnToRemove) + { + continue; + } + + result[resultRow][resultColumn] = _MatrixRowValues[currentRow][currentColumn]; + resultColumn++; + } + + resultRow++; + } + + return new Matrix(Rows - 1, Columns - 1, result); + } + + private double GetCofactor(int rowToRemove, int columnToRemove) + { + // See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for details + // REVIEW: should things be reversed since I'm 0 indexed? + int sum = rowToRemove + columnToRemove; + bool isEven = (sum%2 == 0); + + if (isEven) + { + return GetMinorMatrix(rowToRemove, columnToRemove).Determinant; + } + else + { + return -1.0*GetMinorMatrix(rowToRemove, columnToRemove).Determinant; + } + } + + // Equality stuff + // See http://msdn.microsoft.com/en-us/library/ms173147.aspx + + public static bool operator ==(Matrix a, Matrix b) + { + // If both are null, or both are same instance, return true. + if (ReferenceEquals(a, b)) + { + return true; + } + + // If one is null, but not both, return false. + if (((object) a == null) || ((object) b == null)) + { + return false; + } + + if ((a.Rows != b.Rows) || (a.Columns != b.Columns)) + { + return false; + } + + const double errorTolerance = 0.0000000000001; + + for (int currentRow = 0; currentRow < a.Rows; currentRow++) + { + for (int currentColumn = 0; currentColumn < a.Columns; currentColumn++) + { + double delta = + Math.Abs(a._MatrixRowValues[currentRow][currentColumn] - + b._MatrixRowValues[currentRow][currentColumn]); + + if (delta > errorTolerance) + { + return false; + } + } + } + + return true; + } + + public static bool operator !=(Matrix a, Matrix b) + { + return !(a == b); + } + + public override int GetHashCode() + { + double result = Rows; + result += 2*Columns; + + unchecked + { + for (int currentRow = 0; currentRow < Rows; currentRow++) + { + bool eventRow = (currentRow%2) == 0; + double multiplier = eventRow ? 1.0 : 2.0; + + for (int currentColumn = 0; currentColumn < Columns; currentColumn++) + { + result += multiplier*_MatrixRowValues[currentRow][currentColumn]; + } + } + } + + // Ok, now convert that double to an int + byte[] resultBytes = BitConverter.GetBytes(result); + + var finalBytes = new byte[4]; + for (int i = 0; i < 4; i++) + { + finalBytes[i] = (byte) (resultBytes[i] ^ resultBytes[i + 4]); + } + + int hashCode = BitConverter.ToInt32(finalBytes, 0); + return hashCode; + } + + public override bool Equals(object obj) + { + var other = obj as Matrix; + if (other == null) + { + return base.Equals(obj); + } + + return this == other; + } + } + + internal class DiagonalMatrix : Matrix + { + public DiagonalMatrix(IList diagonalValues) + : base(diagonalValues.Count, diagonalValues.Count) + { + for (int i = 0; i < diagonalValues.Count; i++) + { + _MatrixRowValues[i][i] = diagonalValues[i]; + } + } + } + + internal class Vector : Matrix + { + public Vector(IList vectorValues) + : base(vectorValues.Count, 1, new IEnumerable[] {vectorValues}) + { + } + } + + internal class SquareMatrix : Matrix + { + public SquareMatrix(params double[] allValues) + { + Rows = (int) Math.Sqrt(allValues.Length); + Columns = Rows; + + int allValuesIndex = 0; + + _MatrixRowValues = new double[Rows][]; + for (int currentRow = 0; currentRow < Rows; currentRow++) + { + var currentRowValues = new double[Columns]; + _MatrixRowValues[currentRow] = currentRowValues; + + for (int currentColumn = 0; currentColumn < Columns; currentColumn++) + { + currentRowValues[currentColumn] = allValues[allValuesIndex++]; + } + } + } + } + + internal class IdentityMatrix : DiagonalMatrix + { + public IdentityMatrix(int rows) + : base(CreateDiagonal(rows)) + { + } + + private static double[] CreateDiagonal(int rows) + { + var result = new double[rows]; + for (int i = 0; i < rows; i++) + { + result[i] = 1.0; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Skills/Numerics/Range.cs b/Skills/Numerics/Range.cs new file mode 100644 index 0000000..7d5b581 --- /dev/null +++ b/Skills/Numerics/Range.cs @@ -0,0 +1,49 @@ +using System; + +namespace Moserware.Skills.Numerics +{ + // The whole purpose of this class is to make the code for the SkillCalculator(s) + // look a little cleaner + + public abstract class Range where T : Range, new() + { + private static readonly T _Instance = new T(); + + protected Range(int min, int max) + { + if (min > max) + { + throw new ArgumentOutOfRangeException(); + } + + Min = min; + Max = max; + } + + public int Min { get; private set; } + public int Max { get; private set; } + protected abstract T Create(int min, int max); + + // REVIEW: It's probably bad form to have access statics via a derived class, but the syntax looks better :-) + + public static T Inclusive(int min, int max) + { + return _Instance.Create(min, max); + } + + public static T Exactly(int value) + { + return _Instance.Create(value, value); + } + + public static T AtLeast(int minimumValue) + { + return _Instance.Create(minimumValue, int.MaxValue); + } + + public bool IsInRange(int value) + { + return (Min <= value) && (value <= Max); + } + } +} \ No newline at end of file diff --git a/Skills/PairwiseComparison.cs b/Skills/PairwiseComparison.cs new file mode 100644 index 0000000..7848eb3 --- /dev/null +++ b/Skills/PairwiseComparison.cs @@ -0,0 +1,15 @@ +namespace Moserware.Skills +{ + /// + /// Represents a comparison between two players. + /// + /// + /// The actual values for the enum were chosen so that the also correspond to the multiplier for updates to means. + /// + public enum PairwiseComparison + { + Win = 1, + Draw = 0, + Lose = -1 + } +} \ No newline at end of file diff --git a/Skills/PartialPlay.cs b/Skills/PartialPlay.cs new file mode 100644 index 0000000..b24d08f --- /dev/null +++ b/Skills/PartialPlay.cs @@ -0,0 +1,26 @@ +namespace Moserware.Skills +{ + internal static class PartialPlay + { + public static double GetPartialPlayPercentage(object player) + { + // If the player doesn't support the interface, assume 1.0 == 100% + var partialPlay = player as ISupportPartialPlay; + if (partialPlay == null) + { + return 1.0; + } + + double partialPlayPercentage = partialPlay.PartialPlayPercentage; + + // HACK to get around bug near 0 + const double smallestPercentage = 0.0001; + if (partialPlayPercentage < smallestPercentage) + { + partialPlayPercentage = smallestPercentage; + } + + return partialPlayPercentage; + } + } +} \ No newline at end of file diff --git a/Skills/Player.cs b/Skills/Player.cs new file mode 100644 index 0000000..74bcad6 --- /dev/null +++ b/Skills/Player.cs @@ -0,0 +1,129 @@ +namespace Moserware.Skills +{ + /// + /// Represents a player who has a . + /// + public class Player : ISupportPartialPlay, ISupportPartialUpdate + { + private const double DefaultPartialPlayPercentage = 1.0; // = 100% play time + private const double DefaultPartialUpdatePercentage = 1.0; // = receive 100% update + private readonly T _Id; + private readonly double _PartialPlayPercentage; + + private readonly double _PartialUpdatePercentage; + + /// + /// Constructs a player. + /// + /// The identifier for the player, such as a name. + public Player(T id) + : this(id, DefaultPartialPlayPercentage, DefaultPartialUpdatePercentage) + { + } + + /// + /// Constructs a player. + /// + /// The identifier for the player, such as a name. + /// The weight percentage to give this player when calculating a new rank. + public Player(T id, double partialPlayPercentage) + : this(id, partialPlayPercentage, DefaultPartialUpdatePercentage) + { + } + + /// + /// Constructs a player. + /// + /// The identifier for the player, such as a name. + /// The weight percentage to give this player when calculating a new rank. + /// /// Indicated how much of a skill update a player should receive where 0 represents no update and 1.0 represents 100% of the update. + public Player(T id, double partialPlayPercentage, double partialUpdatePercentage) + { + // If they don't want to give a player an id, that's ok... + Guard.ArgumentInRangeInclusive(partialPlayPercentage, 0, 1.0, "partialPlayPercentage"); + Guard.ArgumentInRangeInclusive(partialUpdatePercentage, 0, 1.0, "partialUpdatePercentage"); + _Id = id; + _PartialPlayPercentage = partialPlayPercentage; + _PartialUpdatePercentage = partialUpdatePercentage; + } + + /// + /// The identifier for the player, such as a name. + /// + public T Id + { + get { return _Id; } + } + + #region ISupportPartialPlay Members + + /// + /// Indicates the percent of the time the player should be weighted where 0.0 indicates the player didn't play and 1.0 indicates the player played 100% of the time. + /// + public double PartialPlayPercentage + { + get { return _PartialPlayPercentage; } + } + + #endregion + + #region ISupportPartialUpdate Members + + /// + /// Indicated how much of a skill update a player should receive where 0.0 represents no update and 1.0 represents 100% of the update. + /// + public double PartialUpdatePercentage + { + get { return _PartialUpdatePercentage; } + } + + #endregion + + public override string ToString() + { + if (Id != null) + { + return Id.ToString(); + } + + return base.ToString(); + } + } + + /// + /// Represents a player who has a . + /// + public class Player : Player + { + /// + /// Constructs a player. + /// + /// The identifier for the player, such as a name. + public Player(object id) + : base(id) + { + } + + /// + /// Constructs a player. + /// + /// The identifier for the player, such as a name. + /// The weight percentage to give this player when calculating a new rank. + /// Indicated how much of a skill update a player should receive where 0 represents no update and 1.0 represents 100% of the update. + public Player(object id, double partialPlayPercentage) + : base(id, partialPlayPercentage) + { + } + + /// + /// Constructs a player. + /// + /// The identifier for the player, such as a name. + /// The weight percentage to give this player when calculating a new rank. + /// Indicated how much of a skill update a player should receive where 0 represents no update and 1.0 represents 100% of the update. + public Player(object id, double partialPlayPercentage, double partialUpdatePercentage) + : base(id, partialPlayPercentage, partialUpdatePercentage) + { + } + } +} \ No newline at end of file diff --git a/Skills/PlayersRange.cs b/Skills/PlayersRange.cs new file mode 100644 index 0000000..b3c2963 --- /dev/null +++ b/Skills/PlayersRange.cs @@ -0,0 +1,22 @@ +using Moserware.Skills.Numerics; + +namespace Moserware.Skills +{ + public class PlayersRange : Range + { + public PlayersRange() + : base(int.MinValue, int.MinValue) + { + } + + private PlayersRange(int min, int max) + : base(min, max) + { + } + + protected override PlayersRange Create(int min, int max) + { + return new PlayersRange(min, max); + } + } +} \ No newline at end of file diff --git a/Skills/Properties/AssemblyInfo.cs b/Skills/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8d32e79 --- /dev/null +++ b/Skills/Properties/AssemblyInfo.cs @@ -0,0 +1,45 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly: AssemblyTitle("Moserware.Skills")] +[assembly: AssemblyDescription("Implementation of the TrueSkill algorithm.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Jeff Moser")] +[assembly: AssemblyProduct("TrueSkill Calculator")] +[assembly: AssemblyCopyright("Copyright © Jeff Moser 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly: Guid("4326f9ed-f234-42ed-bee0-84f7757ab28f")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +#if DEBUG + +[assembly: InternalsVisibleTo("UnitTests")] +#endif \ No newline at end of file diff --git a/Skills/README.txt b/Skills/README.txt new file mode 100644 index 0000000..fcc9b11 --- /dev/null +++ b/Skills/README.txt @@ -0,0 +1,58 @@ +Hi there! + +Thanks for downloading this code and opening up this file. The goal of this +project is to provide an annotated reference implementation of Microsoft's +TrueSkill algorithm. + +I describe the philosophy and the buildup of the math involved in my blog post +"Computing Your Skill" available at moserware.com. + +In addition, there is a math paper that goes along with the blog post that explains +most of the more technical concepts. + +This project isn't intended to win performance tests, it's meant to be read +and understood. If you see ways to improve its clarity, please submit a patch. + +If you just want to use the TrueSkill algorithm, simply use the TrueSkillCalculator +class and enjoy. If you need examples, please look in the UnitTests\TrueSkill folder. + +If you want to understand the inner workings of the algorithm and implement it +yourself, look in the Skills\TrueSkill folder. There are three separate +implementations of the algorithm in increasing levels of difficulty: + + 1. TwoPlayerTrueSkillCalculator.cs is the easiest to follow and implement. It uses + the simple equations directly from the TrueSkill website. + 2. TwoTeamTrueSkillCalculator.cs is slightly more complicated than the two player + version and supports two teams that have at least one player each. It extends + the equations on the website and incorporates some things implied in the paper. + 3. FactorGraphTrueSkillCalculator.cs is a wholly different animal than the first two + and it is at least an order of magnitude more complex. It implements the complete + TrueSkill algorithm and builds up a "factor graph" composed of several layers. + Each layer is composed of "factors", "variables", and "messages" between the two. + + Work happens on the factor graph according to a "schedule" which can either be + a single step (e.g. sending a message from a factor to a variable) or a sequence of + steps (e.g. everything that happens in a "layer") or a loop where the schedule runs + until values start to stabilize (e.g. the bottom layer is approximated and runs until + it converges) + +TrueSkill is more general than the popular Elo algorithm. As a comparison, I implemented +the Elo algorithm using the both the bell curve (Gaussian) and curve that the FIDE chess +league uses (logistic curve). I specifically implemented them in a way to show how the +only difference among these Elo implementations is the curve. I also implemented the +"duelling" Elo calculator as implied in the paper. + +Everything else was implemented to support these classes. Note that a "player" can be an +arbitrary class. However, if that player class supports the "ISupportPartialPlay" or +"ISupportPartialUpdate" interfaces, you can add these extra parameters. The only calculator +that uses this info is the factor graph implementation. See those files for more details. + +I use this code personally to rank around 45 people, so it's important that it's accurate. +Please let me know if you find errors. Bug fix patches are strongly encouraged! Also, feel +free to fork the project for different language implementations. + +I'd love to hear from you via comments on the "Computing Your Skill" blog post. + +Have fun and enjoy! + +Jeff Moser \ No newline at end of file diff --git a/Skills/RankSorter.cs b/Skills/RankSorter.cs new file mode 100644 index 0000000..c3dc1f6 --- /dev/null +++ b/Skills/RankSorter.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Moserware.Skills +{ + /// + /// Helper class to sort ranks in non-decreasing order. + /// + internal static class RankSorter + { + /// + /// Performs an in-place sort of the in according to the in non-decreasing order. + /// + /// The types of items to sort. + /// The items to sort according to the order specified by . + /// The ranks for each item where 1 is first place. + public static void Sort(ref IEnumerable teams, ref int[] teamRanks) + { + Guard.ArgumentNotNull(teams, "teams"); + Guard.ArgumentNotNull(teamRanks, "teamRanks"); + + int lastObserverdRank = 0; + bool needToSort = false; + + foreach (int currentRank in teamRanks) + { + // We're expecting ranks to go up (e.g. 1, 2, 2, 3, ...) + // If it goes down, then we've got to sort it. + if (currentRank < lastObserverdRank) + { + needToSort = true; + break; + } + + lastObserverdRank = currentRank; + } + + if (!needToSort) + { + // Don't bother doing more work, it's already in a good order + return; + } + + // Get the existing items as an indexable list. + List itemsInList = teams.ToList(); + + // item -> rank + var itemToRank = new Dictionary(); + + for (int i = 0; i < itemsInList.Count; i++) + { + T currentItem = itemsInList[i]; + int currentItemRank = teamRanks[i]; + itemToRank[currentItem] = currentItemRank; + } + + // Now we need a place for our results... + var sortedItems = new T[teamRanks.Length]; + var sortedRanks = new int[teamRanks.Length]; + + // where are we in the result? + int currentIndex = 0; + + // Let LINQ-to-Objects to the actual sorting + foreach (var sortedKeyValuePair in itemToRank.OrderBy(pair => pair.Value)) + { + sortedItems[currentIndex] = sortedKeyValuePair.Key; + sortedRanks[currentIndex++] = sortedKeyValuePair.Value; + } + + // And we're done + teams = sortedItems; + teamRanks = sortedRanks; + } + } +} \ No newline at end of file diff --git a/Skills/Rating.cs b/Skills/Rating.cs new file mode 100644 index 0000000..429f51f --- /dev/null +++ b/Skills/Rating.cs @@ -0,0 +1,94 @@ +using System; +using Moserware.Numerics; + +namespace Moserware.Skills +{ + /// + /// Container for a player's rating. + /// + public class Rating + { + private const int ConservativeStandardDeviationMultiplier = 3; + private readonly double _ConservativeStandardDeviationMultiplier; + private readonly double _Mean; + private readonly double _StandardDeviation; + + /// + /// Constructs a rating. + /// + /// The statistical mean value of the rating (also known as μ). + /// The standard deviation of the rating (also known as σ). + public Rating(double mean, double standardDeviation) + : this(mean, standardDeviation, ConservativeStandardDeviationMultiplier) + { + } + + /// + /// Constructs a rating. + /// + /// The statistical mean value of the rating (also known as μ). + /// The standard deviation (the spread) of the rating (also known as σ). + /// The number of s to subtract from the to achieve a conservative rating. + public Rating(double mean, double standardDeviation, double conservativeStandardDeviationMultiplier) + { + _Mean = mean; + _StandardDeviation = standardDeviation; + _ConservativeStandardDeviationMultiplier = conservativeStandardDeviationMultiplier; + } + + /// + /// The statistical mean value of the rating (also known as μ). + /// + public double Mean + { + get { return _Mean; } + } + + /// + /// The standard deviation (the spread) of the rating. This is also known as σ. + /// + public double StandardDeviation + { + get { return _StandardDeviation; } + } + + /// + /// A conservative estimate of skill based on the mean and standard deviation. + /// + public double ConservativeRating + { + get { return _Mean - ConservativeStandardDeviationMultiplier*_StandardDeviation; } + } + + public static Rating GetPartialUpdate(Rating prior, Rating fullPosterior, double updatePercentage) + { + var priorGaussian = new GaussianDistribution(prior.Mean, prior.StandardDeviation); + var posteriorGaussian = new GaussianDistribution(fullPosterior.Mean, fullPosterior.StandardDeviation); + + // From a clarification email from Ralf Herbrich: + // "the idea is to compute a linear interpolation between the prior and posterior skills of each player + // ... in the canonical space of parameters" + + double precisionDifference = posteriorGaussian.Precision - priorGaussian.Precision; + double partialPrecisionDifference = updatePercentage*precisionDifference; + + double precisionMeanDifference = posteriorGaussian.PrecisionMean - priorGaussian.PrecisionMean; + double partialPrecisionMeanDifference = updatePercentage*precisionMeanDifference; + + GaussianDistribution partialPosteriorGaussion = GaussianDistribution.FromPrecisionMean( + priorGaussian.PrecisionMean + partialPrecisionMeanDifference, + priorGaussian.Precision + partialPrecisionDifference); + + return new Rating(partialPosteriorGaussion.Mean, partialPosteriorGaussion.StandardDeviation, + prior._ConservativeStandardDeviationMultiplier); + } + + public override string ToString() + { + // As a debug helper, display a localized rating: + return String.Format( + "μ={0:0.0000}, σ={1:0.0000}", + Mean, StandardDeviation); + } + } +} \ No newline at end of file diff --git a/Skills/SkillCalculator.cs b/Skills/SkillCalculator.cs new file mode 100644 index 0000000..6f70b6e --- /dev/null +++ b/Skills/SkillCalculator.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; + +namespace Moserware.Skills +{ + /// + /// Base class for all skill calculator implementations. + /// + public abstract class SkillCalculator + { + [Flags] + public enum SupportedOptions + { + None = 0x00, + PartialPlay = 0x01, + PartialUpdate = 0x02, + } + + private readonly SupportedOptions _SupportedOptions; + private readonly PlayersRange _PlayersPerTeamAllowed; + private readonly TeamsRange _TotalTeamsAllowed; + + protected SkillCalculator(SupportedOptions supportedOptions, TeamsRange totalTeamsAllowed, PlayersRange playerPerTeamAllowed) + { + _SupportedOptions = supportedOptions; + _TotalTeamsAllowed = totalTeamsAllowed; + _PlayersPerTeamAllowed = playerPerTeamAllowed; + } + + /// + /// Calculates new ratings based on the prior ratings and team ranks. + /// + /// The underlying type of the player. + /// Parameters for the game. + /// A mapping of team players and their ratings. + /// The ranks of the teams where 1 is first place. For a tie, repeat the number (e.g. 1, 2, 2) + /// All the players and their new ratings. + public abstract IDictionary CalculateNewRatings(GameInfo gameInfo, + IEnumerable + > + teams, + params int[] teamRanks); + + /// + /// Calculates the match quality as the likelihood of all teams drawing. + /// + /// The underlying type of the player. + /// Parameters for the game. + /// A mapping of team players and their ratings. + /// The quality of the match between the teams as a percentage (0% = bad, 100% = well matched). + public abstract double CalculateMatchQuality(GameInfo gameInfo, + IEnumerable> teams); + + public bool IsSupported(SupportedOptions option) + { + return (_SupportedOptions & option) == option; + } + + /// + /// Helper function to square the . + /// + /// * + protected static double Square(double value) + { + return value*value; + } + + protected void ValidateTeamCountAndPlayersCountPerTeam(IEnumerable> teams) + { + ValidateTeamCountAndPlayersCountPerTeam(teams, _TotalTeamsAllowed, _PlayersPerTeamAllowed); + } + + private static void ValidateTeamCountAndPlayersCountPerTeam( + IEnumerable> teams, TeamsRange totalTeams, PlayersRange playersPerTeam) + { + Guard.ArgumentNotNull(teams, "teams"); + int countOfTeams = 0; + foreach (var currentTeam in teams) + { + if (!playersPerTeam.IsInRange(currentTeam.Count)) + { + throw new ArgumentException(); + } + countOfTeams++; + } + + if (!totalTeams.IsInRange(countOfTeams)) + { + throw new ArgumentException(); + } + } + } +} \ No newline at end of file diff --git a/Skills/Skills.csproj b/Skills/Skills.csproj new file mode 100644 index 0000000..3cf270e --- /dev/null +++ b/Skills/Skills.csproj @@ -0,0 +1,116 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {15AD1345-984C-48ED-AF9A-2EAB44E5AA2B} + Library + Properties + Moserware.Skills + Moserware.Skills + v3.5 + 512 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Skills/Skills.suo b/Skills/Skills.suo new file mode 100644 index 0000000000000000000000000000000000000000..2d273c621e602b758643497c7dca24117bf864ee GIT binary patch literal 142336 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 + /// Helper class for working with a single team. + /// + public class Team + { + private readonly Dictionary _PlayerRatings = new Dictionary(); + + /// + /// Constructs a new team. + /// + public Team() + { + } + + /// + /// Constructs a and populates it with the specified . + /// + /// The player to add. + /// The rating of the . + public Team(TPlayer player, Rating rating) + { + AddPlayer(player, rating); + } + + /// + /// Adds the to the team. + /// + /// The player to add. + /// The rating of the . + /// The instance of the team (for chaining convenience). + public Team AddPlayer(TPlayer player, Rating rating) + { + _PlayerRatings[player] = rating; + return this; + } + + /// + /// Returns the as a simple dictionary. + /// + /// The as a simple dictionary. + public IDictionary AsDictionary() + { + return _PlayerRatings; + } + } + + /// + /// Helper class for working with a single team. + /// + public class Team : Team + { + /// + /// Constructs a new team. + /// + public Team() + { + } + + /// + /// Constructs a and populates it with the specified . + /// + /// The player to add. + /// The rating of the . + public Team(Player player, Rating rating) + : base(player, rating) + { + } + } + + /// + /// Helper class for working with multiple teams. + /// + public static class Teams + { + /// + /// Concatenates multiple teams into a list of teams. + /// + /// The teams to concatenate together. + /// A sequence of teams. + public static IEnumerable> Concat(params Team[] teams) + { + return teams.Select(t => t.AsDictionary()); + } + } +} \ No newline at end of file diff --git a/Skills/TeamsRange.cs b/Skills/TeamsRange.cs new file mode 100644 index 0000000..22c40e7 --- /dev/null +++ b/Skills/TeamsRange.cs @@ -0,0 +1,22 @@ +using Moserware.Skills.Numerics; + +namespace Moserware.Skills +{ + public class TeamsRange : Range + { + public TeamsRange() + : base(int.MinValue, int.MinValue) + { + } + + private TeamsRange(int min, int max) + : base(min, max) + { + } + + protected override TeamsRange Create(int min, int max) + { + return new TeamsRange(min, max); + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/DrawMargin.cs b/Skills/TrueSkill/DrawMargin.cs new file mode 100644 index 0000000..25335d5 --- /dev/null +++ b/Skills/TrueSkill/DrawMargin.cs @@ -0,0 +1,23 @@ +using System; +using Moserware.Numerics; + +namespace Moserware.Skills.TrueSkill +{ + internal static class DrawMargin + { + public static double GetDrawMarginFromDrawProbability(double drawProbability, double beta) + { + // Derived from TrueSkill technical report (MSR-TR-2006-80), page 6 + + // draw probability = 2 * CDF(margin/(sqrt(n1+n2)*beta)) -1 + + // implies + // + // margin = inversecdf((draw probability + 1)/2) * sqrt(n1+n2) * beta + // n1 and n2 are the number of players on each team + double margin = GaussianDistribution.InverseCumulativeTo(.5*(drawProbability + 1), 0, 1)*Math.Sqrt(1 + 1)* + beta; + return margin; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/FactorGraphTrueSkillCalculator.cs b/Skills/TrueSkill/FactorGraphTrueSkillCalculator.cs new file mode 100644 index 0000000..8a291a0 --- /dev/null +++ b/Skills/TrueSkill/FactorGraphTrueSkillCalculator.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Moserware.Numerics; + +namespace Moserware.Skills.TrueSkill +{ + /// + /// Calculates TrueSkill using a full factor graph. + /// + internal class FactorGraphTrueSkillCalculator : SkillCalculator + { + public FactorGraphTrueSkillCalculator() + : base(SupportedOptions.PartialPlay | SupportedOptions.PartialUpdate, TeamsRange.AtLeast(2), PlayersRange.AtLeast(1)) + { + } + + public override IDictionary CalculateNewRatings(GameInfo gameInfo, + IEnumerable> teams, + params int[] teamRanks) + { + Guard.ArgumentNotNull(gameInfo, "gameInfo"); + ValidateTeamCountAndPlayersCountPerTeam(teams); + + RankSorter.Sort(ref teams, ref teamRanks); + + var factorGraph = new TrueSkillFactorGraph(gameInfo, teams, teamRanks); + factorGraph.BuildGraph(); + factorGraph.RunSchedule(); + + double probabilityOfOutcome = factorGraph.GetProbabilityOfRanking(); + + return factorGraph.GetUpdatedRatings(); + } + + + public override double CalculateMatchQuality(GameInfo gameInfo, + IEnumerable> teams) + { + // We need to create the A matrix which is the player team assigments. + List> teamAssignmentsList = teams.ToList(); + Matrix skillsMatrix = GetPlayerCovarianceMatrix(teamAssignmentsList); + Vector meanVector = GetPlayerMeansVector(teamAssignmentsList); + Matrix meanVectorTranspose = meanVector.Transpose; + + Matrix playerTeamAssignmentsMatrix = CreatePlayerTeamAssignmentMatrix(teamAssignmentsList, meanVector.Rows); + Matrix playerTeamAssignmentsMatrixTranspose = playerTeamAssignmentsMatrix.Transpose; + + double betaSquared = Square(gameInfo.Beta); + + Matrix start = meanVectorTranspose * playerTeamAssignmentsMatrix; + Matrix aTa = (betaSquared * playerTeamAssignmentsMatrixTranspose) * playerTeamAssignmentsMatrix; + Matrix aTSA = playerTeamAssignmentsMatrixTranspose * skillsMatrix * playerTeamAssignmentsMatrix; + Matrix middle = aTa + aTSA; + + Matrix middleInverse = middle.Inverse; + + Matrix end = playerTeamAssignmentsMatrixTranspose * meanVector; + + Matrix expPartMatrix = -0.5 * (start * middleInverse * end); + double expPart = expPartMatrix.Determinant; + + double sqrtPartNumerator = aTa.Determinant; + double sqrtPartDenominator = middle.Determinant; + double sqrtPart = sqrtPartNumerator / sqrtPartDenominator; + + double result = Math.Exp(expPart) * Math.Sqrt(sqrtPart); + + return result; + } + + private static Vector GetPlayerMeansVector( + IEnumerable> teamAssignmentsList) + { + // A simple vector of all the player means. + return new Vector(GetPlayerRatingValues(teamAssignmentsList, rating => rating.Mean)); + } + + private static Matrix GetPlayerCovarianceMatrix( + IEnumerable> teamAssignmentsList) + { + // This is a square matrix whose diagonal values represent the variance (square of standard deviation) of all + // players. + return + new DiagonalMatrix(GetPlayerRatingValues(teamAssignmentsList, rating => Square(rating.StandardDeviation))); + } + + // Helper function that gets a list of values for all player ratings + private static IList GetPlayerRatingValues( + IEnumerable> teamAssignmentsList, Func playerRatingFunction) + { + var playerRatingValues = new List(); + + foreach (var currentTeam in teamAssignmentsList) + { + foreach (Rating currentRating in currentTeam.Values) + { + playerRatingValues.Add(playerRatingFunction(currentRating)); + } + } + + return playerRatingValues; + } + + private static Matrix CreatePlayerTeamAssignmentMatrix( + IList> teamAssignmentsList, int totalPlayers) + { + // The team assignment matrix is often referred to as the "A" matrix. It's a matrix whose rows represent the players + // and the columns represent teams. At Matrix[row, column] represents that player[row] is on team[col] + // Positive values represent an assignment and a negative value means that we subtract the value of the next + // team since we're dealing with pairs. This means that this matrix always has teams - 1 columns. + // The only other tricky thing is that values represent the play percentage. + + // For example, consider a 3 team game where team1 is just player1, team 2 is player 2 and player 3, and + // team3 is just player 4. Furthermore, player 2 and player 3 on team 2 played 25% and 75% of the time + // (e.g. partial play), the A matrix would be: + + // A = this 4x2 matrix: + // | 1.00 0.00 | + // | -0.25 0.25 | + // | -0.75 0.75 | + // | 0.00 -1.00 | + + var playerAssignments = new List>(); + int totalPreviousPlayers = 0; + + for (int i = 0; i < teamAssignmentsList.Count - 1; i++) + { + IDictionary currentTeam = teamAssignmentsList[i]; + + // Need to add in 0's for all the previous players, since they're not + // on this team + var currentRowValues = new List(new double[totalPreviousPlayers]); + playerAssignments.Add(currentRowValues); + + foreach (var currentRating in currentTeam) + { + currentRowValues.Add(PartialPlay.GetPartialPlayPercentage(currentRating.Key)); + // indicates the player is on the team + totalPreviousPlayers++; + } + + IDictionary nextTeam = teamAssignmentsList[i + 1]; + foreach (var nextTeamPlayerPair in nextTeam) + { + // Add a -1 * playing time to represent the difference + currentRowValues.Add(-1 * PartialPlay.GetPartialPlayPercentage(nextTeamPlayerPair.Key)); + } + } + + var playerTeamAssignmentsMatrix = new Matrix(totalPlayers, teamAssignmentsList.Count - 1, playerAssignments); + + return playerTeamAssignmentsMatrix; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Factors/GaussianFactor.cs b/Skills/TrueSkill/Factors/GaussianFactor.cs new file mode 100644 index 0000000..3417627 --- /dev/null +++ b/Skills/TrueSkill/Factors/GaussianFactor.cs @@ -0,0 +1,33 @@ +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; + +namespace Moserware.Skills.TrueSkill.Factors +{ + public abstract class GaussianFactor : Factor + { + protected GaussianFactor(string name) + : base(name) + { + } + + /// Sends the factor-graph message with and returns the log-normalization constant + protected override double SendMessage(Message message, + Variable variable) + { + GaussianDistribution marginal = variable.Value; + GaussianDistribution messageValue = message.Value; + double logZ = GaussianDistribution.LogProductNormalization(marginal, messageValue); + variable.Value = marginal*messageValue; + return logZ; + } + + public override Message CreateVariableToMessageBinding( + Variable variable) + { + return CreateVariableToMessageBinding(variable, + new Message( + GaussianDistribution.FromPrecisionMean(0, 0), + "message from {0} to {1}", this, variable)); + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Factors/GaussianGreaterThanFactor.cs b/Skills/TrueSkill/Factors/GaussianGreaterThanFactor.cs new file mode 100644 index 0000000..31c4d4a --- /dev/null +++ b/Skills/TrueSkill/Factors/GaussianGreaterThanFactor.cs @@ -0,0 +1,75 @@ +using System; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; + +namespace Moserware.Skills.TrueSkill.Factors +{ + /// + /// Factor representing a team difference that has exceeded the draw margin. + /// + /// See the accompanying math paper for more details. + public class GaussianGreaterThanFactor : GaussianFactor + { + private readonly double _Epsilon; + + public GaussianGreaterThanFactor(double epsilon, Variable variable) + : base(String.Format("{0} > {1:0.000}", variable, epsilon)) + { + _Epsilon = epsilon; + CreateVariableToMessageBinding(variable); + } + + public override double LogNormalization + { + get + { + GaussianDistribution marginal = Variables[0].Value; + GaussianDistribution message = Messages[0].Value; + GaussianDistribution messageFromVariable = marginal/message; + return -GaussianDistribution.LogProductNormalization(messageFromVariable, message) + + + Math.Log( + GaussianDistribution.CumulativeTo((messageFromVariable.Mean - _Epsilon)/ + messageFromVariable.StandardDeviation)); + } + } + + protected override double UpdateMessage(Message message, + Variable variable) + { + GaussianDistribution oldMarginal = variable.Value.Clone(); + GaussianDistribution oldMessage = message.Value.Clone(); + GaussianDistribution messageFromVar = oldMarginal/oldMessage; + + double c = messageFromVar.Precision; + double d = messageFromVar.PrecisionMean; + + double sqrtC = Math.Sqrt(c); + + double dOnSqrtC = d/sqrtC; + + double epsilsonTimesSqrtC = _Epsilon*sqrtC; + d = messageFromVar.PrecisionMean; + + double denom = 1.0 - TruncatedGaussianCorrectionFunctions.WExceedsMargin(dOnSqrtC, epsilsonTimesSqrtC); + + double newPrecision = c/denom; + double newPrecisionMean = (d + + sqrtC* + TruncatedGaussianCorrectionFunctions.VExceedsMargin(dOnSqrtC, epsilsonTimesSqrtC))/ + denom; + + GaussianDistribution newMarginal = GaussianDistribution.FromPrecisionMean(newPrecisionMean, newPrecision); + + GaussianDistribution newMessage = oldMessage*newMarginal/oldMarginal; + + /// Update the message and marginal + message.Value = newMessage; + + variable.Value = newMarginal; + + /// Return the difference in the new marginal + return newMarginal - oldMarginal; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Factors/GaussianLikelihoodFactor.cs b/Skills/TrueSkill/Factors/GaussianLikelihoodFactor.cs new file mode 100644 index 0000000..95d4a6d --- /dev/null +++ b/Skills/TrueSkill/Factors/GaussianLikelihoodFactor.cs @@ -0,0 +1,72 @@ +using System; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; + +namespace Moserware.Skills.TrueSkill.Factors +{ + /// + /// Connects two variables and adds uncertainty. + /// + /// See the accompanying math paper for more details. + public class GaussianLikelihoodFactor : GaussianFactor + { + private readonly double _Precision; + + public GaussianLikelihoodFactor(double betaSquared, Variable variable1, + Variable variable2) + : base(String.Format("Likelihood of {0} going to {1}", variable2, variable1)) + { + _Precision = 1.0/betaSquared; + CreateVariableToMessageBinding(variable1); + CreateVariableToMessageBinding(variable2); + } + + public override double LogNormalization + { + get { return GaussianDistribution.LogRatioNormalization(Variables[0].Value, Messages[0].Value); } + } + + private double UpdateHelper(Message message1, Message message2, + Variable variable1, Variable variable2) + { + GaussianDistribution message1Value = message1.Value.Clone(); + GaussianDistribution message2Value = message2.Value.Clone(); + + GaussianDistribution marginal1 = variable1.Value.Clone(); + GaussianDistribution marginal2 = variable2.Value.Clone(); + + double a = _Precision/(_Precision + marginal2.Precision - message2Value.Precision); + + GaussianDistribution newMessage = GaussianDistribution.FromPrecisionMean( + a*(marginal2.PrecisionMean - message2Value.PrecisionMean), + a*(marginal2.Precision - message2Value.Precision)); + + GaussianDistribution oldMarginalWithoutMessage = marginal1/message1Value; + + GaussianDistribution newMarginal = oldMarginalWithoutMessage*newMessage; + + /// Update the message and marginal + + message1.Value = newMessage; + variable1.Value = newMarginal; + + /// Return the difference in the new marginal + return newMarginal - marginal1; + } + + public override double UpdateMessage(int messageIndex) + { + switch (messageIndex) + { + case 0: + return UpdateHelper(Messages[0], Messages[1], + Variables[0], Variables[1]); + case 1: + return UpdateHelper(Messages[1], Messages[0], + Variables[1], Variables[0]); + default: + throw new ArgumentOutOfRangeException(); + } + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Factors/GaussianPriorFactor.cs b/Skills/TrueSkill/Factors/GaussianPriorFactor.cs new file mode 100644 index 0000000..3921880 --- /dev/null +++ b/Skills/TrueSkill/Factors/GaussianPriorFactor.cs @@ -0,0 +1,39 @@ +using System; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; + +namespace Moserware.Skills.TrueSkill.Factors +{ + /// + /// Supplies the factor graph with prior information. + /// + /// See the accompanying math paper for more details. + public class GaussianPriorFactor : GaussianFactor + { + private readonly GaussianDistribution _NewMessage; + + public GaussianPriorFactor(double mean, double variance, Variable variable) + : base(String.Format("Prior value going to {0}", variable)) + { + _NewMessage = new GaussianDistribution(mean, Math.Sqrt(variance)); + CreateVariableToMessageBinding(variable, + new Message( + GaussianDistribution.FromPrecisionMean(0, 0), "message from {0} to {1}", + this, variable)); + } + + protected override double UpdateMessage(Message message, + Variable variable) + { + GaussianDistribution oldMarginal = variable.Value.Clone(); + Message oldMessage = message; + GaussianDistribution newMarginal = + GaussianDistribution.FromPrecisionMean( + oldMarginal.PrecisionMean + _NewMessage.PrecisionMean - oldMessage.Value.PrecisionMean, + oldMarginal.Precision + _NewMessage.Precision - oldMessage.Value.Precision); + variable.Value = newMarginal; + message.Value = _NewMessage; + return oldMarginal - newMarginal; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs b/Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs new file mode 100644 index 0000000..b95d04b --- /dev/null +++ b/Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; + +namespace Moserware.Skills.TrueSkill.Factors +{ + /// + /// Factor that sums together multiple Gaussians. + /// + /// See the accompanying math paper for more details. + public class GaussianWeightedSumFactor : GaussianFactor + { + private readonly List _VariableIndexOrdersForWeights = new List(); + + // This following is used for convenience, for example, the first entry is [0, 1, 2] + // corresponding to v[0] = a1*v[1] + a2*v[2] + private readonly double[][] _Weights; + private readonly double[][] _WeightsSquared; + + public GaussianWeightedSumFactor(Variable sumVariable, + Variable[] variablesToSum) + : this(sumVariable, + variablesToSum, + variablesToSum.Select(v => 1.0).ToArray()) // By default, set the weight to 1.0 + { + } + + public GaussianWeightedSumFactor(Variable sumVariable, + Variable[] variablesToSum, double[] variableWeights) + : base(CreateName(sumVariable, variablesToSum, variableWeights)) + { + _Weights = new double[variableWeights.Length + 1][]; + _WeightsSquared = new double[_Weights.Length][]; + + // The first weights are a straightforward copy + // v_0 = a_1*v_1 + a_2*v_2 + ... + a_n * v_n + _Weights[0] = new double[variableWeights.Length]; + Array.Copy(variableWeights, _Weights[0], variableWeights.Length); + _WeightsSquared[0] = _Weights[0].Select(w => w*w).ToArray(); + + // 0..n-1 + _VariableIndexOrdersForWeights.Add(Enumerable.Range(0, 1 + variablesToSum.Length).ToArray()); + + + // The rest move the variables around and divide out the constant. + // For example: + // v_1 = (-a_2 / a_1) * v_2 + (-a3/a1) * v_3 + ... + (1.0 / a_1) * v_0 + // By convention, we'll put the v_0 term at the end + + for (int weightsIndex = 1; weightsIndex < _Weights.Length; weightsIndex++) + { + var currentWeights = new double[variableWeights.Length]; + _Weights[weightsIndex] = currentWeights; + + var variableIndices = new int[variableWeights.Length + 1]; + variableIndices[0] = weightsIndex; + + var currentWeightsSquared = new double[variableWeights.Length]; + _WeightsSquared[weightsIndex] = currentWeightsSquared; + + // keep a single variable to keep track of where we are in the array. + // This is helpful since we skip over one of the spots + int currentDestinationWeightIndex = 0; + + for (int currentWeightSourceIndex = 0; + currentWeightSourceIndex < variableWeights.Length; + currentWeightSourceIndex++) + { + // TODO: get this test to be right + if (currentWeightSourceIndex == (weightsIndex - 1)) + { + continue; + } + + double currentWeight = (-variableWeights[currentWeightSourceIndex]/variableWeights[weightsIndex - 1]); + + if (variableWeights[weightsIndex - 1] == 0) + { + // HACK: Getting around division by zero + currentWeight = 0; + } + + currentWeights[currentDestinationWeightIndex] = currentWeight; + currentWeightsSquared[currentDestinationWeightIndex] = currentWeight*currentWeight; + + variableIndices[currentDestinationWeightIndex + 1] = currentWeightSourceIndex + 1; + currentDestinationWeightIndex++; + } + + // And the final one + double finalWeight = 1.0/variableWeights[weightsIndex - 1]; + + if (variableWeights[weightsIndex - 1] == 0) + { + // HACK: Getting around division by zero + finalWeight = 0; + } + currentWeights[currentDestinationWeightIndex] = finalWeight; + currentWeightsSquared[currentDestinationWeightIndex] = finalWeight*finalWeight; + variableIndices[variableIndices.Length - 1] = 0; + _VariableIndexOrdersForWeights.Add(variableIndices); + } + + CreateVariableToMessageBinding(sumVariable); + + foreach (var currentVariable in variablesToSum) + { + CreateVariableToMessageBinding(currentVariable); + } + } + + public override double LogNormalization + { + get + { + ReadOnlyCollection> vars = Variables; + ReadOnlyCollection> messages = Messages; + + double result = 0.0; + + // We start at 1 since offset 0 has the sum + for (int i = 1; i < vars.Count; i++) + { + result += GaussianDistribution.LogRatioNormalization(vars[i].Value, messages[i].Value); + } + + return result; + } + } + + private double UpdateHelper(double[] weights, double[] weightsSquared, + IList> messages, + IList> variables) + { + // Potentially look at http://mathworld.wolfram.com/NormalSumDistribution.html for clues as + // to what it's doing + + GaussianDistribution message0 = messages[0].Value.Clone(); + GaussianDistribution marginal0 = variables[0].Value.Clone(); + + // The math works out so that 1/newPrecision = sum of a_i^2 /marginalsWithoutMessages[i] + double inverseOfNewPrecisionSum = 0.0; + double anotherInverseOfNewPrecisionSum = 0.0; + double weightedMeanSum = 0.0; + double anotherWeightedMeanSum = 0.0; + + for (int i = 0; i < weightsSquared.Length; i++) + { + // These flow directly from the paper + + inverseOfNewPrecisionSum += weightsSquared[i]/ + (variables[i + 1].Value.Precision - messages[i + 1].Value.Precision); + + GaussianDistribution diff = (variables[i + 1].Value/messages[i + 1].Value); + anotherInverseOfNewPrecisionSum += weightsSquared[i]/diff.Precision; + + weightedMeanSum += weights[i] + * + (variables[i + 1].Value.PrecisionMean - messages[i + 1].Value.PrecisionMean) + / + (variables[i + 1].Value.Precision - messages[i + 1].Value.Precision); + + anotherWeightedMeanSum += weights[i]*diff.PrecisionMean/diff.Precision; + } + + double newPrecision = 1.0/inverseOfNewPrecisionSum; + double anotherNewPrecision = 1.0/anotherInverseOfNewPrecisionSum; + + double newPrecisionMean = newPrecision*weightedMeanSum; + double anotherNewPrecisionMean = anotherNewPrecision*anotherWeightedMeanSum; + + GaussianDistribution newMessage = GaussianDistribution.FromPrecisionMean(newPrecisionMean, newPrecision); + GaussianDistribution oldMarginalWithoutMessage = marginal0/message0; + + GaussianDistribution newMarginal = oldMarginalWithoutMessage*newMessage; + + /// Update the message and marginal + + messages[0].Value = newMessage; + variables[0].Value = newMarginal; + + /// Return the difference in the new marginal + return newMarginal - marginal0; + } + + public override double UpdateMessage(int messageIndex) + { + ReadOnlyCollection> allMessages = Messages; + ReadOnlyCollection> allVariables = Variables; + + Guard.ArgumentIsValidIndex(messageIndex, allMessages.Count, "messageIndex"); + + var updatedMessages = new List>(); + var updatedVariables = new List>(); + + int[] indicesToUse = _VariableIndexOrdersForWeights[messageIndex]; + + // The tricky part here is that we have to put the messages and variables in the same + // order as the weights. Thankfully, the weights and messages share the same index numbers, + // so we just need to make sure they're consistent + for (int i = 0; i < allMessages.Count; i++) + { + updatedMessages.Add(allMessages[indicesToUse[i]]); + updatedVariables.Add(allVariables[indicesToUse[i]]); + } + + return UpdateHelper(_Weights[messageIndex], _WeightsSquared[messageIndex], updatedMessages, updatedVariables); + } + + private static string CreateName(Variable sumVariable, + IList> variablesToSum, double[] weights) + { + var sb = new StringBuilder(); + sb.Append(sumVariable.ToString()); + sb.Append(" = "); + for (int i = 0; i < variablesToSum.Count; i++) + { + bool isFirst = (i == 0); + + if (isFirst && (weights[i] < 0)) + { + sb.Append("-"); + } + + sb.Append(Math.Abs(weights[i]).ToString("0.00")); + sb.Append("*["); + sb.Append(variablesToSum[i]); + sb.Append("]"); + + bool isLast = (i == variablesToSum.Count - 1); + + if (!isLast) + { + if (weights[i + 1] >= 0) + { + sb.Append(" + "); + } + else + { + sb.Append(" - "); + } + } + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Factors/GaussianWithinFactor.cs b/Skills/TrueSkill/Factors/GaussianWithinFactor.cs new file mode 100644 index 0000000..71113b7 --- /dev/null +++ b/Skills/TrueSkill/Factors/GaussianWithinFactor.cs @@ -0,0 +1,73 @@ +using System; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; + +namespace Moserware.Skills.TrueSkill.Factors +{ + /// + /// Factor representing a team difference that has not exceeded the draw margin. + /// + /// See the accompanying math paper for more details. + public class GaussianWithinFactor : GaussianFactor + { + private readonly double _Epsilon; + + public GaussianWithinFactor(double epsilon, Variable variable) + : base(String.Format("{0} <= {1:0.000}", variable, epsilon)) + { + _Epsilon = epsilon; + CreateVariableToMessageBinding(variable); + } + + public override double LogNormalization + { + get + { + GaussianDistribution marginal = Variables[0].Value; + GaussianDistribution message = Messages[0].Value; + GaussianDistribution messageFromVariable = marginal/message; + double mean = messageFromVariable.Mean; + double std = messageFromVariable.StandardDeviation; + double z = GaussianDistribution.CumulativeTo((_Epsilon - mean)/std) + - + GaussianDistribution.CumulativeTo((-_Epsilon - mean)/std); + + return -GaussianDistribution.LogProductNormalization(messageFromVariable, message) + Math.Log(z); + } + } + + protected override double UpdateMessage(Message message, + Variable variable) + { + GaussianDistribution oldMarginal = variable.Value.Clone(); + GaussianDistribution oldMessage = message.Value.Clone(); + GaussianDistribution messageFromVariable = oldMarginal/oldMessage; + + double c = messageFromVariable.Precision; + double d = messageFromVariable.PrecisionMean; + + double sqrtC = Math.Sqrt(c); + double dOnSqrtC = d/sqrtC; + + double epsilonTimesSqrtC = _Epsilon*sqrtC; + d = messageFromVariable.PrecisionMean; + + double denominator = 1.0 - TruncatedGaussianCorrectionFunctions.WWithinMargin(dOnSqrtC, epsilonTimesSqrtC); + double newPrecision = c/denominator; + double newPrecisionMean = (d + + sqrtC* + TruncatedGaussianCorrectionFunctions.VWithinMargin(dOnSqrtC, epsilonTimesSqrtC))/ + denominator; + + GaussianDistribution newMarginal = GaussianDistribution.FromPrecisionMean(newPrecisionMean, newPrecision); + GaussianDistribution newMessage = oldMessage*newMarginal/oldMarginal; + + /// Update the message and marginal + message.Value = newMessage; + variable.Value = newMarginal; + + /// Return the difference in the new marginal + return newMarginal - oldMarginal; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Layers/IteratedTeamDifferencesInnerLayer.cs b/Skills/TrueSkill/Layers/IteratedTeamDifferencesInnerLayer.cs new file mode 100644 index 0000000..94da9ba --- /dev/null +++ b/Skills/TrueSkill/Layers/IteratedTeamDifferencesInnerLayer.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; +using Moserware.Skills.TrueSkill.Factors; + +namespace Moserware.Skills.TrueSkill.Layers +{ + // The whole purpose of this is to do a loop on the bottom + internal class IteratedTeamDifferencesInnerLayer : + TrueSkillFactorGraphLayer + , GaussianWeightedSumFactor, Variable> + { + private readonly TeamDifferencesComparisonLayer _TeamDifferencesComparisonLayer; + + private readonly TeamPerformancesToTeamPerformanceDifferencesLayer + _TeamPerformancesToTeamPerformanceDifferencesLayer; + + public IteratedTeamDifferencesInnerLayer(TrueSkillFactorGraph parentGraph, + TeamPerformancesToTeamPerformanceDifferencesLayer + teamPerformancesToPerformanceDifferences, + TeamDifferencesComparisonLayer teamDifferencesComparisonLayer) + : base(parentGraph) + { + _TeamPerformancesToTeamPerformanceDifferencesLayer = teamPerformancesToPerformanceDifferences; + _TeamDifferencesComparisonLayer = teamDifferencesComparisonLayer; + } + + public override IEnumerable> UntypedFactors + { + get + { + return + _TeamPerformancesToTeamPerformanceDifferencesLayer.UntypedFactors.Concat( + _TeamDifferencesComparisonLayer.UntypedFactors); + } + } + + public override void BuildLayer() + { + _TeamPerformancesToTeamPerformanceDifferencesLayer.SetRawInputVariablesGroups(InputVariablesGroups); + _TeamPerformancesToTeamPerformanceDifferencesLayer.BuildLayer(); + + _TeamDifferencesComparisonLayer.SetRawInputVariablesGroups( + _TeamPerformancesToTeamPerformanceDifferencesLayer.GetRawOutputVariablesGroups()); + _TeamDifferencesComparisonLayer.BuildLayer(); + } + + public override Schedule CreatePriorSchedule() + { + Schedule loop = null; + + switch (InputVariablesGroups.Count) + { + case 0: + case 1: + throw new InvalidOperationException(); + case 2: + loop = CreateTwoTeamInnerPriorLoopSchedule(); + break; + default: + loop = CreateMultipleTeamInnerPriorLoopSchedule(); + break; + } + + // When dealing with differences, there are always (n-1) differences, so add in the 1 + int totalTeamDifferences = _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors.Count; + int totalTeams = totalTeamDifferences + 1; + + var innerSchedule = new ScheduleSequence( + "inner schedule", + new[] + { + loop, + new ScheduleStep( + "teamPerformanceToPerformanceDifferenceFactors[0] @ 1", + _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors[0], 1), + new ScheduleStep( + String.Format("teamPerformanceToPerformanceDifferenceFactors[teamTeamDifferences = {0} - 1] @ 2", + totalTeamDifferences), + _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors[totalTeamDifferences - 1], 2) + } + ); + + return innerSchedule; + } + + private Schedule CreateTwoTeamInnerPriorLoopSchedule() + { + return ScheduleSequence( + new[] + { + new ScheduleStep( + "send team perf to perf differences", + _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors[0], + 0), + new ScheduleStep( + "send to greater than or within factor", + _TeamDifferencesComparisonLayer.LocalFactors[0], + 0) + }, + "loop of just two teams inner sequence"); + } + + private Schedule CreateMultipleTeamInnerPriorLoopSchedule() + { + int totalTeamDifferences = _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors.Count; + + var forwardScheduleList = new List>(); + + for (int i = 0; i < totalTeamDifferences - 1; i++) + { + Schedule currentForwardSchedulePiece = + ScheduleSequence( + new Schedule[] + { + new ScheduleStep( + String.Format("team perf to perf diff {0}", + i), + _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors[i], 0), + new ScheduleStep( + String.Format("greater than or within result factor {0}", + i), + _TeamDifferencesComparisonLayer.LocalFactors[i], + 0), + new ScheduleStep( + String.Format("team perf to perf diff factors [{0}], 2", + i), + _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors[i], 2) + }, "current forward schedule piece {0}", i); + + forwardScheduleList.Add(currentForwardSchedulePiece); + } + + var forwardSchedule = + new ScheduleSequence( + "forward schedule", + forwardScheduleList); + + var backwardScheduleList = new List>(); + + for (int i = 0; i < totalTeamDifferences - 1; i++) + { + var currentBackwardSchedulePiece = new ScheduleSequence( + "current backward schedule piece", + new Schedule[] + { + new ScheduleStep( + String.Format("teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - {0}] @ 0", + i), + _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors[ + totalTeamDifferences - 1 - i], 0), + new ScheduleStep( + String.Format("greaterThanOrWithinResultFactors[totalTeamDifferences - 1 - {0}] @ 0", + i), + _TeamDifferencesComparisonLayer.LocalFactors[totalTeamDifferences - 1 - i], 0), + new ScheduleStep( + String.Format("teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - {0}] @ 1", + i), + _TeamPerformancesToTeamPerformanceDifferencesLayer.LocalFactors[ + totalTeamDifferences - 1 - i], 1) + } + ); + backwardScheduleList.Add(currentBackwardSchedulePiece); + } + + var backwardSchedule = + new ScheduleSequence( + "backward schedule", + backwardScheduleList); + + var forwardBackwardScheduleToLoop = + new ScheduleSequence( + "forward Backward Schedule To Loop", + new Schedule[] + { + forwardSchedule, backwardSchedule + }); + + const double initialMaxDelta = 0.0001; + + var loop = new ScheduleLoop( + String.Format("loop with max delta of {0}", + initialMaxDelta), + forwardBackwardScheduleToLoop, + initialMaxDelta); + + return loop; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Layers/PlayerPerformancesToTeamPerformancesLayer.cs b/Skills/TrueSkill/Layers/PlayerPerformancesToTeamPerformancesLayer.cs new file mode 100644 index 0000000..2aae362 --- /dev/null +++ b/Skills/TrueSkill/Layers/PlayerPerformancesToTeamPerformancesLayer.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; +using Moserware.Skills.TrueSkill.Factors; + +namespace Moserware.Skills.TrueSkill.Layers +{ + internal class PlayerPerformancesToTeamPerformancesLayer : + TrueSkillFactorGraphLayer + , GaussianWeightedSumFactor, + Variable> + { + public PlayerPerformancesToTeamPerformancesLayer(TrueSkillFactorGraph parentGraph) + : base(parentGraph) + { + } + + public override void BuildLayer() + { + foreach (var currentTeam in InputVariablesGroups) + { + Variable teamPerformance = CreateOutputVariable(currentTeam); + AddLayerFactor(CreatePlayerToTeamSumFactor(currentTeam, teamPerformance)); + + // REVIEW: Does it make sense to have groups of one? + OutputVariablesGroups.Add(new[] {teamPerformance}); + } + } + + public override Schedule CreatePriorSchedule() + { + return ScheduleSequence( + from weightedSumFactor in LocalFactors + select new ScheduleStep("Perf to Team Perf Step", weightedSumFactor, 0), + "all player perf to team perf schedule"); + } + + protected GaussianWeightedSumFactor CreatePlayerToTeamSumFactor( + IList> teamMembers, Variable sumVariable) + { + return new GaussianWeightedSumFactor(sumVariable, teamMembers.ToArray(), + teamMembers.Select(v => PartialPlay.GetPartialPlayPercentage(v.Key)). + ToArray()); + } + + public override Schedule CreatePosteriorSchedule() + { + return ScheduleSequence(from currentFactor in LocalFactors + from currentIteration in + Enumerable.Range(1, currentFactor.NumberOfMessages - 1) + select new ScheduleStep( + "team sum perf @" + currentIteration, + currentFactor, + currentIteration), + "all of the team's sum iterations"); + } + + private Variable CreateOutputVariable( + IList> team) + { + string teamMemberNames = String.Join(", ", team.Select(teamMember => teamMember.Key.ToString()).ToArray()); + + return ParentFactorGraph.VariableFactory.CreateBasicVariable("Team[{0}]'s performance", teamMemberNames); + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Layers/PlayerPriorValuesToSkillsLayer.cs b/Skills/TrueSkill/Layers/PlayerPriorValuesToSkillsLayer.cs new file mode 100644 index 0000000..cec4c27 --- /dev/null +++ b/Skills/TrueSkill/Layers/PlayerPriorValuesToSkillsLayer.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using System.Linq; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; +using Moserware.Skills.TrueSkill.Factors; + +namespace Moserware.Skills.TrueSkill.Layers +{ + // We intentionally have no Posterior schedule since the only purpose here is to + internal class PlayerPriorValuesToSkillsLayer : + TrueSkillFactorGraphLayer + , GaussianPriorFactor, + KeyedVariable> + { + private readonly IEnumerable> _Teams; + + public PlayerPriorValuesToSkillsLayer(TrueSkillFactorGraph parentGraph, + IEnumerable> teams) + : base(parentGraph) + { + _Teams = teams; + } + + public override void BuildLayer() + { + foreach (var currentTeam in _Teams) + { + var currentTeamSkills = new List>(); + + foreach (var currentTeamPlayer in currentTeam) + { + KeyedVariable playerSkill = + CreateSkillOutputVariable(currentTeamPlayer.Key); + AddLayerFactor(CreatePriorFactor(currentTeamPlayer.Key, currentTeamPlayer.Value, playerSkill)); + currentTeamSkills.Add(playerSkill); + } + + OutputVariablesGroups.Add(currentTeamSkills); + } + } + + public override Schedule CreatePriorSchedule() + { + return ScheduleSequence( + from prior in LocalFactors + select new ScheduleStep("Prior to Skill Step", prior, 0), + "All priors"); + } + + private GaussianPriorFactor CreatePriorFactor(TPlayer player, Rating priorRating, + Variable skillsVariable) + { + return new GaussianPriorFactor(priorRating.Mean, + Square(priorRating.StandardDeviation) + + Square(ParentFactorGraph.GameInfo.DynamicsFactor), skillsVariable); + } + + private KeyedVariable CreateSkillOutputVariable(TPlayer key) + { + return ParentFactorGraph.VariableFactory.CreateKeyedVariable(key, "{0}'s skill", key); + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Layers/PlayerSkillsToPerformancesLayer.cs b/Skills/TrueSkill/Layers/PlayerSkillsToPerformancesLayer.cs new file mode 100644 index 0000000..1899092 --- /dev/null +++ b/Skills/TrueSkill/Layers/PlayerSkillsToPerformancesLayer.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Linq; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; +using Moserware.Skills.TrueSkill.Factors; + +namespace Moserware.Skills.TrueSkill.Layers +{ + internal class PlayerSkillsToPerformancesLayer : + TrueSkillFactorGraphLayer + , GaussianLikelihoodFactor, + KeyedVariable> + { + public PlayerSkillsToPerformancesLayer(TrueSkillFactorGraph parentGraph) + : base(parentGraph) + { + } + + public override void BuildLayer() + { + foreach (var currentTeam in InputVariablesGroups) + { + var currentTeamPlayerPerformances = new List>(); + + foreach (var playerSkillVariable in currentTeam) + { + KeyedVariable playerPerformance = + CreateOutputVariable(playerSkillVariable.Key); + AddLayerFactor(CreateLikelihood(playerSkillVariable, playerPerformance)); + currentTeamPlayerPerformances.Add(playerPerformance); + } + + OutputVariablesGroups.Add(currentTeamPlayerPerformances); + } + } + + private GaussianLikelihoodFactor CreateLikelihood(KeyedVariable playerSkill, + KeyedVariable playerPerformance) + { + return new GaussianLikelihoodFactor(Square(ParentFactorGraph.GameInfo.Beta), playerPerformance, playerSkill); + } + + private KeyedVariable CreateOutputVariable(TPlayer key) + { + return ParentFactorGraph.VariableFactory.CreateKeyedVariable(key, "{0}'s performance", key); + } + + public override Schedule CreatePriorSchedule() + { + return ScheduleSequence( + from likelihood in LocalFactors + select new ScheduleStep("Skill to Perf step", likelihood, 0), + "All skill to performance sending"); + } + + public override Schedule CreatePosteriorSchedule() + { + return ScheduleSequence( + from likelihood in LocalFactors + select new ScheduleStep("name", likelihood, 1), + "All skill to performance sending"); + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Layers/TeamDifferencesComparisonLayer.cs b/Skills/TrueSkill/Layers/TeamDifferencesComparisonLayer.cs new file mode 100644 index 0000000..748aec0 --- /dev/null +++ b/Skills/TrueSkill/Layers/TeamDifferencesComparisonLayer.cs @@ -0,0 +1,38 @@ +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; +using Moserware.Skills.TrueSkill.Factors; + +namespace Moserware.Skills.TrueSkill.Layers +{ + internal class TeamDifferencesComparisonLayer : + TrueSkillFactorGraphLayer + , GaussianFactor, DefaultVariable> + { + private readonly double _Epsilon; + private readonly int[] _TeamRanks; + + public TeamDifferencesComparisonLayer(TrueSkillFactorGraph parentGraph, int[] teamRanks) + : base(parentGraph) + { + _TeamRanks = teamRanks; + GameInfo gameInfo = ParentFactorGraph.GameInfo; + _Epsilon = DrawMargin.GetDrawMarginFromDrawProbability(gameInfo.DrawProbability, gameInfo.Beta); + } + + public override void BuildLayer() + { + for (int i = 0; i < InputVariablesGroups.Count; i++) + { + bool isDraw = (_TeamRanks[i] == _TeamRanks[i + 1]); + Variable teamDifference = InputVariablesGroups[i][0]; + + GaussianFactor factor = + isDraw + ? (GaussianFactor) new GaussianWithinFactor(_Epsilon, teamDifference) + : new GaussianGreaterThanFactor(_Epsilon, teamDifference); + + AddLayerFactor(factor); + } + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Layers/TeamPerformancesToTeamPerformanceDifferencesLayer.cs b/Skills/TrueSkill/Layers/TeamPerformancesToTeamPerformanceDifferencesLayer.cs new file mode 100644 index 0000000..cec409d --- /dev/null +++ b/Skills/TrueSkill/Layers/TeamPerformancesToTeamPerformanceDifferencesLayer.cs @@ -0,0 +1,43 @@ +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; +using Moserware.Skills.TrueSkill.Factors; + +namespace Moserware.Skills.TrueSkill.Layers +{ + internal class TeamPerformancesToTeamPerformanceDifferencesLayer : + TrueSkillFactorGraphLayer + , GaussianWeightedSumFactor, Variable> + { + public TeamPerformancesToTeamPerformanceDifferencesLayer(TrueSkillFactorGraph parentGraph) + : base(parentGraph) + { + } + + public override void BuildLayer() + { + for (int i = 0; i < InputVariablesGroups.Count - 1; i++) + { + Variable strongerTeam = InputVariablesGroups[i][0]; + Variable weakerTeam = InputVariablesGroups[i + 1][0]; + + Variable currentDifference = CreateOutputVariable(); + AddLayerFactor(CreateTeamPerformanceToDifferenceFactor(strongerTeam, weakerTeam, currentDifference)); + + // REVIEW: Does it make sense to have groups of one? + OutputVariablesGroups.Add(new[] {currentDifference}); + } + } + + private GaussianWeightedSumFactor CreateTeamPerformanceToDifferenceFactor( + Variable strongerTeam, Variable weakerTeam, + Variable output) + { + return new GaussianWeightedSumFactor(output, new[] {strongerTeam, weakerTeam}, new[] {1.0, -1.0}); + } + + private Variable CreateOutputVariable() + { + return ParentFactorGraph.VariableFactory.CreateBasicVariable("Team performance difference"); + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/Layers/TrueSkillFactorGraphLayer.cs b/Skills/TrueSkill/Layers/TrueSkillFactorGraphLayer.cs new file mode 100644 index 0000000..fedb182 --- /dev/null +++ b/Skills/TrueSkill/Layers/TrueSkillFactorGraphLayer.cs @@ -0,0 +1,20 @@ +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; + +namespace Moserware.Skills.TrueSkill.Layers +{ + internal abstract class TrueSkillFactorGraphLayer + : + FactorGraphLayer + , GaussianDistribution, Variable, TInputVariable, + TFactor, TOutputVariable> + where TInputVariable : Variable + where TFactor : Factor + where TOutputVariable : Variable + { + public TrueSkillFactorGraphLayer(TrueSkillFactorGraph parentGraph) + : base(parentGraph) + { + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/TrueSkillFactorGraph.cs b/Skills/TrueSkill/TrueSkillFactorGraph.cs new file mode 100644 index 0000000..ffe5d0a --- /dev/null +++ b/Skills/TrueSkill/TrueSkillFactorGraph.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Moserware.Numerics; +using Moserware.Skills.FactorGraphs; +using Moserware.Skills.TrueSkill.Layers; + +namespace Moserware.Skills.TrueSkill +{ + public class TrueSkillFactorGraph : + FactorGraph, GaussianDistribution, Variable> + { + private readonly List> _Layers; + private readonly PlayerPriorValuesToSkillsLayer _PriorLayer; + + public TrueSkillFactorGraph(GameInfo gameInfo, IEnumerable> teams, int[] teamRanks) + { + _PriorLayer = new PlayerPriorValuesToSkillsLayer(this, teams); + GameInfo = gameInfo; + VariableFactory = + new VariableFactory(() => GaussianDistribution.FromPrecisionMean(0, 0)); + + _Layers = new List> + { + _PriorLayer, + new PlayerSkillsToPerformancesLayer(this), + new PlayerPerformancesToTeamPerformancesLayer(this), + new IteratedTeamDifferencesInnerLayer( + this, + new TeamPerformancesToTeamPerformanceDifferencesLayer(this), + new TeamDifferencesComparisonLayer(this, teamRanks)) + }; + } + + public GameInfo GameInfo { get; private set; } + + public void BuildGraph() + { + object lastOutput = null; + + foreach (var currentLayer in _Layers) + { + if (lastOutput != null) + { + currentLayer.SetRawInputVariablesGroups(lastOutput); + } + + currentLayer.BuildLayer(); + + lastOutput = currentLayer.GetRawOutputVariablesGroups(); + } + } + + public void RunSchedule() + { + Schedule fullSchedule = CreateFullSchedule(); + double fullScheduleDelta = fullSchedule.Visit(); + } + + public double GetProbabilityOfRanking() + { + var factorList = new FactorList(); + + foreach (var currentLayer in _Layers) + { + foreach (var currentFactor in currentLayer.UntypedFactors) + { + factorList.AddFactor(currentFactor); + } + } + + double logZ = factorList.LogNormalization; + return Math.Exp(logZ); + } + + private Schedule CreateFullSchedule() + { + var fullSchedule = new List>(); + + foreach (var currentLayer in _Layers) + { + Schedule currentPriorSchedule = currentLayer.CreatePriorSchedule(); + if (currentPriorSchedule != null) + { + fullSchedule.Add(currentPriorSchedule); + } + } + + // Casting to IEnumerable to get the LINQ Reverse() + IEnumerable> allLayers = _Layers; + + foreach (var currentLayer in allLayers.Reverse()) + { + Schedule currentPosteriorSchedule = currentLayer.CreatePosteriorSchedule(); + if (currentPosteriorSchedule != null) + { + fullSchedule.Add(currentPosteriorSchedule); + } + } + + return new ScheduleSequence("Full schedule", fullSchedule); + } + + public IDictionary GetUpdatedRatings() + { + var result = new Dictionary(); + foreach (var currentTeam in _PriorLayer.OutputVariablesGroups) + { + foreach (var currentPlayer in currentTeam) + { + result[currentPlayer.Key] = new Rating(currentPlayer.Value.Mean, + currentPlayer.Value.StandardDeviation); + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/TruncatedGaussianCorrectionFunctions.cs b/Skills/TrueSkill/TruncatedGaussianCorrectionFunctions.cs new file mode 100644 index 0000000..252ee6a --- /dev/null +++ b/Skills/TrueSkill/TruncatedGaussianCorrectionFunctions.cs @@ -0,0 +1,188 @@ +using System; +using Moserware.Numerics; + +namespace Moserware.Skills.TrueSkill +{ + internal static class TruncatedGaussianCorrectionFunctions + { + // These functions from the bottom of page 4 of the TrueSkill paper. + + /// + /// The "V" function where the team performance difference is greater than the draw margin. + /// + /// In the reference F# implementation, this is referred to as "the additive + /// correction of a single-sided truncated Gaussian with unit variance." + /// + /// In the paper, it's referred to as just "ε". + /// + public static double VExceedsMargin(double teamPerformanceDifference, double drawMargin, double c) + { + return VExceedsMargin(teamPerformanceDifference/c, drawMargin/c); + //return GaussianDistribution.At((teamPerformanceDifference - drawMargin) / c) / GaussianDistribution.CumulativeTo((teamPerformanceDifference - drawMargin) / c); + } + + public static double VExceedsMargin(double teamPerformanceDifference, double drawMargin) + { + double denominator = GaussianDistribution.CumulativeTo(teamPerformanceDifference - drawMargin); + + if (denominator < 2.222758749e-162) + { + return -teamPerformanceDifference + drawMargin; + } + + return GaussianDistribution.At(teamPerformanceDifference - drawMargin)/denominator; + } + + /// + /// The "W" function where the team performance difference is greater than the draw margin. + /// + /// In the reference F# implementation, this is referred to as "the multiplicative + /// correction of a single-sided truncated Gaussian with unit variance." + /// + /// + /// + /// + public static double WExceedsMargin(double teamPerformanceDifference, double drawMargin, double c) + { + return WExceedsMargin(teamPerformanceDifference/c, drawMargin/c); + //var vWin = VExceedsMargin(teamPerformanceDifference, drawMargin, c); + //return vWin * (vWin + (teamPerformanceDifference - drawMargin) / c); + } + + public static double WExceedsMargin(double teamPerformanceDifference, double drawMargin) + { + double denominator = GaussianDistribution.CumulativeTo(teamPerformanceDifference - drawMargin); + + if (denominator < 2.222758749e-162) + { + if (teamPerformanceDifference < 0.0) + { + return 1.0; + } + return 0.0; + } + + double vWin = VExceedsMargin(teamPerformanceDifference, drawMargin); + return vWin*(vWin + teamPerformanceDifference - drawMargin); + } + + // the additive correction of a double-sided truncated Gaussian with unit variance + public static double VWithinMargin(double teamPerformanceDifference, double drawMargin, double c) + { + return VWithinMargin(teamPerformanceDifference/c, drawMargin/c); + //var teamPerformanceDifferenceAbsoluteValue = Math.Abs(teamPerformanceDifference); + //return (GaussianDistribution.At((-drawMargin - teamPerformanceDifferenceAbsoluteValue) / c) - GaussianDistribution.At((drawMargin - teamPerformanceDifferenceAbsoluteValue) / c)) + // / + // (GaussianDistribution.CumulativeTo((drawMargin - teamPerformanceDifferenceAbsoluteValue) / c) - GaussianDistribution.CumulativeTo((-drawMargin - teamPerformanceDifferenceAbsoluteValue) / c)); + } + + // My original: + //public static double VWithinMargin(double teamPerformanceDifference, double drawMargin) + //{ + // var teamPerformanceDifferenceAbsoluteValue = Math.Abs(teamPerformanceDifference); + // return (GaussianDistribution.At(-drawMargin - teamPerformanceDifferenceAbsoluteValue) - GaussianDistribution.At(drawMargin - teamPerformanceDifferenceAbsoluteValue)) + // / + // (GaussianDistribution.CumulativeTo(drawMargin - teamPerformanceDifferenceAbsoluteValue) - GaussianDistribution.CumulativeTo(-drawMargin - teamPerformanceDifferenceAbsoluteValue)); + //} + + // from F#: + public static double VWithinMargin(double teamPerformanceDifference, double drawMargin) + { + double teamPerformanceDifferenceAbsoluteValue = Math.Abs(teamPerformanceDifference); + double denominator = + GaussianDistribution.CumulativeTo(drawMargin - teamPerformanceDifferenceAbsoluteValue) - + GaussianDistribution.CumulativeTo(-drawMargin - teamPerformanceDifferenceAbsoluteValue); + if (denominator < 2.222758749e-162) + { + if (teamPerformanceDifference < 0.0) + { + return -teamPerformanceDifference - drawMargin; + } + + return -teamPerformanceDifference + drawMargin; + } + + double numerator = GaussianDistribution.At(-drawMargin - teamPerformanceDifferenceAbsoluteValue) - + GaussianDistribution.At(drawMargin - teamPerformanceDifferenceAbsoluteValue); + + if (teamPerformanceDifference < 0.0) + { + return -numerator/denominator; + } + + return numerator/denominator; + } + + // the multiplicative correction of a double-sided truncated Gaussian with unit variance + public static double WWithinMargin(double teamPerformanceDifference, double drawMargin, double c) + { + return WWithinMargin(teamPerformanceDifference/c, drawMargin/c); + //var teamPerformanceDifferenceAbsoluteValue = Math.Abs(teamPerformanceDifference); + //var vDraw = VWithinMargin(teamPerformanceDifferenceAbsoluteValue, drawMargin, c); + + //return (vDraw * vDraw) + // + + // ( + // ( + // ( + // ((drawMargin - teamPerformanceDifferenceAbsoluteValue) / c) + // * + // GaussianDistribution.At((drawMargin - teamPerformanceDifferenceAbsoluteValue) / c) + // ) + // + + // ( + // ((drawMargin + teamPerformanceDifferenceAbsoluteValue) / c) + // * + // GaussianDistribution.At((drawMargin + teamPerformanceDifferenceAbsoluteValue) / c) + // ) + // ) + // / + // ( + // GaussianDistribution.CumulativeTo((drawMargin - teamPerformanceDifferenceAbsoluteValue) / c) + // - + // GaussianDistribution.CumulativeTo((-drawMargin - teamPerformanceDifferenceAbsoluteValue) / c) + // ) + // ); + } + + // My original: + //public static double WWithinMargin(double teamPerformanceDifference, double drawMargin) + //{ + // var teamPerformanceDifferenceAbsoluteValue = Math.Abs(teamPerformanceDifference); + // var vDraw = VWithinMargin(teamPerformanceDifferenceAbsoluteValue, drawMargin); + // return (vDraw * vDraw) + // + + // ( + // ((drawMargin - teamPerformanceDifferenceAbsoluteValue) * GaussianDistribution.At(drawMargin - teamPerformanceDifferenceAbsoluteValue) + (drawMargin + teamPerformanceDifferenceAbsoluteValue) * GaussianDistribution.At(drawMargin + teamPerformanceDifferenceAbsoluteValue)) + // / + // (GaussianDistribution.CumulativeTo(drawMargin - teamPerformanceDifferenceAbsoluteValue) - GaussianDistribution.CumulativeTo(-drawMargin - teamPerformanceDifferenceAbsoluteValue)) + // ); + //} + + // From F#: + public static double WWithinMargin(double teamPerformanceDifference, double drawMargin) + { + double teamPerformanceDifferenceAbsoluteValue = Math.Abs(teamPerformanceDifference); + double denominator = GaussianDistribution.CumulativeTo(drawMargin - teamPerformanceDifferenceAbsoluteValue) + - + GaussianDistribution.CumulativeTo(-drawMargin - teamPerformanceDifferenceAbsoluteValue); + + if (denominator < 2.222758749e-162) + { + return 1.0; + } + + double vt = VWithinMargin(teamPerformanceDifferenceAbsoluteValue, drawMargin); + + return vt*vt + + ( + (drawMargin - teamPerformanceDifferenceAbsoluteValue) + * + GaussianDistribution.At( + drawMargin - teamPerformanceDifferenceAbsoluteValue) + - (-drawMargin - teamPerformanceDifferenceAbsoluteValue) + * + GaussianDistribution.At(-drawMargin - teamPerformanceDifferenceAbsoluteValue))/denominator; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/TwoPlayerTrueSkillCalculator.cs b/Skills/TrueSkill/TwoPlayerTrueSkillCalculator.cs new file mode 100644 index 0000000..e494474 --- /dev/null +++ b/Skills/TrueSkill/TwoPlayerTrueSkillCalculator.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Moserware.Skills.Numerics; + +namespace Moserware.Skills.TrueSkill +{ + /// + /// Calculates the new ratings for only two players. + /// + /// + /// When you only have two players, a lot of the math simplifies. The main purpose of this class + /// is to show the bare minimum of what a TrueSkill implementation should have. + /// + public class TwoPlayerTrueSkillCalculator : SkillCalculator + { + public TwoPlayerTrueSkillCalculator() + : base(SupportedOptions.None, Range.Exactly(2), Range.Exactly(1)) + { + } + + /// + public override IDictionary CalculateNewRatings(GameInfo gameInfo, + IEnumerable + > + teams, params int[] teamRanks) + { + // Basic argument checking + Guard.ArgumentNotNull(gameInfo, "gameInfo"); + ValidateTeamCountAndPlayersCountPerTeam(teams); + + // Make sure things are in order + RankSorter.Sort(ref teams, ref teamRanks); + + // Get the teams as a list to make it easier to index + List> teamList = teams.ToList(); + + // Since we verified that each team has one player, we know the player is the first one + IDictionary winningTeam = teamList[0]; + TPlayer winner = winningTeam.Keys.First(); + Rating winnerPreviousRating = winningTeam[winner]; + + IDictionary losingTeam = teamList[1]; + TPlayer loser = losingTeam.Keys.First(); + Rating loserPreviousRating = losingTeam[loser]; + + bool wasDraw = (teamRanks[0] == teamRanks[1]); + + var results = new Dictionary(); + results[winner] = CalculateNewRating(gameInfo, winnerPreviousRating, loserPreviousRating, + wasDraw ? PairwiseComparison.Draw : PairwiseComparison.Win); + results[loser] = CalculateNewRating(gameInfo, loserPreviousRating, winnerPreviousRating, + wasDraw ? PairwiseComparison.Draw : PairwiseComparison.Lose); + + // And we're done! + return results; + } + + private static Rating CalculateNewRating(GameInfo gameInfo, Rating selfRating, Rating opponentRating, + PairwiseComparison comparison) + { + double drawMargin = DrawMargin.GetDrawMarginFromDrawProbability(gameInfo.DrawProbability, gameInfo.Beta); + + double c = + Math.Sqrt( + Square(selfRating.StandardDeviation) + + + Square(opponentRating.StandardDeviation) + + + 2*Square(gameInfo.Beta)); + + double winningMean = selfRating.Mean; + double losingMean = opponentRating.Mean; + + switch (comparison) + { + case PairwiseComparison.Win: + case PairwiseComparison.Draw: + // NOP + break; + case PairwiseComparison.Lose: + winningMean = opponentRating.Mean; + losingMean = selfRating.Mean; + break; + } + + double meanDelta = winningMean - losingMean; + + double v; + double w; + double rankMultiplier; + + if (comparison != PairwiseComparison.Draw) + { + // non-draw case + v = TruncatedGaussianCorrectionFunctions.VExceedsMargin(meanDelta, drawMargin, c); + w = TruncatedGaussianCorrectionFunctions.WExceedsMargin(meanDelta, drawMargin, c); + rankMultiplier = (int) comparison; + } + else + { + v = TruncatedGaussianCorrectionFunctions.VWithinMargin(meanDelta, drawMargin, c); + w = TruncatedGaussianCorrectionFunctions.WWithinMargin(meanDelta, drawMargin, c); + rankMultiplier = 1; + } + + double meanMultiplier = (Square(selfRating.StandardDeviation) + Square(gameInfo.DynamicsFactor))/c; + + double varianceWithDynamics = Square(selfRating.StandardDeviation) + Square(gameInfo.DynamicsFactor); + double stdDevMultiplier = varianceWithDynamics/Square(c); + + double newMean = selfRating.Mean + (rankMultiplier*meanMultiplier*v); + double newStdDev = Math.Sqrt(varianceWithDynamics*(1 - w*stdDevMultiplier)); + + return new Rating(newMean, newStdDev); + } + + /// + public override double CalculateMatchQuality(GameInfo gameInfo, + IEnumerable> teams) + { + Guard.ArgumentNotNull(gameInfo, "gameInfo"); + ValidateTeamCountAndPlayersCountPerTeam(teams); + + Rating player1Rating = teams.First().Values.First(); + Rating player2Rating = teams.Last().Values.First(); + + // We just use equation 4.1 found on page 8 of the TrueSkill 2006 paper: + double betaSquared = Square(gameInfo.Beta); + double player1SigmaSquared = Square(player1Rating.StandardDeviation); + double player2SigmaSquared = Square(player2Rating.StandardDeviation); + + // This is the square root part of the equation: + double sqrtPart = + Math.Sqrt( + (2*betaSquared) + / + (2*betaSquared + player1SigmaSquared + player2SigmaSquared)); + + // This is the exponent part of the equation: + double expPart = + Math.Exp( + (-1*Square(player1Rating.Mean - player2Rating.Mean)) + / + (2*(2*betaSquared + player1SigmaSquared + player2SigmaSquared))); + + return sqrtPart*expPart; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkill/TwoTeamTrueSkillCalculator.cs b/Skills/TrueSkill/TwoTeamTrueSkillCalculator.cs new file mode 100644 index 0000000..8a493b8 --- /dev/null +++ b/Skills/TrueSkill/TwoTeamTrueSkillCalculator.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Moserware.Skills.Numerics; + +namespace Moserware.Skills.TrueSkill +{ + /// + /// Calculates new ratings for only two teams where each team has 1 or more players. + /// + /// + /// When you only have two teams, the math is still simple: no factor graphs are used yet. + /// + public class TwoTeamTrueSkillCalculator : SkillCalculator + { + public TwoTeamTrueSkillCalculator() + : base(SupportedOptions.None, Range.Exactly(2), Range.AtLeast(1)) + { + } + + /// + public override IDictionary CalculateNewRatings(GameInfo gameInfo, + IEnumerable + > + teams, params int[] teamRanks) + { + Guard.ArgumentNotNull(gameInfo, "gameInfo"); + ValidateTeamCountAndPlayersCountPerTeam(teams); + + RankSorter.Sort(ref teams, ref teamRanks); + + IDictionary team1 = teams.First(); + IDictionary team2 = teams.Last(); + + bool wasDraw = (teamRanks[0] == teamRanks[1]); + + var results = new Dictionary(); + + UpdatePlayerRatings(gameInfo, + results, + team1, + team2, + wasDraw ? PairwiseComparison.Draw : PairwiseComparison.Win); + + UpdatePlayerRatings(gameInfo, + results, + team2, + team1, + wasDraw ? PairwiseComparison.Draw : PairwiseComparison.Lose); + + return results; + } + + private static void UpdatePlayerRatings(GameInfo gameInfo, + IDictionary newPlayerRatings, + IDictionary selfTeam, + IDictionary otherTeam, + PairwiseComparison selfToOtherTeamComparison) + { + double drawMargin = DrawMargin.GetDrawMarginFromDrawProbability(gameInfo.DrawProbability, gameInfo.Beta); + double betaSquared = Square(gameInfo.Beta); + double tauSquared = Square(gameInfo.DynamicsFactor); + + int totalPlayers = selfTeam.Count() + otherTeam.Count(); + + double selfMeanSum = selfTeam.Values.Sum(r => r.Mean); + double otherTeamMeanSum = otherTeam.Values.Sum(r => r.Mean); + + double c = Math.Sqrt(selfTeam.Values.Sum(r => Square(r.StandardDeviation)) + + + otherTeam.Values.Sum(r => Square(r.StandardDeviation)) + + + totalPlayers*betaSquared); + + double winningMean = selfMeanSum; + double losingMean = otherTeamMeanSum; + + switch (selfToOtherTeamComparison) + { + case PairwiseComparison.Win: + case PairwiseComparison.Draw: + // NOP + break; + case PairwiseComparison.Lose: + winningMean = otherTeamMeanSum; + losingMean = selfMeanSum; + break; + } + + double meanDelta = winningMean - losingMean; + + double v; + double w; + double rankMultiplier; + + if (selfToOtherTeamComparison != PairwiseComparison.Draw) + { + // non-draw case + v = TruncatedGaussianCorrectionFunctions.VExceedsMargin(meanDelta, drawMargin, c); + w = TruncatedGaussianCorrectionFunctions.WExceedsMargin(meanDelta, drawMargin, c); + rankMultiplier = (int) selfToOtherTeamComparison; + } + else + { + // assume draw + v = TruncatedGaussianCorrectionFunctions.VWithinMargin(meanDelta, drawMargin, c); + w = TruncatedGaussianCorrectionFunctions.WWithinMargin(meanDelta, drawMargin, c); + rankMultiplier = 1; + } + + foreach (var teamPlayerRatingPair in selfTeam) + { + Rating previousPlayerRating = teamPlayerRatingPair.Value; + + double meanMultiplier = (Square(previousPlayerRating.StandardDeviation) + tauSquared)/c; + double stdDevMultiplier = (Square(previousPlayerRating.StandardDeviation) + tauSquared)/Square(c); + + double playerMeanDelta = (rankMultiplier*meanMultiplier*v); + double newMean = previousPlayerRating.Mean + playerMeanDelta; + + double newStdDev = + Math.Sqrt((Square(previousPlayerRating.StandardDeviation) + tauSquared)*(1 - w*stdDevMultiplier)); + + newPlayerRatings[teamPlayerRatingPair.Key] = new Rating(newMean, newStdDev); + } + } + + /// + public override double CalculateMatchQuality(GameInfo gameInfo, + IEnumerable> teams) + { + Guard.ArgumentNotNull(gameInfo, "gameInfo"); + ValidateTeamCountAndPlayersCountPerTeam(teams); + + // We've verified that there's just two teams + ICollection team1 = teams.First().Values; + int team1Count = team1.Count(); + + ICollection team2 = teams.Last().Values; + int team2Count = team2.Count(); + + int totalPlayers = team1Count + team2Count; + + double betaSquared = Square(gameInfo.Beta); + + double team1MeanSum = team1.Sum(r => r.Mean); + double team1StdDevSquared = team1.Sum(r => Square(r.StandardDeviation)); + + double team2MeanSum = team2.Sum(r => r.Mean); + double team2SigmaSquared = team2.Sum(r => Square(r.StandardDeviation)); + + // This comes from equation 4.1 in the TrueSkill paper on page 8 + // The equation was broken up into the part under the square root sign and + // the exponential part to make the code easier to read. + + double sqrtPart + = Math.Sqrt( + (totalPlayers*betaSquared) + / + (totalPlayers*betaSquared + team1StdDevSquared + team2SigmaSquared) + ); + + double expPart + = Math.Exp( + (-1*Square(team1MeanSum - team2MeanSum)) + / + (2*(totalPlayers*betaSquared + team1StdDevSquared + team2SigmaSquared)) + ); + + return expPart*sqrtPart; + } + } +} \ No newline at end of file diff --git a/Skills/TrueSkillCalculator.cs b/Skills/TrueSkillCalculator.cs new file mode 100644 index 0000000..9f3d05d --- /dev/null +++ b/Skills/TrueSkillCalculator.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using Moserware.Skills.TrueSkill; + +namespace Moserware.Skills +{ + /// + /// Calculates a TrueSkill rating using . + /// + public static class TrueSkillCalculator + { + // Keep a singleton around + private static readonly SkillCalculator _Calculator + = new FactorGraphTrueSkillCalculator(); + + /// + /// Calculates new ratings based on the prior ratings and team ranks. + /// + /// Parameters for the game. + /// A mapping of team players and their ratings. + /// The ranks of the teams where 1 is first place. For a tie, repeat the number (e.g. 1, 2, 2) + /// All the players and their new ratings. + public static IDictionary CalculateNewRatings(GameInfo gameInfo, + IEnumerable + > teams, + params int[] teamRanks) + { + // Just punt the work to the full implementation + return _Calculator.CalculateNewRatings(gameInfo, teams, teamRanks); + } + + /// + /// Calculates the match quality as the likelihood of all teams drawing. + /// + /// The underlying type of the player. + /// Parameters for the game. + /// A mapping of team players and their ratings. + /// The match quality as a percentage (between 0.0 and 1.0). + public static double CalculateMatchQuality(GameInfo gameInfo, + IEnumerable> teams) + { + // Just punt the work to the full implementation + return _Calculator.CalculateMatchQuality(gameInfo, teams); + } + } +} \ No newline at end of file diff --git a/Skills/bin/Debug/Moserware.Skills.dll b/Skills/bin/Debug/Moserware.Skills.dll new file mode 100644 index 0000000000000000000000000000000000000000..27ce8d265830e42b2f4eb96d643cbc7e35ffd468 GIT binary patch literal 63488 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 literal 0 HcmV?d00001 diff --git a/Skills/bin/Debug/Moserware.Skills.pdb b/Skills/bin/Debug/Moserware.Skills.pdb new file mode 100644 index 0000000000000000000000000000000000000000..5a376b1ec75ea39fbb07d83168f14e4100fc133b GIT binary patch literal 247296 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 literal 0 HcmV?d00001 diff --git a/UnitTests/Elo/DuellingEloTest.cs b/UnitTests/Elo/DuellingEloTest.cs new file mode 100644 index 0000000..baf3ff1 --- /dev/null +++ b/UnitTests/Elo/DuellingEloTest.cs @@ -0,0 +1,51 @@ +using Moserware.Skills; +using Moserware.Skills.Elo; +using NUnit.Framework; + +namespace UnitTests.Elo +{ + [TestFixture] + public class DuellingEloTest + { + private const double ErrorTolerance = 0.1; + + [Test] + public void TwoOnTwoDuellingTest() + { + var calculator = new DuellingEloCalculator(new GaussianEloCalculator()); + + var player1 = new Player(1); + var player2 = new Player(2); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating) + .AddPlayer(player2, gameInfo.DefaultRating); + + var player3 = new Player(3); + var player4 = new Player(4); + + var team2 = new Team() + .AddPlayer(player3, gameInfo.DefaultRating) + .AddPlayer(player4, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // TODO: Verify? + AssertRating(37, newRatingsWinLose[player1]); + AssertRating(37, newRatingsWinLose[player2]); + AssertRating(13, newRatingsWinLose[player3]); + AssertRating(13, newRatingsWinLose[player4]); + + var quality = calculator.CalculateMatchQuality(gameInfo, teams); + Assert.AreEqual(1.0, quality, 0.001); + } + + private static void AssertRating(double expected, Rating actual) + { + Assert.AreEqual(expected, actual.Mean, ErrorTolerance); + } + } +} diff --git a/UnitTests/Elo/EloAssert.cs b/UnitTests/Elo/EloAssert.cs new file mode 100644 index 0000000..2242120 --- /dev/null +++ b/UnitTests/Elo/EloAssert.cs @@ -0,0 +1,37 @@ +using Moserware.Skills; +using Moserware.Skills.Elo; +using NUnit.Framework; + +namespace UnitTests.Elo +{ + internal static class EloAssert + { + private const double ErrorTolerance = 0.1; + + public static void AssertChessRating(TwoPlayerEloCalculator calculator, + double player1BeforeRating, + double player2BeforeRating, + PairwiseComparison player1Result, + double player1AfterRating, + double player2AfterRating) + { + var player1 = new Player(1); + var player2 = new Player(2); + + var teams = Teams.Concat( + new Team(player1, new EloRating(player1BeforeRating)), + new Team(player2, new EloRating(player2BeforeRating))); + + var chessGameInfo = new GameInfo(1200, 0, 200, 0, 0); + + var result = calculator.CalculateNewRatings(chessGameInfo, teams, + (player1Result == PairwiseComparison.Win) ? new[] { 1, 2 } : + (player1Result == PairwiseComparison.Lose) ? new[] { 2, 1 } : + new[] { 1, 1 }); + + + Assert.AreEqual(player1AfterRating, result[player1].Mean, ErrorTolerance); + Assert.AreEqual(player2AfterRating, result[player2].Mean, ErrorTolerance); + } + } +} diff --git a/UnitTests/Elo/FideEloCalculatorTest.cs b/UnitTests/Elo/FideEloCalculatorTest.cs new file mode 100644 index 0000000..56febae --- /dev/null +++ b/UnitTests/Elo/FideEloCalculatorTest.cs @@ -0,0 +1,36 @@ +using Moserware.Skills; +using Moserware.Skills.Elo; +using NUnit.Framework; + +namespace UnitTests.Elo +{ + [TestFixture] + public class FideEloCalculatorTest + { + [Test] + public void FideProvisionalEloCalculatorTests() + { + // verified against http://ratings.fide.com/calculator_rtd.phtml + var calc = new FideEloCalculator(new FideKFactor.Provisional()); + + EloAssert.AssertChessRating(calc, 1200, 1500, PairwiseComparison.Win, 1221.25, 1478.75); + EloAssert.AssertChessRating(calc, 1200, 1500, PairwiseComparison.Draw, 1208.75, 1491.25); + EloAssert.AssertChessRating(calc, 1200, 1500, PairwiseComparison.Lose, 1196.25, 1503.75); + } + + [Test] + public void FideNonProvisionalEloCalculatorTests() + { + // verified against http://ratings.fide.com/calculator_rtd.phtml + var calc = new FideEloCalculator(); + + EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Win, 1207.5, 1192.5); + EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Draw, 1200, 1200); + EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Lose, 1192.5, 1207.5); + + EloAssert.AssertChessRating(calc, 2600, 2500, PairwiseComparison.Win, 2603.6, 2496.4); + EloAssert.AssertChessRating(calc, 2600, 2500, PairwiseComparison.Draw, 2598.6, 2501.4); + EloAssert.AssertChessRating(calc, 2600, 2500, PairwiseComparison.Lose, 2593.6, 2506.4); + } + } +} \ No newline at end of file diff --git a/UnitTests/Elo/GaussianEloCalculatorTest.cs b/UnitTests/Elo/GaussianEloCalculatorTest.cs new file mode 100644 index 0000000..a6325e5 --- /dev/null +++ b/UnitTests/Elo/GaussianEloCalculatorTest.cs @@ -0,0 +1,26 @@ +using Moserware.Skills; +using Moserware.Skills.Elo; +using NUnit.Framework; + +namespace UnitTests.Elo +{ + [TestFixture] + public class GaussianEloCalculatorTest + { + [Test] + public void GaussianEloCalculatorTests() + { + const double defaultKFactor = 24.0; + var calc = new GaussianEloCalculator(); + + EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Win, 1212, 1188); + EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Draw, 1200, 1200); + EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Lose, 1188, 1212); + + // verified using TrueSkill paper equation + EloAssert.AssertChessRating(calc, 1200, 1000, PairwiseComparison.Win, 1200 + ((1 - 0.76024993890652326884) * defaultKFactor), 1000 - (1 - 0.76024993890652326884) * defaultKFactor); + EloAssert.AssertChessRating(calc, 1200, 1000, PairwiseComparison.Draw, 1200 - (0.76024993890652326884 - 0.5) * defaultKFactor, 1000 + (0.76024993890652326884 - 0.5) * defaultKFactor); + EloAssert.AssertChessRating(calc, 1200, 1000, PairwiseComparison.Lose, 1200 - 0.76024993890652326884 * defaultKFactor, 1000 + 0.76024993890652326884 * defaultKFactor); + } + } +} diff --git a/UnitTests/Numerics/GaussianDistributionTests.cs b/UnitTests/Numerics/GaussianDistributionTests.cs new file mode 100644 index 0000000..e0b0447 --- /dev/null +++ b/UnitTests/Numerics/GaussianDistributionTests.cs @@ -0,0 +1,68 @@ +using System; +using Moserware.Numerics; +using NUnit.Framework; + +namespace UnitTests.Numerics +{ + [TestFixture] + public class GaussianDistributionTests + { + private const double ErrorTolerance = 0.000001; + + [Test] + public void MultiplicationTests() + { + // I verified this against the formula at http://www.tina-vision.net/tina-knoppix/tina-memo/2003-003.pdf + var standardNormal = new GaussianDistribution(0, 1); + var shiftedGaussian = new GaussianDistribution(2, 3); + + var product = standardNormal * shiftedGaussian; + + Assert.AreEqual(0.2, product.Mean, ErrorTolerance); + Assert.AreEqual(3.0 / Math.Sqrt(10), product.StandardDeviation, ErrorTolerance); + + var m4s5 = new GaussianDistribution(4, 5); + var m6s7 = new GaussianDistribution(6, 7); + + var product2 = m4s5 * m6s7; + Func square = x => x*x; + + var expectedMean = (4 * square(7) + 6 * square(5)) / (square(5) + square(7)); + Assert.AreEqual(expectedMean, product2.Mean, ErrorTolerance); + + var expectedSigma = Math.Sqrt(((square(5) * square(7)) / (square(5) + square(7)))); + Assert.AreEqual(expectedSigma, product2.StandardDeviation, ErrorTolerance); + } + + [Test] + public void DivisionTests() + { + // Since the multiplication was worked out by hand, we use the same numbers but work backwards + var product = new GaussianDistribution(0.2, 3.0 / Math.Sqrt(10)); + var standardNormal = new GaussianDistribution(0, 1); + + var productDividedByStandardNormal = product / standardNormal; + Assert.AreEqual(2.0, productDividedByStandardNormal.Mean, ErrorTolerance); + Assert.AreEqual(3.0, productDividedByStandardNormal.StandardDeviation, ErrorTolerance); + + Func square = x => x * x; + var product2 = new GaussianDistribution((4 * square(7) + 6 * square(5)) / (square(5) + square(7)), Math.Sqrt(((square(5) * square(7)) / (square(5) + square(7))))); + var m4s5 = new GaussianDistribution(4,5); + var product2DividedByM4S5 = product2 / m4s5; + Assert.AreEqual(6.0, product2DividedByM4S5.Mean, ErrorTolerance); + Assert.AreEqual(7.0, product2DividedByM4S5.StandardDeviation, ErrorTolerance); + } + + [Test] + public void LogProductNormalizationTests() + { + var m4s5 = new GaussianDistribution(4, 5); + var m6s7 = new GaussianDistribution(6, 7); + + var product2 = m4s5 * m6s7; + var normConstant = 1.0 / (Math.Sqrt(2 * Math.PI) * product2.StandardDeviation); + var lpn = GaussianDistribution.LogProductNormalization(m4s5, m6s7); + + } + } +} \ No newline at end of file diff --git a/UnitTests/Numerics/MatrixTests.cs b/UnitTests/Numerics/MatrixTests.cs new file mode 100644 index 0000000..1e5ce56 --- /dev/null +++ b/UnitTests/Numerics/MatrixTests.cs @@ -0,0 +1,186 @@ +using Moserware.Numerics; +using NUnit.Framework; + +namespace UnitTests.Numerics +{ + [TestFixture] + public class MatrixTests + { + [Test] + public void TwoByTwoDeterminantTests() + { + var a = new SquareMatrix(1, 2, + 3, 4); + Assert.AreEqual(-2, a.Determinant); + + var b = new SquareMatrix(3, 4, + 5, 6); + Assert.AreEqual(-2, b.Determinant); + + var c = new SquareMatrix(1, 1, + 1, 1); + Assert.AreEqual(0, c.Determinant); + + var d = new SquareMatrix(12, 15, + 17, 21); + Assert.AreEqual(12 * 21 - 15 * 17, d.Determinant); + } + + [Test] + public void ThreeByThreeDeterminantTests() + { + var a = new SquareMatrix(1, 2, 3, + 4, 5, 6, + 7, 8, 9); + Assert.AreEqual(0, a.Determinant); + + var π = new SquareMatrix(3, 1, 4, + 1, 5, 9, + 2, 6, 5); + + // Verified against http://www.wolframalpha.com/input/?i=determinant+%7B%7B3%2C1%2C4%7D%2C%7B1%2C5%2C9%7D%2C%7B2%2C6%2C5%7D%7D + Assert.AreEqual(-90, π.Determinant); + } + + [Test] + public void FourByFourDeterminantTests() + { + var a = new SquareMatrix( 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16); + + Assert.AreEqual(0, a.Determinant); + + var π = new SquareMatrix(3, 1, 4, 1, + 5, 9, 2, 6, + 5, 3, 5, 8, + 9, 7, 9, 3); + + // Verified against http://www.wolframalpha.com/input/?i=determinant+%7B+%7B3%2C1%2C4%2C1%7D%2C+%7B5%2C9%2C2%2C6%7D%2C+%7B5%2C3%2C5%2C8%7D%2C+%7B9%2C7%2C9%2C3%7D%7D + Assert.AreEqual(98, π.Determinant); + } + + [Test] + public void EightByEightDeterminantTests() + { + var a = new SquareMatrix( 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 32, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64); + + Assert.AreEqual(0, a.Determinant); + + var π = new SquareMatrix(3, 1, 4, 1, 5, 9, 2, 6, + 5, 3, 5, 8, 9, 7, 9, 3, + 2, 3, 8, 4, 6, 2, 6, 4, + 3, 3, 8, 3, 2, 7, 9, 5, + 0, 2, 8, 8, 4, 1, 9, 7, + 1, 6, 9, 3, 9, 9, 3, 7, + 5, 1, 0, 5, 8, 2, 0, 9, + 7, 4, 9, 4, 4, 5, 9, 2); + + // Verified against http://www.wolframalpha.com/input/?i=det+%7B%7B3%2C1%2C4%2C1%2C5%2C9%2C2%2C6%7D%2C%7B5%2C3%2C5%2C8%2C9%2C7%2C9%2C3%7D%2C%7B2%2C3%2C8%2C4%2C6%2C2%2C6%2C4%7D%2C%7B3%2C3%2C8%2C3%2C2%2C7%2C9%2C5%7D%2C%7B0%2C2%2C8%2C8%2C4%2C1%2C9%2C7%7D%2C%7B1%2C6%2C9%2C3%2C9%2C9%2C3%2C7%7D%2C%7B5%2C1%2C0%2C5%2C8%2C2%2C0%2C9%7D%2C%7B7%2C4%2C9%2C4%2C4%2C5%2C9%2C2%7D%7D + Assert.AreEqual(1378143, π.Determinant); + } + + [Test] + public void EqualsTest() + { + var a = new SquareMatrix(1, 2, + 3, 4); + + var b = new SquareMatrix(1, 2, + 3, 4); + + Assert.IsTrue(a == b); + Assert.AreEqual(a, b); + + var c = new Matrix(2, 3, + 1, 2, 3, + 4, 5, 6); + + var d = new Matrix(2, 3, + 1, 2, 3, + 4, 5, 6); + + Assert.IsTrue(c == d); + Assert.AreEqual(c, d); + + var e = new Matrix(3, 2, + 1, 4, + 2, 5, + 3, 6); + + var f = e.Transpose; + Assert.IsTrue(d == f); + Assert.AreEqual(d, f); + Assert.AreEqual(d.GetHashCode(), f.GetHashCode()); + + } + + [Test] + public void AdjugateTests() + { + // From Wikipedia: http://en.wikipedia.org/wiki/Adjugate_matrix + + var a = new SquareMatrix(1, 2, + 3, 4); + + var b = new SquareMatrix( 4, -2, + -3, 1); + + Assert.AreEqual(b, a.Adjugate); + + + var c = new SquareMatrix(-3, 2, -5, + -1, 0, -2, + 3, -4, 1); + + var d = new SquareMatrix(-8, 18, -4, + -5, 12, -1, + 4, -6, 2); + + Assert.AreEqual(d, c.Adjugate); + } + + [Test] + public void InverseTests() + { + // see http://www.mathwords.com/i/inverse_of_a_matrix.htm + var a = new SquareMatrix(4, 3, + 3, 2); + + var b = new SquareMatrix(-2, 3, + 3, -4); + + var aInverse = a.Inverse; + Assert.AreEqual(b, aInverse); + + var identity2x2 = new IdentityMatrix(2); + + var aaInverse = a * aInverse; + Assert.IsTrue(identity2x2 == aaInverse); + + var c = new SquareMatrix(1, 2, 3, + 0, 4, 5, + 1, 0, 6); + + var cInverse = c.Inverse; + var d = (1.0 / 22) * new SquareMatrix(24, -12, -2, + 5, 3, -5, + -4, 2, 4); + + + Assert.IsTrue(d == cInverse); + var identity3x3 = new IdentityMatrix(3); + + var ccInverse = c * cInverse; + Assert.IsTrue(identity3x3 == ccInverse); + } + } +} \ No newline at end of file diff --git a/UnitTests/Properties/AssemblyInfo.cs b/UnitTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5e1fe1e --- /dev/null +++ b/UnitTests/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("UnitTests")] +[assembly: AssemblyDescription("Unit tests for Moserware.Skills")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Jeff Moser")] +[assembly: AssemblyProduct("UnitTests")] +[assembly: AssemblyCopyright("Copyright © Jeff Moser 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ddd7d430-f9c0-45c8-9576-70418d766e1f")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnitTests/README.txt b/UnitTests/README.txt new file mode 100644 index 0000000..d8eea37 --- /dev/null +++ b/UnitTests/README.txt @@ -0,0 +1,23 @@ +These tests were written using NUnit 2.5.2 that is available for download +at: + +http://sourceforge.net/projects/nunit/files/NUnit%20Version%202/NUnit-2.5.2.9222.msi/download + +If you have a different version or setup, you'll need to update the path under +the UnitTests project properties by right clicking on UnitTests and then +click "properties" and then click the "debug" tab. The "start external program" +points to the NUnit test runner. + +I did it this way so you didn't need more than the express version of +Visual Studio to run. If you have a fancy test runner already, feel +free to use that. + +Additionally, it should be easy to update the tests to your tool +of choice. + +Finally, realize that these tests test *all* of the calculators +implementations. For that reason, they create a new instance of +a particular calculator. If you're using this code in your application, +you can just use the convenience helper class of "TrueSkillCalculator" +that has static methods. If you do that, you won't have to worry +about creating your own instances. \ No newline at end of file diff --git a/UnitTests/RankSorterTest.cs b/UnitTests/RankSorterTest.cs new file mode 100644 index 0000000..82ed457 --- /dev/null +++ b/UnitTests/RankSorterTest.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using Moserware.Skills; +using NUnit.Framework; + +namespace UnitTests +{ + [TestFixture] + public class RankSorterTest + { + [Test] + public void SortAlreadySortedTest() + { + IEnumerable people = new[] { "One", "Two", "Three" }; + int[] ranks = new[] { 1, 2, 3 }; + + RankSorter.Sort(ref people, ref ranks); + + CollectionAssert.AreEqual(new[] { "One", "Two", "Three" }, people); + CollectionAssert.AreEqual(new[] { 1, 2, 3 }, ranks); + } + + [Test] + public void SortUnsortedTest() + { + IEnumerable people = new[] { "Five", "Two1", "Two2", "One", "Four" }; + int[] ranks = new[] { 5, 2, 2, 1, 4 }; + + RankSorter.Sort(ref people, ref ranks); + + CollectionAssert.AreEqual(new[] { "One", "Two1", "Two2", "Four", "Five" }, people); + CollectionAssert.AreEqual(new[] { 1, 2, 2, 4, 5 }, ranks); + } + } +} \ No newline at end of file diff --git a/UnitTests/TrueSkill/DrawMarginTest.cs b/UnitTests/TrueSkill/DrawMarginTest.cs new file mode 100644 index 0000000..831c9c6 --- /dev/null +++ b/UnitTests/TrueSkill/DrawMarginTest.cs @@ -0,0 +1,27 @@ +using Moserware.Skills.TrueSkill; +using NUnit.Framework; + +namespace UnitTests.TrueSkill +{ + [TestFixture] + public class DrawMarginTest + { + private const double ErrorTolerance = .000001; + + [Test] + public void GetDrawMarginFromDrawProbabilityTest() + { + double beta = 25.0 / 6.0; + // The expected values were compared against Ralf Herbrich's implementation in F# + AssertDrawMargin(0.10, beta, 0.74046637542690541); + AssertDrawMargin(0.25, beta, 1.87760059883033); + AssertDrawMargin(0.33, beta, 2.5111010132487492); + } + + private static void AssertDrawMargin(double drawProbability, double beta, double expected) + { + double actual = DrawMargin.GetDrawMarginFromDrawProbability(drawProbability, beta); + Assert.AreEqual(expected, actual, ErrorTolerance); + } + } +} \ No newline at end of file diff --git a/UnitTests/TrueSkill/FactorGraphTrueSkillCalculatorTests.cs b/UnitTests/TrueSkill/FactorGraphTrueSkillCalculatorTests.cs new file mode 100644 index 0000000..1f15f23 --- /dev/null +++ b/UnitTests/TrueSkill/FactorGraphTrueSkillCalculatorTests.cs @@ -0,0 +1,22 @@ +using Moserware.Skills.TrueSkill; +using NUnit.Framework; + +namespace UnitTests.TrueSkill +{ + [TestFixture] + public class FactorGraphTrueSkillCalculatorTests + { + [Test] + public void FullFactorGraphCalculatorTests() + { + var calculator = new FactorGraphTrueSkillCalculator(); + + // We can test all classes + TrueSkillCalculatorTests.TestAllTwoPlayerScenarios(calculator); + TrueSkillCalculatorTests.TestAllTwoTeamScenarios(calculator); + TrueSkillCalculatorTests.TestAllMultipleTeamScenarios(calculator); + + TrueSkillCalculatorTests.TestPartialPlayScenarios(calculator); + } + } +} \ No newline at end of file diff --git a/UnitTests/TrueSkill/TrueSkillCalculatorTests.cs b/UnitTests/TrueSkill/TrueSkillCalculatorTests.cs new file mode 100644 index 0000000..33c0307 --- /dev/null +++ b/UnitTests/TrueSkill/TrueSkillCalculatorTests.cs @@ -0,0 +1,987 @@ +using Moserware.Skills; +using NUnit.Framework; + +namespace UnitTests.TrueSkill +{ + public static class TrueSkillCalculatorTests + { + private const double ErrorTolerance = 0.085; + + // These are the roll-up ones + + public static void TestAllTwoPlayerScenarios(SkillCalculator calculator) + { + TwoPlayerTestNotDrawn(calculator); + TwoPlayerTestDrawn(calculator); + OneOnOneMassiveUpsetDrawTest(calculator); + + TwoPlayerChessTestNotDrawn(calculator); + } + + public static void TestAllTwoTeamScenarios(SkillCalculator calculator) + { + OneOnTwoSimpleTest(calculator); + OneOnTwoDrawTest(calculator); + OneOnTwoSomewhatBalanced(calculator); + OneOnThreeDrawTest(calculator); + OneOnThreeSimpleTest(calculator); + OneOnSevenSimpleTest(calculator); + + TwoOnTwoSimpleTest(calculator); + TwoOnTwoUnbalancedDrawTest(calculator); + TwoOnTwoDrawTest(calculator); + TwoOnTwoUpsetTest(calculator); + + ThreeOnTwoTests(calculator); + + FourOnFourSimpleTest(calculator); + } + + public static void TestAllMultipleTeamScenarios(SkillCalculator calculator) + { + ThreeTeamsOfOneNotDrawn(calculator); + ThreeTeamsOfOneDrawn(calculator); + FourTeamsOfOneNotDrawn(calculator); + FiveTeamsOfOneNotDrawn(calculator); + EightTeamsOfOneDrawn(calculator); + EightTeamsOfOneUpset(calculator); + SixteenTeamsOfOneNotDrawn(calculator); + + TwoOnFourOnTwoWinDraw(calculator); + } + + public static void TestPartialPlayScenarios(SkillCalculator calculator) + { + OneOnTwoBalancedPartialPlay(calculator); + } + + //------------------- Actual Tests --------------------------- + // If you see more than 3 digits of precision in the decimal point, then the expected values calculated from + // F# RalfH's implementation with the same input. It didn't support teams, so team values all came from the + // online calculator at http://atom.research.microsoft.com/trueskill/rankcalculator.aspx + // + // All match quality expected values came from the online calculator + + // In both cases, there may be some discrepancy after the first decimal point. I think this is due to my implementation + // using slightly higher precision in GaussianDistribution. + + //------------------------------------------------------------------------------ + // Two Player Tests + //------------------------------------------------------------------------------ + + private static void TwoPlayerTestNotDrawn(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, gameInfo.DefaultRating); + var team2 = new Team(player2, gameInfo.DefaultRating); + var teams = Teams.Concat(team1, team2); + + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + var player1NewRating = newRatings[player1]; + AssertRating(29.39583201999924, 7.171475587326186, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(20.60416798000076, 7.171475587326186, player2NewRating); + + AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void TwoPlayerTestDrawn(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, gameInfo.DefaultRating); + var team2 = new Team(player2, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); + + var player1NewRating = newRatings[player1]; + AssertRating(25.0, 6.4575196623173081, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(25.0, 6.4575196623173081, player2NewRating); + + AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void TwoPlayerChessTestNotDrawn(SkillCalculator calculator) + { + // Inspired by a real bug :-) + var player1 = new Player(1); + var player2 = new Player(2); + var gameInfo = new GameInfo(1200.0, 1200.0 / 3.0, 200.0, 1200.0 / 300.0, 0.03); + + var team1 = new Team(player1, new Rating(1301.0007, 42.9232)); + var team2 = new Team(player2, new Rating(1188.7560, 42.5570)); + + var newRatings = calculator.CalculateNewRatings(gameInfo, Teams.Concat(team1, team2), 1, 2); + + var player1NewRating = newRatings[player1]; + AssertRating(1304.7820836053318, 42.843513887848658, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(1185.0383099003536, 42.485604606897752, player2NewRating); + } + + private static void OneOnOneMassiveUpsetDrawTest(SkillCalculator calculator) + { + var player1 = new Player(1); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating); + + var player2 = new Player(2); + + var team2 = new Team() + .AddPlayer(player2, new Rating(50, 12.5)); + + var teams = Teams.Concat(team1, team2); + + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); + + // Winners + AssertRating(31.662, 7.137, newRatingsWinLose[player1]); + + // Losers + AssertRating(35.010, 7.910, newRatingsWinLose[player2]); + + AssertMatchQuality(0.110, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + //------------------------------------------------------------------------------ + // Two Team Tests + //------------------------------------------------------------------------------ + + private static void TwoOnTwoSimpleTest(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating) + .AddPlayer(player2, gameInfo.DefaultRating); + + var player3 = new Player(3); + var player4 = new Player(4); + + var team2 = new Team() + .AddPlayer(player3, gameInfo.DefaultRating) + .AddPlayer(player4, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // Winners + AssertRating(28.108, 7.774, newRatingsWinLose[player1]); + AssertRating(28.108, 7.774, newRatingsWinLose[player2]); + + // Losers + AssertRating(21.892, 7.774, newRatingsWinLose[player3]); + AssertRating(21.892, 7.774, newRatingsWinLose[player4]); + + AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void TwoOnTwoDrawTest(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating) + .AddPlayer(player2, gameInfo.DefaultRating); + + var player3 = new Player(3); + var player4 = new Player(4); + + var team2 = new Team() + .AddPlayer(player3, gameInfo.DefaultRating) + .AddPlayer(player4, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); + + // Winners + AssertRating(25, 7.455, newRatingsWinLose[player1]); + AssertRating(25, 7.455, newRatingsWinLose[player2]); + + // Losers + AssertRating(25, 7.455, newRatingsWinLose[player3]); + AssertRating(25, 7.455, newRatingsWinLose[player4]); + + AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void TwoOnTwoUnbalancedDrawTest(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, new Rating(15, 8)) + .AddPlayer(player2, new Rating(20, 6)); + + var player3 = new Player(3); + var player4 = new Player(4); + + var team2 = new Team() + .AddPlayer(player3, new Rating(25, 4)) + .AddPlayer(player4, new Rating(30, 3)); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); + + // Winners + AssertRating(21.570, 6.556, newRatingsWinLose[player1]); + AssertRating(23.696, 5.418, newRatingsWinLose[player2]); + + // Losers + AssertRating(23.357, 3.833, newRatingsWinLose[player3]); + AssertRating(29.075, 2.931, newRatingsWinLose[player4]); + + AssertMatchQuality(0.214, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void TwoOnTwoUpsetTest(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, new Rating(20, 8)) + .AddPlayer(player2, new Rating(25, 6)); + + var player3 = new Player(3); + var player4 = new Player(4); + + var team2 = new Team() + .AddPlayer(player3, new Rating(35, 7)) + .AddPlayer(player4, new Rating(40, 5)); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // Winners + AssertRating(29.698, 7.008, newRatingsWinLose[player1]); + AssertRating(30.455, 5.594, newRatingsWinLose[player2]); + + // Losers + AssertRating(27.575, 6.346, newRatingsWinLose[player3]); + AssertRating(36.211, 4.768, newRatingsWinLose[player4]); + + AssertMatchQuality(0.084, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void FourOnFourSimpleTest(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating) + .AddPlayer(player2, gameInfo.DefaultRating) + .AddPlayer(player3, gameInfo.DefaultRating) + .AddPlayer(player4, gameInfo.DefaultRating); + + var player5 = new Player(5); + var player6 = new Player(6); + var player7 = new Player(7); + var player8 = new Player(8); + + var team2 = new Team() + .AddPlayer(player5, gameInfo.DefaultRating) + .AddPlayer(player6, gameInfo.DefaultRating) + .AddPlayer(player7, gameInfo.DefaultRating) + .AddPlayer(player8, gameInfo.DefaultRating); + + + var teams = Teams.Concat(team1, team2); + + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // Winners + AssertRating(27.198, 8.059, newRatingsWinLose[player1]); + AssertRating(27.198, 8.059, newRatingsWinLose[player2]); + AssertRating(27.198, 8.059, newRatingsWinLose[player3]); + AssertRating(27.198, 8.059, newRatingsWinLose[player4]); + + // Losers + AssertRating(22.802, 8.059, newRatingsWinLose[player5]); + AssertRating(22.802, 8.059, newRatingsWinLose[player6]); + AssertRating(22.802, 8.059, newRatingsWinLose[player7]); + AssertRating(22.802, 8.059, newRatingsWinLose[player8]); + + AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void OneOnTwoSimpleTest(SkillCalculator calculator) + { + var player1 = new Player(1); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating); + + var player2 = new Player(2); + var player3 = new Player(3); + + var team2 = new Team() + .AddPlayer(player2, gameInfo.DefaultRating) + .AddPlayer(player3, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // Winners + AssertRating(33.730, 7.317, newRatingsWinLose[player1]); + + // Losers + AssertRating(16.270, 7.317, newRatingsWinLose[player2]); + AssertRating(16.270, 7.317, newRatingsWinLose[player3]); + + AssertMatchQuality(0.135, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void OneOnTwoSomewhatBalanced(SkillCalculator calculator) + { + var player1 = new Player(1); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, new Rating(40, 6)); + + var player2 = new Player(2); + var player3 = new Player(3); + + var team2 = new Team() + .AddPlayer(player2, new Rating(20, 7)) + .AddPlayer(player3, new Rating(25, 8)); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // Winners + AssertRating(42.744, 5.602, newRatingsWinLose[player1]); + + // Losers + AssertRating(16.266, 6.359, newRatingsWinLose[player2]); + AssertRating(20.123, 7.028, newRatingsWinLose[player3]); + + AssertMatchQuality(0.478, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void OneOnThreeSimpleTest(SkillCalculator calculator) + { + var player1 = new Player(1); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating); + + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + + var team2 = new Team() + .AddPlayer(player2, gameInfo.DefaultRating) + .AddPlayer(player3, gameInfo.DefaultRating) + .AddPlayer(player4, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // Winners + AssertRating(36.337, 7.527, newRatingsWinLose[player1]); + + // Losers + AssertRating(13.663, 7.527, newRatingsWinLose[player2]); + AssertRating(13.663, 7.527, newRatingsWinLose[player3]); + AssertRating(13.663, 7.527, newRatingsWinLose[player4]); + + AssertMatchQuality(0.012, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void OneOnTwoDrawTest(SkillCalculator calculator) + { + var player1 = new Player(1); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating); + + var player2 = new Player(2); + var player3 = new Player(3); + + var team2 = new Team() + .AddPlayer(player2, gameInfo.DefaultRating) + .AddPlayer(player3, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); + + // Winners + AssertRating(31.660, 7.138, newRatingsWinLose[player1]); + + // Losers + AssertRating(18.340, 7.138, newRatingsWinLose[player2]); + AssertRating(18.340, 7.138, newRatingsWinLose[player3]); + + AssertMatchQuality(0.135, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void OneOnThreeDrawTest(SkillCalculator calculator) + { + var player1 = new Player(1); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating); + + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + + var team2 = new Team() + .AddPlayer(player2, gameInfo.DefaultRating) + .AddPlayer(player3, gameInfo.DefaultRating) + .AddPlayer(player4, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); + + // Winners + AssertRating(34.990, 7.455, newRatingsWinLose[player1]); + + // Losers + AssertRating(15.010, 7.455, newRatingsWinLose[player2]); + AssertRating(15.010, 7.455, newRatingsWinLose[player3]); + AssertRating(15.010, 7.455, newRatingsWinLose[player4]); + + AssertMatchQuality(0.012, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void OneOnSevenSimpleTest(SkillCalculator calculator) + { + var player1 = new Player(1); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, gameInfo.DefaultRating); + + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + var player5 = new Player(5); + var player6 = new Player(6); + var player7 = new Player(7); + var player8 = new Player(8); + + var team2 = new Team() + .AddPlayer(player2, gameInfo.DefaultRating) + .AddPlayer(player3, gameInfo.DefaultRating) + .AddPlayer(player4, gameInfo.DefaultRating) + .AddPlayer(player5, gameInfo.DefaultRating) + .AddPlayer(player6, gameInfo.DefaultRating) + .AddPlayer(player7, gameInfo.DefaultRating) + .AddPlayer(player8, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // Winners + AssertRating(40.582, 7.917, newRatingsWinLose[player1]); + + // Losers + AssertRating(9.418, 7.917, newRatingsWinLose[player2]); + AssertRating(9.418, 7.917, newRatingsWinLose[player3]); + AssertRating(9.418, 7.917, newRatingsWinLose[player4]); + AssertRating(9.418, 7.917, newRatingsWinLose[player5]); + AssertRating(9.418, 7.917, newRatingsWinLose[player6]); + AssertRating(9.418, 7.917, newRatingsWinLose[player7]); + AssertRating(9.418, 7.917, newRatingsWinLose[player8]); + + AssertMatchQuality(0.000, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void ThreeOnTwoTests(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + + var team1 = new Team() + .AddPlayer(player1, new Rating(28, 7)) + .AddPlayer(player2, new Rating(27, 6)) + .AddPlayer(player3, new Rating(26, 5)); + + + var player4 = new Player(4); + var player5 = new Player(5); + + var team2 = new Team() + .AddPlayer(player4, new Rating(30, 4)) + .AddPlayer(player5, new Rating(31, 3)); + + var gameInfo = GameInfo.DefaultGameInfo; + + var teams = Teams.Concat(team1, team2); + var newRatingsWinLoseExpected = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + + // Winners + AssertRating(28.658, 6.770, newRatingsWinLoseExpected[player1]); + AssertRating(27.484, 5.856, newRatingsWinLoseExpected[player2]); + AssertRating(26.336, 4.917, newRatingsWinLoseExpected[player3]); + + // Losers + AssertRating(29.785, 3.958, newRatingsWinLoseExpected[player4]); + AssertRating(30.879, 2.983, newRatingsWinLoseExpected[player5]); + + var newRatingsWinLoseUpset = calculator.CalculateNewRatings(gameInfo, Teams.Concat(team1, team2), 2, 1); + + // Winners + AssertRating(32.012, 3.877, newRatingsWinLoseUpset[player4]); + AssertRating(32.132, 2.949, newRatingsWinLoseUpset[player5]); + + // Losers + AssertRating(21.840, 6.314, newRatingsWinLoseUpset[player1]); + AssertRating(22.474, 5.575, newRatingsWinLoseUpset[player2]); + AssertRating(22.857, 4.757, newRatingsWinLoseUpset[player3]); + + AssertMatchQuality(0.254, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + //------------------------------------------------------------------------------ + // Multiple Teams Tests + //------------------------------------------------------------------------------ + + private static void TwoOnFourOnTwoWinDraw(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team() + .AddPlayer(player1, new Rating(40,4)) + .AddPlayer(player2, new Rating(45,3)); + + var player3 = new Player(3); + var player4 = new Player(4); + var player5 = new Player(5); + var player6 = new Player(6); + + var team2 = new Team() + .AddPlayer(player3, new Rating(20, 7)) + .AddPlayer(player4, new Rating(19, 6)) + .AddPlayer(player5, new Rating(30, 9)) + .AddPlayer(player6, new Rating(10, 4)); + + var player7 = new Player(7); + var player8 = new Player(8); + + var team3 = new Team() + .AddPlayer(player7, new Rating(50,5)) + .AddPlayer(player8, new Rating(30,2)); + + + var teams = Teams.Concat(team1, team2, team3); + var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 2); + + // Winners + AssertRating(40.877, 3.840, newRatingsWinLose[player1]); + AssertRating(45.493, 2.934, newRatingsWinLose[player2]); + AssertRating(19.609, 6.396, newRatingsWinLose[player3]); + AssertRating(18.712, 5.625, newRatingsWinLose[player4]); + AssertRating(29.353, 7.673, newRatingsWinLose[player5]); + AssertRating(9.872, 3.891, newRatingsWinLose[player6]); + AssertRating(48.830, 4.590, newRatingsWinLose[player7]); + AssertRating(29.813, 1.976, newRatingsWinLose[player8]); + + AssertMatchQuality(0.367, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void ThreeTeamsOfOneNotDrawn(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, gameInfo.DefaultRating); + var team2 = new Team(player2, gameInfo.DefaultRating); + var team3 = new Team(player3, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2, team3); + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3); + + var player1NewRating = newRatings[player1]; + AssertRating(31.675352419172107, 6.6559853776206905, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(25.000000000003912, 6.2078966412243233, player2NewRating); + + var player3NewRating = newRatings[player3]; + AssertRating(18.324647580823971, 6.6559853776218318, player3NewRating); + + AssertMatchQuality(0.200, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void ThreeTeamsOfOneDrawn(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, gameInfo.DefaultRating); + var team2 = new Team(player2, gameInfo.DefaultRating); + var team3 = new Team(player3, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2, team3); + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 1, 1); + + var player1NewRating = newRatings[player1]; + AssertRating(25.000, 5.698, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(25.000, 5.695, player2NewRating); + + var player3NewRating = newRatings[player3]; + AssertRating(25.000, 5.698, player3NewRating); + + AssertMatchQuality(0.200, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void FourTeamsOfOneNotDrawn(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, gameInfo.DefaultRating); + var team2 = new Team(player2, gameInfo.DefaultRating); + var team3 = new Team(player3, gameInfo.DefaultRating); + var team4 = new Team(player4, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2, team3, team4); + + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3, 4); + + var player1NewRating = newRatings[player1]; + AssertRating(33.206680965631264, 6.3481091698077057, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(27.401454693843323, 5.7871629348447584, player2NewRating); + + var player3NewRating = newRatings[player3]; + AssertRating(22.598545306188374, 5.7871629348413451, player3NewRating); + + var player4NewRating = newRatings[player4]; + AssertRating(16.793319034361271, 6.3481091698144967, player4NewRating); + + AssertMatchQuality(0.089, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void FiveTeamsOfOneNotDrawn(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + var player5 = new Player(5); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, gameInfo.DefaultRating); + var team2 = new Team(player2, gameInfo.DefaultRating); + var team3 = new Team(player3, gameInfo.DefaultRating); + var team4 = new Team(player4, gameInfo.DefaultRating); + var team5 = new Team(player5, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2, team3, team4, team5); + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3, 4, 5); + + var player1NewRating = newRatings[player1]; + AssertRating(34.363135705841188, 6.1361528798112692, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(29.058448805636779, 5.5358352402833413, player2NewRating); + + var player3NewRating = newRatings[player3]; + AssertRating(25.000000000031758, 5.4200805474429847, player3NewRating); + + var player4NewRating = newRatings[player4]; + AssertRating(20.941551194426314, 5.5358352402709672, player4NewRating); + + var player5NewRating = newRatings[player5]; + AssertRating(15.636864294158848, 6.136152879829349, player5NewRating); + + AssertMatchQuality(0.040, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void EightTeamsOfOneDrawn(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + var player5 = new Player(5); + var player6 = new Player(6); + var player7 = new Player(7); + var player8 = new Player(8); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, gameInfo.DefaultRating); + var team2 = new Team(player2, gameInfo.DefaultRating); + var team3 = new Team(player3, gameInfo.DefaultRating); + var team4 = new Team(player4, gameInfo.DefaultRating); + var team5 = new Team(player5, gameInfo.DefaultRating); + var team6 = new Team(player6, gameInfo.DefaultRating); + var team7 = new Team(player7, gameInfo.DefaultRating); + var team8 = new Team(player8, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2, team3, team4, team5, team6, team7, team8); + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 1, 1, 1, 1, 1, 1, 1); + + var player1NewRating = newRatings[player1]; + AssertRating(25.000, 4.592, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(25.000, 4.583, player2NewRating); + + var player3NewRating = newRatings[player3]; + AssertRating(25.000, 4.576, player3NewRating); + + var player4NewRating = newRatings[player4]; + AssertRating(25.000, 4.573, player4NewRating); + + var player5NewRating = newRatings[player5]; + AssertRating(25.000, 4.573, player5NewRating); + + var player6NewRating = newRatings[player6]; + AssertRating(25.000, 4.576, player6NewRating); + + var player7NewRating = newRatings[player7]; + AssertRating(25.000, 4.583, player7NewRating); + + var player8NewRating = newRatings[player8]; + AssertRating(25.000, 4.592, player8NewRating); + + AssertMatchQuality(0.004, calculator.CalculateMatchQuality(gameInfo, teams)); + } + + private static void EightTeamsOfOneUpset(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + var player5 = new Player(5); + var player6 = new Player(6); + var player7 = new Player(7); + var player8 = new Player(8); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, new Rating(10, 8)); + var team2 = new Team(player2, new Rating(15, 7)); + var team3 = new Team(player3, new Rating(20, 6)); + var team4 = new Team(player4, new Rating(25, 5)); + var team5 = new Team(player5, new Rating(30, 4)); + var team6 = new Team(player6, new Rating(35, 3)); + var team7 = new Team(player7, new Rating(40, 2)); + var team8 = new Team(player8, new Rating(45, 1)); + + var teams = Teams.Concat(team1, team2, team3, team4, team5, team6, team7, team8); + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3, 4, 5, 6, 7, 8); + + var player1NewRating = newRatings[player1]; + AssertRating(35.135, 4.506, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(32.585, 4.037, player2NewRating); + + var player3NewRating = newRatings[player3]; + AssertRating(31.329, 3.756, player3NewRating); + + var player4NewRating = newRatings[player4]; + AssertRating(30.984, 3.453, player4NewRating); + + var player5NewRating = newRatings[player5]; + AssertRating(31.751, 3.064, player5NewRating); + + var player6NewRating = newRatings[player6]; + AssertRating(34.051, 2.541, player6NewRating); + + var player7NewRating = newRatings[player7]; + AssertRating(38.263, 1.849, player7NewRating); + + var player8NewRating = newRatings[player8]; + AssertRating(44.118, 0.983, player8NewRating); + + AssertMatchQuality(0.000, calculator.CalculateMatchQuality(gameInfo,teams)); + } + + private static void SixteenTeamsOfOneNotDrawn(SkillCalculator calculator) + { + var player1 = new Player(1); + var player2 = new Player(2); + var player3 = new Player(3); + var player4 = new Player(4); + var player5 = new Player(5); + var player6 = new Player(6); + var player7 = new Player(7); + var player8 = new Player(8); + var player9 = new Player(9); + var player10 = new Player(10); + var player11 = new Player(11); + var player12 = new Player(12); + var player13 = new Player(13); + var player14 = new Player(14); + var player15 = new Player(15); + var player16 = new Player(16); + var gameInfo = GameInfo.DefaultGameInfo; + + var team1 = new Team(player1, gameInfo.DefaultRating); + var team2 = new Team(player2, gameInfo.DefaultRating); + var team3 = new Team(player3, gameInfo.DefaultRating); + var team4 = new Team(player4, gameInfo.DefaultRating); + var team5 = new Team(player5, gameInfo.DefaultRating); + var team6 = new Team(player6, gameInfo.DefaultRating); + var team7 = new Team(player7, gameInfo.DefaultRating); + var team8 = new Team(player8, gameInfo.DefaultRating); + var team9 = new Team(player9, gameInfo.DefaultRating); + var team10 = new Team(player10, gameInfo.DefaultRating); + var team11 = new Team(player11, gameInfo.DefaultRating); + var team12 = new Team(player12, gameInfo.DefaultRating); + var team13 = new Team(player13, gameInfo.DefaultRating); + var team14 = new Team(player14, gameInfo.DefaultRating); + var team15 = new Team(player15, gameInfo.DefaultRating); + var team16 = new Team(player16, gameInfo.DefaultRating); + + var newRatings = + calculator.CalculateNewRatings( + gameInfo, + Teams.Concat( + team1, team2, team3, team4, team5, + team6, team7, team8, team9, team10, + team11, team12, team13, team14, team15, + team16), + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + + var player1NewRating = newRatings[player1]; + AssertRating(40.53945776946920, 5.27581643889050, player1NewRating); + + var player2NewRating = newRatings[player2]; + AssertRating(36.80951229454210, 4.71121217610266, player2NewRating); + + var player3NewRating = newRatings[player3]; + AssertRating(34.34726355544460, 4.52440328139991, player3NewRating); + + var player4NewRating = newRatings[player4]; + AssertRating(32.33614722608720, 4.43258628279632, player4NewRating); + + var player5NewRating = newRatings[player5]; + AssertRating(30.55048814671730, 4.38010805034365, player5NewRating); + + var player6NewRating = newRatings[player6]; + AssertRating(28.89277312234790, 4.34859291776483, player6NewRating); + + var player7NewRating = newRatings[player7]; + AssertRating(27.30952161972210, 4.33037679041216, player7NewRating); + + var player8NewRating = newRatings[player8]; + AssertRating(25.76571046519540, 4.32197078088701, player8NewRating); + + var player9NewRating = newRatings[player9]; + AssertRating(24.23428953480470, 4.32197078088703, player9NewRating); + + var player10NewRating = newRatings[player10]; + AssertRating(22.69047838027800, 4.33037679041219, player10NewRating); + + var player11NewRating = newRatings[player11]; + AssertRating(21.10722687765220, 4.34859291776488, player11NewRating); + + var player12NewRating = newRatings[player12]; + AssertRating(19.44951185328290, 4.38010805034375, player12NewRating); + + var player13NewRating = newRatings[player13]; + AssertRating(17.66385277391300, 4.43258628279643, player13NewRating); + + var player14NewRating = newRatings[player14]; + AssertRating(15.65273644455550, 4.52440328139996, player14NewRating); + + var player15NewRating = newRatings[player15]; + AssertRating(13.19048770545810, 4.71121217610273, player15NewRating); + + var player16NewRating = newRatings[player16]; + AssertRating(9.46054223053080, 5.27581643889032, player16NewRating); + } + + //------------------------------------------------------------------------------ + // Partial Play Tests + //------------------------------------------------------------------------------ + + private static void OneOnTwoBalancedPartialPlay(SkillCalculator calculator) + { + var gameInfo = GameInfo.DefaultGameInfo; + + var p1 = new Player(1); + var team1 = new Team(p1, gameInfo.DefaultRating); + + var p2 = new Player(2, 0.0); + var p3 = new Player(3, 1.00); + + var team2 = new Team() + .AddPlayer(p2, gameInfo.DefaultRating) + .AddPlayer(p3, gameInfo.DefaultRating); + + var teams = Teams.Concat(team1, team2); + var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); + var matchQuality = calculator.CalculateMatchQuality(gameInfo, teams); + + } + + //------------------------------------------------------------------------------ + // Helpers + //------------------------------------------------------------------------------ + + private static void AssertRating(double expectedMean, double expectedStandardDeviation, Rating actual) + { + Assert.AreEqual(expectedMean, actual.Mean, ErrorTolerance); + Assert.AreEqual(expectedStandardDeviation, actual.StandardDeviation, ErrorTolerance); + } + + private static void AssertMatchQuality(double expectedMatchQuality, double actualMatchQuality) + { + Assert.AreEqual(expectedMatchQuality, actualMatchQuality, 0.0005); + } + } +} \ No newline at end of file diff --git a/UnitTests/TrueSkill/TwoPlayerTrueSkillCalculatorTest.cs b/UnitTests/TrueSkill/TwoPlayerTrueSkillCalculatorTest.cs new file mode 100644 index 0000000..89bd38c --- /dev/null +++ b/UnitTests/TrueSkill/TwoPlayerTrueSkillCalculatorTest.cs @@ -0,0 +1,20 @@ +using Moserware.Skills.TrueSkill; +using NUnit.Framework; + +namespace UnitTests.TrueSkill +{ + [TestFixture] + public class TwoPlayerTrueSkillCalculatorTest + { + [Test] + public void TwoPlayerTrueSkillCalculatorTests() + { + var calculator = new TwoPlayerTrueSkillCalculator(); + + // We only support two players + TrueSkillCalculatorTests.TestAllTwoPlayerScenarios(calculator); + + // TODO: Assert failures for larger teams + } + } +} \ No newline at end of file diff --git a/UnitTests/TrueSkill/TwoTeamTrueSkillCalculatorTest.cs b/UnitTests/TrueSkill/TwoTeamTrueSkillCalculatorTest.cs new file mode 100644 index 0000000..af334b5 --- /dev/null +++ b/UnitTests/TrueSkill/TwoTeamTrueSkillCalculatorTest.cs @@ -0,0 +1,19 @@ +using Moserware.Skills.TrueSkill; +using NUnit.Framework; + +namespace UnitTests.TrueSkill +{ + [TestFixture] + public class TwoTeamTrueSkillCalculatorTest + { + [Test] + public void TwoTeamTrueSkillCalculatorTests() + { + var calculator = new TwoTeamTrueSkillCalculator(); + + // This calculator supports up to two teams with many players each + TrueSkillCalculatorTests.TestAllTwoPlayerScenarios(calculator); + TrueSkillCalculatorTests.TestAllTwoTeamScenarios(calculator); + } + } +} \ No newline at end of file diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj new file mode 100644 index 0000000..ffde503 --- /dev/null +++ b/UnitTests/UnitTests.csproj @@ -0,0 +1,80 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {6F80946D-AC8B-4063-8588-96841C18BF0A} + Library + Properties + UnitTests + UnitTests + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + {15AD1345-984C-48ED-AF9A-2EAB44E5AA2B} + Skills + + + + + + + + \ No newline at end of file diff --git a/UnitTests/UnitTests.csproj.user b/UnitTests/UnitTests.csproj.user new file mode 100644 index 0000000..68c3597 --- /dev/null +++ b/UnitTests/UnitTests.csproj.user @@ -0,0 +1,9 @@ + + + Program + C:\Program Files (x86)\NUnit 2.5.2\bin\net-2.0\nunit.exe + + + UnitTests.dll + + \ No newline at end of file From 3d1a26a6e32187a94c51254852959507ad415ffa Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Thu, 18 Mar 2010 07:43:44 -0400 Subject: [PATCH 02/14] Added root README.txt --- README.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 README.txt diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..c7a875e --- /dev/null +++ b/README.txt @@ -0,0 +1,4 @@ +The code for the TrueSkill calculator is in the "Skills" folder and its unit +tests are in the "UnitTests" folder. + +For more details, see the "README" file in each of those folders. \ No newline at end of file From ddbae4b47ab597410076dcd4f5df14b89011f9ac Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Thu, 18 Mar 2010 09:12:57 -0400 Subject: [PATCH 03/14] Removed .suo file --- Skills.suo | Bin 64512 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Skills.suo diff --git a/Skills.suo b/Skills.suo deleted file mode 100644 index e468e1956d38ed06a520638028bb9842ac359d0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64512 zcmeHQ33MIBm2DY90!hqbaKIQ4#snu|MV4e)Hef8tk}YFnBgsn=4Z*e~TedbNc>}YA zVH>t#7{U@vNEovWIDu>g7%~YSvOvO^Y?BGIg_%Q!oH+?$I5|m9CidK0)upcPu3x`? zcYnzel+IK2@2=nPRn>d1UcGu%|K)v0|NL`bobsv{N%Or!y!{6b_YTwUm*AQp(ovo_ z0T+h=_8&NKK;HB`T)vaWPz(GCv>uAidoO@}{Vu?J0PhB%i@lQoM*!XjI2!PNz(l~2 zfMWnt0PO!s$j=2F2bc`_0N{AQ34nQk69H2JCj(9almb2oI2AAra2jAb;B-JOU^!q0 z;6s291I`4T1(*pa1AGKf4wwa~08|310J8zrfH{B~z+6Bb;B3G-fWrav0p|f006qa& z2B-%t1T+8|0gC{O0Zo7j3Kk?SKwICtw3$BVYiq39uQ^4d?;%0{Q^`fJ*>t0io80DP_hm&2(UZ|d`g&>szW?-1~jGWRqY9HU;w{(c zmn}{ACX`SvC@-$~OHh_F#-!@s0S*`f2X+8|7ka-}P$A3M{+9wj`F0Y(75@a3CCyBV zCrmkMq`Xl6sUN5Vbopl+@_W<+%#THGl7H$5%HC7}^@*+nPQ~YGfYSg<{>evY0A>K9 z@=rXv{PS}@`KPS29DzED^8X+Hz0V-8^RJcsvz(HDUMu6qO#mJTHD*5MqCI7tc^2<{G`B}+7ua*4sntV$6=QZV@`HRRY&C~(> zOkH!ie|;tLs{q?qKfh_tyqBAHow&NI*eKy@JGG78Wax!^G19kPv=X}f5W&* zK)&*PPTbU0Oi}!GprHdaY)1d}p$#}D+US@8{Y!l+Yww2tT`0c*z!b&L@sI7^54>HV zpx26>Hk7PCb+v2#4?|fs{zUPUQ+i>Ev;g-Ov_(E10R9rAU43aO(p*N+u7kW{i4~JnkSyCbk(MFvMcR>jS)hB0eh% zMZYhI8;D{byv*?qR~~^CphH4|4*KWW%rK zVhe>$uvUH{^1lq@ALsh4n=AfFDEqw6pd9BY5vq<-&vv558*rEQlX?WZ z)`WW|V7hwXz~TwRuF9I8*_^?ORN5`Bhd-47=NyL+w>JjBQAUnz-pA*PR^nNTe4q_Sn)Ce z2c+pi*dz2uPX|Q(1-b6ie{U*}+ag8ZQ_TDHr7i=DcZ;Ec-paLTO8PAOhu2o=g(1z1 z0;t0OET?*97_hbpFKK{xx$xfWSZg!K+6<=PiVmmN9hh*|VxZ*OQ$1?E5(>Bz6HyMR zTuG@z$#zf>w8DAA^o*wM`3~;UZ-FBEREEZ}4yV71np@edYTnOP$yBde{K(%42Tvh1V7W` z%QfQLwZeb868%6KYZdY%eai8BvUjrfUCZ}LtBdnXN^l!EL;A3}DBX>rmNHG7tXLeP z`|w=)L_}$YI%R&Ad@`aw?SrESq>LtO`;*6P+e?kuE*1pKAb|`|kgGM6&`QWD*Ix)T zA-@%n*a}?D!XH;o7)T&+o?|4PSf+jc{1&>~<^PX{zd zv07Kx9m&?i%EysD9~q8L-{u43sLkX4^<*n#w9L4sT+C56jV{{yw&*k6yBP0T(|U8U z`z=kMagH-yY}I&gP|jS|w)`H-Cg7nA1G|djEz}n!J#yJ~h?__5NSGjIZ=qafqPOfl zBI+tjW;q+v8~Pu!tZg$|KCLG(OM23B0)uE85m3Xxo(5r3)`@FQ9;KN{A-tB;V6*(|9<4T>vJ}qws_Ou`={D7 zZ+UL<7hidF-=qguAGy>UcwtHHhwk2V{v$vA>?fP|KgI9`>@RxxnK#$mFzxAvJ@bCD z{_fvxKS|!5_`;O#|2zD&<+mNU{`dR#?rxBG|NGd}fB5)mr!9K&wO21cV_gqL1gXWV z={$Dt{=FwJ-F;vC7w$Uwjk(3cB{Amze_<*2&lDasrY}V?GPVS;CiQ#F6Gv5x#R=YT z3T~6sUX;<>Y&5UP2!{&ClP&Qv?XC5~B}vx?ZBYq(FAb~BApKH!QDrj#q#F>a_&)DC0qxypux+b^W{5RhJy}> zNqt(gPx>N*FoZ>*XDxVXqoAk}*D63Ecp|40aurj&Ui^!$Tgo-V__}DW^-soob00|b zJqkngK3R}*6TP3SeDpqJ+|_O}Q~$&bLDfTilMLZljy~ib3c5218#KvVh&uxcX^tH7 zS1|u~;axSS$rna@-&O7vIa4A396K%qPzKd~TRsmDXZQu8`+r-&H`GB~Ic3Y_lfWeP zr`@3TUo{F#rd-%Mbc4@?T&8zUgYW=sLp*sH(y{C@Ub z(B45HyxuNtpi54}g1fxOAmLW%Oa=+F#BKOr=+4pLjnss0co+l}e9uO6NTIgI76Y4Y*GA;nLJo{dKS#14@SxQXJkY{Y9alCrGS?t*{LL z8CXrrTyeyr8|(IR#vRZVSRnBln(PC;_xL=m{UNQHL7aue@EM-tplE%1_Pt+a6lp+f z5V9<_a%XD%7hu#3&qCR1Luj`y_!JZ+TQ7RDiF<1UN~9EBT?G75X{Vl|%}$DV)`i-% zplG{g-v{QO7@|!divn4fu^*1%Bn-(m|ExsN zK)%HNugg&==+}JTkmq7?&l{5+Klae&NyL8w%1i~g*8eh;h6l4 z=fvFTzqYQvWktiJ&mXt+?q4l_{L^KREqv|KGiy%A`Db-4^*mQ1t#;5kS@L^7)ZrHEzZ5)3o*jfA@X?Vs9C$bWONx4A)VA*z6p!(bV=u?Bb)cHMc!zo*@>B4?Pwe1s z(`e?oI^1kQn`N8$7BynHCE5k$>SZP@)bXaYsBURf7Cob^sJPxHhPgnUw(rB5itVSo zaxIwU@Pwas(SvHdAl}Xl@R~-!z!sEqW;tf%vXt{%(`MT5&g-@Lt^q6iCD34Bl+wqPU;e)&I(NEYE-{y}srV zz9j=Jrn(1Xk3Q0x$4k@r5qv-BC!Uy@RGoW&ZW1HP4fA6@;?$BV!x6?`k;_AK>ylpAvS z;dDLzkqml8jU(shutSz)fWsuwdMleOC7y4_jb8Mq>1Bh~&w?kLFx%q}WS$|)F`Ra@ z9Lu@pp!7_Db4DhuA?Gx~Tjyu+R@IMkL{pU0GI8M~dS$16UG>YH5hUst47kGHSh>p?#RQc^5U6qlGd zZT7xDCxbRJ*Pb$CeiF1x7Ir}3^Rm};RR%SUw=QE#RQv#IoYguat%#Aao^^d2%sdNO zxhAbycnjqmd^0qu9ML!e1iX@kr^nQPx!1v1uhAM^s6|{>Z%Je8h;X*fCxOh#lihR8 zWCGa;`Z0@{HaUe}3$6qPZ)U7bT1!BUF)}yf$wF%>JUok=ak#n0umu^^$*hH`ttjPO zF9S%E$O*0_o=5Uec|fw9P(j*@Uoj73RjB!XENQ2v>y1I8Qgo{V~hYaQ^Ey2>p9ddrM1=f`_bQLocD8ZyBs z6}^RZdPZ|ZVSJ=cR~hz$aKzE+8;c_icNCiHRVH?;a7eqR3!ejVha!E}jMt%!L0chyPg-gHuuK?R)pP&1?z>TH3G<3o!P}>rv>B`WkA#|TStygWISdVhitw=O8B_kB8=hB_C+&s?vjvHnfoXzuk zRdBZIlj8MACA3HK-!~agXP)$m#T+^y)wbge=m~vuRXd(gLZSiJs+SH@Oy21D$f&c$pcNuZ$$f2e_l-Ka{RrN9Oso^jJ_K$ zzaJFtlR`(QgSU@r##JAgMxleZ?Wd37wpZJmIO^-$o3gi<)7f2RW44XsBRXv>Iex1x zT-mpF8hdKVcxmfgaR3~O^;Ljir6js;=y}yoT=p7g%xWK!2lI=fvKkYWd{H=;=9!;{ zce_fXLN`&`{5Yh-BbGg{?92at6L;PObVsLJYR)YctNfMST_K8Bg+6h;I{z;s?;McteruNmJyLueTgaJ;Y{OY@A{NaCw zUMv}Fd%1XuifJ!byfu`koc+U8=bNIPaWSR60$OU~w9f?FuvXR=gEV+Sb-GxOmI+AITutmKNvyNWOUxHHv+;`-&KhFSU z>CPj6EW6o$U7%Ak8ZiV4ztXg$Eom~QAy|5VfDCKXgIQYW>9EU{UX!sDrx=fa zQIU+~9VTkB@unf(iC)?!mgGy(A_5o&Rr-7RYzLr^&Y$wzkcy1kv>aIm`3BCHvmGeE-_GUljkZ5^1bz96`e%Ete=xlEk*pumpMRN~e@rJl zd0zX}m#z(;DVdCN`K^H>@=tUJmumZ-x8AkAxx^{r2+*xv$fnc>dstC~^{j zl3*__pMDbAHGV-G{wnNl$(NFxe@NWdIpOE7MSCKCo+vU6;9CFdQT7i1wf6eUQwsf} z#wph7e2Ad^H%M>|36(@B>nhn-&d$S`%3p*H)YbiL$y}1^B;H9+7tQj6cjlX z;L86uqb$#PWU}MuT8}*?;s0Cl%B%g?+VQ)cKU<1-O$WHv|F2NiP5-!^KdU(06+d;) zc0d*>{rG9;-}t^*&%1N(`6c`f9#!u&^=MBm|M3+Wxx%cUgZ(6tB)k*R8((>u2k@fopZS|jBfc-NA?{lsHE|eYe@n4h)|K&Q{%JVL`@|7uJj`I=w zS!)LPyI}#ybLG`2*L%e?Kbisz>=pZL^WseL$4^@HykD;V;|aOvEBtkm!cY6e8rAZ) z_z~Sz5d0qe;x$hO9gh)kuJ7`Q4#5WKf)A` zrR4a^u3Nh7mUMdkLHyzKYCP|I1Cpu6y*R-|^RIqZF-3 z+5UF^bF+WX1YI+I+K}Z<52Hl8U&@ZZIQH+~0{0V6_}%Ouo|>fk#(%9f+k>YM`6cZ2 zFOL25IBj_8l8Wk;^EN$h*LsS2&l{cJuX2g( z=P$x~-jUmzo8N~#7dI8>_XG7-HMPI}6j;c>ODFxz&Nr$D9w`d{2YW0?z4GDE!qa(= zzf$3Px|`?y;)PpZIy}}BcKzcv|KS;>v=rILs$Fb3b|a%PSNwkm+&}m6kHqgUsu3pn8StL>o1a~`+BA#$ z{s_pQqCc0cW%X+@o_FYL|NClwpS9n0B1=2|+U3t}{=-tV6kYl68z}2ye^ui|vwTVU ze`zVY;@^w1F7wZ7&&mE0c$Ez1qnFRW1-Q*GXm5Wv{Yx!z1i-ca-$mIgeEeqnB|QGb zEgXG(4OYg3Zz)UWh*QtqqpvpjNVP1<`nM_mJnn_H?XvN_t-HG>s5WzLH;wG!%bf}I zkBR zp2xWD^wAS$ONJt-KT#tXS2~Lqu|hv$lJQ9Q2}H*?GIF>sCVvQRIF}RcrJb2J<}6H4 zU_X*Fx0oZYxD-)@Fr@N{6(c--nY@Cmy5e$ zMm8ddzT5OM+;OeN-M0fUnzrFwo8XvCr61^9Poi7%k92_!;AoPK=bXR8v?qZUDU{kK ztV7es&-G~jY8hv?jBPdhO`Bl-a1Zc+_A5uKeHr&Mk~8}T;2TQNLMA<{Mjw|mOFVA@ zFlTp$l>3OMTAH!1QVB(npP zjG6Rx`qO!^ZVDQAC(r}oRxne?^Q(HrL|kgesH_(9JGU|_Fg>4`?NHM^M)l$hv{3q4 ztJ0CtHZc8CmFJZLXRf+7;@Rl!p_>luw-t$B3irLLKH>^o+PEs}f^b|7*Rs<44jB2e z9&hGv$nY12hR}PAaj^QS{ux z=&yRlOPIBCyid*ph3R#19KXp!qWIug;7so!4cf?ti)-TP>u2Aeqhv$Xk8#jR)^vj! zar89zVDw3JPxI-(y)yyFnPe>4dhEhXYM%@@qcF0Y37KbKHg1~){JE@*K8#XaXiRgO zKnupbjnHUZpy?K4pNuf%N^cU6w5ivXR#Phv^0TSdQQcY#DsIn+_mZ!}D5`?BaIPIc zn}DvcJjQigR0}ITKz~H?IH^H{FN2Y=*A%4&@miVnj?!(6@lNk6GvlCcGoN?xL10ZX z@5|qVIwiy(olUq$`OX84X(JKrks!3@bsmfNor{!y0CX1X#BRpn6vy7l*H5m|@Qh|l zvPP7ilk^%WX<{sL5{;Rjn!tuP(Z!g%^cGrNhwJfZstt}#*aoJtD=rZx>)9qH!KlF# zJ=UexxoR|(IelBveO6O}hg252J{RQyIny@nzT{4p^ee@xCT9Q2slc%_buAQ*_w@E-X)AB^Uu(zD7z}%2{C5+IaBOpp<7E$C?Z4KBKY#Q&eXE7npFY>!4*2uwD4Pdh4 zFV6m(X5e+(|077W{saG&u->%5UF*LRWncE+YOlZB{wK;aR}Ee9e-vfE31G70cawkO zRY|_p{=W^6zvLIO;m^POBANVu0=RcM;Lk7p0)NSIco%({YyQ9}T zFOmPKPwN1#_&ZSc8vn&M{1rIcJYS;z;R*wzL0$24?CJMkY{NgRfc;0r&E&ttT2Zv0np{kH-4Lr(ae#{Yuxe;>GA^lydR z_%Fsk+7zzszYk@fbgF-T4NU%9hIdUV0RInB_E{(VZt~B1pI-p}pP=mRKK_yLy8Yp; zr)SU)O*)x;)FMj~1!$VZnY^&eLrS{JXyXs_u`{B6ri)IYLi!)>d#bFOQf z{>d->$?Tth1~D%BC%^SC?Vlxh-wHsKw{q3_vv{!6e`u?JMXncU_mj;3{uSTn7@Sp7 zeeYU-9d8m3tV#ajUX(0+_?Ef|O>FbQPKoHPd6Rza8<^u;7Pw+~3 z3#q1OHg3sODt^CQ?0oj`aHm+XCoH;e>~aXoIXHBrPlUSAecOkSg88_syI|!$#Bv;h zQ3pp%t@vMox7NaeF$YHcOgw4C&zm;lYA){8<9a4?8u%4>#=knRT0oUYoH$Sf(#QJT i<4_;5``xdP%w8;H51iN=m!u8i9a)@~;QrVmrT+&C7M=wF From 76c130bf438d4094cb8ea45606714a98fd8d9ef7 Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Thu, 18 Mar 2010 18:28:24 -0400 Subject: [PATCH 04/14] Fixed .SLN so that Release builds correctly. Thanks to Jacob Carpenter for noticing it --- Skills.sln | 1 - Skills/bin/Release/Moserware.Skills.dll | Bin 0 -> 58368 bytes Skills/bin/Release/Moserware.Skills.pdb | Bin 0 -> 196096 bytes 3 files changed, 1 deletion(-) create mode 100644 Skills/bin/Release/Moserware.Skills.dll create mode 100644 Skills/bin/Release/Moserware.Skills.pdb diff --git a/Skills.sln b/Skills.sln index 7e5e0f9..575703b 100644 --- a/Skills.sln +++ b/Skills.sln @@ -18,7 +18,6 @@ Global {6F80946D-AC8B-4063-8588-96841C18BF0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6F80946D-AC8B-4063-8588-96841C18BF0A}.Debug|Any CPU.Build.0 = Debug|Any CPU {6F80946D-AC8B-4063-8588-96841C18BF0A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6F80946D-AC8B-4063-8588-96841C18BF0A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Skills/bin/Release/Moserware.Skills.dll b/Skills/bin/Release/Moserware.Skills.dll new file mode 100644 index 0000000000000000000000000000000000000000..9b960f148d21a471c8122fb498203d5ded91be78 GIT binary patch literal 58368 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 z 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 Y2O9W510QJM0}Xtjfe$qBpQnNU3y@7Hx&QzG literal 0 HcmV?d00001 From e01f7d16209f0e4dd126ede6eb60694fd1b9d594 Mon Sep 17 00:00:00 2001 From: Daniel Lee Harple Date: Fri, 19 Mar 2010 05:04:40 -0400 Subject: [PATCH 05/14] Always make internals visible to UnitTests, so tests can be run in non-debug builds. --- Skills/Properties/AssemblyInfo.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Skills/Properties/AssemblyInfo.cs b/Skills/Properties/AssemblyInfo.cs index 8d32e79..5f3b598 100644 --- a/Skills/Properties/AssemblyInfo.cs +++ b/Skills/Properties/AssemblyInfo.cs @@ -38,8 +38,4 @@ using System.Runtime.InteropServices; [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] - -#if DEBUG - [assembly: InternalsVisibleTo("UnitTests")] -#endif \ No newline at end of file From 62fd3194d0630a51e11c7daee81ecbe7c337e3b1 Mon Sep 17 00:00:00 2001 From: Daniel Lee Harple Date: Fri, 19 Mar 2010 05:06:37 -0400 Subject: [PATCH 06/14] Added basic cmake build system --- CMakeLists.txt | 79 +++++ cmake/modules/CMakeCSharpCompiler.cmake.in | 7 + cmake/modules/CMakeCSharpInformation.cmake | 321 ++++++++++++++++++ .../CMakeDetermineCSharpCompiler.cmake | 85 +++++ cmake/modules/FindMono.cmake | 36 ++ 5 files changed, 528 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/modules/CMakeCSharpCompiler.cmake.in create mode 100644 cmake/modules/CMakeCSharpInformation.cmake create mode 100644 cmake/modules/CMakeDetermineCSharpCompiler.cmake create mode 100644 cmake/modules/FindMono.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..419d94d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,79 @@ +cmake_minimum_required(VERSION 2.6) +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules) +enable_language(CSharp) + +csharp_add_library(Moserware.Skills + Skills/Elo/DuellingEloCalculator.cs + Skills/Elo/EloRating.cs + Skills/Elo/FideEloCalculator.cs + Skills/Elo/FideKFactor.cs + Skills/Elo/GaussianEloCalculator.cs + Skills/Elo/GaussianKFactor.cs + Skills/Elo/KFactor.cs + Skills/Elo/TwoPlayerEloCalculator.cs + Skills/FactorGraphs/Factor.cs + Skills/FactorGraphs/FactorGraph.cs + Skills/FactorGraphs/FactorGraphLayer.cs + Skills/FactorGraphs/FactorList.cs + Skills/FactorGraphs/Message.cs + Skills/FactorGraphs/Schedule.cs + Skills/FactorGraphs/Variable.cs + Skills/FactorGraphs/VariableFactory.cs + Skills/GameInfo.cs + Skills/Guard.cs + Skills/ISupportPartialPlay.cs + Skills/ISupportPartialUpdate.cs + Skills/Numerics/GaussianDistribution.cs + Skills/Numerics/Matrix.cs + Skills/Numerics/Range.cs + Skills/PairwiseComparison.cs + Skills/PartialPlay.cs + Skills/Player.cs + Skills/PlayersRange.cs + Skills/Properties/AssemblyInfo.cs + Skills/RankSorter.cs + Skills/Rating.cs + Skills/SkillCalculator.cs + Skills/Team.cs + Skills/TeamsRange.cs + Skills/TrueSkill/DrawMargin.cs + Skills/TrueSkill/FactorGraphTrueSkillCalculator.cs + Skills/TrueSkill/TrueSkillFactorGraph.cs + Skills/TrueSkill/TruncatedGaussianCorrectionFunctions.cs + Skills/TrueSkill/TwoTeamTrueSkillCalculator.cs + Skills/TrueSkill/TwoPlayerTrueSkillCalculator.cs + Skills/TrueSkill/Factors/GaussianFactor.cs + Skills/TrueSkill/Factors/GaussianGreaterThanFactor.cs + Skills/TrueSkill/Factors/GaussianLikelihoodFactor.cs + Skills/TrueSkill/Factors/GaussianPriorFactor.cs + Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs + Skills/TrueSkill/Factors/GaussianWithinFactor.cs + Skills/TrueSkill/Layers/IteratedTeamDifferencesInnerLayer.cs + Skills/TrueSkill/Layers/PlayerPerformancesToTeamPerformancesLayer.cs + Skills/TrueSkill/Layers/PlayerPriorValuesToSkillsLayer.cs + Skills/TrueSkill/Layers/PlayerSkillsToPerformancesLayer.cs + Skills/TrueSkill/Layers/TeamDifferencesComparisonLayer.cs + Skills/TrueSkill/Layers/TeamPerformancesToTeamPerformanceDifferencesLayer.cs + Skills/TrueSkill/Layers/TrueSkillFactorGraphLayer.cs + Skills/TrueSkillCalculator.cs +) + +# find_program(NUNIT_CONSOLE nunit-console) + +csharp_add_library(UnitTests + UnitTests/Elo/GaussianEloCalculatorTest.cs + UnitTests/Elo/DuellingEloTest.cs + UnitTests/Elo/EloAssert.cs + UnitTests/Elo/FideEloCalculatorTest.cs + UnitTests/Numerics/MatrixTests.cs + UnitTests/Numerics/GaussianDistributionTests.cs + UnitTests/Properties/AssemblyInfo.cs + UnitTests/RankSorterTest.cs + UnitTests/TrueSkill/DrawMarginTest.cs + UnitTests/TrueSkill/FactorGraphTrueSkillCalculatorTests.cs + UnitTests/TrueSkill/TrueSkillCalculatorTests.cs + UnitTests/TrueSkill/TwoPlayerTrueSkillCalculatorTest.cs + UnitTests/TrueSkill/TwoTeamTrueSkillCalculatorTest.cs + REFERENCES Moserware.Skills nunit.framework +) +add_dependencies(UnitTests Moserware.Skills) diff --git a/cmake/modules/CMakeCSharpCompiler.cmake.in b/cmake/modules/CMakeCSharpCompiler.cmake.in new file mode 100644 index 0000000..7d17148 --- /dev/null +++ b/cmake/modules/CMakeCSharpCompiler.cmake.in @@ -0,0 +1,7 @@ +set(CMAKE_CSharp_COMPILER "@CMAKE_CSharp_COMPILER@") +set(CMAKE_CSharp_COMPILER_LOADED @CMAKE_CSharp_COMPILER_LOADED@) +set(GAC_DIR @GAC_DIR@) + +set(_csc_default_lib_path @_csc_default_lib_path@ CACHE INTERNAL "") + +set(CMAKE_CSharp_COMPILER_ENV_VAR "CSC") diff --git a/cmake/modules/CMakeCSharpInformation.cmake b/cmake/modules/CMakeCSharpInformation.cmake new file mode 100644 index 0000000..ecb6585 --- /dev/null +++ b/cmake/modules/CMakeCSharpInformation.cmake @@ -0,0 +1,321 @@ +# copyright (c) 2007, 2009 Arno Rehn arno@arnorehn.de +# copyright (c) 2008 Helio castro helio@kde.org +# +# Redistribution and use is allowed according to the terms of the GPL license. + +# This file adds support for the C# language to cmake. +# +# It adds the following functions: +# +# csharp_add_executable ( [UNSAFE] [WINEXE] [REFERENCES ] +# [COMPILE_FLAGS ] +# [COMPILE_DEFINITIONS ] ) +# +# csharp_add_library ( [UNSAFE] [REFERENCES ] +# [COMPILE_FLAGS ] +# [COMPILE_DEFINITIONS ] ) +# +# install_assembly ( DESTINATION +# [PACKAGE ] ) +# The assembly destination directory is only used if we compile with Visual C# and thus can't use gacutil. +# If a package is specified and a file called .pc.cmake exists in the current source directory, +# this function will configure the template file. All occurences of @assembly@ will be replaced with +# the path to the assembly. The resulting .pc file will be installed to +# /lib/pkgconfig/ . If you want to have a different basename for the template file, +# set the 'pkg-config_template_basename' property of the target with set_property. +# +# Example: +# ------------------------------ +# cmake code: +# ------------------------------ +# csharp_add_library(foo foo.cs) +# install_assembly(foo DESTINATION lib) +# +# ------------------------------ +# contents of foo.pc.cmake file: +# ------------------------------ +# Name: Foo +# Description: Foo library +# Version: 1.0 +# Libs: -r:@assembly@ + +# ----- support macros ----- +macro(GET_LIBRARY_OUTPUT_DIR var) + if (NOT LIBRARY_OUTPUT_PATH) + set(${var} ${CMAKE_CURRENT_BINARY_DIR}) + else (NOT LIBRARY_OUTPUT_PATH) + set(${var} ${LIBRARY_OUTPUT_PATH}) + endif (NOT LIBRARY_OUTPUT_PATH) +endmacro(GET_LIBRARY_OUTPUT_DIR) + +macro(GET_EXECUTABLE_OUTPUT_DIR var) + if (NOT EXECUTABLE_OUTPUT_PATH) + set(${var} ${CMAKE_CURRENT_BINARY_DIR}) + else (NOT EXECUTABLE_OUTPUT_PATH) + set(${var} ${EXECUTABLE_OUTPUT_PATH}) + endif (NOT EXECUTABLE_OUTPUT_PATH) +endmacro(GET_EXECUTABLE_OUTPUT_DIR) + +# This does just not always work... why?! +# macro(MAKE_PROPER_FILE_LIST var) +# foreach(file ${ARGN}) +# if (IS_ABSOLUTE "${file}") +# file(GLOB globbed "${file}") +# else (IS_ABSOLUTE "${file}") +# file(GLOB globbed "${CMAKE_CURRENT_SOURCE_DIR}/${file}") +# endif (IS_ABSOLUTE "${file}") +# +# foreach (glob ${globbed}) +# file(TO_NATIVE_PATH "${glob}" native) +# list(APPEND proper_file_list "${native}") +# endforeach (glob ${globbed}) +# endforeach(file ${ARGN}) +# endmacro(MAKE_PROPER_FILE_LIST) + +# ----- actual functions ----- + +# ----- add an executable ----- +function(csharp_add_executable target) + set(current "s") + set(dotnet_target "exe") + + foreach (arg ${ARGN}) + file(TO_NATIVE_PATH ${arg} native_path) + + if (arg STREQUAL "UNSAFE") + set (unsafe "/unsafe") + elseif (arg STREQUAL "WINEXE") + set (dotnet_target "winexe") + elseif (arg STREQUAL "REFERENCES") + set (current "r") + elseif (arg STREQUAL "COMPILE_FLAGS") + set (current "flags") + elseif (arg STREQUAL "COMPILE_DEFINITIONS") + set (current "defs") + else (arg STREQUAL "UNSAFE") + if (current STREQUAL "s") + # source file + list(APPEND sources ${native_path}) + elseif (current STREQUAL "r") + # reference + if (TARGET ${arg}) + # this is an existing target - get the target assembly + get_property(prop TARGET ${arg} PROPERTY _assembly) + list(APPEND references "/r:${prop}") + list(APPEND deps ${arg}) + else (TARGET ${arg}) + # something different (e.g. assembly name in the gac) + list(APPEND references "/r:${native_path}") + endif (TARGET ${arg}) + elseif (current STREQUAL "flags") + list(APPEND _csc_opts "${arg}") + elseif (current STREQUAL "defs") + list(APPEND _csc_opts "/define:${arg}") + endif (current STREQUAL "s") + endif (arg STREQUAL "UNSAFE") + endforeach (arg ${ARGN}) + + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + list(APPEND _csc_opts "/define:DEBUG") + list(APPEND _csc_opts "/debug") + endif (CMAKE_BUILD_TYPE STREQUAL "Debug") + + get_executable_output_dir(outdir) + if (NOT IS_ABSOLUTE "${outdir}") + message(FATAL_ERROR "Directory \"${outdir}\" is not an absolute path!") + endif (NOT IS_ABSOLUTE "${outdir}") + + file(RELATIVE_PATH relative_path "${CMAKE_BINARY_DIR}" "${outdir}/${target}.exe") + file(TO_NATIVE_PATH "${outdir}/${target}" native_target) + + # inlined - this doesn't work as a macro :( + foreach(file ${sources}) + file(TO_CMAKE_PATH "${file}" cmake_file) + + if (IS_ABSOLUTE "${cmake_file}") + file(GLOB globbed "${cmake_file}") + else (IS_ABSOLUTE "${cmake_file}") + file(GLOB globbed "${CMAKE_CURRENT_SOURCE_DIR}/${cmake_file}") + endif (IS_ABSOLUTE "${cmake_file}") + + foreach (glob ${globbed}) + file(TO_CMAKE_PATH "${glob}" cmake_path) + list(APPEND cmake_file_list "${cmake_path}") + endforeach (glob ${globbed}) + if (NOT globbed) + list(APPEND cmake_file_list "${cmake_file}") + endif (NOT globbed) + list(APPEND compiler_file_list ${file}) + endforeach(file ${sources}) + + get_directory_property(compile_definitions COMPILE_DEFINITIONS) + foreach (def ${compile_definitions}) + # macros with values aren't supported by C# + if (NOT def MATCHES ".*=.*") + list(APPEND _csc_opts "/define:${def}") + endif (NOT def MATCHES ".*=.*") + endforeach (def ${compile_definitions}) + + get_directory_property(link_dirs LINK_DIRECTORIES) + foreach (dir ${link_dirs}) + list(APPEND _csc_opts "/lib:${dir}") + endforeach (dir ${link_dirs}) + + add_custom_command(OUTPUT "${outdir}/${target}.stubexe" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${outdir}" # create the output dir + COMMAND "${CMAKE_CSharp_COMPILER}" /nologo /target:${dotnet_target} "/out:${native_target}.exe" # build the executable + ${_csc_opts} ${unsafe} ${references} ${compiler_file_list} + COMMAND "${CMAKE_COMMAND}" -E touch "${outdir}/${target}.stubexe" # create the stub so that DEPENDS will work + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" # working directory is the source directory, so we don't have to care about relative paths + DEPENDS ${cmake_file_list} + COMMENT "Building ${relative_path}" VERBATIM) # nice comment + add_custom_target(${target} ALL DEPENDS "${outdir}/${target}.stubexe" SOURCES ${cmake_file_list}) # create the actual target + if (deps) + add_dependencies(${target} ${deps}) + endif(deps) +endfunction(csharp_add_executable) + +# ----- add a library ----- +function(csharp_add_library target) + set(current "s") + + foreach (arg ${ARGN}) + file(TO_NATIVE_PATH ${arg} native_path) + + if (arg STREQUAL "UNSAFE") + set (unsafe "/unsafe") + elseif (arg STREQUAL "REFERENCES") + set (current "r") + elseif (arg STREQUAL "COMPILE_FLAGS") + set (current "flags") + elseif (arg STREQUAL "COMPILE_DEFINITIONS") + set (current "defs") + else (arg STREQUAL "UNSAFE") + if (current STREQUAL "s") + # source file + list(APPEND sources ${native_path}) + elseif (current STREQUAL "r") + # reference + if (TARGET ${arg}) + # this is an existing target - get the target assembly + get_property(prop TARGET ${arg} PROPERTY _assembly) + list(APPEND references "/r:${prop}") + list(APPEND deps ${arg}) + else (TARGET ${arg}) + # something different (e.g. assembly name in the gac) + list(APPEND references "/r:${native_path}") + endif (TARGET ${arg}) + elseif (current STREQUAL "flags") + list(APPEND _csc_opts "${arg}") + elseif (current STREQUAL "defs") + list(APPEND _csc_opts "/define:${arg}") + endif (current STREQUAL "s") + endif (arg STREQUAL "UNSAFE") + endforeach (arg ${ARGN}) + + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + list(APPEND _csc_opts "/define:DEBUG") + list(APPEND _csc_opts "/debug") + endif (CMAKE_BUILD_TYPE STREQUAL "Debug") + + get_library_output_dir(outdir) + if (NOT IS_ABSOLUTE "${outdir}") + message(FATAL_ERROR "Directory \"${outdir}\" is not an absolute path!") + endif (NOT IS_ABSOLUTE "${outdir}") + + file(RELATIVE_PATH relative_path "${CMAKE_BINARY_DIR}" "${outdir}/${target}.dll") + file(TO_NATIVE_PATH "${outdir}/${target}" native_target) + + # inlined - this doesn't work as a macro :( + foreach(file ${sources}) + file(TO_CMAKE_PATH "${file}" cmake_file) + + if (IS_ABSOLUTE "${cmake_file}") + file(GLOB globbed "${cmake_file}") + else (IS_ABSOLUTE "${cmake_file}") + file(GLOB globbed "${CMAKE_CURRENT_SOURCE_DIR}/${cmake_file}") + endif (IS_ABSOLUTE "${cmake_file}") + + foreach (glob ${globbed}) + file(TO_CMAKE_PATH "${glob}" cmake_path) + list(APPEND cmake_file_list "${cmake_path}") + endforeach (glob ${globbed}) + if (NOT globbed) + list(APPEND cmake_file_list "${cmake_file}") + endif (NOT globbed) + list(APPEND compiler_file_list ${file}) + endforeach(file ${sources}) + +# message("CMake File List for target ${target}: ${cmake_file_list}") + + get_directory_property(compile_definitions COMPILE_DEFINITIONS) + foreach (def ${compile_definitions}) + # macros with values aren't supported by C# + if (NOT def MATCHES ".*=.*") + list(APPEND _csc_opts "/define:${def}") + endif (NOT def MATCHES ".*=.*") + endforeach (def ${compile_definitions}) + + get_directory_property(link_dirs LINK_DIRECTORIES) + foreach (dir ${link_dirs}) + list(APPEND _csc_opts "/lib:${dir}") + endforeach (dir ${link_dirs}) + + add_custom_command(OUTPUT "${outdir}/${target}.dll" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${outdir}" # create the output dir + COMMAND "${CMAKE_CSharp_COMPILER}" /nologo /target:library "/out:${native_target}.dll" # build the executable + ${_csc_opts} ${unsafe} ${references} ${compiler_file_list} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" # working directory is the source directory, so we don't have to care about relative paths + DEPENDS ${cmake_file_list} + COMMENT "Building ${relative_path}" VERBATIM) # nice comment + add_custom_target(${target} ALL DEPENDS "${outdir}/${target}.dll" SOURCES ${cmake_file_list}) # create the actual target + set_property(TARGET ${target} PROPERTY _assembly "${native_target}.dll") + if (deps) + add_dependencies(${target} ${deps}) + endif(deps) +endfunction(csharp_add_library) + +# ----- install a library assembly ----- +function(install_assembly target DESTINATION destination_dir) + # retrieve the absolute path of the generated assembly + get_property(filename TARGET ${target} PROPERTY _assembly) + get_property(pc_file TARGET ${target} PROPERTY pkg-config_template_basename) + if (NOT pc_file) + set (pc_file ${target}) + endif (NOT pc_file) + + if (NOT filename) + message(FATAL_ERROR "Couldn't retrieve the assembly filename for target ${target}! Are you sure the target is a .NET library assembly?") + endif (NOT filename) + + if (NOT MONO_FOUND) + install(FILES "${filename}" DESTINATION ${destination_dir}) + if (EXISTS "${filename}.config") + install(FILES "${filename}.config" DESTINATION ${destination_dir}) + endif (EXISTS "${filename}.config") + return() + endif (NOT MONO_FOUND) + + if (ARGV3 STREQUAL "PACKAGE" AND ARGV4) + set (package_option "-package ${ARGV4}") + + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${pc_file}.pc.cmake") + set(assembly "${GAC_DIR}/${ARGV4}/${target}.dll") + configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/${pc_file}.pc.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${pc_file}.pc") + + if (NOT LIB_INSTALL_DIR) + set (LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib) + endif (NOT LIB_INSTALL_DIR) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${pc_file}.pc" DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + endif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${pc_file}.pc.cmake") + + endif (ARGV3 STREQUAL "PACKAGE" AND ARGV4) + + # So we have the mono runtime and we can use gacutil (it has the -root option, which the MS version doesn't have). + install(CODE "execute_process(COMMAND ${GACUTIL_EXECUTABLE} -i ${filename} ${package_option} -root ${CMAKE_CURRENT_BINARY_DIR}/tmp_gac)") + file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/tmp_gac/mono) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tmp_gac/mono) + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tmp_gac/mono/ DESTINATION ${GAC_DIR} ) +endfunction(install_assembly) + +set(CMAKE_CSharp_INFORMATION_LOADED 1) diff --git a/cmake/modules/CMakeDetermineCSharpCompiler.cmake b/cmake/modules/CMakeDetermineCSharpCompiler.cmake new file mode 100644 index 0000000..b0fdd61 --- /dev/null +++ b/cmake/modules/CMakeDetermineCSharpCompiler.cmake @@ -0,0 +1,85 @@ +# copyright (c) 2007, 2009 Arno Rehn arno@arnorehn.de +# copyright (c) 2008 Helio castro helio@kde.org +# +# Redistribution and use is allowed according to the terms of the GPL license. + +# determine the compiler to use for C# programs +# NOTE, a generator may set CMAKE_CSharp_COMPILER before +# loading this file to force a compiler. + +if(NOT CMAKE_CSharp_COMPILER) + # prefer the environment variable CSC + if($ENV{CSC} MATCHES ".+") + if (EXISTS $ENV{CSC}) + message(STATUS "Found compiler set in environment variable CSC: $ENV{CSC}.") + set(CMAKE_CSharp_COMPILER $ENV{CSC}) + else (EXISTS $ENV{CSC}) + message(SEND_ERROR "Could not find compiler set in environment variable CSC:\n$ENV{CSC}.") + endif (EXISTS $ENV{CSC}) + endif($ENV{CSC} MATCHES ".+") + + # if no compiler has been specified yet, then look for one + if (NOT CMAKE_CSharp_COMPILER) + find_package(Mono) + set (CMAKE_CSharp_COMPILER "${GMCS_EXECUTABLE}") + + # still not found, try csc.exe + if (NOT CMAKE_CSharp_COMPILER) + get_filename_component(dotnet_path "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\.NETFramework;InstallRoot]" PATH) + find_program(CMAKE_CSharp_COMPILER NAMES csc PATHS "${dotnet_path}/Framework/v2.0.50727") + file(TO_NATIVE_PATH "${dotnet_path}/Framework/v2.0.50727" native_path) + message(STATUS "Looking for csc: ${CMAKE_CSharp_COMPILER}") + + # give up + if (NOT CMAKE_CSharp_COMPILER) + message (STATUS "Couldn't find a valid C# compiler. Set either CMake_CSharp_COMPILER or the CSC environment variable to a valid path.") + endif (NOT CMAKE_CSharp_COMPILER) + endif (NOT CMAKE_CSharp_COMPILER) + endif (NOT CMAKE_CSharp_COMPILER) + +endif(NOT CMAKE_CSharp_COMPILER) + +# now try to find the gac location +if (CMAKE_CSharp_COMPILER AND NOT GAC_DIR AND MONO_FOUND) + find_package(PkgConfig) + + if (PKG_CONFIG_FOUND) + pkg_search_module(MONO_CECIL mono-cecil) + if(MONO_CECIL_FOUND) + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} mono-cecil --variable=assemblies_dir OUTPUT_VARIABLE GAC_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) + endif(MONO_CECIL_FOUND) + + pkg_search_module(CECIL cecil) + if(CECIL_FOUND) + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} cecil --variable=assemblies_dir OUTPUT_VARIABLE GAC_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) + endif(CECIL_FOUND) + + if (NOT GAC_DIR) + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} mono --variable=libdir OUTPUT_VARIABLE MONO_LIB_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) + if (MONO_LIB_DIR) + set (GAC_DIR "${MONO_LIB_DIR}/mono") + message (STATUS "Could not find cecil, guessing GAC dir from mono prefix: ${GAC_DIR}") + endif (MONO_LIB_DIR) + endif (NOT GAC_DIR) + endif (PKG_CONFIG_FOUND) + + if (NOT GAC_DIR) + set (GAC_DIR "/usr/lib/mono") + message(STATUS "Could not find cecil or mono. Using default GAC dir: ${GAC_DIR}") + endif (NOT GAC_DIR) +endif (CMAKE_CSharp_COMPILER AND NOT GAC_DIR AND MONO_FOUND) + +# Create a cache entry so the user can modify this. +set(GAC_DIR "${GAC_DIR}" CACHE PATH "Location of the GAC") +message(STATUS "Using GAC dir: ${GAC_DIR}") + +mark_as_advanced(CMAKE_CSharp_COMPILER) + +if (CMAKE_CSharp_COMPILER) + set (CMAKE_CSharp_COMPILER_LOADED 1) +endif (CMAKE_CSharp_COMPILER) + +# configure variables set in this file for fast reload later on +configure_file(${CMAKE_SOURCE_DIR}/cmake/modules/CMakeCSharpCompiler.cmake.in + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCSharpCompiler.cmake IMMEDIATE @ONLY) +set(CMAKE_CSharp_COMPILER_ENV_VAR "CSC") diff --git a/cmake/modules/FindMono.cmake b/cmake/modules/FindMono.cmake new file mode 100644 index 0000000..7a87c09 --- /dev/null +++ b/cmake/modules/FindMono.cmake @@ -0,0 +1,36 @@ +# - Try to find the mono, mcs, gmcs and gacutil +# +# defines +# +# MONO_FOUND - system has mono, mcs, gmcs and gacutil +# MONO_PATH - where to find 'mono' +# GMCS_PATH - where to find 'gmcs' +# GACUTIL_PATH - where to find 'gacutil' +# +# copyright (c) 2007 Arno Rehn arno@arnorehn.de +# +# Redistribution and use is allowed according to the terms of the GPL license. + +FIND_PROGRAM (MONO_EXECUTABLE mono) +FIND_PROGRAM (GMCS_EXECUTABLE gmcs) +FIND_PROGRAM (GACUTIL_EXECUTABLE gacutil) + +SET (MONO_FOUND FALSE CACHE INTERNAL "") + +IF (MONO_EXECUTABLE AND GMCS_EXECUTABLE AND GACUTIL_EXECUTABLE) + SET (MONO_FOUND TRUE CACHE INTERNAL "") +ENDIF (MONO_EXECUTABLE AND GMCS_EXECUTABLE AND GACUTIL_EXECUTABLE) + +IF (NOT Mono_FIND_QUIETLY) + MESSAGE(STATUS "Path of mono: ${MONO_EXECUTABLE}") + MESSAGE(STATUS "Path of gmcs: ${GMCS_EXECUTABLE}") + MESSAGE(STATUS "Path of gacutil: ${GACUTIL_EXECUTABLE}") +ENDIF (NOT Mono_FIND_QUIETLY) + +IF (NOT MONO_FOUND) + IF (Mono_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find one or more of the following programs: mono, gmcs, gacutil") + ENDIF (Mono_FIND_REQUIRED) +ENDIF (NOT MONO_FOUND) + +MARK_AS_ADVANCED(MONO_EXECUTABLE GMCS_EXECUTABLE GACUTIL_EXECUTABLE) From a0ad1929eea7202066ab1ccdbec9ebddec07b7bd Mon Sep 17 00:00:00 2001 From: Daniel Lee Harple Date: Fri, 19 Mar 2010 05:08:58 -0400 Subject: [PATCH 07/14] Added ignores --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..18f2477 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +CMakeCache.txt +CMakeFiles +Makefile +Moserware.Skills.dll +UnitTests.dll +cmake_install.cmake +TestResult.xml From b37e76f100e5e48d83f15c2d650158acd432a03d Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Fri, 19 Mar 2010 09:44:54 -0400 Subject: [PATCH 08/14] Pulled dlh's changes and added a few more entries to .gitignore --- .gitignore | 17 +++++++++++++++-- Skills/bin/Debug/Moserware.Skills.dll | Bin 63488 -> 63488 bytes Skills/bin/Debug/Moserware.Skills.pdb | Bin 247296 -> 216576 bytes Skills/bin/Release/Moserware.Skills.dll | Bin 58368 -> 58368 bytes Skills/bin/Release/Moserware.Skills.pdb | Bin 196096 -> 196096 bytes 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 18f2477..73f6849 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,20 @@ +cmake_install.cmake CMakeCache.txt CMakeFiles Makefile Moserware.Skills.dll -UnitTests.dll -cmake_install.cmake TestResult.xml +UnitTests.dll + +bin +deploy +deploy/* +obj +*.suo +*.cache +*.tmp + +_Resharper.* + +*.resharper +*.resharper.user \ No newline at end of file diff --git a/Skills/bin/Debug/Moserware.Skills.dll b/Skills/bin/Debug/Moserware.Skills.dll index 27ce8d265830e42b2f4eb96d643cbc7e35ffd468..45ffcedbbcfce4012428ed2ef089148a2ca689f5 100644 GIT binary patch delta 130 zcmZqpz})bGc|r#>Q|;n~-3L`%UERzaO&ra1ja|%)bWJP_4RoC>T%2`{jSMW^+)NBj z-5gCeuRmzYBd~1Aw|7al0vt(-3L`%oLwv}jVz6HUCa%fbxm9?Ep;8u94&NR%p9G~Ov)azhU(VVn=mL%LW&i>vAPxs&4<1Gak9Q0V fLBTG;D_^}!R}<~=?X>qh7CR-^fO&K5yTzOUh(0Z9 diff --git a/Skills/bin/Debug/Moserware.Skills.pdb b/Skills/bin/Debug/Moserware.Skills.pdb index 5a376b1ec75ea39fbb07d83168f14e4100fc133b..7a90cc5a952d595edc459b9336e8ed4dc1e3ed96 100644 GIT binary patch delta 6491 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 delta 8458 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 diff --git a/Skills/bin/Release/Moserware.Skills.dll b/Skills/bin/Release/Moserware.Skills.dll index 9b960f148d21a471c8122fb498203d5ded91be78..5a279e34f353026248f6dacf8143788033e37b68 100644 GIT binary patch delta 13900 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 O&<^v+=X^u0{{H|YgJpmK diff --git a/Skills/bin/Release/Moserware.Skills.pdb b/Skills/bin/Release/Moserware.Skills.pdb index 4d4b070c63ef7c40e17ac6ee33757b34aed9ed12..6893d59750d7110579b88b662639d0d516d4d1f4 100644 GIT binary patch delta 2506 zcmZ`*ZBSHY6u#%YS3qP06s8pjNCm&L#h_v`l_V2IBR|F%DL+D!(qhd>v~t(XA{>=m z^+i!YG+6;zrd3|bQq(4i)L|NPnDT?vF%nHuM{(5boO@ZcAN|?A=j%DodCs{z>$uy) zakoc}?r)j#(e_l(G|m2Q`XsIFT+*kpBmQce7C*of;eUB$_oj&ab6H0k0ls+N>Pad% z=Z_OC&URObC$Xp+V6^9tErE!`BRw6(?+XffY-KMZ23w@97lb%%4Svps>Hts6j-EO> zJ?*X;RO3vmIL{>sl}3q?>Zz}uAt1pM_0>oMs2dc3)IQ7A1v~v zukatQ8_j}_T?8_39d~#0_Vj#v;+zpHZQiI8A(P02(-oX|+Rf?ZXFY--GtMve&!!a-wdhaj}dWgduxBff?9| zBs&l`LxQyWLa1^H=t*Tt`M`A=LRAL9;ck?uNSwEPDDayFh7cp=8wQzOWR)Wls##MN z_ZYk(m;&i7tNOzla>|w%2$3(xbQxt{rz(tve;D2vSyep_{*0}L!de!@^u9U_Xp+(D zNCJdYRJs$1XU9`ei{vCDn@ggeg=E^3${Y^9-C09nNq;$!lnaG9 z(fLqD&n5J%n)6{WO=B9C)i9Z}vOlMYV-0-F2B%3&0npKyS*Hr1FN=MD9i-AIGJ7>; z&sqRU~LXme!b-5ZU z*ieOEL8Nh5b+xdQvSuo~hIwqy+Xwsjbhy7W;EbP2Itbq|hdYNL3b;?i z_psE*D~hUWghn1>@iCav)wQJwF49XXkNg6PFzqM7&8KGl6+SaI=>17hCtBc;V9>$~ z@C3g(=53z32(he4+C7%66&eYPpH)XI_;WYW2EOzyXI>>|^c5J%PBJo$Lz;CJLR9nL zkk1%KO73-DNT<upDMq-fj4SZh%`A5$(2naHl6GXih$by8-wl6I5}5 zNHULB*+JMtC+hOU5d4|4(?W5k@y^kCena;BaI|{`sg1&77PllCQ~BiE`r-<>5*$UVSi`)DIdAji5Ys!c%oRa3HuqYnDw|wmtSl}f73#gg;4L^-1ci5!%wemPxF6VpuZh-!`(@NtTqyi{ z83KgK-CHqLGz9H=pjk{Y&J-yuP&vlPs$!fYa!nehrXxylzHpfp{p9fyqUj=7dnxvn zBT8|U$RZKR%F&Z}YDX!C%ih~?q9`Ox@<&MfHX1n5Yn`W|<8F)(zfE61rKi&b&q+oGM2>@J)u3QUkL zW&C8HU4)ivqIDkOF3c27W<`XIs-WTXNHFTwRpu)TEAUl4ngydvjh90ziA4$vSxN2c zNbReYxKMX=-BErO-Fh?m&sNc#DKx&jnijBRH%*pAq$%AhZ|FUyH zm1O1UHa?%|t@x-M<0i?{Sxz@52R}>yel!h@PyVpU^KKkqe^b-Ruy(pZTh#faX`oHj z;>q&uisd{MTc9!EgV>UXVso|U{}WsAP%K+ZAuFKM1E?)ht7>q`(Et61rXtSZg{Xf4 Dm1sY% delta 2430 zcmZ`*ZBUd|6y}`!$|5pC3B!jBkOF0 z8g~-~L<3x4cZUrwWhH8(M&>Y$I!qywI)qY*AEWDp+BxsbqJR3e_k2C)InOz}v(|wT z)`1ajEifXnwkj3;{QOR2=0p#i@|*v|z{ZbWsY%K9LOFeSqU&2gSfrqt;rda9?@nJHkZC${lt&a_o_gl$_#g))!k`ibq-TDl9_G3RkU5poL_4>lF~=&w%bI;?TPajxaNq1ycA<=?S(+@Ci=icpK|GCa>o4)GucT-j($j4mmySjT!CW7 z&{GPo@j?cT?(1-x=;#r7+{%eUboE&WjQpc!Ms z1tR%_2D$Z1jJNf7`paE5%n-eIn(uiMw&S~6NlTMnGEuf|$7eL}9Rp#t);@@3mg)<9 zUMpDBsOOpG+=(Bf7x!wWMLicU}{t3+%IvC=qDVqHfr_)qi>>|xq~1A3LA~A13QS6 zdvN?nnNUW}J7~J#8hlummysCVL%|1j5|@$)AJKd=MJs7@U?;vVLJl>{*j@OJ7Wa*z zM5Jukg{h)jHQgswIW84hElmucAnVKV4dJC>hQyswfw`j9s2D3xR1nklgUzz26356H zl{ib3P#3cD#k{-vBU+ByjV}r}L6SRK7VV~?(|y)?jvc!_n3-0EY2aX4vqcE$uIu~I z9zvZ)91OMD>ZcyMf;ab2dHP{}t{Ay&FO3^V(5}7IKZ}xrYw2KK{0dVw>(KU^$P^*Q z4jz>gs&TRCC>Ydwe>J`&lDM!2*Nc8qPM4vj245Cd7Nr*77L^eWSyYS5L{^l(NaN~A zm;f2MkI=jZ+Tbzn!yM6VR7A^I2MzBgz3$i3B<&7-O*}$+=|hdLBN7&tv5va6lh&8( zXlt8>PN}$_PQIV~XX`N^Er+GkiDTuO2AV62C{wms-e{oBSgEheiR0v3PP)4e(vYlt zQ9##2hY%y@xJWQ7i|N7?LH~i|6&FUze_R-C^7GTkVU}0i7(Q$=Jx#{*se8}a_n!0U W8KfsDyBpt{@W216RCE_!i2V<}ENO=T From 67cada345e94dc145eaa5b3d2722378a3d52567a Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Fri, 19 Mar 2010 09:57:12 -0400 Subject: [PATCH 09/14] Decided to add back building UnitTests in the .sln after accepting dlh's change to always make InternalsVisibleTo UnitTests dll. --- Skills.sln | 1 + Skills/bin/Debug/Moserware.Skills.dll | Bin 63488 -> 63488 bytes Skills/bin/Debug/Moserware.Skills.pdb | Bin 216576 -> 216576 bytes Skills/bin/Release/Moserware.Skills.dll | Bin 58368 -> 58368 bytes Skills/bin/Release/Moserware.Skills.pdb | Bin 196096 -> 196096 bytes 5 files changed, 1 insertion(+) diff --git a/Skills.sln b/Skills.sln index 575703b..7e5e0f9 100644 --- a/Skills.sln +++ b/Skills.sln @@ -18,6 +18,7 @@ Global {6F80946D-AC8B-4063-8588-96841C18BF0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6F80946D-AC8B-4063-8588-96841C18BF0A}.Debug|Any CPU.Build.0 = Debug|Any CPU {6F80946D-AC8B-4063-8588-96841C18BF0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F80946D-AC8B-4063-8588-96841C18BF0A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Skills/bin/Debug/Moserware.Skills.dll b/Skills/bin/Debug/Moserware.Skills.dll index 45ffcedbbcfce4012428ed2ef089148a2ca689f5..fe02208004603b4b46e17a2aec08cee042f680a1 100644 GIT binary patch delta 129 zcmZqpz})bGc|r%1L(|4C#)B#rM$V>Yj;=0^)EW_TXV;@Oa0- f5ESeZeEv$^Ifp=B-;FwZ50;#Bi`^XaZV4vh5+q)!N0goMbj5z;0#xL3Y<*bc@4pZ%7Zw4S>0^)EW_TXV;@Oa0- f5ESeZ{GMrT@}%Zq*S3~-7uj7z7H*Dtw}cY_o8v0@ diff --git a/Skills/bin/Debug/Moserware.Skills.pdb b/Skills/bin/Debug/Moserware.Skills.pdb index 7a90cc5a952d595edc459b9336e8ed4dc1e3ed96..940efc4f38315e022227f969b978ce1ceada4dcd 100644 GIT binary patch delta 3376 zcmZ`+eRPah8h@YXjm!u|m?0uZ5MRZTZHiP>2Ca{(6Kt1|pib*!k2tc6McX6eYd0s^ zC2O|5IUygVhpYx+$V~}}kCNhq-L=c^IuZ#ojWih%F)Cr7=e{!|{iFZnzR&0V{eJhk zcTVhkUbF9ctuP=c#I|MM4A3;~+Ko*Ww%Idh9vyM|?AnSc3!Py>_1n#nNB(?e<)zCY zf~V+_PFqHG5N3rq+y^br=-m|np$=2F6OVRulw=>~B`N11FCn@Apv76AyCs0qoylKK zL0l0cl1GBYadm$a$I1?j)XC>`AKXN3oU03T;L5d!xQ}z-;Xfc%8Wm-QT;Vu=RBiF` zF_mF)-T{blbUkWym{08Bn#>b(I#5SPS+(WZsUW}@%~4ijar7(6;p(!IW5!}}q@MPA zEROMK)TjMhi_?APuugn(&q>b9J7;kuo!`r!-7XaQJhv~f$7%m|0z!f!fFk3}dctLnj_(Egy{s+56ABL?MppKL$t0492nQY;QPqb4)rT7>Q~SY5 zcD~aeSRWOXod>`I(n2mD3??(FC25Gd@Tf@pDA=KMUbiSCKe;D0yA=gruu~b^-ZTu# zu!zXfaFVuuI2!nbjfCPc?2~K8LMNkVG}LwQor$zhfH~|IH)4$)QfJ&p{+cerNW2)acrz+SPG97qQW&U(%2=wn#Fbjr}(DLSN*y*1K@!7AT zg>%==g$gA8ljlPMXXP${u{5WGR;#RE2wCj><6_v#hu>)lEbgR+kEO6D8SFz=DJ-&l z6$JSYr0O=9r8^lWaedV9AdY5AZe0t#OtkL)6o&Kdl;xWskP^hT6u7C7+hGjio)B5J z1zvDP<#v!fh9WZ!n5axlhefYgT;Bmr9KEm;_H#5T1B|EO_%7uTi4J3YTOIK4Kt`^P z%9Uk!Q+LB&z)($G&n7;$Y$YEXd=2H=9N5I_%jUfbrF_1RP?AH<{?)@^7ViCOqUE*& zP{cf9{sx!0G~gf{n7~4)3BO%LP5j4}Uks>* zqu?7gSIbYrO)85$1qYb1>lE-)C~T()d47ojWBh3t!!RhxDpJoF&ahG#$If|WkjoXG zGUGb@^(-{`a`&85_fOT?&l`1?3lPMU5q=TU>F~wZm*5E3Czczd*ZDg`ro!)_A&3Gp z?*^pt4drQ-wwt_bsQmO6#QBtvG!%0Pij2Ag^B7WkC0ygm#41?E{_}UCrUN_jYoUQ# z$;>+MZOnfNJp-tuw9(*S)=0cRb3=pSvkLno1zT`H4sC*wya8ofMbcvxDQZ?a$e1Tk z%Xd)0jD8N)Os-EGe9h#_+vqybn)$-Gk?+4W$hN*zH}mu3$WMn{0XXv2JuV2uI#x<_ z#3-BCRY_U>pA@Ap78VeTH-!iBXx@tTRJlYha))xMa<7~;c? ztk!VMLUMdzLyIgJfT8}ME_r((PGR^FgYhNl7cm55sh{}hb>s(BTpvpnVZ-n;=Uf|$ zJw@Aa{0kGv7=eR1lblw0btG2s21b72Fa7yenGuD%yv0@-JsRiITPb$Fh0lqSs?8gR zZ@j8?jmL3xZAC;Z{*Um`jGKDVYMO^b)Nw}6M|$+B!va+A^M@aj8u1Clk9KcPK=nQs zCZc);X{94xs6-I`78%Zr1>~$>g#4o&#*zgXrAS-mSBQ9n!;uHU$WDe<6_^T z6s^QFJZGgzn9i@ujMcc0?Z#w`RS#z5dgNOrZ?8uh3!0yeSjl$YC%BAWMQPfEFZnr= z=B=3HzpJ8T8#b`FU^|vC&@aMhZw#yNU7VvwZzvQyYjL2%{UA_e z-^Bzye#41ZoE3+ODUTd5KJLQN4%iRZ^*o_Rlvchl)YpW1K#XTRvd{zGne^vEVvF z(XEdc;5xR733q87F4QwgrSOONTis)j4;62=ew7o7vhxnizR6@e-hi+F1A#g|C3l!yVz=NDOtf@51_V2 yroX`D-B8m+a~FLutum~uUKB(~P48&hTjI;!dN1kjty{YP?EgVBY=nNV|NjB{3d&vp delta 3298 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 diff --git a/Skills/bin/Release/Moserware.Skills.dll b/Skills/bin/Release/Moserware.Skills.dll index 5a279e34f353026248f6dacf8143788033e37b68..5e356be60f78277c43a7576087cb0211e6daace6 100644 GIT binary patch delta 126 zcmZoT!Q60yc|r%1PSeJ&ZR?c{4NP1uUCebYj7%JLP0Y-UbuFBoopjAi+?-uZ%?(@) z3@kS%Z!qN%xc-vG(5orgt><*gpQ{BAI5)4@qa&xI)3n%|0SK6YI1-58`~c!x3=BcR aF2S0<53c2R&Gz2o@KR`cbf3?<`dS delta 126 zcmZoT!Q60yc|r$MTj_v5m0CIn0Hp<_Ps0z-OVfZ=*a2B)h_mC00Jf;js)U2KY;ia14B@- aOK^QrL?FYWM-FXjw(nkt8LKb4%?SX!peSqr diff --git a/Skills/bin/Release/Moserware.Skills.pdb b/Skills/bin/Release/Moserware.Skills.pdb index 6893d59750d7110579b88b662639d0d516d4d1f4..9d35f8049e770678d0309318c4b50288f3c1c05e 100644 GIT binary patch delta 2394 zcmZ`*eN>cX7N2{cR|b(I_`wFqGH61X=44vyiA~2?QzMtMj#*Ubfs7NoJ9IXbZTAS~ zei(aFbJU9<9}X@I49rYT@la#Y$DSZckEc@}PMNal(J5;2>nLru?Y-~IQ2#9dy!YPc zKEM0Bzk46fR9~A^eQi?6NJyRcTuVOKY_>V8hmN~z>hlk~zMM)AfAmZ^BjM}6OiZph z-CNc-0Px~6XV|stiv+0ijQCQ*i|Ydb>EUw+k`R><9&OyDpf2q8u0SXy_f$ynl=sJb z`U8pKp+l1mC=HMJiui)3pyRaUFY-&inHYX6@VJ89u;b+qIM35Gn6g`c#s09~Hi0X+ z-$*jpt9rZM&Yv0YUy?dWN6rCzSC0lKjFk%?{`dxMVPCKM%pMuGJN$WVc#N@R<5#F5ub(#e!i{tobsW6wxXnQ&o$7t&6 zObCdG`j(lnQE_$FmpW&|4vx`KHcY4cvd0~7EU0U9;J=J*YN$KsL4pA5n_*{6SpDb% z;1<$#-y)d7hZJ1Q6i07^ZsZ_4Zn@#O1M+w5gjGgOJz1 z+yGm~DIO~U9$Tpnmx3dX!Gh^rJ^DL%PbdY;A&*yrE}wxs-Mybf)LM+DCK zcSxbE8t}5+#I_!+ft$Ds%Sn9!)<~B7c|NJ$0ndpeX_UGPctfnL6T4uR2>iot$mcG| z{Q_sN-va}Q%#TN_T?Zju+AH*eJ0|kKT44dB>1jUrg`noQLs0s<)(%S~p6iGDvHtYe z0q9^`)63wHCDPr{#wkS_oRYe;#~SPpufdbzKN*1t?}?Q5B%X}duD9WJDgWI&-~g$S z@lSX*ZhVmjU_jV!J^~NK3Jx8Ev-}3B?-S4rSalqNvR2Md;cqgt*lX7x55YT15NprC ze0~+yYMwX?Iif?s_aamj1{g_fJsO1sDW!(N&R;4T;b7J`utb9F6q{?aegvlL!3$6$ z7-mZ4B^kq*Gjth_Ga2)QJ{*NsMmMvze+%#N+@(}KlOFyazMG7>Hcz>Cy1tf(w=zHN zOv0rig*zE18BCo1G#x+UFC+5mO579~=z8!lCp_ZQZV1_49mq-n}ah=jV6DfHw z=1`^w*Wlt3+OZ$AJ?BrvQG*8yRdYv#cJ9a7W+ZzL{@w^>y=2~)PXl}KE+f0p9Twye~TSz%{k?{Fqz)nkM|qfH(RxHXh|I- zjWUv%-CKvNz-J0T+4WeUc5!z}ZFmDU*5g_jv`(fRU@~uw^Q>SOdrIid16YLJJ>+P> zrw!LkON2D)YQTJD%X;Z2Dm7w}s^$nIXH#b*mZ+%3z*6zfCM;7!4)ezKbhL>_%CJ?< zIE(IVMi*++sZch5M4}lq?I5mJ#~9G`st)3ERUY$B%UN~%SZ0Bjz4G)fYVzU+75_w7 zj7*x@f=ltnN^10?gSNIuY>61EiRX~PFqv*_W&->T%aE~@h3Mr4-b zi^Y<}Q(8M?MJ+5#sfKneR?VEq7c$7vfp?2iKfPtA+75hF4Ov^di01k&233A8b)GdI z@yoRQvCXRK#5F3Jxt!|c7P;|YfMx$f7x%P|`Es_Cu5|Ivgt#i7&7t1}(53o$e(Y7K zTeuJ}Kqf5@;!0_CXAtw0GHi4qh-viiAZFNYHiLiHIO#$NubZ%tO}k~@@uRuyM{^~c riDrVX4Pk4>RO9FW$+g+yIV^umZIOxkz9aZb^8fwCq%%(98OQ$sgtAo+ delta 2485 zcmZ`*e^gX;7Jv7?Cm?bJREmHYQh}3JW5MovA{8Zng0f+$M@%%d+{N9YT#DMZ8FSZl z>7=ZqUKC+)G#LSBIF0eOaQ)Sua9Q*gre%~9<}Z1T$A?JopP)11#NdqneI&flCh?X&(RIoZLq*iZj3vL~(P z^17~WfIrW)2lHz$$3l^Nz?T%9TJHy#6}-AP9x*RHIMn#84n;wScP>IAImSSeyYfto z`;0#>7&$LVY^>#8o?PH ze~CBPa-OP>=11z^u1lWyb60__8|MQf!s&v?-n%RjPcIo^Vt3JpEdu&5AlT+hL7nMJ zuRIscEpQfh-zOK@-_@Uu{1~{_X>hppb2~R6;o#sGzvQyq_Aj}WAwNTGUlsFFvfqtK zZ~PusqD4bP2zwxx?9q^ieF)BI*$|Gee zS33AbL^b6ucv9!=tS_}qgstqOP$rC{pJxsm-iTAxWx@ZL+tg6C-2<^gtnP(v5nw zq1EuxaEU!@fX9}og6qH*#bkjL&ffQHct=VKR6+r-1YQ4)WKbVeF_SeM)mIH)N=uhs zfMy}x@>{r%No8ij*@~L+mM23!9+>B3n{`7 z<5fnl+5z2hTpy2CAqYrcHxI#d@#nQdeYijM zsUKSSUD4}clO<9e(9DoB1$KdMJ8BK~yEow}v7hRMPTmtq?T)(`qw-I|Tax~p(_jP1 zk@i=3A!>M$x}jUDf9@PCjwB5Az{h+Csp}u0n9%t?1Z1u3|AIft%p$j4y%&Phx-iy# z1o!dvuvYWJ$B-pD6n`s1^+7i?$-5frgIGzW_d_&4sce9q8P{OCIN2yS*JjlKj8nb; zg&N^7A=TGq3}GYm1-#G2m=QWV1P7VjL~Z#B-r>1Rs(LQE|6BNGH0EmVO7A#zGY%i% z`jkB$XNVMz1RP~>;q>A-e3!w+NmwRVi?^|p&5BfXhPCLhVWWuZ$-qL{?*8$(No>bN zJi)V2e0#>qz7$Nx6QYE15Av0sr7G;0Cx0HIl{)rQJX)%|o(NL>PRypp?YI+*Opoi-BA zHA3?()-3v*aDhH`Z3oS$!_~%=!ib;CkD{JBoQWyzv~4%$(%juR8+)Fht-Eovo^0jM zrs;e5{1!fMVovPg+G;HcQYfNqeA{d)oz@=U-eZ_KZ~&h*2kT>f z7QV(ECa~P*)ZP%wm28SXiS9j!OZ8>UY?5^z#1ivZGj4>Q;k6>wjF0K-L=hkUN*`n@ zrw^Y*i)2`o7`o#SvsGJcmb>8)mg_y%fi$wU;2hCvSZbCsn(A6`g^?j*@xtcNS^4J=Vt+<6_K6A-^9d(Rx4T z>&tkC46QOMWpgqb@J^Z?z Date: Mon, 19 Apr 2010 07:39:24 -0400 Subject: [PATCH 10/14] Updated GaussianDistributionTests.cs based off feedback from nsp --- .../Numerics/GaussianDistributionTests.cs | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/UnitTests/Numerics/GaussianDistributionTests.cs b/UnitTests/Numerics/GaussianDistributionTests.cs index e0b0447..c1e3b12 100644 --- a/UnitTests/Numerics/GaussianDistributionTests.cs +++ b/UnitTests/Numerics/GaussianDistributionTests.cs @@ -9,6 +9,22 @@ namespace UnitTests.Numerics { private const double ErrorTolerance = 0.000001; + [Test] + public void CumulativeToTests() + { + // Verified with WolframAlpha + // (e.g. http://www.wolframalpha.com/input/?i=CDF%5BNormalDistribution%5B0%2C1%5D%2C+0.5%5D ) + Assert.AreEqual(0.691462, GaussianDistribution.CumulativeTo(0.5), ErrorTolerance); + } + + [Test] + public void AtTests() + { + // Verified with WolframAlpha + // (e.g. http://www.wolframalpha.com/input/?i=PDF%5BNormalDistribution%5B0%2C1%5D%2C+0.5%5D ) + Assert.AreEqual(0.352065, GaussianDistribution.At(0.5), ErrorTolerance); + } + [Test] public void MultiplicationTests() { @@ -56,13 +72,39 @@ namespace UnitTests.Numerics [Test] public void LogProductNormalizationTests() { - var m4s5 = new GaussianDistribution(4, 5); - var m6s7 = new GaussianDistribution(6, 7); + // Verified with Ralf Herbrich's F# implementation + var standardNormal = new GaussianDistribution(0, 1); + var lpn = GaussianDistribution.LogProductNormalization(standardNormal, standardNormal); + Assert.AreEqual(-1.2655121234846454, lpn, ErrorTolerance); - var product2 = m4s5 * m6s7; - var normConstant = 1.0 / (Math.Sqrt(2 * Math.PI) * product2.StandardDeviation); - var lpn = GaussianDistribution.LogProductNormalization(m4s5, m6s7); + var m1s2 = new GaussianDistribution(1, 2); + var m3s4 = new GaussianDistribution(3, 4); + var lpn2 = GaussianDistribution.LogProductNormalization(m1s2, m3s4); + Assert.AreEqual(-2.5168046699816684, lpn2, ErrorTolerance); + } + [Test] + public void LogRatioNormalizationTests() + { + // Verified with Ralf Herbrich's F# implementation + var m1s2 = new GaussianDistribution(1, 2); + var m3s4 = new GaussianDistribution(3, 4); + var lrn = GaussianDistribution.LogRatioNormalization(m1s2, m3s4); + Assert.AreEqual(2.6157405972171204, lrn, ErrorTolerance); + } + + [Test] + public void AbsoluteDifferenceTests() + { + // Verified with Ralf Herbrich's F# implementation + var standardNormal = new GaussianDistribution(0, 1); + var absDiff = GaussianDistribution.AbsoluteDifference(standardNormal, standardNormal); + Assert.AreEqual(0.0, absDiff, ErrorTolerance); + + var m1s2 = new GaussianDistribution(1, 2); + var m3s4 = new GaussianDistribution(3, 4); + var absDiff2 = GaussianDistribution.AbsoluteDifference(m1s2, m3s4); + Assert.AreEqual(0.4330127018922193, absDiff2, ErrorTolerance); } } } \ No newline at end of file From 9bc97fa1c332249ea2eefc775c221ad82fe88756 Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Sun, 25 Apr 2010 21:50:46 -0400 Subject: [PATCH 11/14] Fixed a rounding bug in the Matrix GetHashCode that would cause matrices that were deemed equal to not have the same hash code --- Skills/Numerics/Matrix.cs | 16 ++++++++++------ Skills/bin/Debug/Moserware.Skills.dll | Bin 63488 -> 63488 bytes Skills/bin/Debug/Moserware.Skills.pdb | Bin 216576 -> 220672 bytes Skills/bin/Release/Moserware.Skills.dll | Bin 58368 -> 58368 bytes Skills/bin/Release/Moserware.Skills.pdb | Bin 196096 -> 200192 bytes UnitTests/Numerics/MatrixTests.cs | 10 ++++++++++ 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Skills/Numerics/Matrix.cs b/Skills/Numerics/Matrix.cs index 926065e..feadcb9 100644 --- a/Skills/Numerics/Matrix.cs +++ b/Skills/Numerics/Matrix.cs @@ -9,6 +9,10 @@ namespace Moserware.Numerics /// internal class Matrix { + // Anything smaller than this will be assumed to be rounding error in terms of equality matching + private const int FractionalDigitsToRoundTo = 10; + private static readonly double ErrorTolerance = Math.Pow(0.1, FractionalDigitsToRoundTo); // e.g. 1/10^10 + protected double[][] _MatrixRowValues; // Note: some properties like Determinant, Inverse, etc are properties instead // of methods to make the syntax look nicer even though this sort of goes against @@ -386,9 +390,7 @@ namespace Moserware.Numerics { return false; } - - const double errorTolerance = 0.0000000000001; - + for (int currentRow = 0; currentRow < a.Rows; currentRow++) { for (int currentColumn = 0; currentColumn < a.Columns; currentColumn++) @@ -397,7 +399,7 @@ namespace Moserware.Numerics Math.Abs(a._MatrixRowValues[currentRow][currentColumn] - b._MatrixRowValues[currentRow][currentColumn]); - if (delta > errorTolerance) + if (delta > ErrorTolerance) { return false; } @@ -426,7 +428,9 @@ namespace Moserware.Numerics for (int currentColumn = 0; currentColumn < Columns; currentColumn++) { - result += multiplier*_MatrixRowValues[currentRow][currentColumn]; + double cellValue = _MatrixRowValues[currentRow][currentColumn]; + double roundedValue = Math.Round(cellValue, FractionalDigitsToRoundTo); + result += multiplier*roundedValue; } } } @@ -443,7 +447,7 @@ namespace Moserware.Numerics int hashCode = BitConverter.ToInt32(finalBytes, 0); return hashCode; } - + public override bool Equals(object obj) { var other = obj as Matrix; diff --git a/Skills/bin/Debug/Moserware.Skills.dll b/Skills/bin/Debug/Moserware.Skills.dll index fe02208004603b4b46e17a2aec08cee042f680a1..5452efb7c851a38976347ff7aa325a0453aadf50 100644 GIT binary patch literal 63488 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 DJK6k& literal 63488 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 diff --git a/Skills/bin/Debug/Moserware.Skills.pdb b/Skills/bin/Debug/Moserware.Skills.pdb index 940efc4f38315e022227f969b978ce1ceada4dcd..f014cf6c71651e437107754b13a43191696522e7 100644 GIT binary patch literal 220672 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%0D991ZQ-4f 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 KO5p!@3H%+*&e2!^ delta 53562 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 E0><7*H2?qr diff --git a/Skills/bin/Release/Moserware.Skills.dll b/Skills/bin/Release/Moserware.Skills.dll index 5e356be60f78277c43a7576087cb0211e6daace6..be69042e83f8d2f4764c118c4b744e8c317bdfb1 100644 GIT binary patch literal 58368 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 diff --git a/Skills/bin/Release/Moserware.Skills.pdb b/Skills/bin/Release/Moserware.Skills.pdb index 9d35f8049e770678d0309318c4b50288f3c1c05e..41589475892323ed2b51abc366590a7427793f11 100644 GIT binary patch literal 200192 zcmeF44}euwwg2x$9Kjd`1Vu$1kbffbPgK$o`7``eP=rx2M`f6~z?ESJ=iX5)(~F{M zT2WbPQd(M>Sy@rfl8Oq8eE6i)qOu|%m6er09~Je?exL8&XPvw6aLJiFhRB%Sz^U? zyL`rt*B35k|252o_Fva(b!+_k;>7;hnmtR;KkM5EJ=JghqQvI&?(6Z9Ei=!#>o>pp ze!ul+`Rg})=;k-|TlQ4HuZ~V6_Vk+j)g>Qqocd(_4fDSA;`FE2Hhi^4UCC5Mau0xOb+V$r)U2yo>@7_PT+4Wl8S^fW(zyI{54^?0C)a;6vNA>>J(#N|V zC-%=8cUJ$Of6t!p9(qNOao7BQ&o@py>38M(CpWuZt2?XzAAA1ck++=rj+2J{>6Ev9 zsJ`0G7rGud_P-i;R{uY7z+cKP{mPDQ-+iptma=C~zhnR7WY=tQXZ8P?m0vh_&Xnyx z+VqV>el+ID&#mv8+}QtW-C6zr=)!Z#AAb5f!+$$^$;e4BeD$vVkCR=q#humvL*I45 z_vf88>hd=%U;qAR{&d2EuE~x4uhyN_|A&3}ZATn;_#NNB>Xy%aW8?|DFWvt**)?0- zS^a;{6I-Tz=%z3CnDVJ>fA^Um+;el+(1)`@4x@;M;i_rOl-_yZk+Xkv-#tBQ zcKmF0_qLKQB1)ar|39gHy#M^$s{XS0!}q`Qu)5*tF4Fw{zM7rY|3~zlecxl3UNWP4 z)>YF-Z@lKu`#od32m?B+|9{>0dlNStlR5Cg5xaiTXV^U}yGZl*`)YPp{~!L!Lm&P9 zwA%*`d*bMeZd>|+ar-@Ey9fh1tN-VIp=Qu^2mbeQw@%sh%oS7jbkG0xv;P0k^JmTe z+6CFSoV01);s7is=}U(L?y|J!a~`pLP;H$D6Dhkx_6dwTG#Eu&|BWZ0^&bdl!o_tosI{vSL3h(CSiJtw_!z^`TnE7q1VT{Ll@vcXZ3%w<;*pg9{1xtnbfb2 zs9APFV;5+8cNO74XZ8Q4_YHjP(@$J_&U-h!>-*>bc-^RO=5`GZbXNa=^rPc@ulf8- z>t4S7fs-bsmQC#%t?#a7XZ8Q$SIQ50bb9u{>QzVl>OY?tv%H(LU4sLi)&JLD@y&T} zfBxhDbLXdy``Kr|@u5ClqxIdj?5zI($*!|E9s1?Z?S3d*_1vAmJbQLGXS)UmI;;OT z{r#vX|2ky+O&8w#&A%QrVCx6FM(ew4*;)O6;MzMs`ild8RW)(PmM4FB>zto=bGB=6 zptJgaSbE4k*X=lS%eg;$)0nfTe7&w~w7$ERoz?&En)-%2uA13!)aBRLzHiXdv75U& z+ch}QS^a;^gTH=h(&odKeEI#4E*^Jt<7c`?>$_{&S^fXi6CYZ6+3}bC;7!X{{Q8~e zOg_7tvt5G&oz?%B&iwe?r>FhT^yxbvJa0wIwl{T+)_2#kv-*1#=R$uhR zkvq=6=mXuH?HU~Dtp0!VfCok%eA|vGPi?O_a>A^MZ|oYa@2+KM_5b6yt@-e!XI(eq zGw)sbwuS!~xwV_KU4sLi)&H4!HCI0W-|wzCcFy#RZ~A(&`~07-(fytF{Qto@2Uqr7 zKQFs;(@np;Zo_XM?IO+J@2lBa`afX&U5l62y!4I{&;Rti-AU zJTUf%yB|6A+mGjNc>LoZc|#Xz{(fK0&g%cngyiowANu|u{rIXkZD07l^IzQW8QX;z zpl^HdnYV-v?a;>E0|9;fL!W!=1@s0E2Bg&5*rCIH4*?DZ`U3rc{=i|t0AL_+IB*0o z2sjcr3OEKh7SP~O0Sp0#0>=ZxfZ@OhU?iXogeL%eb|7&gFa|gY7z^m-VjVCu0hkD! z3`_#_(&4GVX@I_Iq)F)Mz!^X#a3(MXI188xOarC^Gk_{!CNK-o=7l-HTtEw%=K%A7 zbAj`K1;F{hLO|ch)61?G02cxm0gHi)0WE@E0@MIH5bZMHa$pHi3oHfdfO;SWECZGU zD*zp!aRsmvXaH6LjX)Ey8n_Z@1~NbvxC*!$SOZ)GTnoGvxDL1;$N_7C8-N>ub-+!) z&A{7$TYy`Ew*$8Uw*&70-U+-5SP#4#cn|Pi;11w@!25x_fDZz90~>%30UrkL0qzAp z0(=y>54a!r81Ql66Tkz&CxHinPXP}Bp9Ve)JPdpe_&o3hU?cEF;7h=N0FMA)2EGEw z;oJm#75EzPbzn2_4d9!=w}36cW5Bn8?*LnY?*fkl{|RgZo&f#}coNtSd=L0O@D%Vg z@C@(+;D^8t;77oZfu8`+0zUTs z_#^QDfR}*(0d@m_0{#sA1=s`p75E3B5A!5}9>4)WPvAhH3^)kr1@s0E2Fig$fJ1@4 zKtG^Aa2PNE7zi8=903dhjs%VZjs^w;#{kCy#{olun;Gl5yaY+w#B7dRWx2aDzd=K|*e3xM;1 zqhZNlU=hEof%*Jy0p1L}1^57PC-52I=fI1=-+=!GUIzXSyaK#|w0(dIUA(zN9LdXKNO%OgA)S3{^L`q}-jFd9~Ll@qz|n zPgLEsAl1CAsd-gxV_hoa2*%cB81_!DX>lc8p_1z3l2%<)Q6H3)@g+qlOG)l$jVmEj zv)W@vlx2GnW@QAPJOYJtN7-O+J?H8hFZqBl53b(j(~ab&ANgD zN@_t+?@Y~w=yUDThLpc~P06(m>YAy!D$3N~beVR%rt?#oOzrYi=hSdjKC_Z)<~^|t z2BrfwikvJ=jL)Q`n#^oys;R!Z$ybPrPLRM9S!Sfo=o!Sdt-Sb}Vg64Env%gugg5??Q z^*-V>%Z*P94)a&#GulHyc_q=R9kovD}Pj$(+jTny+QPm*=Hd zrW(>Knwsi;Ovx4AcUL#WMfgUQ-U_s|gZ5Qwo#|LV%eu}=*Qd_uAj4!*myyrPPT)%E zy#_x@?hik}lw7tSOiC_2FVk)?u%!@Zwl1t~VD+N9$ywX{N=RKNE`&G(c9kn9+vKcq zreh<6$rZR0#s`xwaHozEg}e?Hf%Y1$Un8~$Mea39cd!TclBl^%6Kk`ndif!N^D(!v zG1crCQL^mkt)&y1Oiel}N(L%$Hqt7pV{(;ml{Z*<+ka6iy?h1DThy|ugSIT+9B<6> zZ5@(7+m9=UJcnD96sRK(kwFo9jzfx8;_)B>vrU8=ana(Va2yz3)>yn zJ&?&xwq|ktz1DQXDpXwQ&SZEea96qmbZ~(i9jO62xXvB(sD@vSbsD*Bg?UC(b91Ur z>&vr<5zdsXOmXMd@XHrtOU`w1G0VbYI;eGCPV?i|?B*10Yp!1L8a|3y?#swhhL_<^ z@KdoK@+9JJ>P%7A>WqAcxN|x|w&RLQp8R9Sz+`le{P<^#fte_o&(cH__s*D`nM`+d zezu^tIh(F+&}6A(mhp&1d1%JeA^vm*UpmT4a2C;AENcQ!R<^tf` z2e2=uCwp$V{{diOANE%P8`&_^j}0@G$FfHZSks^VNWgnYy92Or9qCU6!fu~m29mw7*@;+R945Dxo_of5e4rXu98|-c#H&fRi z10#sP1~{agb^sfI-vW=(?gpTdx<953Kd%ywJ&OHqK(X)&^_+Gnd)@l7{|k6|0Q>f6 z*8qN>4?Ig-M#Gay+`kjJkTyL4WNH5v;Ho3o7Y4K?tfQQ5z#~2APvCFlGnuq6P`3s2 z#YX!7oA6^LamNA&(?_*!$+$$Cqn{g}+<@HdymjH-&+U3#TgloL#zTD>Aklc@6WNMW zkNEnwcP?9lg!#T71y&hz5Bk_|7xP>4A~}&lM;b+|{u8a@ zLR!hQ(VkX*UbSc?=b}|yNGm&Gv`6-SewS!vKSZmzkXAZsv};eFI9{~UUC}Boq?P^| z?M11Rel1$*rDzow(n=?cw%^>xo)oQgMYM_wX=N9TcI98oKO$P$3(+brq?K(n+81tZ ze7|UAGexVokXClZX!}0D=0?%V-iTIlA+2ns(T<$`i(iUXHdM5V3u&e2Mtk3n{_<1N zO8-TxxR6%%#b`hIsh^D%t?Z6y6&KRVjvMWrW0(F$w6gD_Ra{6byJob1Kl$(Hi&pkd zw2BL9W&4cw(f^)sq-bRmMXR`wR^x=x-hBC`*Nax;hG-QR(rTPB+BJWl;rOfZN3@Cy zX*C8I?b?65`xWJ@u|c$o3u$G`jka%f{|3>@#*0>QA+5$hqdjW(?}v$2W20yl7t(4> zGum_BHRN{DYOE8j;zC;4Z=-EG^zPq@R`y)9iVJDw3mEOOOINNJt;PY-DlVke7;m(9 zZU4ar(Q51$t>Qvjjn78ACzc5R*8b3v=xR6$UfYCm)b;}P$EB`>WiVJBqP8;oSw%xl- zv>LxftGJL>eu&XN`@jF|`b|EIXcZUIYP>btSzlYVNcn0!7Omn!TKOPG`-!g~ew%3J zlZaMvA+3BdqaE_lGowT+A5FB13u)!w8SU{GO-+ebexGO+7t+cXGTO6xJ#mm|vzGTYcko?sq5jpo=yh2!HX{uL@>dM0Kp8g|OC@dU0Ee;~M6`~>c+ zAL_|h{^508e?2N&>9`EivEjOf)wag07JFQ}O{CjMI{As;jna)E9k=(D&i4WFDt9-8 z50icd*FOx>b8BDe{j=F9{Uit<0@Ti5MCny;_*{_QKaq7syM9z3gfRBi`jvY2Os3p> zYrly4aC+2-D^wT(GZ}}e$wb+_p^>~-&Tva^?)j}fAeplC^2@1o+sgIt%UQWoqH>>& z$~`?U)x9HBcCnRPq*#%bQs(JVne!yv1o7Jf`djwiB4v6lE3G`^ttpXgy@g*=-nR?`rMfzSr$!Y!~`+ZyTV1i=UIM{o#+V z%}}cMm2$Xw=zAhJJc=I~U5^7-@ao=~U|5&aczHbda;1OKk09L-Y zMfdLl!^7MO?yX7HdpOKn$~%)&h!O2L+H^LM1t!y8Swk^+3iJdqmU0I1hNJi?S})H@_YS5ALfSFBhFH#Z zU-}Uq*SUA*dQqnQa|P>1*>}oz?{_W%-vZnVYyqAHUIz3ooZj`?9|F1*kN<0;21hJ& zSG)^Y_T5tp$N%<>rOMwz&mPB@hhwSwQ~l!ePnuF=-@W`O9d7Ab=@9AAw_}~I?dDp2 ztNFEpe(PPo75hn_xkh)=pRoToM|t)S^1cI`{T=x1Sli0~le~!5;t$UIcg}ZFHt5T13`v0g^{o6K1__15<5B3#u)~WN zXBw9iUrITq6P~9@$6pl{>cqk5gqX@$f=-<1bVBK>0pHeS%mew4a{vX#oE+1B<>|&D zrjoe5=@L5)ff44I0GWv+{DWn&2Dl>oa&+`g)~>EYF8SC=6UjM!}w@^nBP)Je5vy+ z$&Au2jOHGd(R}AL^0e?dXuf9r_46H7KX}=qx+z~7o00grK@E-TMV`vf^02wV#C`Bz z@#0&tc=+Jj+BSRb=ML6Jo6|iUwUH*p;q$cdPlau4J=JN~7-40;LouXjnOgDO;g zK1@FdELpDAe1*9RV?;%4$JcYu%WN{1cg7QU9tg;d4a!Gz3dys^2F+14?~&ik@7&2? z?0RlGSa!b#+#kFo!jf<1Gr9iJDAbRWQ2KESNBmVW{WxW18tX2{a1u*6zWBaO zx_%`KXLB@uC>&3I;T*v8H9yX&Z;f`8qfN(Sk=BqEDu7-zPCBLahXue2;9fv$D9-}> zTL|s{#;Ec1WgO`9vH=i@zpdB*)X$=|_|X5`*H|FCFy+6Ig7HjjrD9itx8>$<{k7V3hhXll79u$9sM3pnOc8w)lu7Kus1K&d=4Meu?5l%9<6#4J-HkvfozZGMR0g=4 z4(qpj55o3cac%3G1vE`8Q|pDVR&-)V0Udi3(;3*DAB!z*sVSUtpLzGz*CenYuwEin` z4rJxLM4rfCWLJvMff$e0s>3x7_2%>~8%L_S=XF0nHiUDa3h2eFp>B-u;|gP(#!WW| z8t(F2#oXs8U=pw-&KsJ9*ZE|uqtX%69qOMuEKw1!Q+d5DPCLobo)pu1eM`o9h51%G z+Djen8p`vspN#cKK6nG5Fb!JS4OE%_$sS?WAX9-A&5k4 z@!|Mi%CkV1CjTrjdgd2D5_CR#DQiY*W9zlY)?@CQtifQ`k;+=E%`>8-3{vN&uJ&Ue zPagevv38M zD;Gw#t-aotYh7-Q7)j{kk^9Rza%De#wQ}jCj+Fa!k#ae^uIx9jRxXpRQpz>?UK4ff zQyNgBFr0G#WaSp=UXjV)+CiPGNUyX;uX(g|o^d1cx7;)9_!*qy8Jk+z5XLuUSNP=Ja7vMQ|9E?#3}7~jy8 zv1k{MFIN!1N^WARAzRCRm8&Ujm|oBSbf0;D!Tqbb7EdJaAw4ggubhtsNw025r<#3# zYs{TW#qWXks589Hm+xBMDy{5UXb%?DrpdwQ(F=xDlE+P4j|%cQq*WfPo0-2fwPeD4 zl!xkiXe(N^J*=zzdCd*O_GGe}5rtGfF9~T#=l2t+8$35au(}oJx70SIv)9N9PZDw4 z$}Y5rR`zNMA|bSg3n=@^S1Yt&RQ3uf7$IyoXLpu8 z_v&S9*|DUu%_iR>B_+Jzk^4J>vj1RZ7wvAZUk%i|n)FI*^yYJ%7u#g^qeec5Y?18g zUU4&;S{k!?zoT_L!=1B38n*U|i_%J0Wk(C*i`ZJ((vT*!=gLDiG>mt3mj=oh6Qu8w zk-ccVCKlL!iBxO4iLLTd*Y8EMD7}1DJj(dC%f^OunJb&!x&*hKPo{1R<5O!^YuUot zgtqBLp-=V_`Dxzk{pn=vhs#wO1}I?n*2*RU%zIbFbJO+Q^FCyyD(g0;6L1J=38n1I}JF#bdCN-+LH z?ycZ!kh711ujTp?u+nby zZf4;))+9{itC-WNe(CUJ-2FNAlpu z%i^;09_l-hx|;0x@vXQ#ycgQZoa}D2emp9k@B3Qi>&K7c`Mw|8(^zRyzUp&tzmxGe za47dS0}AV)mA>8t?hn2NEP1;XJRE!*SRA+=EV+9p7@5>L?YXnT?*U&1R$H3Es^`sM z)!~ES4P?C$d>{B%;0L*%*Xt?t(-=VdEUZ2joDN(N;cD;^5e$#ld-T4E!V*DG+0k#7#1KL|Y8R!lj=K$S- zruqHf^-*?*2ibCld|AKoh3h|U8{52Z^$P34@{z3!+oN-GP)0Ax7-?l($Z9)A$vyvu z=0!lX7C#hUKuN1YUq?QNKNv@+2*m3wAx(WWck*?4mA&BDx1LEqHe3Crvl<6IFOt;H z2l0Ds7FB-TsxgMj|#dVtyM z>1=>(?*Oisay<;Jv0)T=30SsZ8MvI0TkEw7{oqnRMs&ZQ=crgm^$w;&Utj?R)&ti9 z>w)gDe{n$aYioh_EH%{43Fzj1XGQv-e=etKJ9{?pP+9I78fv+(_=3!&8AS3Y;(N|B$#c}?;iC34dXh`{`-f@h0hocpo}}M zj8^tvev)jS#oJsLzQl6US+?D`v$$;^64~})^q*||aInni2(Y*9$I^fKcL5mAqB<9! z$BiZ(vY~Gq<-A{2+&(`~zrPF&puwXg44oW`^?z8*<aNq4Cl^+yBv?@t?U&!T7&5 zsz3S?ho3{Uz7xwB<0|XtzgEaj%DAf&%8(zRzV$pQzW0i8*!clzCmTn^BRf2OE}1c5|(~^iHh8AYdvts(}U| z2iyrf1ayb}mjj{xKOC_kHmqDfhTi=0xI+E6v0h`NXf3`i&u`m5E+-k63*W)C@k;OM zD3~tk_qVC4Q;B1zG+wXOzV2i&2Z{+x_)kB zeQFIf?a@)STlKcNk=|cX2+QmX%`f*VvvHxmlrXokuAwEveo4}lQm$-+))hQIla9As zCJq3k`wE(4=$bmYxd;9vx_caUWNNJM%ER*|8P`3`17BaRfb=_lC$*flRqfF>TcbRD zJB#OWY?Mbul*dqTIkmJr%$Df<9tGKwdDsm-%UTCK0Bi=H2fD-mEeE9kr$+04QzIEy z|5#XrjQUAix)q$+}jG=%>6x4I$QHx5X^Zir!2qx z@^oW5J5PrTj;Cn97olyo#;1`^&SVvg>)UK$Tc1(wP?Sz-Zt1 zI4au#(Ho7PH*-th$Bo>`z0b5zR{41BKy4=LUySiGHJJ>y0nCvT?}*A44^)RRUG&b9 zKV*Zr_VK{`V#Wj00eg=}&tfd_?a#8U#)E||jdm1-;?-x`)2cnJN@H}^XA5IKus+L} z8KzZzOX)8glcpZ%Yxri5++XItWk0mKYQ3(xX=&}!wDyafw~Uc#rGGWm)q5j#?n53* zZ)wzjvI&dgdhgwTDz;es1nw(6D2S)s?h}amLYIGTE-}ler~jLlvqbKBslC5?J|vm? zZL7Wy)3ok;^@E->^(3txK_#bnnN>eX9*d-nUn(=XX?uSZ%8vO@T1Qv-ut)AM-@h$8 zKdMW@&lP5cVxW3gQRnfbRXU>;A7yK*|4BcnxMK0@2a~^i{ND1XGSn9#4QsPzBAtxn zsN20%WEgby0Z*liVY*`dF_?5400~56lvex6)E`CC796tzNvzM}k?Jvq2A{zFhk|-Y zR*U2n+XSV(pE`^pt=8-QBTB1xILNYC+6DH`L~C6&Icb~D`n_IeUra`}%Gn~^?2-FB z78&_tRIda&>$haq$GeTyh85KR4$>-}(OUmq@K0n!{3#YM8L_q0d^~42x_!l77w@Oc z^^{o)ZP{5~pH!y$K1>t!eKlK-oXiX&&F#SH&>az_Gd(Pl&Tj#P*7#eh9?EByoO(Z` z_`4JX@lB`kHFeQ00sPpTjK^$5MKa-n{AyjxuRaV6kx{&DOjQ8#s_%GZvtNqR=d!{+*_jfbztT59&n2Lm&M?MyPZRps1!K#2)gP^NgW5{w?Wx*Qo@SAbV> zUoxsXs!w%|yrLP2wLBMh*Gr@L)nMhbCc0MJvRv!A*a=a;>D;1m(cU26hjnou+Bro! zuVOc8djUG9RY7{8#k0Y{Bw!A(1h^Ks19%wN3cLvPLMg`pRX{zkKZKq%(&jJEMh%wC zTBu-bng|nR^X>VM#v`S>0}!pnhx5LU%;9AJ+cP)QIPQbacqqPRwB0ozZ`(ybgtlF5 zZClQJuJf9fpQ~?`H>BSjy;|$Wvz^dxAbmC1=rs;$m?Rb*)TMya%Nq-ha;1 z?Pu))O_8`+%}uM~gV5SO4*L0=`bueRE+b!BVWUUx?@(wyZEg0BM)b*2KjuG8JGYQd zX^hU=Iz4D>Q$xM~nm5fgpP+So)LiF_s=Z-+^l8(my(-)Lq9IKkX>?z*7T&MtTE2_= zJ-n~|xih$@`p7ngarNglE{dWZ{|{;vpIV(sH}J{m>NGWrC{>1RNkKlT#wKi;Yg6x5 zalALMz+USm%9VpzDM%mExR(rwSAAt}!gBNug8RUE#NR$e;*Gzh%E?RQIS26in{>L& zWkUR})DHr4+O@Lp{jtZ#f*J2}BftZ|y-8i3&>48A#y)`Z^E#4@{irZM{3rL^8-K=) zk(g;W)-!Id^ZS*iqfqmKWo{hWMSflmld&92;dTHDqew5_$afk99u2Mlj{(azodlMT z1h}ymk0^&9;`TA)Cpcf}eDJB<*O-fHy;JPX*r%M!s_Qf$>9fp90ff z#wooYtNpKM0~3H#fD?d`fc8yl?`sw~5jY9B8dwO70!9O4<8e#pfGemi*CG__fd_zX zz%C%(>@1>A2u7?4>-o^LrUPQl*pyfvE%S}qYUBC>wKG20|)sMUR-3!n;=?X%F z5WY#kJfI%vYC-*P;O=7& z9A-YFbIGu2XJP9^rOH+&PQ&Ls27T7E5bJ;Y4vJ*qTH3fC=&B*?|6NfdWFIYHr^|FU zaysqU};Q$bm)t*ll)ZAaRrHGKv7 zk`{(=sdKMgmv&-V^^x#~ws$CHeaXsNn98KG<`QPyyhIOwbw-BL7@hgz_{Nc~EnL5s zjedl5V@Rj@`gfxIZM`_3E3FQv$&J)`Rr31i%7YJi_xcBz$J;@LaaPa0R30N$o2 zoqgxh=|Hu95SaJ4cav~O*Xoh}pImm^9|qPc(*SU9PA}}8mh;V1Hir zFlfBp&F^az|1@SRAfK$S<=-Rp_Okf9RoEM7N5}r0w{yj5DHqy_F|D^##c4IKI1Ha& zd>IdTJCjUI<+lQ2>wHc99tW-X0UiG0MYJ`4X0^8&IMX5|gzY@V(fcwQi1WH!+^0d; zbLxBfGVoct@79Llx9bC4GY4|<@@ZIp$Jd$9FX_?=^wD^@G{#+9KQM=h^eP$aCF&N> z0jtPE?V1HfSM_#DPQ37QAGK5Of6fC=c6^eYcwNZvnU~6_9EI~quW@N1Sbe<+JRD5A z+ywB2U_XBvMxJ`FRC1G-125~zSn)$%UgFZ`_pd!oehP~L`HGu>r-3~{-*S9+U>>jn zpiuYil#Sr+!1F-QLs&ZmDuHTXHE;{?2(TS^9_Y$J{cL{9j;JA$X$zPYC$i#k^!#$K z=XACnD1Xq>ioQMmV6kt5$WEWymN_P6VQUg8zI-ZHLk*_5+ ztEo9Uez09*sM=utBD>|=lV2AQ@2$URdrktcF)rLUTgg3NpJbwf-wKj5<)?tDa5jxD zaJI5P*zd(Vnz$q4zSB1i71Vdv@_Rk-0I)T>?;`&X|AhVjLR7AF$->*=-L)8h*AKz| zC8fI`5Us^`RNwdY%s_otip;5wt!2(^o!0Xe!ny8kv~|6;b;iEW{d$pfI-6N(jb1*d z@*5HOqki9u-!G*$w9S@ypHqBS8msSSHHPpDkKEteq4}@9>Kh&r)efLnM`_l<0{_k%eW0Ynir6~fG)E#-O!MsoaVGM8EU(9D9mdW$9G)F zOkUrMQd!cK;_=lSMU+|17ogyeU+WL){CPdvS`gGMD*ANjWeVF!pD&0ssQCTo$leENyrX|X=|%%-7^X7Myvaarg6)~9o#BzRl2@jGZOLm4MpSTHeSV< zRgmDj`7@ltGMOp4wAh}4GNW@y;to<<E6A5ndkzhpB^-+Dil_I^DJR6sWnhKpV{LpHZaI&+bn4=kN(yIvK_x5?T@ z87_jxJqzpM`NdIPY+m4+U1+Lf8>BhH;9fXIbiZ2!)@;@JM z{13(p(re$L_!iP--C0!y2hkxZl28BKH>CY%x8>Kj=sx#62}J++^(|D?J*(C_)Y04ra>KwpFK}xt ztl_(L5Uo9(#{D7S{24l@;rHt-EUjJWIq>C8m_gjvq7dbkewlT~hmkE_M^cZ#;06H<)UkB7zA z_AY?-V(M?Se(WlqZ#A-1&XY~iidTO8NXFw3vKH@+gZDWNkC(Z+__a9sSh_~G5=+3x zgSCb?Ji0y!yp;P|vs(g&=Pv$yu+m)|U8lgyxR#uq5UtQ@Z`?%fk|Z33bPPn+?0l^J z-nfyj?t1UU+umes&ynxMWHFp@EqSZ%Zv{&yt_P#$t}bfBTCUNH#7$uJ#m!*k(w$F* z+&Mbggj=|eJSEWA+(qEq!K}@>`}JV8y&25doue#wZWVdC`=oW(?*_k@_%B4)o1*x~ z!K&APMfh3p2e|${_%5*Di!nNQj=PA#Mc*EIBYY8u#V73ptpmpJ4~-)9V+C?j#M7g& zE(4L{3DPRURJ7n2W@F{-Y}LDMySXR+=)2bnbAX*NXgAOYgEJnO12h2ZfQNytzzaan zeylqJ^8kG}{C41BU@Nc(_`eK2DeRxE|7^wH9#l~{|1V`Ot~Rxvi(9$sKLy!33*V*O zLn;c(ZQD5EeHhhSMmCda#S|h%IM%4la(j?Fdpzc%iFUa+>^d2^g>3< zz~~j@QvS@4O78hKCu3e5z&+)s&?iadrT`L9J76(^0D{_NTP z5*buND1QveWewbO{9zoRzWb1b(qz#3rmqxvRTD7%phSKn#%{tNff zo0M(q7cZMM$Jqt*0d_`ZMaUI*7&PmxEPu*#8~eVnjF-q`381|7JkIQ!#$d^u!Z5}~ zt-%fl%SRsp9s(W(9tj=|mY1lxSa0Suz3B;m{<7vXCl!ppCqt)lOvc13(+|q#x&8Qf z&f)D(aoWj_*6$0TewvT%Gv6~E?Wj0kukXd@J<}cSS&mli_j;F~_Z-MQrB|2@t=hr0 zn+Kc&mK>f7);!=mus{EI2!c3nFJ5@PD&D?DF71h~9^=W&%Xa>Z31mC=nJ$I47uSAH zRYf^9aXK%L`EQbk>FP))TUhVP8d=a!UbZ-Agm{IppVE$gQ0(X1GuH*s-HQ@z1hxUY zfj$W8Bw!xU0IUNZ05$_J06hob!vS-E6+jNS7kC8N4*V;F+HN|SjVf|fP@x~9gIg;+ zZ*2c>`_FLNx9`6rDhoEofqP}oRTP%l9^0Zid)w#FwdEOr3m3*E@SS96c6VYK_eN!y z&a0>&Q^wgtqINjHroLVF%i3XM?H~y@AuQu3lyQDoM)cu4t+$1TVwS=`8#C`HQZ9a6 z+2SJQ`Yn-R$?Y36t80h zx^rW@C41`SHmQA5E=V4h_@8dP(zvE^>Uc11&P@fM1fC6M40G?CY8+zyOZBH-Z^E9| z11o^T0i8vfKSM}kkC)@(cKkH*IE*K%;)iIxJQk;&=4kU{nwO#CwDTRU-&3Z!vG32M z>su}pbaOm6u7*~A3OvaT1z+s02Qw!5Z<+7rp2iP550SAo@jSNoWnjQS#(7{WPz^Ky z>wpcw7T{T+7adpuOa@+0A+-PZMh!bIXy68P?QjG;se7&Ve=O#fXe~b6{~?_!Wt~Xn zv|cANTcEW|g|G`gO8ri;`UQt>$rjuXZC}!e-e@}87KlG;tJU%OB6YkEnscmBBkZKHFfO6LZdJcF8@DQ*Ccox_V^f`h& zfl8nn=njP(=*gw&LVXk!`j<~3t{<)_wEykVg(pcL`r=!oGI~c?=xJy^R?+b?Os;%= z^FBo=SCz<>^lb{bH`dMcN3!JWQ2adAnfPOpy*VzOUvD>g4BrQBK*prFcLEP}0eK7i z|6basfK7_SujrfK4K3^&jR{Jp@n5tS|5}azCZ9cJObF@+3%{m*e`!^}_Qk1buRF%Hv-+>a=bd(Xf8dB9=1LrEul(BGxYKdX|y z`1a-B841&2dUKKy#-DZmdFMW81)1_M=!=nnrU98e$Gdau1F zp>fy3EPSE+Mn(FcKmSwR@8n(SCG$#SbfF#SjQ4630v}M<7Wxa)6^fTtMyrhl#ZZ! zS(pvY&#a7mpG{PJdu*eXW$oD>74mGbXVAFM7#vvu zw+?gau<-=$D_(NcD*iOZi-)qW)#SUFd|%=E-8i4BiaiU-r{g_1-=x3Mq zA<|Zp_Lro&Gf1mE!nDzzw~Krh`Ms7QjlEAw0qMF_2G88@BMoT^^NBxG$z0Lz<10d2 z#fNdUlbY{X`Qohs;*IQZm}VK24W7)k?|Is{fc7nc?!Th;**S+{x`KKwYHHy#K30s& zXDf4}dE~TXt@6pi=ZLSm};<64KW;y03FbFH7v5O!k59EJ)++LyA|;{by#SzcjCaCd$`q zSf13`8?i5}LwK$eQOLWubsEMyz07%dhYJ+(-@t}@>zi_ za~^J#F5~)LvfL`(Y?jk=$(rOjq-j}QU&~YZI3LM|WVi^;UU^AwL%OsdZ>pOvaIXb9 zzVD_jFVdFNp#4MCX7!Wgxgagq9kCs@#@X-&G9vKoDGq;w-&0PC`0dX>aJvx1>oN4t zWYUPEMb!9Ls?2JxHVp8-a`AHy2BUW4qVox4BfY5MF@&r~w>K3dZGYs#0kx`gc|q9feih>Aqw zh9kL8-nkRN!@>9idLEOT2ObT+6s)}O0BgPPv*1&~p95>p@0Y-nx&AtsIkNi(@)=;( zndDozZy#eTayz+3c5}Z0&j7ywo(cXVSo!=v@Y!55X1P5G2h#cHb3G7T4XyxR1Reoi z3?2u56ZnnbOTe6K=Jqzs1kd7n9{6(brQlldDsVkm-~Yi_<*oxS2fq!x0{kv8@|C+A ztoGd#;ZK7bxc(xz5&Q^P_5Esey#>6Q`%gsopNj7P1k5-~A6`r!&S##kZz^kViS`_8 zU%mFwU%@7wH(v_ypIdf|XAD4}|f-+;^5a6Fl)L zu9tv64PFj@7~Bj-PjYVoe*t_m_&>mRfFA+h2YwXn-=B~?==}kN33%S$2k6NBp*L6CgX9noO=(b z0K#VKaS-?$VD;sjTfySz6JYhJ_%{XoB-i5WcJLCg;?XmQ(T@c7 zAXkp;m7@x<3b=1O6pA1^yNIO7O42*Mpx2-v<6InEuvxz1_FA z{{ViF>leYYf6AZ!)OuKM3s~jCCx@Q~|CMXsr`k_-Y|yVdzhwgQJ`AjLGKT>API?7! z7H|x4C!yY) z!0o^Tz-HiCpgVMJ4)mn@w!V{%nldJ6(pC6%8I%W=g3!Ou-x>SAY)|a2s4UrH3u`I! z9xGFG^s3ad+Li|POQgdWNO=AwwHL<)+07;Xr=I(+l`ZP$bl$JCOFgkm?wvz^yL~)V&)K5G z!Mz!`{X2#75sn08yYt@$97cN2zx>`JH5-+7VF-B~#+a}AiPpD0e^ygSdjjKGKm3s0 z(DecasPY8mwHy8K#lT$wOa&GL*8<(4>u?~{f5ssfMh4aYUv%Thv4#4tIi1qo0f^S( z!*&0Co#pb{uEp#8_rh<5n%)oY;Tt92!oth6ZK}2HpR5J$B!TwzD6P@kTER4@x<1EM zc3?M`nnOyD3gV;l2}cm8>J*79IRD+|p@np{jVev^UG+g2m&w+<`vuu{9R02P60G!Gm9TAhU{8L6O=gGi?|MrVAR9`G$#r*i93N$6Y0+gazv zyD)y0k1XJw_;Wz3eCoJ1zJ=-Qxi4OeZ{ht8pC?~uG6(QBp_DV_HLoc=Q(j}J*Sn7FSbGfkWbm=zGr;)xH(U-rp6kN1<|i}$Rsk0R&2C)W1)Z1K z;^)reVY~MVm>;+~Eal}YNP{}K_eI8m0j=5OP6JN_Yu+;nthwwd;Pb)6{nK;j&m#VA z=;$YR?)(h!r?{R4&c8>md6DLJnhTx)=)3`)KcM;H8bD{#>-W__@pI?34^~0r`W-Oz z0bnz*3wRkA1arH?>yHDNXJppzeUTkhkPWg>#>(}{L5Ir9H`CyCJxYdJe>>yJn1^3+GlyDD$?&jn5 zU7j^nsfKK=?#nN^6RdSW<~E7%MdfPjRn@|D(Q|TpE7SQI9?bbp?9+#OP|boli=MqG4EM(D2=_Jr!&bF z-sqA0i+@^nx3$whkF{sZd!0wG{@g^HE6GQBSUPJrG7{R_lHZ%NdYdoc<)-+)Q{>9o z!Z%=-db7r5&zP#IpYNAs+^?Fq&2g=E6?M-g`jbvJRO@K6g9E_FgSC$4-*3~|RZDi$N-}d~TR*8`8rvm2f#&XUKGCSB1$(Q0c61f%F3A_vpU=mUV{JRI~zdhIA8dVnF z$ARaiWou!gYii}9rsnADPi6zwK`DBpdA0qX;l9mz>BcKnkYu_2Ys%95!nGdrF&;qf z74Ti-KtW}|fu zf_TPneFJ@ICe_S=uYCEpaV7D}M@`7*gRM=a>UrhWH9+wPw2Dt>Q>)nZ=+4Sey!tmx zulVXFUx4D(cVT>noKy94m5VE1bAi3%mEP}%k*^WPM?O=*e!`cb(R;Zg!5@qIKxNBp z6-nzVCz(+HDD9X7{JyxKM`^W&Bb^V^rnwgV1~MH5y;N^kP?px%Lwc(x4R!l^u*>_3 zkLwfGX*FdqPf5(cu&9sJr`W23JUlPYNnPVcfx@#7+vY?2wK(aZ%9h<626$b|+f9{k zHfkF7?Hr!xiuP$DyiAjUhzJ_jwno2Uk6Xi#ZB%+aTVSfsn`Qo-L6-M(6a- zx+r%pObr6R23QZ=541JNKA7FSH%dhR$Kg>-i(OSH8S_#J#+Rc*vg)dRI zpDIZ)lv4w!dI!|Y^x(*ak4tL z%?9}An8u5j$W-enp65x&f0ZL!D%+p{UVAtgdyDThIrg0t@A*)C-x<2ibHV&KbbOt$ z9mh%w*`6RM? zNkwt}&p{_zi~o1<{YFLlcQo~~z`V9>RYhSN+M|2oL1>58M`avp1%ST?%`H|2=VJMH z1jXC7?^UpJ?3vrkQ91HWEPS7GK2Q<0Wm={xU8i?NYMZZtpp>#?PbvZ5hxz>ixHrzu zfb?#>+yB`YECWxUV^`AHmHhj&jGYP3SxDk2VHLy^3G`1?;8bGubA3pzoHCrHk>Wn#`>5A!npSb4k zY+_9!{M>bJW>L%P)oykplJ@9|c%b^4oxDBLOYy)0{%BbrE31UF>a2`~(X*HV5_SSU zdK_+{jJ{R|eok7i73jSE8BHyX*=dcD(aE?=j$l%h5|`3etB0MxB>&vPt<>ZA66ztj z(HT}cpGo;y9yS*oUg$T*Yx-JWQ`z}=zD=nnpSMg+%qUKIH;8BCeFEsTsD8>@-Bpmb zrMa08+&K2AUwz-U-A-Fy$#zx)UjCEO?pyzEsO+JF=2G&XWcOsRjsi2^a`sPl(%ZkA z6Mn9swWu=+{53DX`FFZQTQ=F{c}6@h^zv7HzyCBxTj6MBTfH3Rzjqzl)>+VEVa#4JAiG#E?}@8n7qz|Y?z%d_iWVG(BC*6_y1jVqU0`7S!|P( z|9*~*33ouI^p@t;#({mU2bOYnlw`Q|nxM6<+BKl?+4dQGv+x#>2 zM^q`o10K1*&DhU-tlVNOg-ZO?Ue$G^S6ZXja|C5FEVh;GFKt=HTdZ$#&luF7d&ezu z`Q1r=Ir5tV&G(}6wU#E&js|D}f3uXc$jZU* zkB-7ENoLHycp)lBHrPT7<aWXhlgqPji7Y& zdBW>Ue*cDK$JPWenYo$KcRDt6-^*+=mVNPUBcPx%Bv<%1xrtz!mYW1tnJQ7^<_s`- zlc&Ew8?5p3{OJA#5xxwp^h+bW8mzk92d)73V+};-03z$$5$y!>QEN0VpTZOGsrUzH zu+DS}t87}Ms|A8}5Xbl8W3c8Shmp7O)yqQu{Qi)yjCpRobqrYFhSXVJmd^KWe*P7v zW7u-zs(8~|qb6ZD&n5|b|iq_&o|Gy*8f^ChCx*;YCh3|&SX0&H~IM8Rp-@W$- z+x%gdYhWU=GNyI1TGnW7FS5T?OnDek8l$tipB&dcktnvmwRODhyEI=oj1S+-R@>WV zEB&(r^`Fv6&gKBVuaa>etN$wj1=cgxisAi{x8uQw@w~GJEM4qPYXAO~zUA$|-@Sx5 z-|l40H;H34pfH$pvdOT}J&Q#rZ^ZXwrQ3fKhB9(>T%(ETgT4tg6{rRDKAZM2j*aDf zVPxF5s=0}!pncb5KlrheQ0 z{{^lA-j}hqeUrAm&)T*RKdf!K=6w(GN_97zqVrf3KI)PC`z>g`YGoEVV?%!GM$##b z(b@bLUPtzjwKi`sCfEiO(Wr?@z)DYD@EN^LmrRY|nt8p-xuFFt-{(3ov-jMsVB{+IZZLJu-37+?%lUWR^&WuU zI~ObgssOzYtap_)Hk=6fca_Bx-zUkqPi3Df0fjTjQ@onO_@;G*Y2X~V%9S+~p3RIP z|DN0A$jPsOZWn*{0DWoXBw!w}0>}XyfUX?GC-eU{M-4eLXb^o9nHj}Qi&2S==Kf47ynMNwD z(c4^mbgbXnf5V41oBjN?ZMyCKF!51swz_JrtRP*r@Lp){D6A`+M^g2z>$;kH%3oDl zqqn+Z1NvEh9j)t2WF+14{hM@st-RG2rdz#H1K9&?Ku!gtHqH)UpRhkmu{qM;>9Orm zI?vyv<29FBvUT$p{XPu$ZWtIg7}4;?eh9;?UIg2PCbv3$fyreZ^^L&&vDmkjQmGZI&ng*3k}@! z?McS`kl(WeP&lB6KVzdO7(H`qBhob(nqy9e9rW*r3nTN1-e8T3`SUS`Ap4`4e+_rK zV{(70l!c(V)M8}30aypz4|Iq9ivywlZ;zTDnMHSnUs-kszfh%E|84!}7H)~w;ybeD z(_Vi-zOWB_@BcTQ^!3W`lk7nP(@Cv$NZ0x^HuO$ZIGxa7g7SR76HQU_E|62^bcxdsV|L1+3S9zvNhp2qnA#aj+cDau|-Ch9QSzl25 za6WbWWUIQh&4&B2Np16T=bzQAaYCLz8uFnAnmtyA)(FnkNA?=hZ+2(2&S+}PWNRC< z8be>Dt>mroNaKK&YvZmx>#xcetM$3EK{!*cN;4Xo8dKg+y_Oq00nu8#jfI1YjD_tT z*Q{=KKFc;K4dEP*+~3QnTaDFCZ{06wPSx?+UQ?rg`&{-x{_UNB(iyGJ*i;5#J(t(E zWHRa6#;SBC+niq7qTNiQDYf3V_G0@MDwJ6iE~nm~uzEMGzI;As%A{BOZ?Tlpf5szw z-(Z{-1YSZ}-?6f$EzLAFv}9Akaqp#+XKfoGr6I^ZS*WGFKU;aUZBfh8Y%^b)5j#sM z%buI|i45(HRuFh8WxZl$@#K+X@atRZvIUwUawiAWbqApImd4giSQn0cx2tNKk%GFE zj(N4UtT28R=d=dwb8A%+&5(xosTN(?oSnD;r>>*&vnFbH1!Y*Mqupy6IGj$xaGxpwEK;zD;vk4;P_m^UMjO;qoci4lQl>Yv{qqZ8D*SoWlYPK)PI(LpGXlY zHxA3me_oKk`l^z8>;Ob(am93DmA6Z29lR{tELv)(zP_Z{04R;oS^HS>j&+^$oprRzMCEJk3*$Sh4V9WS z5yF1QG?YEMk2aK|!)7OYX<|nBu1D@K`y9%iwz6h6H#arUYH4&PxsZ9{-BjxOG%qSB zy`|B7RT;t0n0IgH+UBw0eOwTCU-D3J{~CXO{Q<4+*EOY*$0;)%JqYEFihK6 z*Myq*d}R*9IP8-vPwHE6p9s~D<`mqoZOm~0fPU+U*iJi7ApR6uCD|6eR5Z*7-Z}aP zXtx2ZXD7}K=p~*ZeRkDqXY(cZZI^w&p9Fn$e&E@Wy{MLxMtIR9_je^UABxIPL??~^ zlP-02?}JQKkeBkYwAQB;L7%Q(?Rg+xg!jWf4ezgkPP|-9{)5SX64!H>$QUox*CD;} z@)76%rpJ)}=HH+PtqHnwezcsYzREHuE&cSPkIFAFuIW8-OMv)vlSk9a_zn30E<;e4(m4-TD5B&m^z6MImQci@g#Di z!4tvSGsK!)ZaNr!$Z7wlKSxSuBI%txJqJ@g{Ti~$^z)MZS;b+QZzKvtE4y!a5Y!o@26HByg!$8z8#l|o&d7q!aJa4&DotfeKz=ATuYDEyF7Fj^Ob^C;H}`p!HLU=3j7pU z^;G*l3x0-c+LrhM_=i#aPa^zt@Q=7(j%@0jW{=elo$;*a^Opwe_EVvmOFKqFIh45J zu}u1LGwF1mEZvxIHkC4RdRA`o>&Ls|{lCl6=D)-2$Eo~th)~vl=WI>>UC(bz7zqym z&%>yffdO>IC}1kE0?-DsJAj9PZNM%-l^z6C0@XkkxEp zoxnrD7GNi^2N*Dd{RBWY&;V=zHUc|<7l8pIi3h5H?ogZqJ-Kb`N(~W-bl<{h>}S9J zz-TU>|CX3DMeXrpuouq9Hre!fCf(Yv$_nLeB3(X`v28c^dja;mO22F9%QfBo2`4%y zsQ+y(W|BIA0RQ9AM8Ey6f7Ji2*8g9KXf3`Y&woZF3clU9Xl1&gAv3nRxh3U(j`jQM z{Ty-<+Vx6KPXYu~W>{q;S3S@j;dzpLTdF^5Gwo8FRc zsGnDR4U0LNvuTgXc+!a8XmnqDSH^I^uHb$JuDIJT>#%-n9Ch<(=tn_6pX(t}S+rLATW(}`-SP++)-T9JhzWy09eoJyiXv1b5+9jBCmta^E2sq%O!EnC)7{P zJ94ngjn$HQ^35Fy#xHYYJbulMXLC*4_j>SN8*(fE~cUQ&2Tc|LdcQ!RI*OgO$xcwow1uWB2jx;{KOE?DI-$F6n~g z%?&2tiS)nxuv6eQeeU)G_Qs3Wx6VV}+F27C4_<_yJxB4QJCwwMu>YTqa?o7G!YAp! z%_s}z20`(*K=w!JZU;nb@!|8|SKI&BneY8chFU*2w)H1F_x-)lSa^^&{lwZdqqd<= z3)!i2Q&;;BOk_l-Hfmm^ci@!P=w%}ne^Ov$ZN1v;Zy0CxS8=jGVchBl4GVe~$=lt% z<0fK{{25+*$4#)$VK^Gu(YuvuZP6+3kdEP~rM4lY@@uE!ZAiD0Yw=Fi4(~U+ zZ-~rTQQNpYMU;Dv=yd>79tHMIc9?G_e?65s!PWxw`yu#tukmemD!ZtzsX3+R=rfvD zt>!sshG({tzr|F3JD{{iZ+_0Wn0Fo9b8h`?^{tX15z-#Hzn`JL&su%sex6^Oty^(E zosrI7#o{M$UwsG);#mjsdK34NXe1~3Jd7qU z|B@xiNJvw!LxIKjQ^s>zLLHAn+W*|x`1cZdtDn3r%%6c0wVfDu2FhBEYlkqt$*(yS z?Dy#V{YT1U1K@2<(%Bs@b#_X;-=6etEr#(k*O&XOSLC#2p?9>71LM=U_WPkwnp`uu0{m|9P_RD_Q)>_!Yqegg^WwE0rSk{`cL5&+{QA@q(s^CZ`*CI5 zs|FMplHK|g!?IhiJprt`;je2d&kjYuZi~Ij>3jkIeJ`EIsc(^~{F7pT(aU`@)*p%I z96$k^lGECU`~}*odSw10IN$4~+3?ao%1=ld-IadCws2LF7>dt^mVB zx8`^bSbUrZ_WYVjeXD?LfczTCh=U;_$Tb% z{hd(-kk2>_Wd462%uMP|towV9mC8r5tF%V{YCeFA&wsDI^_| z`JI2~SVh{Jp!C0-RcWL3ZO!jf4r!&IS~C|db~54Xm~{4sOZvl?r{C~*twh|vlRQbc z;`N%pMTHAhBG*fRHNXa7Bd`tV4*wn;klxz-@7}0N*v~k82_5Y<==TKn?0KH0}rB7vRFhc8pV{x&~dnBsKB>ZS$FX)RgMuD0*VR6A8? zTi3}(WoZns@D*r|v$9Hjo@?bu#~J|7yZm|6DsKs(fR5!fuF79PkDb48JeYAmhpx(@ z%1s3K2TumeH|Xu2H~Q~*`sbc{#xU5;pH-&x+Vd-K146w%l00NP$kUu(jp+6T#M&mM*2yVZY1q_grdEgVVxfAvr5zXd|A zdn=96*&M4^JZE9OHuz4LAK%+zTl`#FJX9L1=hIO=Lp~n`%^PrFUDQQ|d~S~&Yh9N1 zU@PFi#^GqnI$|GXxpfaJp>=JgF*@T3dhX_9$}HrGt$l>?S6!5D6kSL8rSswxLVgXV z4K>z=3-t;b{L&m&q243+m+v{3t=LCd;#V)~_cWk1Mt6ENZ)NC=`K9%C zCYsCi1_4{0^GolxKRkL-U%ZwaglR)wD_-3i#y7UCO0l-##=Va6I~(yJH{5%^=<20laO>fAd0JR0$|(tnLk#uRjp1v6y>$r;t1v5}M2ROK4A0es6%cHO0$j zZ7D9hfqc9TNX9lK^ieRau5A1dSN7>(%2nOmI>Zz(^Yg?s@R{K0;C!8QetHFUlaHdg z|J-<<;&r=t{on_A%y+cw$uP?>haJ9?N zw?X-PIZnoU5U!_u3|h6}<53$Pm@)-?3W!Y zCJ?3qS$wcNfQNu>z%HOCi!+0PN}w884cr3U4{QQ<051Z4#weHW(A7C0J7V*{F-hMV z{GK>qPs%oM<)T{6|8{X-v=;wr>pjJu`RvO-Y|D3o+q!2!<6(Q|qS25<%MQfXEc~{V z%@55dxg9DChr_G;xp2H{_1u3vH@Elj&&-TQb>k#<}Zf!h1_g3+$OR@L~+}BuG zPriCbZ#CEGzbjkm_!*?b&IM=QD%~d1Z6)2M&^;QZn@Bp{RbIPE zw1vE6=f4}}W$W!>UVh!)E%U`kS}6Tg(ryNZlJ=<}J!uQ-;?oBeAYOgj8rtSB`@R2? zZ>6{AT>2J}0%K?#j(|q}C*CCd`2_RQD^m^W6-`a`+-h5S-hZ|7Y)x{Q1b{HgBlnj% zbJ@9t<(=1(UEPw6x#s!4hPu88D6P?3-;-@9Qzd_c!|H4Axon8)8?M1He=57m>Rag< z$_(3j3T^$Wm1%8l%4Abo za|+vwb5Tm!#^;`L00?1w8M@0Jx3Z)5wk}#}N-0-l}`pu z?rgC9+Vi9MH-VMk3h)r_O9}7i)p>ACu5liX%V*@_54Zwq566mEuJqtC13xIDA9VEDxNR$=knbRT`xdo zDoh22;R8+v761*vI^cd_6R;E5160u9$v_Q|1?~kN0e1fX_TC1-%Hlfse=aO!i6FZQ z3JSU)ARr(6&8{xGpL{4N!lD@0$YuA!uI!h4cLfYKOM;0em|$XB?2D;3*kG$IrrMGe z`;wL<*kXb$NwL*b6Kyro1`}XFkrHIWx~Z z^UMQ$82;~TAd4cn`QL+D9O=6*%*WsLT%qlrGXGlxlkhsazwURsb1o@|1hKEIVHYPo zzjNi2^AjZaV>A77wX|7Yux*q7}4zmMXN#D9&U|BT{3&-n-Oo3;!I z|KQ6ZvrYWmSw?P^k#qfNk`M@@$CLDl(evn6KpF6VBKYm!tNP{MGz`lbbKV=BzWtZM zFT9Q}b2)rgu!Q(d@Ng6*NxD58j9)q@;r_d|)vR{$t-_|*W;>r*25&6_Rp3IEmHCXM z;mhh=c4Y^dOP+T@uY^h3p;YDE{4>3r%^G$ie-K=OJmXDpl~-n&3Z{{-;Vg%?c4(>d zPPrbK?b*3!5xRA@_cG~OJw}X9xird>u~ot=5&JCYU%}jG$i6hQ=iz7IX>)_$SnW z-~W$ktn>pHM&TbnM#qvq*x&w7NB8~zVAcYpFPzSOx|Cgl^wZR5#_s-Vk1~DERKTzY zAC)o9)hWZC7U_GP$cwDw7k`9{khM_%{wnF7{mg#o1;mTIj3Mdd3zeSJ4;_DDq3)tVxQ*ru8JRJeLA=gWj+hfmsCIEyJal%Wm-1Z zc&iE4hi1bh=jwh7-uqQn>MCuMEPG9NvwoUL@~lN}2TWgs??F#an$4H<*Doa95h?VJ zFjcD~xqV8KPi(C;K3~3TA>VU|!FN>im2-+^oi#}=QB%AAVRs#xkGV?u-y)suq;n~9 zFMH|8T-i@2EMK2g(vKsqJz7!3?WDyvVbcet?#x4y()M*Da=R!`Gji9!_ZgL&jocai z%h^)dPt+Ry$iCAi(zpzndo_(x(qJl(E^jMe#m9@I8)CIRvDVg>_6@aSckriO6FrJcSd`q4!*vp& z)3j;nWM%pxDoRUt{g`ai(xo4}IZ+~i^i82z=xOZWaBoX8!}$0z+l*cXSo;+r$E*7fxr*YHKPcJ|GRx=m|; zpmMu)mn`Xo1V!dIbIOt5bLFlGowmPGPgj{vZ~epR%;jw!w4~&{l)S%x>b%7)1~~sq zwrw|7l}X1Yyls*BJBGY}=<-fmZENG(QC1f6BJ22_uUHbcTi?Ccl1YNjx$-UT;ht{S zM|`@BH9FMb^X&J-eR|ERX%&~3-+XgTw6QtXRMpBg!jvUz8j%)f)|uT)lST>7&w>-kmnY~hx3 z)BmM^_rq_>c!GRRlFw)1E1=xc=R~LC!hE@w&B*OPqzHwezcpnQM`xY>5s|8YgA$ z!A!SgUTXHdbIWYbzhzH(uiQRQ0rT73^GpL@#Ptll=24~Gp_qMg{O*`I^l*vzl1O#Ec7tM&I3c8X7i?+VF* zuuy71SQ=c%YRF>n8dgr_%#8{#+8~S%)@JZKW8*(Q6h2frr>tsQLPzG#8={teFz!BhOKsxFKpbS_6Yz6KE4g$x4 zcYzPX;53khm|I^xs7ajZCG~68sG87kMB-A`e>W2)ypDc4_y02H4CY>+p`y>dzAOJU zQ%L*XH*7XAf9i7OzmDTNyH9V9CiR!Hy665oG>?zC^uZDG_=L-2ko&@2K5k64I!(OO zF`Rt3y)=PokLmy1i}lJ{1i;#yoN;wtl5ev0PXDdGvyJSO&^Ougr}s@03~yp@_qWE| zau6Skqfj$}N}wKS1-1hphW{BF@caLRTIBP*qA$b#e~O`{>;J9r39qBeyi-IOKMkg* z2HX#X_tXQQXWH)}6?yC9Vp2Arh{;p(5nnJ(eh^;Z8w=zsXJgYB>P=0QdDQ9L)49IpboaXIj(Kqyn6Z!iVjA7$ zz`Gw1UPqVvdl6)A9qMR6YXb##ZH(&ol`XsZ=GKnJXluOawAaQ`>$gG%RKg^S%->S# zcQU1Z1Jj{h&q>Y0ot@4+JPZrSV;qxrsh>ZelJgbhoOI!Jbg>obpSWMuVfy`n>FB7@ ztU<`y^f3~-h3l!Buk+IhIqcUw)U@U+cKD z$lYP7m#3JNFWc3zDXG7#K;|%T5qy;@C(m&yN|Kze%h){ioeA+BsW7m%OMVvX=6T)N zfdsiXbb))&k@sl10{Iri((V}di340aF?EnNg{1ZDaq4V8?lJ){glCtZPkk51CwF$l zW42A@Z2A|Wi;UxQK8d+t*x&d7fE8nvw5w&av4?%gK98)l%^uA|*1n`&eOc8pJ}Jyx zQ?X@uopj{vcDX& zzi;t|#17o^2D9)){{Ecka@yzLwS3kN;(AK`;B3L|J#8LEMuf*KGJk2OkvZ6i@fTuq zwK4V@vPx^dI--3XdNHyh=XlRUZ*(QOKMU=_f7W*pnN}u8jE6y`rZ4ZgNT$9_lxvBX z{QdZK8ZYhb$2V%cw3#2@#I^KKX=lkhpYqCD+$S|}v0qFoNhYbCp^0oKWuAlV46bF( zTgoLqg62q)UEk6b@3v;99>T7@B9g?%5$AfsnWf8o(JyxkUA(@754#iZ`cie%elKZD2N*e6QqetQChT;RcJ$-)hSF&#s&)-@lPIIZ7GJkP{ilCpIL){7Lwc zj!ojS@rl+i_%u6@h@0me;v0OL`5t9!k9oK$`DHU1C?-Gg18;flD89p&QyVbtC~}*T z%SUcLd?!^-e1P~nUrx?(N*!oKejoC4ke>?w2<*_eJzqZ6_Wb@o@b*cbU%2);hLe%7 z(<1Y?hW07b@&vRGUZ=%<4@t`1Ntqu+PGlTkx^dt3@o=~{{$nq)yOF&T*^Qcq*r3!M z64kaLRo5>=+=W~@4Ma#_el;mgK9I=hyBkw(rI44TyWFtTC=*Mi1)vN9(7vYqx@ zPvMvcLC-_!333+@`^w9WpCqzw~nsFJw_!mCjqgK$)22yX}(-*Y(1~O;5dkv zbm{U*^sbf-&5l9*04htOd->|8s*=Y8zh4i`=cXSU4pL|dz2>j|Q-`hHu5}AI>uq^U zdq``t7$kU+L!z=lWe)pCgLmbS-2 z?G3D*(&u&Gxi*XaVNUY=I~e(=E-(7{l4!iSrlU#RmFXKZDc@S;M8@&CKF*`husz(| zT-r)}U|(AGmTqQG&IkJR_1qD*TC$;I@=5Z|DP>wqnPyU^CiuRmWtVit*8Fr+ZR9QF zrXjZqzQ6V4q@8`a7`;O7zlb*F5g+2y{coI!{mg-wN4mxE{Y=vp+Y|rc%cc4ck=+i% zBxEmy_ZME7Mx@HJEzyl5lD3Rbe%f6fJ-m#-=hp2|)5k_7FVR~Ad0m9;Wy~Y3zU-Le zr_}=8+4#WhE!i))b=Z7)$VSLBf9;Q*))@rX}ex&LyEyO zpYy|KpDz<<*YG3Z+P_r(xXQ7XW8_%-?PVTn-Y>*;iT(8Efv13{f`MMiOZH350Q0+7 z=E3|n`-mi-wK|@>2EB{Gv%%LZ{YJ%2U`eN0@vUISNXqNJpL8K}VflvAROT$=J*A;) zvCBE;_jqC8#?um0Ovx#dp(zfg}wL_P^m@dz;?YCR#XT36CTL4}L zE(14!sh=t9rC=`6sq7cJk}|CX+x;GL#)aDhQxA__GmnI8>C*4;zb3F|YIIFry`pQ@ zv&^@pD#7P-T?HP+DuDf#l;|QqOk3K^u7yX;x;U5SJ*gw|gHXek6{hOw#_oe5Pu^>^ zb*7D_45l6FFQy%@0*h9q-DI93*VJFm&^PTT*VibW{YCQJ#_X4obZ*gj(f74nkD|TC zU@4b~1_|e|8j(xf0@_Z(d9>+xoLhJ+!AvoP(Pk~)ePMonAAx`QbVGa45 zP0L6-KLOaa-iTTE6}sqiulyjag?BVK3KpG69hq9o{`Ow%+?;Qc2X5wCY+LA(e=9mH z08_u-5-@(t*hM3_n(K97^kU9G$z^5w9J5PD#`KjyGxelJ2@}~#bsn_y3{L@k<xd{z%v^`nPk;)^{!T#oI`MN(|33BRx$ zKY4|xk4ua`Dxljnw1}C52>)w5_toVd zNy1p*p!^`bj?72EZ-7l-0*miF0X`Qjx|j&2eR`*We+8Zaej7YX>6d{2gKN>b#MdYm z-Ag*l6t4jP7uWWi7V?d{d~Y1MoHAEl*+VFF@dINc!KWHEeuLspu%sjXM(`bA z&cUTlvS(7pjWVxJRVj69#{1t$%U{X*fxLTP0lz(iwiesB>n{1yyy@CvYuW-GzcYlUw5b7kYY_kB$}sGdz8iQ{P5lTG%J#yK0Gk zak=Ri^`vR<>m%mgf=f>INz6|+kY5(p&EPY@w}7S3w}Qowc7p90=+ZtDD8mZCo}C~% zwfEhT@V?#G>Fvmlf@dpO((VQ4f6eRGpI^*XIWiNCPN$Kky|+$3Z~3ap?*hXsebwIcM$G*$qGoUG}_31?@wrxjsB$X*n7E1 zkSB};u~(_Pgzr!e8LPevmVSE}EPDG}u>D@*g`_=;^ro8hq-6H~EF$+kCJf`Rw5bGa z-`KtAVU*1N2yX$>Ms6S7UVa}Yq340OfNYF64=4tf0c(NHzz$#!Z~!<4oB*;5$qT3e z8UXnU_)cIia0qxFI0@v?5#|83z*=B4unX7+906Viq(e^tih*T7Ga$}q7qAaF415?e zYd~ztefRo=vQ~N`mv9R%XPcVt%G#EEP0XINDj&{}tJH6?*lz=gjYv99*54c0-`UTZUT3fJXi<1SJ zBSHGai`ZC>IP3qRLE7J~HMx0})XRm}&{^3<+Wsl~|HWQ}*U|kp9?bjy{n^ETkFx+r z_IdBX?G@Xs_HeyZ8u(}Et#y4hQe zTV)L5`7r5Ll8D&tGR<4k<^TGe>3eQ{ zbKvWU_F1^tlR_uY2FNNfb(u z`GgBUr)+y%zIw)*pRMo>CQs*MU)DTB2S<9<)b+ZT9n*@`f{G z<6!c4?>DcN4o~pw%>C}jU%33W&grrjxet=}^P2ZqNk~Htb)Pj&{fn!6>Y;X0Z+z?r z$$O1V`Ux^Oa)JBHk!1tPn@%v8yxm!T?#u$;KfHm?SGc@Y=c(0}a(<9}w~w?n9q%d( z=KgNv*ImA<@8rWJMcL)XFUVN{D@a4+os9D*++V8+8$UJZcRW)2{Je{{9=f zI^fD|b(LIXxWxa-c?Z*w7g@(ICaT8FKm-4Gv8poofobRZzs-<4G}X=a0$(>_sehYk<5Cp%+uw5 zRj#F-uXgV%M>$QvjX*8;dNWPDzfNs^ zar*NFX&UZ1+QWN8>p#<%0G4rG;buLLXuHUm3>1HdsrI=}>=5?BLl2X+Gofe*v~yBf%%YHt27HYH)4 zMdmNgbL86?pV+zozKX~_3J9;Gf6)1V`tQMAEnl{1X^ap49#G1f`ppt>}u~*1|C>ea|QHd0RW;E*sXU^2~nw6uM-C|F?T1`p{Ccku+rN^7%GJ z?FYw&CjQB%+5Ii2Kc0#W${6h4lXy!Sl)!p?7&sqeq^$XvsJ?Ax<_C|W*n`N5oa2@D zkoykC#$c8S}^yS+S zbZ2TwzA~lt>9=t$@iOi6<2P|F^Bid_Kc3fvHtOEj7HN3lkv8*rBu}45Y;aTx&ux6O zRz7GWUxlgN(jILyz17;$M^kv?-JAk+o1dcHM}9^MAA7e$J&o>5TV;|V{&eSN&X!#N z->h@wgQVrcIBe;sjF-u_#HP)Z@72dSL^J@ z=UEr)j@lQEnoJ)R`|;_T&#IOUZApA$M}7GUllUY*u_vD|ers3vifC6i(Z*khs(d=% zY&PVCY^%teac{UJRDG=V~x(BE4(D^TD@(3&6L6 z3n|yvIZ53Fa?OzY>1>XezGucZ82mbZ^10w{eWlwJ&h&99r3sAjBY)z` z&2tNTKqVifOMYBo<^>0ks3eUkU?(GUAW4Yv&|vw^_toT7%a--)V_h-EJBd48-zWOC zGIs6rxR!mKB&MMrp5c|D&QJUMz%CExUv2v&zC$&Pe5Pq$^pkDUS6D;9zfKMPtN3NB zi-^&Su={fO)LyZj@#cPBzJXm3-pksur}yW~9n7)Du55e&}zW%|L*yZj5#j+g0;8Y>7gx}4-Cp$o5-C2gxAsi{{R1n=RfX# zggpf&u+|m^bTjf|r?(Bfx4pW(drN1m$u8u_PitLQ+CY4Ud)_4HZAg&$iVJVTQ{(dU zo;RJ&`mxK$&5f50x2b=_Wdg>hjNIn(v1_qOpZXD2v5#?-aRTxp>-c4kDM`|$)u$$} z9SdFTDjmImc)6zpd35&abacotWbTcn84|MGcXxD0Tjj1g;j)>U*!vt&q0h@Lcr5&W z546+u>rQu92iC8TmWmM8SY-bG3f&dWaQ78mG2ZU3-(;TfES21i9+y!c_ZcA(5?#t! zCC33t%gKwbgpNy0tIL6x-@ZTW%D+;}-z_(bgb8YE@*6)r^7F~%*BiN*Xu01?NF8#} zMG5ydBl`iY&>EvZrD)+k}kKVss$(%uKFp(B>>5i^V(XJ-fq-GgN?h(a2GVqyv zN2Ktqi#BfTlNdabuZ*95da1mS@gMfy-RINtRi`9f-yw#GjPyB~Tl+Gu&q=#BQ4u+- z<;BmKf76v26jDe+72+ zH^^_j*!C^A2I8mZ@;^Y{W$;V>+m&DRLR7l^Q}tpC0Iw^lK<(4Ox zyG6;n9?x(*W3b-^8;ZDIkG1 z2;V(uC125r-1o|D9{rBkhm0KSX4^3TBBU-rHU{v!A- zu*kmyzL#6h-=_=@6VHA}Lw{WHUx4=_|1|h9ZdHE{{&VbOJmq`}ep~OAL1I6l?01*F zn{sBa+;7X?@>L%FToabh?p|M=Myj6iz_^$a%6KrgTdH~<_6P5|R* z#5urPU^B1}_%QtU*FY9Uboc*FT3qotET#0DkM7q^LB(O($z=Z9l#K5@35iSvDZ zIrOznY!lN&ZgMCm>Dsa<_M`Z=jl1ua_fVW|?^fl?9AXakTnVfJT7m7rZs5c4KUV|q z6V4ko|ILGRVR0K1aJinP_$4h@ z9UVmCr_sJ|#t{Y6xtb7xz=XH}oGRG%YMfA47d7Ha*jRsG$n`im%i z6wXoddtCKbqUD;X`MiL`5c)Hkey-;GRDq3uSosTP+UvR^i(gQEy>gMgo~!XCs=qt6 zevfPVZ>s(uQ9Zsl(#o}{{N1YOrHV%>ep=;TQ++?D`d+Pio~ZTA&9mt(RC~Eo^L<hDt`J>%ePwX^qbl)&uO`4soWNApXG|DD1KY({j}l-6pvSY zht~gE#nTnPGuP%jeU8Pi%(8g0w)>kG+v|H3kJom4&Gl!+Hzt@>IYG;%_)TuWME*O9?^oQW_*!lEDz%^S zieJc z(c8mpeMTwf{WVj+ZHiYbmO2YOqwV&dw!=5IpS?6i(^31|qW!f^?V?Wm{akI|DXOPu z&$My{TCV3bzlGCm{Bz2`TGMG!J-){LK+5xUj>Ye&{lBDkHbT?ASM^q>?fwv6Z%`~G4}pQU!$qxHT=%h{uNwfc|cTAqhB-o;^{21s^-Y@JW7BPVG3{RuXgzwg9&N5Yv>wl@ zUZPr$Z)^LMsD7W*eBRJ;q(t=}Q+s>F^#k>{qqJTRseQhw*Q?cU+^v519o1Jbgk!jZMTSCSLNCIKdXN5R;~XV+J9uRnkoj5s2<*%Z?DU> zJP(!G>#wLDT9p4`)x)>dU%sH_eq8%kO!YEX^-`tf+@|Btotj^X>SK!PXS(XIMBC?n z)k8$}(5CHktLouSy*`robPdq(MZ zXuCY8?X^YiHKKT_w(ofDXOHQ)@XT4Zyf110dPwVallGfe)Xv_~`rNJjuW5gpsO6Zh z<$YY!c~bLTsCL~p)8_MS)$eo4zg*k>1=Y_z+Rk&ezuchhJVN8YsrlWhetmH#O%$G6o!CTsnFINGNBi1Qz+w-VLsx3zu8YdIfNdwxXId0g$| zCAI4}RA1jweLbcAGxAZJ&rNFgH);G2bsV`@agX-HrK;CEFSBx!wH@D3J-_YrtoHSS z=J$-+^ZjZ+5iQS6n(kLrpO2}2-gJIN_4Ksr^(nQN)tcY6+8$47`Af7tN!GOgd)f|@ zr`qeMRe#^nd|p$%wrKnvs@D-^mj4m8mxXG_OO=0&_M>~$uYFVfNL1V76>W#{YLDC0 z{+EtZy{R9n(tPgJbVq5q#;e`jt$g3n`YhD;jHy1qsp)Oec6vtjTcG-VK=t>6mg`N` z-_xqUa@BuC_4|dVEalQLgm&l)uXLPp!vu*|whJ)lTkE{oJYT^?=&N zbWLx%>i1!_zghWKey-|oqP9;=`^9Qaf1AcHRD1chmg6hhj@K%FcBDu^x!zwMu-CFHwD#XN&F3BG*R*}AG@otiAKp>>`Htc-n*J2E*HK!& zi8`LVr}nj6?duiwD-%`E-&FfqsP;2L>pfybC1<{71zAf+2ie0SK~80FfN2JmIa7mP zR;Wje$PR`Hy^3}3VIzVSLhl_5Jul1Ahf}w#5kXe=Fk-5MAa89jtTJF>5D*=mC3JpZ z65DbrSvMlCGAG;8N3edGofFi8<(uF_7lumuZ7)AZ7&?2$kT>59uOt;xt>mwS5n0Ha z^s}=~{*^(V2v)Mev=_cHmcAs5_OR(^1$hq!d8D7U4f$+2R9vvlj$ahs#7v+Bd2I5N znj@JF}Ywr$WMK>l=gUQkI(WRZ7H<(U)nwtZ??R%BEpdl=aV zBdBTKRH>O{wqgnTmjSrYk^i^Gq4lb z4LkuH0bT}90P-9(50L#}wZICX8R!K#V;d)xoRcDFj+k#Gy$C)DWKlR#>P(;* zSO%;CIsy6a`h9@Bi?JU#1UwJC3IxNkDIgzM0@MSoz-C}OuoKt~>;;|x4gyC2*&FjR zZ~}N2$VPSJfIMIhPzKZj@_m_Rpd07~b^&{UeZT?W81N$SI)MELThZuUz@xx^;1Do@ zhMxw=_bV!ZdSERe-)Gni>;z=Zd@pbiI0768P5|!$O0O0?U9kKoigjYz6KD?gJhK9t92oM}g-7>9q1NWdbk_ zr~sA#^*}4I9oPx%2A%*80>^<9z`MY>F_a&W?*!BWD}ZL87uW+F0FD7K04=e%J0;0#5)h1MdRa%umMwdB7Z?45$TG0K0%a zzyaVea13}6cpW$iWZ{`|fJwkiKs?nlU=7d&bOLt)_W_Rr`+-BiQQ&#tEr3lE!DwIt zAm=Ez0-J&Dz)oN{uopN8WHYvn1M&blueS`S1y%qJKsT@p*aI8}jsY(MuLCE6EXKS_ zU>UFmXaYKct-xJ?oUQyI@F=h!I0PI8o(En9-U7s_jRqzF(*QXiw*puK)B|gQR$w!* z9oPx%2KE9^07rm#fo#U-aljm)45$TG01ZGh&<)7ujvc@*U=OelH~<_5jsY(MuLCE6 zEXMIkz)YYRs05Y)Yk(%86Sxof?-n@!3k#`G7iiR(r-9*d0QUM zyGZu_S=kp;W$h;1Fi%TYx#C2bWxQ~CuG-kr+M06efXmnNseFmN%Wv})otCH3X?bAl zSFj+N_uMqR=UU$Ua?0h>Jw&>xyf)63p`0@CPQPixnY7ipLE@vduFN(*zZBP(5Sdyf)6JTiBH7bCc+E+2%t~_FZ1r=WM+4#}ake9`dj1jFRSvy7zasPM>@rEpL3Uvpme;0Hf=#+Ky1CEFRE|S!aiG zPv_a8uZ~dG@>tnI3g-Kk;xzVNtoEMojs4A(r8ux3r*~~+<7~S5WeNKbpLK=TU&X}n zp^bcPBf0@QaPpSV$`_#*zgz`r%2nXX<@H%9LqVEyg}n4xKiyer(w(KgRKAAdcqQFb zUK?l1o8N>zIo=~_cx{~JjbS&ASL!?^O&O+W85+I0*%N7aZJbTFk+yWcZUR1KijG-` zg*vwJ%1?VbpDN`j4XU~}aB@j|_thQUSNF8GdUBR-3%Rac zEsx52<3Ju|Oys$=ePy(LLu_e#V{1>G@gPxV%V*^a(4CvpOPLl173PFT>FbzGSWio{ zG9_M{%i7Sw6n)z`%Ug&}!u0Wr3++9_;;v|?GLsOY(LM9tuwlG-P)9&7$@nkGb zW!5G7hpY=NH2tHiV_kGzOKVH_mTT6djg7pz>&aU_m2XV+d0DqysBOK7X7jQR%WHX5 zwkgr>&GbZM@;nZ}R%0q;p1^`k$fwR>o()kB>;hJ3@I2;B~rsm2^j#d079tvOKm- z1)d!=perlO`9qupcg=d$SUgc5%cHVQ37s7cWv`QyQP#C`hMd#0rKt=y;PhNUAF%oL z&BxMI20c5Oy++0wTWWh+nw2T^`uRBe$B2Gxz|vF(yK(-k*T}4l#rb@lIgXbvu>0+5 z=_=>hj;ytg2v)_~n_TG3BYS zuSuuxeXosIe*BZO6|upH=9~ILt7|*UV`cLxvzxO$@5`n+#L>xHK9y%O<=gZ{X>9r; zH*R6mt}V8b*G1yrQeKj9d04v5qY-=d^BA8d56*fw>pNxmU8jo^9t@@Y9@i8|~} zmbb%*Y43y|u{*;BDlQ^;@Ql^xRFods!?R@Amj@yz(<1JN}*2mGZ>(E-KWGjaPo= zua5tu;n$BHdgw>}{{ zPvy07Hr*Kgz}a6m`nx1CruI2R$+ef|Q+fJ^o2O=x*F5ju5_b{m)Y7bu)X?4v()r$oTg7%oL`oG0rO6AA7Ob^mV8{< zPB5pKr}OP4vDQvGXVK})(p1LN*MaPWjGH+-8B0?ce2U9Q_7lw0`Kz2-jS9kiEKOyi z2_1{>&rZ>?jkCN9(1G*o;`h!rI;f4UkM^`OM#y1UVIG!l<;w8uPIs@S$}OgFOWW6X zc;&M^Dof)z8<4WhPgB16YR~J}CGvUE@NPKeeQ_v@|8cs@!xrZEb5CSxs=KD-vK6H% zTahhWLB40pQjfwkyoHX}>%-Ew3)8H*g}f>E&74eb&Ifb$A$g5d{S&PFUvWm5XvxHM%Sr)4i=Typ6jr0nAuBUklwcG5^OR1l_bX*T^b`hj1EaY5g? zn$#i81K(MyYXLh=yjca6qmsCfso@LF-Bs^=KMLMU`=YG}lnluWEqKPzK%$x=-n$WA|)igZcC-)O)onm~lJhl!C zXmi&l2hfR?HOdUz(8epjHY&O3!pEsxEo5uLieA@h{He#U%DQyH&5 zuhR}rCUwlWG?huI&pB!8bB@-h+^f$a>T{0z^6F^3rP19Ln|S+7)AHDS%BhbV!#k;u zlf5doMZS=3@2EXl%cHW?%lSCb`I%|Tc&3)In3;;3W60Qdrk1g`CAtB()k;)ola_At zDE9oQX<{f)t&NO~X4@dF45zEBk|_o62kBY#B<>ubU%hp`)?JUXm8&<)J*! z^t;14SU#0!oN;+=HS#sB9qoxVc^jv^O$j}TKN=gz_t!X(y|E>Ze>WQqTwk-qG6A9ZPJ`Ks1!KJXW^UTMKy9$dccx zo^{<_+^xxm22ak?RnF7p1R8W~z?wa0wKnxM@&qmEF-MrMDBV6EH>qQsGK1_HqE$Ze)?_Pr~`0&>BwDq)_T_E*LvR&CNO=bLfVFsCFhNd!%d(PG?c`iOS zsO#$L=vvg%ZkjbIQ=>8wk%*_zQ_I!Pr+ z)Z6l?Ed9;3_mKg}S{{|9|GDewdt6g1H$mPci=3nwf0TIZ#C?m&{EEm$6v#TJ}RuEE!wCukY8@~OOM5Ax1{mv`Fd7M4e4(T^*)=%*}Ax#M2BEsv2cD8Lsu*_V@L z)8=b=RMwkM%bc!^b}wNk!IgX{av&(c-SE9dc3$XU9|VUtdWyRm2LC!fV=Y1isG-)LzngB>~<+1JpY zjHRheQ$l7milSa=^RYCQ@qE(e3^JCcGWZ$aezMZoPnOz`*tM%iK03?l$0u2uNk6{; zn{(|W_2Wcf^XzI_%f?u1OLIpD^>jM3bd|$bx<0holS_VXk&v}KDvK>SzcCX%WDQ_n zy5+MvDPrt*c|U06Gw(~cJeoK5=KY59y`y+Bhv&%J{=`P9|fE_Mr@Y?${zMvH8>hV9{JtLFm71=NQ(pX> z)0^D8j57C_OS@w%csbj(@yd@boV{-j`Rn=AQ@pbyp18NPG?k&voy-L6Me~Tel{%M? zrKt>U@A`)(&@p{R0ex;`5fnc z#s2cKG?l@wobGCKMTU9n@|O0FF1I@)p*u@gId6PDbe781bgbvjx}(d}gQcmAH>c}8 zTgz8>YY*E7ySI2UmZmb^J>`LMDzmhmXZcpj>A})e2EXO>Fmt??ZAmoVT+<<2e?wcf zG?l?mIosZKuE>~z$+S7-xADr4FL(UK6NJC-+}Fk%{(>UP&(^aTTX*B5 zygxTb=TQCaW3xP(H+6G5YQ`5O@-|zr(td#2>B#bH8R$E1+{^-(p@sw$lhG|${O@sdF+M@v<8tOB(7+yUrpVp%( zQ3jbGg!M?CoJu9ImV~WaUM&NC-L>gm%q3hIl9NctS{}`x4(HqJf;9HJz}jm;foD4> zDa(RW%&jbsEn@*~?#lQmc9%}pub<^nS=!0To}`^T*|c*M%cHWik6*vaH1(_0`V~<| z*Omt;OyvOfF<3sEm&_NO&)H0Wmb_B$w{5)Tmve&rvdv9Xwzv6Q#+*9}o%cHXBu~47Ot)PE9*;9SM#Q6#RTX7x(`A_Lrn3zudKry)uwzUJ^u~^7G{U zkAx{MXHqI(NQuoeZ&=6Y+2@Mp9g(C9voDY*SFyDPK~c@3{Hoe&Owt6GU;6y74qnE_ zBrL<`CI92m#5>NXm;c(*ptx{B)uLK?^kYKiyw?TCly3=G^3Kl9>c8&wT|F_QhIyv8 z@p)l{rxin5TO1VDZm)x?g6c)3wWVr+ne*;4XQ@lx&IWc3%mxxO z)u5!dxT>f?o=r-~oZrIWKDGB_R8;D^Ig@U6AJ>AKn%dfGXHBQd< zkDPRN?Y`YTPj76Bix*TC)>Uce$y|>n`M!z?75tSv_NLWaN*?nnE^oYW+a#}< zXJxcO*N3qU-sV`>WA5sU3uK3UNJyo8upc#K9;Upk=9!_ibI+peEqq0#c@eG~) zOYRYsbEDOz`6Uc4Rsosoe?uV8&n3w7eksd?nS7eO0x8?+*nnEMsI;!GsDzn^4Vm+~ z$(*YtoX5#T@(I$~Pyge$eDn-|U0qwUprEG8sycI?^+AKlh_iplPJZU4wIj_l+*4Xu zRK;C?nbs_G9u0x)Tad6{>$NtM{!CWxxhBgkrA6gMg>LjYmE9~0_Om}%!cKg%)MtOD zIZ(oGym3E_^a@c^TV7b4U!$XL=K8MXygyTf;8l>6p>n|O=r;V=;%uQY3kr&hsuxuc z&@WsT?34@%Zv5>$SH28kL&B$~vmxCLMV`gQ1!dKxb+t||bA49?4cfkIwS8x%9X~YB z(EXV=r^&6fysoyev_uDu%z14Nwrc$zrEv0dMcOe#^Rm;axXCG~s;jD7P+qIG%AC)J zV95wud)Mb*{JV7iRr9H9?U=_6n$3<2&vNQ&iVN$?O5Kon3SV1c&fAlm%T$-mndTIs zsk-^2_&tBtXqT0|7|$t&uCOXUzpS)sKy$2*2d}FB4^u|@nV-qF6Xi>t-#e$1S|D2xvRlKsw1 z{wpa@-NWx?y{M|Xs<3tet4=m#&U?MNmlMuQjKIn|${y=(gP_Y;}gTg+d3dudI6VSbI9xt+?c zmYcITsiv8eN_{Icjf2wPuhI$?CV_)P`;?9psZMLRx|79ns82ZKy|b>lO5QBMaIgSvZA80!bKE{kU5X)K=yw~ z*bkVWY43TG#>$|&u&AKCu+}a4oFb2MbAGGj@v_$AWd4Be_s!rFpJyv(1_QG;80W=D zIRG$R?x-tfxnscsvwVMwvaAdarPOzCCYx}5D|xss%3oAew5XPaMM7r%#)Af)$4Y3` z`+}TI`b~_5$#wVEc>0Xip&F_d6xS6LxEWdIa@`he)^hFBa&>0(nW<}GJoE125pk0k zwKrWbU!8Vy28vTwR9;hM>z}zitIT=1!YTVNOcQ17OJRAegH5anT_0=N&`iNr^|Yz) ztuE)LvTBjFj#IVQYI82Jl;fbCS=xsl{rIP7TUS zf`A3P^13=Vbvi}8uLxv+jRaTkvVsggF>T)RQE>EKTUJjy_OwejK}&Rh(z+^XW5MfOH4 zb31kiTXjACdG%%4nc6YYXT!U(Fv`0pE3c|8uc#y$>yHT*{_~r<@67_r!FYVE3T4j&;DmgUzKgttAXD97c&4)!TYIHG;%u7RyP>f_n4V4k(r)m4`* zpcmV8Gq*`ya3tIE$vGUNhagjb3bRZ5081Qpeo1jrS#i}s@@_TXBM{DBK=N)rmH%)C z;OhM;FUssxI`6JoUrQB_hM1>&|bObal@4?#; z2^x}UVkSC$BOSSOvmwIQBqYZKE#^q@b;;K$Jer?o)cBFn${pd`^e#k#s99H-5YoCF zi8LF{_bU?lsUwC%>K6xclv~wnuH^Tp0exfuZ(Eq5&~^e+e+kKQt?~PaQ}ai6i=u`} z`F4A>;emX;(S}G+Yo6`M{j>yKwlKdV!R%bQ2jWvgCM45>kyk^T8Pd$rk>(1$wA}{H z)nRy$<%&$1M-BTlG~4>A`31pKNphMvC=wI|f0HB^x<;diENXPQvWJ-&xoB54G#%Q} zU5gy)U_vDL*>~kxyKCEIIqr#*Xvyu@ltgnW+BWHgR;f{0!PQ=V!*k`H!ljg&-=9I_ zGd(6`1=E}xpniF|Z$fkZm9OF`m(6cB4I_3hAwjXUo1o=dQVOjgXou$PMTauO8DR&_ zZP2ExTrw>P{ueY?mJyseplqfcjzO!`h>^jMmL_QHJH#iSr4jTCS1jbBZ8M-v>W5Yh z&Gn;HIr)xqdfKLyGLLh8)A2|an34Iu${k^T=EzNR6~XJig4~plrawR;HxgyIw6cTf z7DtT)?Hk5Ga~>cY+e*-a;FHi?e`m{Z7$U(FYrhDsMPpoh$R+uWJPFO|C50A@!;oA7 zl4)_C+d)Fk ziDhHU%4YQW&(LlN;GG7n-L}uMW{Ie+ogyMhVH~{MmOm;#~3!C6yNBejXazmrO`5OHb=w zXwDZn-zAKcGxw*^TpPJEIof;BHklN~uZ53JP5ruY$j&E^3B8c5`!)zuRBlX4pZl3tg^G%(+kme|oUtaD65~>YpbT|!?W&^aV^g21e{QR#I zk(Zz)wZr$I&F_cy@6cS^@Y9oPi~X92PbcK`m+EC~QhrIahoF6-AG!H-c2}!2Q*6En z+Qd+9Wz;1qdRYc-MM!fLDa*>}ZfI40P#<$diTdKWgzbinPQ1(~ej6HY#Drwp`i|d&wl_fw$ud?g z9-o*qK=5f>Rzbs@T$&y&2%^xazS8X3v~nS7#-YuzB;oPoqHVwD$tBZPZG0SBQ7AWW zk^UsjO)Fo9=Ee?G6b701uvs{q_axJZhvqbVc8Z_Kf#&!fmV_fgU2qXJ=gX66d^-sm zDm7tT5Ubap$l>Fmxw)I;5jwQo??Zb@nK^qWUw<08KRGwiw&Rj)DKGcWpt-R>InBJ> z??b~)nvhES$A0C4;Fr)gq?HR6+(2foA0?+51WV~CuCLG}VTjOj>ma!PkW6F05VRuY zPNo$H--G6C2^EDw^!Xe#*Y3%*RU73y^;4AloRsnJ90nEVU#MyrBJh z=#u82Ky!V1LXzLj&)*Nt`4Hq>5=QPIwDUC+R1^l%%>5^5Uk+)>HrS4kYrly}^Fh|T zpjCu&{(OSi=EzHi8MZP`n%6VR3&&U%F86TEIyH(jKRv3i#m(UiZrA52nhQ@yr zQsr`)gxsVwrvtf+1oP_Kp=}Ili@WrvDa&)v$~D5JEtgW3v$$z=bB$ygHU`bjCng1} zT=GV41~g}TBp-%IaDB@{Xl^bvIcfZBtyv7s8PMclL9r8*@j<>h@A~8gfqQ}}8e#x}F+#8`ee>M$X7euZtFVQzsX?HMoz27!GzmkyADV0TnMwUU2)+i*wV%sZ z)6D$_wBOZ)_&!ULT`$8Zoqw5?;&*R=c4;W*``wnNFGF()%?iRtL#CX64b9bSR?zOM zU}!&w=H?8uLyFXWQ}7?qoL-V?JVSuyeB|t4Q79SVR~ena$z6hNL0ca_kt*N963 zd%l=lirnu&b9KKYTqU-&JS<+125GRV!M^SCxjO|uM|8-tT+ z@z@Gzi8{#Jqc%t#z7EaJX;SNO0NQHhy#!l!LF97jkZvC0=F37C+Qrb^STiT3el^f8 z7e+#|-23lugZ2$eN})0TqLZ&lOY4q*9-8cLl#rZewCigalC$}_LDyQt#2+c=W6%mT zVs1+N{TNzSNYfu6k^2cWw-!G)seY}|zeG(}^&>ZmhLQK{B+RwQ{FSIDDfrzQmrA>w zh<{2;i^nF;lkctAFfYm1#kwk?b%r$GcH{AV(4Gis{u*_BS=0Q)ST#TFHMZ_u(42qa zXBenM?k9+Fem;d3e2NHXFRtH{Ev(N?Z|GF-Q=H~j~P*lqKF=%dHR_uhpLhFI{Ir%|Irp06L zV`TSR5;T82igoQG2dZI0anKgkpQO1W_C07$pUACE(1PImNi_E~&XgthhtS?u=3-8K zazTpsH&p5jjVN&hu+V-8EhnV;eyKGo-;+3JKPYroQ9X}6>DOrvEK%J{lQ zlm^SZ`W2P$gH|LN6B4Z;Wf>X#l)@b}lvEmH70hQU&CRprQj&Tc+L(~$uU!PeUqW+r zPnCNbTCU0^G$v`b#{Uu8Xr+}0-5vT9TKo0?0u8riLU~}0RWQG$EN75OLN2L|f^(tO zSuwAN**Y{N$@%Tj)zb{EDU_SHSbtKM=9VK#a&9NOq#5lw4((&1T-0kLjGPKztTZ=f z$)!Bwy8&8#S{nWn+7tcIq71g@J_!$N%-al3(#&>>(L1@1u;vS7jrp05QT*$gdNQ-)9S=D$Ln)9s{ z0gu@=NSglu?eH z1`QWu0?CH~yKejuG}jJS1Wi4T7zxS>e*$faM({HXlIHNrgneESGWNZ~^AbFc@RfP~vg z>z^spaMC->?>6!~3tB2v!ZTxd5UgZ?IZnRK$WEhPe?i=n)Tasj7T0T$eH@;eOB+`6 zMtZ#A%Gmn#4YeJO<{OUjhUHuGYP&i**L7@e*wE75U^nPF6z+FvuzP45GVdRr*BBpM zKJ5Ew2=`PCIu(CsUxU6~HR#0pR9&{`dN1~{b2=r)+q-MDHR!DE*0Mp1CraM`CaFOu zo}^>9TXoQ>d3%fopGK>ESZUDW=2Zgo!rGvdFuN=VE$uaz+llQdc?goVsl^-ICaXSM z_6DB^U1HF}?!CkY`-=3S)A5uQZ?G3bnU>iM{=xdQcsKt|pTT;`gr#_O4kHsgAO~H2 zDX4BO9CR9CvwpBX<#Yxff{KMoQUghJhCc5&47%d(UF|_9kfD&?3lP77Q@*Y_Xx&(gw(rwRBEheJ@#|m65|4oWBR>eTsAEGJOD*oV zrG5CZ#0LV&u{0; zjqzZ9ysL43b1d2v>sr^^(YVn@tZ(5X_wySsZRjzJC%4GrNmICZ(zYe9$y+>$n^&nD z6m@euXMQ%c${lLFq0?f+)ZNkPy@+fG(&VNPA0W^5=E&p?UD3|wc!RwdiewX2v1!H| zHt4x=zll7Wx}uxfqFozW+J~a-yj#s1mqU?KJ4*rCuvq9MHkhmnoZ)<*d_R)<*#`=I6aa)>wFrr*S~k!GGhr0L^()zC1ljUM)wH!8{8y}==`lCX3M@o#>Z->nM%?S0Is+hHz#Awmk)zZ;r zBZs2BLx((MEuPl$hoY#7#!l5qYxqH+p;L_5O?=3dBHds;ry^|}+5!%RT5Z=Hij)!! zqywc*+F0yu(N?B%-5qvfH)LJU>Ge17S+p+RjI)n#i4R$|`e?F654cI0dbG5+$GUz4 zxu$loO?r$?yr*pl4LF?K_sPyI)(%}xHYJ_X#~YhtO+BqcGFpoHHR*vQLvDf_Z_5a#1G!O+|5&{jek6&Sjko=^!5{Ibh??p}otQtB}z>-B4?@u6+; z)ULI`9yZd=VIxD=zq|@=G83*aVrW|?OjZHJFbJGsqdGuFoe_QC|O{&d-o|KQ*cI;!7Y%2qlX*n<;1!U~aWw)_|yZrB?e z{G5$D7lK>ZJTnt~7mG#goea)rBhGo?HvrkNd!B3x0w3jKD!7xx&IW&m>nY&BV}s5d z@O^CfIR|_#`LJKeZ0eZ^{yH0TWOJx&=478wFrR!UgPW1NL@yj-mtwT(Dm@ zc%FP@!{P(*%SNr;re15f z{GSZ1I!`5tXFPUcODx&5par-E*a)-&Z9qHF z0dxYl0$o5H=mvTKs$|{=Ws9qM7e)4lRsvN(HBbZ80(HP5U@@=+SPEPTTm>uxmIGq` z*8nR3RByUA>NMS+9%@{SbZb;^x;rLh+=z5hackmoq??N?lkPhK5H}_+QM$EsU2$LH zlEi)H0aJjfz(s(#oaq3~Y23j~@GM|9a0wu7DDGq)FdxVV#0`nd6E`BROWc{bVz!8z zJ}rLyQs7!(C9n#p2UY{u0oMc4$8P{W2HXfV05<_LEZhvN1){(@pb=;SV!(P}1JDe# z0Ji`efmWamXa_ogPT*Fc3y1^VKo4*munE` za3}B?;IqJ8z}>*-fX@RvfO~*10AB=l0`~%60=^8~2YdziZQyr+UBLao?*jh|*bO`Y zd=>aT;6dOa;P-*A0egUlfj8m0a2R+R_#5DFfg`{(!1sY4 z07rpmfxiR(9ykX45cm=B55RHYIp80Ge*&HdUI2a!{4?+(@DlJ7;HSXLz$?JN0RIZS z3cLpV4EQqIff}F|r~?)OivjWdOMxo^d6>5hSPq;j^un_Z_!RKz a0q~zHy$|UhYT!c+e5ipBHSj+}1OFe}&rPrZ delta 47811 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 Date: Sun, 2 May 2010 21:26:31 -0400 Subject: [PATCH 12/14] Removed references to a Variable's factory from Variable itself. They were used early on in debugging. --- Skills/FactorGraphs/Variable.cs | 10 +++------- Skills/FactorGraphs/VariableFactory.cs | 4 +--- Skills/bin/Debug/Moserware.Skills.dll | Bin 63488 -> 62976 bytes Skills/bin/Debug/Moserware.Skills.pdb | Bin 220672 -> 220672 bytes Skills/bin/Release/Moserware.Skills.dll | Bin 58368 -> 58368 bytes Skills/bin/Release/Moserware.Skills.pdb | Bin 200192 -> 200192 bytes 6 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Skills/FactorGraphs/Variable.cs b/Skills/FactorGraphs/Variable.cs index 0ea1e40..7d64f51 100644 --- a/Skills/FactorGraphs/Variable.cs +++ b/Skills/FactorGraphs/Variable.cs @@ -5,15 +5,11 @@ namespace Moserware.Skills.FactorGraphs public class Variable { private readonly string _Name; - private readonly VariableFactory _ParentFactory; private readonly TValue _Prior; - private int _ParentIndex; - public Variable(string name, VariableFactory parentFactory, int parentIndex, TValue prior) + public Variable(string name, TValue prior) { _Name = "Variable[" + name + "]"; - _ParentFactory = parentFactory; - _ParentIndex = parentIndex; _Prior = prior; ResetToPrior(); } @@ -34,7 +30,7 @@ namespace Moserware.Skills.FactorGraphs public class DefaultVariable : Variable { public DefaultVariable() - : base("Default", null, 0, default(TValue)) + : base("Default", default(TValue)) { } @@ -48,7 +44,7 @@ namespace Moserware.Skills.FactorGraphs public class KeyedVariable : Variable { public KeyedVariable(TKey key, string name, VariableFactory parentFactory, int parentIndex, TValue prior) - : base(name, parentFactory, parentIndex, prior) + : base(name, prior) { Key = key; } diff --git a/Skills/FactorGraphs/VariableFactory.cs b/Skills/FactorGraphs/VariableFactory.cs index d6cb1d9..1e1a5b0 100644 --- a/Skills/FactorGraphs/VariableFactory.cs +++ b/Skills/FactorGraphs/VariableFactory.cs @@ -17,9 +17,7 @@ namespace Moserware.Skills.FactorGraphs public Variable CreateBasicVariable(string nameFormat, params object[] args) { var newVar = new Variable( - String.Format(nameFormat, args), - this, - _CreatedVariables.Count, + String.Format(nameFormat, args), _VariablePriorInitializer()); _CreatedVariables.Add(newVar); diff --git a/Skills/bin/Debug/Moserware.Skills.dll b/Skills/bin/Debug/Moserware.Skills.dll index 5452efb7c851a38976347ff7aa325a0453aadf50..52a75bfd053175766f03e3f7810045624a7e3a67 100644 GIT binary patch delta 13591 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 delta 13641 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 delta 15232 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 delta 13496 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 HE?508n4E9g diff --git a/Skills/bin/Release/Moserware.Skills.pdb b/Skills/bin/Release/Moserware.Skills.pdb index 41589475892323ed2b51abc366590a7427793f11..0449ceff4fdff1d8975b8616d224bb7ca0dd918d 100644 GIT binary patch delta 11587 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 Date: Sun, 2 May 2010 21:31:09 -0400 Subject: [PATCH 13/14] Removed some old debugging vestiges of _CreatedVariables from the variable factories --- Skills/FactorGraphs/Variable.cs | 2 +- Skills/FactorGraphs/VariableFactory.cs | 9 ++------- Skills/bin/Debug/Moserware.Skills.dll | Bin 62976 -> 62976 bytes Skills/bin/Debug/Moserware.Skills.pdb | Bin 220672 -> 220672 bytes Skills/bin/Release/Moserware.Skills.dll | Bin 58368 -> 58368 bytes Skills/bin/Release/Moserware.Skills.pdb | Bin 200192 -> 200192 bytes 6 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Skills/FactorGraphs/Variable.cs b/Skills/FactorGraphs/Variable.cs index 7d64f51..80a3bc7 100644 --- a/Skills/FactorGraphs/Variable.cs +++ b/Skills/FactorGraphs/Variable.cs @@ -43,7 +43,7 @@ namespace Moserware.Skills.FactorGraphs public class KeyedVariable : Variable { - public KeyedVariable(TKey key, string name, VariableFactory parentFactory, int parentIndex, TValue prior) + public KeyedVariable(TKey key, string name, TValue prior) : base(name, prior) { Key = key; diff --git a/Skills/FactorGraphs/VariableFactory.cs b/Skills/FactorGraphs/VariableFactory.cs index 1e1a5b0..d07b5ff 100644 --- a/Skills/FactorGraphs/VariableFactory.cs +++ b/Skills/FactorGraphs/VariableFactory.cs @@ -6,7 +6,6 @@ namespace Moserware.Skills.FactorGraphs public class VariableFactory { // using a Func to encourage fresh copies in case it's overwritten - private readonly List> _CreatedVariables = new List>(); private readonly Func _VariablePriorInitializer; public VariableFactory(Func variablePriorInitializer) @@ -20,7 +19,6 @@ namespace Moserware.Skills.FactorGraphs String.Format(nameFormat, args), _VariablePriorInitializer()); - _CreatedVariables.Add(newVar); return newVar; } @@ -28,12 +26,9 @@ namespace Moserware.Skills.FactorGraphs { var newVar = new KeyedVariable( key, - String.Format(nameFormat, args), - this, - _CreatedVariables.Count, + String.Format(nameFormat, args), _VariablePriorInitializer()); - - _CreatedVariables.Add(newVar); + return newVar; } } diff --git a/Skills/bin/Debug/Moserware.Skills.dll b/Skills/bin/Debug/Moserware.Skills.dll index 52a75bfd053175766f03e3f7810045624a7e3a67..7d29b38f5d2b81346f2dc57f806f07df113bf512 100644 GIT binary patch delta 15118 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 N2K$BcqOOPj{{R5_dPM*L delta 15482 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 diff --git a/Skills/bin/Debug/Moserware.Skills.pdb b/Skills/bin/Debug/Moserware.Skills.pdb index f1ac5b1d16d92b844819aa18869c108eb5c9a182..fedcd2f2c99e7ba890e92b2166c77464b4e1baa7 100644 GIT binary patch delta 14642 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 diff --git a/Skills/bin/Release/Moserware.Skills.dll b/Skills/bin/Release/Moserware.Skills.dll index 57140f5a0a99452fdeecbe58ba4eb973b636dc21..ce161dd3b2212fa6b1872794e6621881dc02a899 100644 GIT binary patch delta 14937 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 Gqx~NRP*A}D delta 15133 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 W@F&*Jh_B?xrt(+moI_qO`2QbW5n4|G delta 11254 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 From 31c4d5a3a79e1c02dbf4eeb7d91cf5e3ed84874f Mon Sep 17 00:00:00 2001 From: Jeff Moser Date: Mon, 3 May 2010 06:23:44 -0400 Subject: [PATCH 14/14] Removed some more cruft that was left behind from debugging --- Skills/FactorGraphs/Schedule.cs | 3 +-- Skills/Skills.csproj | 1 + .../Factors/GaussianWeightedSumFactor.cs | 3 +-- Skills/bin/Debug/Moserware.Skills.dll | Bin 62976 -> 62976 bytes Skills/bin/Debug/Moserware.Skills.pdb | Bin 220672 -> 220672 bytes Skills/bin/Release/Moserware.Skills.dll | Bin 58368 -> 58368 bytes Skills/bin/Release/Moserware.Skills.pdb | Bin 200192 -> 200192 bytes 7 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Skills/FactorGraphs/Schedule.cs b/Skills/FactorGraphs/Schedule.cs index ac9d15a..7e43f09 100644 --- a/Skills/FactorGraphs/Schedule.cs +++ b/Skills/FactorGraphs/Schedule.cs @@ -43,8 +43,7 @@ namespace Moserware.Skills.FactorGraphs return delta; } } - - // TODO: Remove + public class ScheduleSequence : ScheduleSequence> { public ScheduleSequence(string name, IEnumerable> schedules) diff --git a/Skills/Skills.csproj b/Skills/Skills.csproj index 3cf270e..4290fde 100644 --- a/Skills/Skills.csproj +++ b/Skills/Skills.csproj @@ -31,6 +31,7 @@ TRACE prompt 4 + true diff --git a/Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs b/Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs index b95d04b..d836574 100644 --- a/Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs +++ b/Skills/TrueSkill/Factors/GaussianWeightedSumFactor.cs @@ -69,8 +69,7 @@ namespace Moserware.Skills.TrueSkill.Factors for (int currentWeightSourceIndex = 0; currentWeightSourceIndex < variableWeights.Length; currentWeightSourceIndex++) - { - // TODO: get this test to be right + { if (currentWeightSourceIndex == (weightsIndex - 1)) { continue; diff --git a/Skills/bin/Debug/Moserware.Skills.dll b/Skills/bin/Debug/Moserware.Skills.dll index 7d29b38f5d2b81346f2dc57f806f07df113bf512..b00b103368de8be8619dbc9cb0369bfbecf25d62 100644 GIT binary patch delta 129 zcmZp8!`$$Oc|r%%*~J^XjP|G)I61kPn_D{Tnj5*g=$e>Xn&~>4S~}{w7`V9_8k<^J znmSo-ez0eSfWVycz1(k$rnxSib>W|I#MGUeXPmtur*n4kJ#PjeU;^SCAnxE|WaxOq gzz`Jd5*+ODefj#Wvs|XUyAc$1FI;c)oHr?)0NT7T!2kdN delta 129 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 PuJ}(?jg6oh&l|o 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 B4>`$%SDhvLzykc NB}4|%GP6|KtO`RFDO&&l delta 107 zcmV-x0F?iL$OC}L1CWRU3Ma9O=Bgt@G%_(nF*7wSMnNz+Ei^VpH7!CoMnf$|H8V9e zF+ngiGBdN2tEmtWHPIo&3HtR$xcv1sQJ_LIvrN3)90Cd_lPcL75Wj3jR#zH_Nx$(Y Nh0mx{nzK~dtP07JD3JgF diff --git a/Skills/bin/Release/Moserware.Skills.pdb b/Skills/bin/Release/Moserware.Skills.pdb index f0f47f885e365cbbc4d308c74f899848c38b7cd3..64309d53c2326fdacfc4c4a8aafe0d840728f6da 100644 GIT binary patch delta 7414 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 Ii|