public static SampleValue MassCompileSample(Symbol outSymbol, SampleValue inSample, Netlist netlist, Style style) { //inSample.Consume(null, 0, null, netlist, style); // this prevents simulating a sample and its massaction version in succession List <ReactionValue> inReactions = inSample.RelevantReactions(netlist, style); CRN inCrn = new CRN(inSample, inReactions); Gui.Log(Environment.NewLine + inCrn.FormatNice(style)); (Lst <Polynomize.ODE> odes, Lst <Polynomize.Equation> eqs) = Polynomize.FromCRN(inCrn); (Lst <Polynomize.PolyODE> polyOdes, Lst <Polynomize.Equation> polyEqs) = Polynomize.PolynomizeODEs(odes, eqs.Reverse(), style); Gui.Log("Polynomize:" + Environment.NewLine + Polynomize.PolyODE.Format(polyOdes, style) + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(polyEqs, style)); (Lst <Polynomize.PolyODE> posOdes, Lst <Polynomize.Equation> posEqs, Dictionary <Symbol, SpeciesFlow> dict, Lst <Positivize.Subst> substs) = Positivize.PositivizeODEs(polyOdes, polyEqs, style); Gui.Log("Positivize:" + Environment.NewLine + Polynomize.PolyODE.Format(posOdes, style) + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(posEqs, style)); Lst <ReactionValue> outReactions = Hungarize.ToReactions(posOdes, style); Gui.Log("Hungarize:" + Environment.NewLine + outReactions.FoldR((r, s) => { return(r.FormatNormal(style) + Environment.NewLine + s); }, "") + "Initial:" + Environment.NewLine + Polynomize.Equation.Format(posEqs, style)); SampleValue outSample = new SampleValue(outSymbol, new StateMap(outSymbol, new List <SpeciesValue> { }, new State(0, lna: inSample.stateMap.state.lna)), new NumberValue(inSample.Volume()), new NumberValue(inSample.Temperature()), produced: true); netlist.Emit(new SampleEntry(outSample)); posOdes.Each(ode => { Flow initFlow = Polynomize.Equation.ToFlow(ode.var, posEqs, style).Normalize(style); double init; if (initFlow is NumberFlow num) { init = num.value; } else { throw new Error("Cannot generate a simulatable sample because initial values contain constants (but the symbolic version has been generated assuming constants are nonnegative)."); } if (init < 0) { throw new Error("Negative initial value of Polynomized ODE for: " + Polynomize.Lookup(ode.var, eqs, style).Format(style) + " = " + init + Environment.NewLine + Polynomize.Equation.Format(eqs, style)); } outSample.stateMap.AddDimensionedSpecies(new SpeciesValue(ode.var.species, -1.0), init, 0.0, "M", outSample.Volume(), style); }); outReactions.Each(reaction => { netlist.Emit(new ReactionEntry(reaction)); }); substs.Each(subst => { ReportEntry report = new ReportEntry(null, OpFlow.Op(subst.plus, "-", subst.minus), null, outSample); outSample.AddReport(report); }); foreach (KeyValuePair <Symbol, SpeciesFlow> keypair in dict) { ReportEntry report = new ReportEntry(null, keypair.Value, null, outSample); outSample.AddReport(report); } ; return(outSample); }
public ExecutionInstance(SampleValue vessel, Netlist netlist, Style style, DateTime startTime, DateTime evalTime) { this.Id = id; id++; this.vessel = vessel; this.environment = new NullEnv(); this.netlist = netlist; this.style = style; this.lastCRN = null; this.startTime = startTime; this.evalTime = evalTime; this.endTime = DateTime.MinValue; this.graphCache = new Dictionary <string, AdjacencyGraph <Vertex, Edge <Vertex> > >(); this.layoutCache = new Dictionary <string, object>(); this.rejected = 0; }
public static (Lst <ODE> odes, Lst <Equation> eqs) FromCRN(CRN crn) { (SpeciesValue[] vars, Flow[] flows) = crn.MeanFlow(); Lst <ODE> odes = new Nil <ODE>(); for (int i = vars.Length - 1; i >= 0; i--) { odes = new Cons <ODE>(new ODE(new SpeciesFlow(vars[i].symbol), flows[i]), odes); } List <SpeciesValue> species = crn.sample.stateMap.species; Lst <Equation> eqs = new Nil <Equation>(); for (int i = species.Count - 1; i >= 0; i--) { eqs = new Cons <Equation>(new Equation(new SpeciesFlow(species[i].symbol), "id", new Lst <Monomial>[1] { Monomial.Singleton(new Monomial(crn.sample.stateMap.state.Mean(i))) }), eqs); } return(odes, eqs); }
public static SampleValue Equilibrate(Env env, Symbol outSymbol, SampleValue inSample, Noise noise, double fortime, Netlist netlist, Style style) { inSample.CheckConsumed(style); // we will consume it later, but we need to check now double initialTime = 0.0; double finalTime = fortime; string sampleName = (outSymbol.Raw() == "vessel") ? "" : "Sample " + inSample.FormatSymbol(style); KChartHandler.ChartClear(sampleName, "s", "M", style); List <SpeciesValue> inSpecies = inSample.stateMap.species; State initialState = inSample.stateMap.state; if ((noise == Noise.None) && initialState.lna) { initialState = new State(initialState.size, lna: false).InitMeans(initialState.MeanVector()); } if ((noise != Noise.None) && !initialState.lna) { initialState = new State(initialState.size, lna: true).InitMeans(initialState.MeanVector()); } List <ReactionValue> reactions = inSample.RelevantReactions(netlist, style); CRN crn = new CRN(inSample, reactions, precomputeLNA: (noise != Noise.None) && KControls.precomputeLNA); KChartHandler.SetMeanFlowDictionary(crn.MeanFlowDictionary(), style); // List<ReportEntry> reports = netlist.Reports(inSpecies); List <ReportEntry> reports = inSample.RelevantReports(style); Exec.lastExecution.lastCRN = crn; KGui.gui.GuiOutputSetText(crn.FormatNice(style)); Exec.lastExecution.ResetGraphCache(); Func <double, double, Vector, Func <double, Vector, Vector>, IEnumerable <SolPoint> > Solver; if (KControls.solver == "GearBDF") { Solver = Ode.GearBDF; } else if (KControls.solver == "RK547M") { Solver = Ode.RK547M; } else { throw new Error("No solver"); } Func <double, Vector, Vector> Flux; if (noise != Noise.None) { Flux = (t, x) => crn.LNAFlux(t, x, style); } else { Flux = (t, x) => crn.Flux(t, x, style); } bool nonTrivialSolution = (inSpecies.Count > 0) && // we don't want to run on the empty species list: Oslo crashes (!crn.Trivial(style)) && // we don't want to run trivial ODEs: some Oslo solvers hang on very small stepping finalTime > 0; // we don't want to run when fortime==0 // INTEGRATE (double lastTime, State lastState) = Integrate(Solver, initialState, initialTime, finalTime, Flux, inSample, reports, noise, nonTrivialSolution, style); if (lastState == null) { lastState = initialState.Clone(); } lastState = lastState.Positive(); List <SpeciesValue> outSpecies = new List <SpeciesValue> { }; foreach (SpeciesValue sp in inSpecies) { outSpecies.Add(sp); // the species list may be destructively modified (added to) later in the new sample } SampleValue outSample = new SampleValue(outSymbol, new StateMap(outSymbol, outSpecies, lastState), new NumberValue(inSample.Volume()), new NumberValue(inSample.Temperature()), produced: true); outSample.AddReports(inSample.RelevantReports(style)); foreach (ReportEntry report in reports) { // an equilibrate may pick up the reports of a previous equilibrate, so we reassign the report even if it has already been assigned // this does not really affect lexical binding because a second report with the same name will get a new symbol // P.S. this was changed so that an equilibrate no longer picks up reports of previous equilibrate, so the issue should not arise if (report.timecourse != null) { env.AssignValue(report.timecourse, KChartHandler.ToTimecourse(report.timecourse, report.flow, style), reassign: true); } } inSample.Consume(reactions, lastTime, lastState, netlist, style); return(outSample); }