protected function updateMessageVariable(Message $message, Variable $variable)
 {
     $oldMarginal = clone $variable->getValue();
     $oldMessage = $message;
     $newMarginal = GaussianDistribution::fromPrecisionMean($oldMarginal->getPrecisionMean() + $this->_newMessage->getPrecisionMean() - $oldMessage->getValue()->getPrecisionMean(), $oldMarginal->getPrecision() + $this->_newMessage->getPrecision() - $oldMessage->getValue()->getPrecision());
     $variable->setValue($newMarginal);
     $newMessage = $this->_newMessage;
     $message->setValue($newMessage);
     return GaussianDistribution::subtract($oldMarginal, $newMarginal);
 }
示例#2
0
 public function __construct(GameInfo &$gameInfo, array &$teams, array $teamRanks)
 {
     $this->_priorLayer = new PlayerPriorValuesToSkillsLayer($this, $teams);
     $this->_gameInfo = $gameInfo;
     $newFactory = new VariableFactory(function () {
         return GaussianDistribution::fromPrecisionMean(0, 0);
     });
     $this->setVariableFactory($newFactory);
     $this->_layers = array($this->_priorLayer, new PlayerSkillsToPerformancesLayer($this), new PlayerPerformancesToTeamPerformancesLayer($this), new IteratedTeamDifferencesInnerLayer($this, new TeamPerformancesToTeamPerformanceDifferencesLayer($this), new TeamDifferencesComparisonLayer($this, $teamRanks)));
 }
 public function testAbsoluteDifference()
 {
     // Verified with Ralf Herbrich's F# implementation
     $standardNormal = new GaussianDistribution(0, 1);
     $absDiff = GaussianDistribution::absoluteDifference($standardNormal, $standardNormal);
     $this->assertEquals(0.0, $absDiff, '', GaussianDistributionTest::ERROR_TOLERANCE);
     $m1s2 = new GaussianDistribution(1, 2);
     $m3s4 = new GaussianDistribution(3, 4);
     $absDiff2 = GaussianDistribution::absoluteDifference($m1s2, $m3s4);
     $this->assertEquals(0.4330127018922193, $absDiff2, '', GaussianDistributionTest::ERROR_TOLERANCE);
 }
示例#4
0
 public static function getDrawMarginFromDrawProbability($drawProbability, $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
     $margin = GaussianDistribution::inverseCumulativeTo(0.5 * ($drawProbability + 1), 0, 1) * sqrt(1 + 1) * $beta;
     return $margin;
 }
 private function updateHelper(Message $message1, Message $message2, Variable $variable1, Variable $variable2)
 {
     $message1Value = clone $message1->getValue();
     $message2Value = clone $message2->getValue();
     $marginal1 = clone $variable1->getValue();
     $marginal2 = clone $variable2->getValue();
     $a = $this->_precision / ($this->_precision + $marginal2->getPrecision() - $message2Value->getPrecision());
     $newMessage = GaussianDistribution::fromPrecisionMean($a * ($marginal2->getPrecisionMean() - $message2Value->getPrecisionMean()), $a * ($marginal2->getPrecision() - $message2Value->getPrecision()));
     $oldMarginalWithoutMessage = GaussianDistribution::divide($marginal1, $message1Value);
     $newMarginal = GaussianDistribution::multiply($oldMarginalWithoutMessage, $newMessage);
     // Update the message and marginal
     $message1->setValue($newMessage);
     $variable1->setValue($newMarginal);
     // Return the difference in the new marginal
     return GaussianDistribution::subtract($newMarginal, $marginal1);
 }
示例#6
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);
 }
