public static Lst <Polynomize.PolyODE> PositivizeODEs(Lst <Polynomize.PolyODE> odes, Lst <Subst> substs, Style style) { //const int annihilationOrder = 1; // generation of annihilation reactions has been moved to Hungarize, otherwise two reactions are generated instead of one from the annihilation monomial if (odes is Cons <Polynomize.PolyODE> cons) { Lst <Polynomize.PolyODE> tail = PositivizeODEs(cons.tail, substs, style); Polynomize.PolyODE ode = cons.head; Polynomial poly = Substitute(ode.poly, substs, style); Subst subst = Lookup(ode.var, substs); if (subst == null) // we do not split this ODE { return(new Cons <Polynomize.PolyODE>(new Polynomize.PolyODE(ode.var, poly, split: Polynomize.Split.No), tail)); } else // we split this ODE { (Lst <Monomial> positive, Lst <Monomial> negative) = Separate(poly.monomials, style); return(new Cons <Polynomize.PolyODE>(new Polynomize.PolyODE(subst.plus, positive, split: Polynomize.Split.Pos), new Cons <Polynomize.PolyODE>(new Polynomize.PolyODE(subst.minus, negative, split: Polynomize.Split.Neg), tail))); //Monomial damp = new Monomial(Flow.minusOne, Factor.Cons(new Factor(subst.plus, annihilationOrder), Factor.Singleton(new Factor(subst.minus, annihilationOrder))), style); // annihilation monomial //return new Cons<Polynomize.PolyODE>(new Polynomize.PolyODE(subst.plus, Monomial.Cons(damp, positive), split:Polynomize.Split.Pos), // new Cons<Polynomize.PolyODE>(new Polynomize.PolyODE(subst.minus, Monomial.Cons(damp, negative), split:Polynomize.Split.Neg), // tail)); } } else { return(Polynomize.PolyODE.nil); } }
// substitute x with (x+ - x-) in a flow that is already in polynomial form as a result of Polynomize public static Lst <Polynomize.PolyODE> Substitute(Lst <Polynomize.PolyODE> odes, Lst <Subst> substs, Style style) { if (odes is Cons <Polynomize.PolyODE> cons) { Polynomize.PolyODE ode = cons.head; Subst subst = Lookup(ode.var, substs); if (subst == null) { return(new Cons <Polynomize.PolyODE>(new Polynomize.PolyODE(ode.var, Substitute(ode.poly, substs, style), ode.split), Substitute(cons.tail, substs, style))); } else // this should never happen because we split ODEs in PositivizeODEs { throw new Error("Polynomize.Substitute"); //return // new Cons<Polynomize.PolyODE>(new Polynomize.PolyODE(subst.plus, Substitute(ode.poly, substs, style)), // new Cons<Polynomize.PolyODE>(new Polynomize.PolyODE(subst.minus, Substitute(ode.poly, substs, style)), // Substitute(cons.tail, substs, style))); } } else { return(Polynomize.PolyODE.nil); } }
public static Polynomize.PolyODE Rename(Dictionary <Symbol, SpeciesFlow> dict, Polynomize.PolyODE ode, Style style) { return(new Polynomize.PolyODE( dict.ContainsKey(ode.var.species) ? dict[ode.var.species] : ode.var, new Polynomial(Rename(dict, ode.poly.monomials, style)), ode.split)); }