public void should_calculate_propensity_for_multiple_species() { var reaction = new Reaction( new Dictionary <Species, int>() { { "A", 2 }, { "B", 2 } }, new Dictionary <Species, int>(), 0.5); var system = new ChemicalSystem(new Dictionary <Species, int> { { "A", 2 }, { "B", 3 } }); Assert.Equal(6.0, reaction.Propensity(system)); }
public void should_return_() { var random = Substitute.For <IRandom>(); random.GetNext().Returns(new RandomPair(0.1, 0.8)); var gillespieAlgorithm = new GillespieDirect(random); var r1 = new Reaction( new Dictionary <Species, int>() { { "A", 2 }, { "B", 2 } }, new Dictionary <Species, int>() { { "C", 1 } }, 0.5); var r2 = new Reaction( new Dictionary <Species, int>() { { "A", 1 }, { "B", 1 } }, new Dictionary <Species, int>(), 0.25); var r3 = new Reaction( new Dictionary <Species, int>(), new Dictionary <Species, int>() { { "A", 1 } }, 0.2); var system = new ChemicalSystem(new Dictionary <Species, int> { { "A", 2 }, { "B", 3 } }); var evolvedSystem = gillespieAlgorithm.GetPath(new [] { r1, r2, r3 }, system, 0.0, 1).Single().Value; Assert.Equal(1, evolvedSystem.Count("A")); Assert.Equal(2, evolvedSystem.Count("B")); }
public IEnumerable <TimePoint <ChemicalSystem> > GetPath(IList <Reaction> reactions, ChemicalSystem initialSystem, double endTime, int numPoints) { double t = 0; var evolvingSystem = initialSystem; int numReactions = reactions.Count; double reportingInterval = endTime / (double)numPoints; double nextPoint = reportingInterval; do { var randoms = _random.GetNext(); var propensities = reactions.Select(r => r.Propensity(evolvingSystem)); var totalPropensity = propensities.Sum(); var normalisedPropensities = propensities.Select(p => p / totalPropensity).ToList(); var selectedReaction = Partitioner.ToIntervals(normalisedPropensities) .Zip(reactions, (interval, reaction) => new Tuple <Tuple <double, double>, Reaction>(interval, reaction)) .Single(pair => randoms.r2 > pair.Item1.Item1 && randoms.r2 < pair.Item1.Item2) .Item2; t += Math.Log(1.0 / randoms.r1) / totalPropensity; evolvingSystem = evolvingSystem.React(selectedReaction); if (t > nextPoint) { yield return(new TimePoint <ChemicalSystem>(t, evolvingSystem)); nextPoint += reportingInterval; } } while (t <= endTime); }