private static function calculateNewRating(GameInfo $gameInfo, Rating $selfRating, Rating $opponentRating, $comparison)
 {
     $drawMargin = DrawMargin::getDrawMarginFromDrawProbability($gameInfo->getDrawProbability(), $gameInfo->getBeta());
     $c = sqrt(square($selfRating->getStandardDeviation()) + square($opponentRating->getStandardDeviation()) + 2 * square($gameInfo->getBeta()));
     $winningMean = $selfRating->getMean();
     $losingMean = $opponentRating->getMean();
     switch ($comparison) {
         case PairwiseComparison::WIN:
         case PairwiseComparison::DRAW:
             // NOP
             break;
         case PairwiseComparison::LOSE:
             $winningMean = $opponentRating->getMean();
             $losingMean = $selfRating->getMean();
             break;
     }
     $meanDelta = $winningMean - $losingMean;
     if ($comparison != PairwiseComparison::DRAW) {
         // non-draw case
         $v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c);
         $w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c);
         $rankMultiplier = (int) $comparison;
     } else {
         $v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c);
         $w = TruncatedGaussianCorrectionFunctions::wWithinMarginScaled($meanDelta, $drawMargin, $c);
         $rankMultiplier = 1;
     }
     $meanMultiplier = (square($selfRating->getStandardDeviation()) + square($gameInfo->getDynamicsFactor())) / $c;
     $varianceWithDynamics = square($selfRating->getStandardDeviation()) + square($gameInfo->getDynamicsFactor());
     $stdDevMultiplier = $varianceWithDynamics / square($c);
     $newMean = $selfRating->getMean() + $rankMultiplier * $meanMultiplier * $v;
     $newStdDev = sqrt($varianceWithDynamics * (1 - $w * $stdDevMultiplier));
     return new Rating($newMean, $newStdDev);
 }
示例#2
0
 protected function updateMessageVariable(Message &$message, Variable &$variable)
 {
     $oldMarginal = clone $variable->getValue();
     $oldMessage = clone $message->getValue();
     $messageFromVariable = GaussianDistribution::divide($oldMarginal, $oldMessage);
     $c = $messageFromVariable->getPrecision();
     $d = $messageFromVariable->getPrecisionMean();
     $sqrtC = sqrt($c);
     $dOnSqrtC = $d / $sqrtC;
     $epsilonTimesSqrtC = $this->_epsilon * $sqrtC;
     $d = $messageFromVariable->getPrecisionMean();
     $denominator = 1.0 - TruncatedGaussianCorrectionFunctions::wWithinMargin($dOnSqrtC, $epsilonTimesSqrtC);
     $newPrecision = $c / $denominator;
     $newPrecisionMean = ($d + $sqrtC * TruncatedGaussianCorrectionFunctions::vWithinMargin($dOnSqrtC, $epsilonTimesSqrtC)) / $denominator;
     $newMarginal = GaussianDistribution::fromPrecisionMean($newPrecisionMean, $newPrecision);
     $newMessage = GaussianDistribution::divide(GaussianDistribution::multiply($oldMessage, $newMarginal), $oldMarginal);
     // Update the message and marginal
     $message->setValue($newMessage);
     $variable->setValue($newMarginal);
     // Return the difference in the new marginal
     return GaussianDistribution::subtract($newMarginal, $oldMarginal);
 }
 private static function updatePlayerRatings(GameInfo $gameInfo, RatingContainer &$newPlayerRatings, Team $selfTeam, Team $otherTeam, $selfToOtherTeamComparison)
 {
     $drawMargin = DrawMargin::getDrawMarginFromDrawProbability($gameInfo->getDrawProbability(), $gameInfo->getBeta());
     $betaSquared = square($gameInfo->getBeta());
     $tauSquared = square($gameInfo->getDynamicsFactor());
     $totalPlayers = $selfTeam->count() + $otherTeam->count();
     $meanGetter = function ($currentRating) {
         return $currentRating->getMean();
     };
     $selfMeanSum = sum($selfTeam->getAllRatings(), $meanGetter);
     $otherTeamMeanSum = sum($otherTeam->getAllRatings(), $meanGetter);
     $varianceGetter = function ($currentRating) {
         return square($currentRating->getStandardDeviation());
     };
     $c = sqrt(sum($selfTeam->getAllRatings(), $varianceGetter) + sum($otherTeam->getAllRatings(), $varianceGetter) + $totalPlayers * $betaSquared);
     $winningMean = $selfMeanSum;
     $losingMean = $otherTeamMeanSum;
     switch ($selfToOtherTeamComparison) {
         case PairwiseComparison::WIN:
         case PairwiseComparison::DRAW:
             // NOP
             break;
         case PairwiseComparison::LOSE:
             $winningMean = $otherTeamMeanSum;
             $losingMean = $selfMeanSum;
             break;
     }
     $meanDelta = $winningMean - $losingMean;
     if ($selfToOtherTeamComparison != PairwiseComparison::DRAW) {
         // non-draw case
         $v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c);
         $w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c);
         $rankMultiplier = (int) $selfToOtherTeamComparison;
     } else {
         // assume draw
         $v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c);
         $w = TruncatedGaussianCorrectionFunctions::wWithinMarginScaled($meanDelta, $drawMargin, $c);
         $rankMultiplier = 1;
     }
     $selfTeamAllPlayers =& $selfTeam->getAllPlayers();
     foreach ($selfTeamAllPlayers as &$selfTeamCurrentPlayer) {
         $localSelfTeamCurrentPlayer =& $selfTeamCurrentPlayer;
         $previousPlayerRating = $selfTeam->getRating($localSelfTeamCurrentPlayer);
         $meanMultiplier = (square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / $c;
         $stdDevMultiplier = (square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / square($c);
         $playerMeanDelta = $rankMultiplier * $meanMultiplier * $v;
         $newMean = $previousPlayerRating->getMean() + $playerMeanDelta;
         $newStdDev = sqrt((square($previousPlayerRating->getStandardDeviation()) + $tauSquared) * (1 - $w * $stdDevMultiplier));
         $newPlayerRatings->setRating($localSelfTeamCurrentPlayer, new Rating($newMean, $newStdDev));
     }
 }