public static Lst <ReactionValue> ToReactions(Lst <Polynomize.PolyODE> odes, Style style) { if (odes is Cons <Polynomize.PolyODE> cons) { Lst <ReactionValue> reactions = ToReactions(cons.head.var, cons.head.poly.monomials, ToReactions(cons.tail, style), style); if (cons.head.split == Polynomize.Split.Pos) { SpeciesFlow pos = cons.head.var; SpeciesFlow neg = (cons.tail is Cons <Polynomize.PolyODE> tailCons && tailCons.head.split == Polynomize.Split.Neg) ? tailCons.head.var : throw new Error("ToReactions annihilation"); ReactionValue annihil = new ReactionValue(new List <Symbol> { pos.species, neg.species }, new List <Symbol> { }, new MassActionNumericalRate(1.0)); //ReactionValue annihil = new ReactionValue(new List<Symbol> { pos.species, pos.species, neg.species, neg.species }, new List<Symbol> { }, new MassActionNumericalRate(1.0)); return(new Cons <ReactionValue>(annihil, reactions)); } else { return(reactions); } } else { return(new Nil <ReactionValue>()); } }
public Split splitOp; // op modifier used later by Positivize: can be "No" (= op(args)) "Pos" (= pos(op(args))) or "Neg" (= pos(-op(args))) public Equation(SpeciesFlow var, string op, Lst <Monomial>[] args, Split splitOp = Split.No) { this.var = var; this.op = op; this.args = args; this.splitOp = splitOp; }
public static bool Hungarian(SpeciesFlow differentiationVariable, Lst <Monomial> monomials, Style style) { if (monomials is Cons <Monomial> cons) { return(cons.head.Hungarian(differentiationVariable, style) && Hungarian(differentiationVariable, cons.tail, style)); } else { return(true); } }
public static Lst <ReactionValue> ToReactions(SpeciesFlow variable, Lst <Monomial> monomials, Lst <ReactionValue> rest, Style style) { if (monomials is Cons <Monomial> cons) { return(ToReactions(variable, cons.head, ToReactions(variable, cons.tail, rest, style), style)); } else { return(rest); } }
public static Lst <ReactionValue> ToReactions(SpeciesFlow variable, Monomial monomial, Lst <ReactionValue> rest, Style style) { if (monomial.IsZero()) { return(rest); } else { int decide = Polynomial.DecideNonnegative(monomial.coefficient, style); if (decide == 1) // positive monomials { RateValue rate; if (monomial.coefficient is NumberFlow num) { rate = new MassActionNumericalRate(num.value); } else { rate = new MassActionFlowRate(monomial.coefficient); } return(new Cons <ReactionValue>( new ReactionValue( Factor.ToList(monomial.factors), Factor.ToList(Factor.Product(new Factor(variable, 1), monomial.factors)), rate), rest)); } else if (decide == -1) // negative monomials { RateValue rate; if (monomial.coefficient is NumberFlow num) { rate = new MassActionNumericalRate(-num.value); } else { rate = new MassActionFlowRate(OpFlow.Op("-", monomial.coefficient).Normalize(style)); } return(new Cons <ReactionValue>( new ReactionValue( Factor.ToList(monomial.factors), Factor.ToList(Factor.Quotient(monomial.factors, new Factor(variable, 1), style)), rate), rest)); } else { throw new Error("MassActionCompiler: aborted because it cannot determine the sign of this expression: " + monomial.coefficient.Format(style)); } } }
public static Polynomize.Equation Rename(Dictionary <Symbol, SpeciesFlow> dict, Polynomize.Equation eq, Style style) { Lst <Monomial>[] args = new Lst <Monomial> [eq.args.Length]; for (int i = 0; i < eq.args.Length; i++) { args[i] = Rename(dict, eq.args[i], style); } if (dict.ContainsKey(eq.var.species) && eq.splitOp != Polynomize.Split.No) { throw new Error("Positivize.Rename"); } SpeciesFlow newVar = dict.ContainsKey(eq.var.species) ? dict[eq.var.species] : eq.var; return(new Polynomize.Equation(newVar, eq.op, args, eq.splitOp)); }
public bool Hungarian(SpeciesFlow differentiationVariable, Style style) { int decide = Polynomial.DecideNonnegative(this.coefficient, style); if (decide == 1) { return(true); } else if (decide == -1) { return(Factor.HasFactorVariable(differentiationVariable, this.factors)); } else { throw new Error("MassActionCompiler: aborted because it cannot determine the sign of this expression: " + this.coefficient.Format(style)); } }
public static Subst Lookup(SpeciesFlow var, Lst <Subst> substs) // returns null for not found { if (substs is Cons <Subst> cons) { if (var.SameSpecies(cons.head.var)) { return(cons.head); } else { return(Lookup(var, cons.tail)); } } else { return(null); } }
public static Polynomial Lookup(SpeciesFlow var, Lst <PolyODE> odes, Style style) { if (odes is Cons <PolyODE> cons) { if (cons.head.var.species.SameSymbol(var.species)) { return(cons.head.poly); } else { return(Lookup(var, cons.tail, style)); } } else { throw new Error("ODE Lookup not found: " + var.Format(style)); } }
public static Equation Lookup(SpeciesFlow var, Lst <Equation> eqs, Style style) { if (eqs is Cons <Equation> cons) { if (cons.head.var.species.SameSymbol(var.species)) { return(cons.head); } else { return(Lookup(var, cons.tail, style)); } } else { throw new Error("Equation Lookup not found: " + var.Format(style)); } }
public static bool HasFactorVariable(SpeciesFlow variable, Lst <Factor> factors) { if (factors is Cons <Factor> cons) { if (cons.head.variable.SameSpecies(variable)) { return(true); } else { return(HasFactorVariable(variable, cons.tail)); } } else { return(false); } }
public (SpeciesFlow[, ], Flow[, ]) CovarFlow(Style style) { int speciesNo = sample.Count(); SpeciesFlow[,] covar = new SpeciesFlow[speciesNo, speciesNo]; // fill it with fresh covariance variables for (int speciesI = 0; speciesI < speciesNo; speciesI++) // rows { SpeciesValue variableI = sample.stateMap.species[speciesI]; for (int speciesJ = 0; speciesJ < speciesNo; speciesJ++) // columns { SpeciesValue variableJ = sample.stateMap.species[speciesJ]; if (style.exportTarget == ExportTarget.WolframNotebook) { covar[speciesI, speciesJ] = new SpeciesFlow(new Symbol(variableI.Format(style) + "_" + variableJ.Format(style))); } else { covar[speciesI, speciesJ] = (speciesI == speciesJ) ? new SpeciesFlow(new Symbol("var(" + variableI.Format(style) + ")")) : new SpeciesFlow(new Symbol("cov(" + variableI.Format(style) + "," + variableJ.Format(style) + ")")); } } } Flow[,] covarFlow = new Flow[speciesNo, speciesNo]; Flow[,] jacobian = Jacobian(style); Flow[,] drift = Drift(); for (int speciesI = 0; speciesI < speciesNo; speciesI++) // rows { for (int speciesJ = 0; speciesJ < speciesNo; speciesJ++) // columns { covarFlow[speciesI, speciesJ] = NumberFlow.numberFlowZero; for (int speciesK = 0; speciesK < speciesNo; speciesK++) // dot product index { covarFlow[speciesI, speciesJ] = OpFlow.Op("+", covarFlow[speciesI, speciesJ], OpFlow.Op("*", jacobian[speciesI, speciesK], covar[speciesK, speciesJ])); covarFlow[speciesI, speciesJ] = OpFlow.Op("+", covarFlow[speciesI, speciesJ], OpFlow.Op("*", jacobian[speciesJ, speciesK], covar[speciesI, speciesK])); // jacobian transposed } covarFlow[speciesI, speciesJ] = OpFlow.Op("+", covarFlow[speciesI, speciesJ], drift[speciesI, speciesJ]); } } return(covar, covarFlow); }
public PolyODE(SpeciesFlow var, Lst <Monomial> monomials, Split split) { this.var = var; this.poly = new Polynomial(monomials); this.split = split; }
public Factor(SpeciesFlow variable, int power) { this.variable = variable; this.power = power; }
} // >= 0 public Factor(SpeciesFlow variable) { this.variable = variable; this.power = 1; }
public SpeciesFlow minus; // minus variant of variable public Subst(SpeciesFlow var, Style style) { this.var = var; this.plus = new SpeciesFlow(new Symbol(var.species.Format(style) + "⁺")); this.minus = new SpeciesFlow(new Symbol(var.species.Format(style) + "⁻")); }
public bool Hungarian(SpeciesFlow differentiationVariable, Style style) { return(Monomial.Hungarian(differentiationVariable, this.monomials, style)); }
public static Flow ToFlow(SpeciesFlow var, Lst <Equation> eqs, Style style) { return(Lookup(var, eqs, style).ToFlow(eqs, style)); }
public Split split; // whether this ODE was split by Positivize public PolyODE(SpeciesFlow var, Polynomial poly, Split split) { this.var = var; this.poly = poly; this.split = split; }
public bool Hungarian(SpeciesFlow differentiationVariable, Style style) { return(this.poly.Hungarian(differentiationVariable, style)); }
public PolyODE(SpeciesFlow var, Monomial monomial, Split split) { this.var = var; this.poly = new Polynomial(Monomial.Singleton(monomial)); this.split = split; }
public ODE(SpeciesFlow var, Flow flow) { this.var = var; this.flow = flow; }