mirror of
				https://github.com/furyfire/trueskill.git
				synced 2025-11-04 10:12:28 +01:00 
			
		
		
		
	Initial version of Moserware.Skills TrueSkill calculator to go along with my Computing Your Skill blog post
This commit is contained in:
		
							
								
								
									
										94
									
								
								Skills/FactorGraphs/Factor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								Skills/FactorGraphs/Factor.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Collections.ObjectModel;
 | 
			
		||||
 | 
			
		||||
namespace Moserware.Skills.FactorGraphs
 | 
			
		||||
{    
 | 
			
		||||
    public abstract class Factor<TValue>        
 | 
			
		||||
    {
 | 
			
		||||
        private readonly List<Message<TValue>> _Messages = new List<Message<TValue>>();
 | 
			
		||||
 | 
			
		||||
        private readonly Dictionary<Message<TValue>, Variable<TValue>> _MessageToVariableBinding =
 | 
			
		||||
            new Dictionary<Message<TValue>, Variable<TValue>>();
 | 
			
		||||
 | 
			
		||||
        private readonly string _Name;
 | 
			
		||||
        private readonly List<Variable<TValue>> _Variables = new List<Variable<TValue>>();
 | 
			
		||||
 | 
			
		||||
        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<Variable<TValue>> Variables
 | 
			
		||||
        {
 | 
			
		||||
            get { return _Variables.AsReadOnly(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected ReadOnlyCollection<Message<TValue>> 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<TValue> message, Variable<TValue> 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<TValue> message = _Messages[messageIndex];
 | 
			
		||||
            Variable<TValue> variable = _MessageToVariableBinding[message];
 | 
			
		||||
            return SendMessage(message, variable);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected abstract double SendMessage(Message<TValue> message, Variable<TValue> variable);
 | 
			
		||||
 | 
			
		||||
        public abstract Message<TValue> CreateVariableToMessageBinding(Variable<TValue> variable);
 | 
			
		||||
 | 
			
		||||
        protected Message<TValue> CreateVariableToMessageBinding(Variable<TValue> variable, Message<TValue> message)
 | 
			
		||||
        {
 | 
			
		||||
            int index = _Messages.Count;
 | 
			
		||||
            _Messages.Add(message);
 | 
			
		||||
            _MessageToVariableBinding[message] = variable;
 | 
			
		||||
            _Variables.Add(variable);
 | 
			
		||||
 | 
			
		||||
            return message;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            return _Name ?? base.ToString();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								Skills/FactorGraphs/FactorGraph.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Skills/FactorGraphs/FactorGraph.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
namespace Moserware.Skills.FactorGraphs
 | 
			
		||||
{
 | 
			
		||||
    public class FactorGraph<TSelf, TValue, TVariable>
 | 
			
		||||
        where TSelf : FactorGraph<TSelf, TValue, TVariable>
 | 
			
		||||
        where TVariable : Variable<TValue>
 | 
			
		||||
    {
 | 
			
		||||
        public VariableFactory<TValue> VariableFactory { get; protected set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								Skills/FactorGraphs/FactorGraphLayer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								Skills/FactorGraphs/FactorGraphLayer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace Moserware.Skills.FactorGraphs
 | 
			
		||||
{
 | 
			
		||||
    public abstract class FactorGraphLayerBase<TValue>
 | 
			
		||||
    {
 | 
			
		||||
        public abstract IEnumerable<Factor<TValue>> UntypedFactors { get; }
 | 
			
		||||
        public abstract void BuildLayer();
 | 
			
		||||
 | 
			
		||||
        public virtual Schedule<TValue> CreatePriorSchedule()
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual Schedule<TValue> CreatePosteriorSchedule()
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // HACK
 | 
			
		||||
 | 
			
		||||
        public abstract void SetRawInputVariablesGroups(object value);
 | 
			
		||||
        public abstract object GetRawOutputVariablesGroups();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public abstract class FactorGraphLayer<TParentGraph, TValue, TBaseVariable, TInputVariable, TFactor, TOutputVariable>
 | 
			
		||||
        : FactorGraphLayerBase<TValue>
 | 
			
		||||
        where TParentGraph : FactorGraph<TParentGraph, TValue, TBaseVariable>
 | 
			
		||||
        where TBaseVariable : Variable<TValue>
 | 
			
		||||
        where TInputVariable : TBaseVariable
 | 
			
		||||
        where TFactor : Factor<TValue>
 | 
			
		||||
        where TOutputVariable : TBaseVariable
 | 
			
		||||
    {
 | 
			
		||||
        private readonly List<TFactor> _LocalFactors = new List<TFactor>();
 | 
			
		||||
        private readonly List<IList<TOutputVariable>> _OutputVariablesGroups = new List<IList<TOutputVariable>>();
 | 
			
		||||
        private IList<IList<TInputVariable>> _InputVariablesGroups = new List<IList<TInputVariable>>();
 | 
			
		||||
 | 
			
		||||
        protected FactorGraphLayer(TParentGraph parentGraph)
 | 
			
		||||
        {
 | 
			
		||||
            ParentFactorGraph = parentGraph;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected IList<IList<TInputVariable>> InputVariablesGroups
 | 
			
		||||
        {
 | 
			
		||||
            get { return _InputVariablesGroups; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // HACK
 | 
			
		||||
 | 
			
		||||
        public TParentGraph ParentFactorGraph { get; private set; }
 | 
			
		||||
 | 
			
		||||
        public IList<IList<TOutputVariable>> OutputVariablesGroups
 | 
			
		||||
        {
 | 
			
		||||
            get { return _OutputVariablesGroups; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IList<TFactor> LocalFactors
 | 
			
		||||
        {
 | 
			
		||||
            get { return _LocalFactors; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override IEnumerable<Factor<TValue>> UntypedFactors
 | 
			
		||||
        {
 | 
			
		||||
            get { return _LocalFactors.Cast<Factor<TValue>>(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void SetRawInputVariablesGroups(object value)
 | 
			
		||||
        {
 | 
			
		||||
            var newList = value as IList<IList<TInputVariable>>;
 | 
			
		||||
            if (newList == null)
 | 
			
		||||
            {
 | 
			
		||||
                // TODO: message
 | 
			
		||||
                throw new ArgumentException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _InputVariablesGroups = newList;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override object GetRawOutputVariablesGroups()
 | 
			
		||||
        {
 | 
			
		||||
            return _OutputVariablesGroups;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected Schedule<TValue> ScheduleSequence<TSchedule>(
 | 
			
		||||
            IEnumerable<TSchedule> itemsToSequence,
 | 
			
		||||
            string nameFormat,
 | 
			
		||||
            params object[] args)
 | 
			
		||||
            where TSchedule : Schedule<TValue>
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            string formattedName = String.Format(nameFormat, args);
 | 
			
		||||
            return new ScheduleSequence<TValue, TSchedule>(formattedName, itemsToSequence);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void AddLayerFactor(TFactor factor)
 | 
			
		||||
        {
 | 
			
		||||
            _LocalFactors.Add(factor);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Helper utility
 | 
			
		||||
        protected double Square(double x)
 | 
			
		||||
        {
 | 
			
		||||
            return x*x;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								Skills/FactorGraphs/FactorList.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Skills/FactorGraphs/FactorList.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace Moserware.Skills.FactorGraphs
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Helper class for computing the factor graph's normalization constant.
 | 
			
		||||
    /// </summary>    
 | 
			
		||||
    public class FactorList<TValue>
 | 
			
		||||
    {        
 | 
			
		||||
        private readonly List<Factor<TValue>> _List = new List<Factor<TValue>>();
 | 
			
		||||
 | 
			
		||||
        public double LogNormalization
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {                
 | 
			
		||||
                _List.ForEach(f => f.ResetMarginals());
 | 
			
		||||
 | 
			
		||||
                double sumLogZ = 0.0;
 | 
			
		||||
                                
 | 
			
		||||
                for (int i = 0; i < _List.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    Factor<TValue> 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<TValue> AddFactor(Factor<TValue> factor)
 | 
			
		||||
        {
 | 
			
		||||
            _List.Add(factor);
 | 
			
		||||
            return factor;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								Skills/FactorGraphs/Message.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Skills/FactorGraphs/Message.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Moserware.Skills.FactorGraphs
 | 
			
		||||
{
 | 
			
		||||
    public class Message<T>
 | 
			
		||||
    {
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										105
									
								
								Skills/FactorGraphs/Schedule.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								Skills/FactorGraphs/Schedule.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Moserware.Skills.FactorGraphs
 | 
			
		||||
{
 | 
			
		||||
    public abstract class Schedule<T>
 | 
			
		||||
    {
 | 
			
		||||
        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<T> : Schedule<T>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Factor<T> _Factor;
 | 
			
		||||
        private readonly int _Index;
 | 
			
		||||
 | 
			
		||||
        public ScheduleStep(string name, Factor<T> 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<TValue> : ScheduleSequence<TValue, Schedule<TValue>>
 | 
			
		||||
    {
 | 
			
		||||
        public ScheduleSequence(string name, IEnumerable<Schedule<TValue>> schedules)
 | 
			
		||||
            : base(name, schedules)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ScheduleSequence<TValue, TSchedule> : Schedule<TValue>
 | 
			
		||||
        where TSchedule : Schedule<TValue>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IEnumerable<TSchedule> _Schedules;
 | 
			
		||||
 | 
			
		||||
        public ScheduleSequence(string name, IEnumerable<TSchedule> 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<T> : Schedule<T>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly double _MaxDelta;
 | 
			
		||||
        private readonly Schedule<T> _ScheduleToLoop;
 | 
			
		||||
 | 
			
		||||
        public ScheduleLoop(string name, Schedule<T> 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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								Skills/FactorGraphs/Variable.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								Skills/FactorGraphs/Variable.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Moserware.Skills.FactorGraphs
 | 
			
		||||
{
 | 
			
		||||
    public class Variable<TValue>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly string _Name;
 | 
			
		||||
        private readonly VariableFactory<TValue> _ParentFactory;
 | 
			
		||||
        private readonly TValue _Prior;
 | 
			
		||||
        private int _ParentIndex;
 | 
			
		||||
 | 
			
		||||
        public Variable(string name, VariableFactory<TValue> 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<TValue> : Variable<TValue>
 | 
			
		||||
    {
 | 
			
		||||
        public DefaultVariable()
 | 
			
		||||
            : base("Default", null, 0, default(TValue))
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override TValue Value
 | 
			
		||||
        {
 | 
			
		||||
            get { return default(TValue); }
 | 
			
		||||
            set { throw new NotSupportedException(); }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class KeyedVariable<TKey, TValue> : Variable<TValue>
 | 
			
		||||
    {
 | 
			
		||||
        public KeyedVariable(TKey key, string name, VariableFactory<TValue> parentFactory, int parentIndex, TValue prior)
 | 
			
		||||
            : base(name, parentFactory, parentIndex, prior)
 | 
			
		||||
        {
 | 
			
		||||
            Key = key;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TKey Key { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								Skills/FactorGraphs/VariableFactory.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								Skills/FactorGraphs/VariableFactory.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Moserware.Skills.FactorGraphs
 | 
			
		||||
{
 | 
			
		||||
    public class VariableFactory<TValue>
 | 
			
		||||
    {
 | 
			
		||||
        // using a Func<TValue> to encourage fresh copies in case it's overwritten
 | 
			
		||||
        private readonly List<Variable<TValue>> _CreatedVariables = new List<Variable<TValue>>();
 | 
			
		||||
        private readonly Func<TValue> _VariablePriorInitializer;
 | 
			
		||||
 | 
			
		||||
        public VariableFactory(Func<TValue> variablePriorInitializer)
 | 
			
		||||
        {
 | 
			
		||||
            _VariablePriorInitializer = variablePriorInitializer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Variable<TValue> CreateBasicVariable(string nameFormat, params object[] args)
 | 
			
		||||
        {
 | 
			
		||||
            var newVar = new Variable<TValue>(
 | 
			
		||||
                String.Format(nameFormat, args),
 | 
			
		||||
                this,
 | 
			
		||||
                _CreatedVariables.Count,
 | 
			
		||||
                _VariablePriorInitializer());
 | 
			
		||||
 | 
			
		||||
            _CreatedVariables.Add(newVar);
 | 
			
		||||
            return newVar;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public KeyedVariable<TKey, TValue> CreateKeyedVariable<TKey>(TKey key, string nameFormat, params object[] args)
 | 
			
		||||
        {
 | 
			
		||||
            var newVar = new KeyedVariable<TKey, TValue>(
 | 
			
		||||
                key,
 | 
			
		||||
                String.Format(nameFormat, args),
 | 
			
		||||
                this,
 | 
			
		||||
                _CreatedVariables.Count,
 | 
			
		||||
                _VariablePriorInitializer());
 | 
			
		||||
 | 
			
		||||
            _CreatedVariables.Add(newVar);
 | 
			
		||||
            return newVar;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user