/**
*
*/
package org.cmg.ml.sam.sim.pm;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
import org.apache.commons.math3.random.RandomGenerator;
import org.cmg.ml.sam.sim.Activity;
import org.cmg.ml.sam.sim.ModelI;
import org.cmg.ml.sam.sim.util.WeightedElement;
import org.cmg.ml.sam.sim.util.WeightedLinkedList;
import org.cmg.ml.sam.sim.util.WeightedStructure;
/**
*
* This class implements a population model. This class is parametrised with respect
* to types <code>S</code> and and <code>T</code>. The former is the data type used to identify
* population species in the population vector. Parameter <code>T</code> identifies environment
*
* @author loreti
*
*/
public abstract class PopulationModel<S,T extends PopulationState<S>> implements ModelI {
private LinkedList<PopulationRule<S,T>> rules;
private double time;
protected abstract T getCurrentState();
protected abstract T copyState();
protected abstract void setState(T newState);
@Override
public WeightedStructure<Activity> getActivities( RandomGenerator r ) {
WeightedLinkedList<Activity> activities = new WeightedLinkedList<>();
T currentState = getCurrentState();
for (PopulationRule<S,T> rule : rules) {
LinkedList<PopulationTransition<S,T>> enabled = rule.apply(r, currentState);
for (PopulationTransition<S,T> tra : enabled) {
activities.add(
new WeightedElement<Activity>(
tra.getRate(),
tra
)
);
}
}
return activities;
}
@Override
public void timeStep(double dt) {
this.time += dt;
}
protected void apply(PopulationDrift<S> drift, Consumer<T> postTransitionAction) {
T newState = copyState();
drift.apply(newState);
postTransitionAction.accept(newState);
setState(newState);
}
}