2010-09-18 11:11:44 -04:00
|
|
|
<?php
|
|
|
|
namespace Moserware\Skills\TrueSkill\Factors;
|
|
|
|
|
2010-09-25 10:15:51 -04:00
|
|
|
require_once(dirname(__FILE__) . "/GaussianFactor.php");
|
|
|
|
require_once(dirname(__FILE__) . "/../TruncatedGaussianCorrectionFunctions.php");
|
|
|
|
require_once(dirname(__FILE__) . "/../../FactorGraphs/Message.php");
|
|
|
|
require_once(dirname(__FILE__) . "/../../FactorGraphs/Variable.php");
|
|
|
|
require_once(dirname(__FILE__) . "/../../Numerics/GaussianDistribution.php");
|
2010-09-18 17:56:57 -04:00
|
|
|
|
|
|
|
use Moserware\Numerics\GaussianDistribution;
|
|
|
|
use Moserware\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
|
|
|
|
use Moserware\Skills\FactorGraphs\Message;
|
|
|
|
use Moserware\Skills\FactorGraphs\Variable;
|
|
|
|
|
2010-09-18 11:11:44 -04:00
|
|
|
/// <summary>
|
|
|
|
/// Factor representing a team difference that has exceeded the draw margin.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>See the accompanying math paper for more details.</remarks>
|
|
|
|
class GaussianGreaterThanFactor extends GaussianFactor
|
|
|
|
{
|
|
|
|
private $_epsilon;
|
|
|
|
|
2010-09-25 15:46:23 -04:00
|
|
|
public function __construct($epsilon, Variable &$variable)
|
2010-09-18 11:11:44 -04:00
|
|
|
{
|
2010-09-25 22:40:56 -04:00
|
|
|
parent::__construct("{0} > {1:0.000}");
|
2010-09-18 11:11:44 -04:00
|
|
|
$this->_epsilon = $epsilon;
|
|
|
|
$this->createVariableToMessageBinding($variable);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getLogNormalization()
|
|
|
|
{
|
2010-09-25 22:40:56 -04:00
|
|
|
$vars = &$this->getVariables();
|
|
|
|
$marginal = &$vars[0]->getValue();
|
|
|
|
$messages = &$this->getMessages();
|
|
|
|
$message = &$messages[0]->getValue();
|
2010-09-18 11:11:44 -04:00
|
|
|
$messageFromVariable = GaussianDistribution::divide($marginal, $message);
|
|
|
|
return -GaussianDistribution::logProductNormalization($messageFromVariable, $message)
|
|
|
|
+
|
|
|
|
log(
|
|
|
|
GaussianDistribution::cumulativeTo(($messageFromVariable->getMean() - $this->_epsilon)/
|
|
|
|
$messageFromVariable->getStandardDeviation()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-09-25 15:46:23 -04:00
|
|
|
protected function updateMessageVariable(Message &$message, Variable &$variable)
|
2010-09-18 11:11:44 -04:00
|
|
|
{
|
|
|
|
$oldMarginal = clone $variable->getValue();
|
|
|
|
$oldMessage = clone $message->getValue();
|
|
|
|
$messageFromVar = GaussianDistribution::divide($oldMarginal, $oldMessage);
|
|
|
|
|
|
|
|
$c = $messageFromVar->getPrecision();
|
|
|
|
$d = $messageFromVar->getPrecisionMean();
|
|
|
|
|
|
|
|
$sqrtC = sqrt($c);
|
|
|
|
|
|
|
|
$dOnSqrtC = $d/$sqrtC;
|
|
|
|
|
|
|
|
$epsilsonTimesSqrtC = $this->_epsilon*$sqrtC;
|
|
|
|
$d = $messageFromVar->getPrecisionMean();
|
|
|
|
|
|
|
|
$denom = 1.0 - TruncatedGaussianCorrectionFunctions::vExceedsMargin($dOnSqrtC, $epsilsonTimesSqrtC);
|
|
|
|
|
|
|
|
$newPrecision = $c/$denom;
|
|
|
|
$newPrecisionMean = ($d +
|
|
|
|
$sqrtC*
|
|
|
|
TruncatedGaussianCorrectionFunctions::vExceedsMargin($dOnSqrtC, $epsilsonTimesSqrtC))/
|
|
|
|
$denom;
|
|
|
|
|
|
|
|
$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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|