示例#7
0
 public function createVariableToMessageBinding(Variable $variable)
 {
     $newDistribution = GaussianDistribution::fromPrecisionMean(0, 0);
     $binding = parent::createVariableToMessageBindingWithMessage($variable, new Message($newDistribution, sprintf("message from %s to %s", $this, $variable)));
     return $binding;
 }
 public function getPlayerWinProbability(GameInfo $gameInfo, $playerRating, $opponentRating)
 {
     $ratingDifference = $playerRating - $opponentRating;
     // See equation 1.1 in the TrueSkill paper
     return GaussianDistribution::cumulativeTo($ratingDifference / (sqrt(2) * $gameInfo->getBeta()));
 }
 private function updateHelper(array $weights, array $weightsSquared, array $messages, array $variables)
 {
     // Potentially look at http://mathworld.wolfram.com/NormalSumDistribution.html for clues as
     // to what it's doing
     $message0 = clone $messages[0]->getValue();
     $marginal0 = clone $variables[0]->getValue();
     // The math works out so that 1/newPrecision = sum of a_i^2 /marginalsWithoutMessages[i]
     $inverseOfNewPrecisionSum = 0.0;
     $anotherInverseOfNewPrecisionSum = 0.0;
     $weightedMeanSum = 0.0;
     $anotherWeightedMeanSum = 0.0;
     $weightsSquaredLength = count($weightsSquared);
     for ($i = 0; $i < $weightsSquaredLength; $i++) {
         // These flow directly from the paper
         $inverseOfNewPrecisionSum += $weightsSquared[$i] / ($variables[$i + 1]->getValue()->getPrecision() - $messages[$i + 1]->getValue()->getPrecision());
         $diff = GaussianDistribution::divide($variables[$i + 1]->getValue(), $messages[$i + 1]->getValue());
         $anotherInverseOfNewPrecisionSum += $weightsSquared[$i] / $diff->getPrecision();
         $weightedMeanSum += $weights[$i] * ($variables[$i + 1]->getValue()->getPrecisionMean() - $messages[$i + 1]->getValue()->getPrecisionMean()) / ($variables[$i + 1]->getValue()->getPrecision() - $messages[$i + 1]->getValue()->getPrecision());
         $anotherWeightedMeanSum += $weights[$i] * $diff->getPrecisionMean() / $diff->getPrecision();
     }
     $newPrecision = 1.0 / $inverseOfNewPrecisionSum;
     $anotherNewPrecision = 1.0 / $anotherInverseOfNewPrecisionSum;
     $newPrecisionMean = $newPrecision * $weightedMeanSum;
     $anotherNewPrecisionMean = $anotherNewPrecision * $anotherWeightedMeanSum;
     $newMessage = GaussianDistribution::fromPrecisionMean($newPrecisionMean, $newPrecision);
     $oldMarginalWithoutMessage = GaussianDistribution::divide($marginal0, $message0);
     $newMarginal = GaussianDistribution::multiply($oldMarginalWithoutMessage, $newMessage);
     // Update the message and marginal
     $messages[0]->setValue($newMessage);
     $variables[0]->setValue($newMarginal);
     // Return the difference in the new marginal
     $finalDiff = GaussianDistribution::subtract($newMarginal, $marginal0);
     return $finalDiff;
 }
 public static function wWithinMargin($teamPerformanceDifference, $drawMargin)
 {
     $teamPerformanceDifferenceAbsoluteValue = abs($teamPerformanceDifference);
     $denominator = GaussianDistribution::cumulativeTo($drawMargin - $teamPerformanceDifferenceAbsoluteValue) - GaussianDistribution::cumulativeTo(-$drawMargin - $teamPerformanceDifferenceAbsoluteValue);
     if ($denominator < 2.222758749E-162) {
         return 1.0;
     }
     $vt = self::vWithinMargin($teamPerformanceDifferenceAbsoluteValue, $drawMargin);
     return $vt * $vt + (($drawMargin - $teamPerformanceDifferenceAbsoluteValue) * GaussianDistribution::at($drawMargin - $teamPerformanceDifferenceAbsoluteValue) - (-$drawMargin - $teamPerformanceDifferenceAbsoluteValue) * GaussianDistribution::at(-$drawMargin - $teamPerformanceDifferenceAbsoluteValue)) / $denominator;
 }