| 
									
										
										
										
											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 not exceeded the draw margin.
 | 
					
						
							|  |  |  | /// </summary>
 | 
					
						
							|  |  |  | /// <remarks>See the accompanying math paper for more details.</remarks>
 | 
					
						
							|  |  |  | class GaussianWithinFactor 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
										 |  |  |     { | 
					
						
							|  |  |  |         $this->_epsilon = $epsilon; | 
					
						
							|  |  |  |         $this->createVariableToMessageBinding($variable); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function getLogNormalization() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-25 22:40:56 -04:00
										 |  |  |         $variables = &$this->getVariables(); | 
					
						
							|  |  |  |         $marginal = &$variables[0]->getValue(); | 
					
						
							| 
									
										
										
										
											2010-09-18 11:11:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-25 22:40:56 -04:00
										 |  |  |         $messages = &$this->getMessages(); | 
					
						
							|  |  |  |         $message = &$messages[0]->getValue(); | 
					
						
							| 
									
										
										
										
											2010-09-18 11:11:44 -04:00
										 |  |  |         $messageFromVariable = GaussianDistribution::divide($marginal, $message); | 
					
						
							|  |  |  |         $mean = $messageFromVariable->getMean(); | 
					
						
							|  |  |  |         $std = $messageFromVariable->getStandardDeviation(); | 
					
						
							|  |  |  |         $z = GaussianDistribution::cumulativeTo(($this->_epsilon - $mean)/$std) | 
					
						
							|  |  |  |              - | 
					
						
							|  |  |  |              GaussianDistribution::cumulativeTo((-$this->_epsilon - $mean)/$std); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return -GaussianDistribution::logProductNormalization($messageFromVariable, $message) + log($z); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-25 15:46:23 -04:00
										 |  |  |     protected function updateMessage(Message &$message, Variable &$variable) | 
					
						
							| 
									
										
										
										
											2010-09-18 11:11:44 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         $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); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ?>
 |