public static void Dispose(List <SampleValue> samples, Netlist netlist, Style style) { foreach (SampleValue sample in samples) { sample.Consume(null, 0, null, netlist, style); } }
public ValueEnv(string name, Type type, Value value, Netlist netlist, Env next) : this(new Symbol(name), type, value, next) { if (netlist != null) { netlist.Emit(new ValueEntry(this.symbol, type, value)); // also emit the new binding to netlist } }
public static SampleValue Mix(Symbol symbol, List <SampleValue> samples, Netlist netlist, Style style) { double sumVolume = 0.0; double sumTemperature = 0.0; bool needLna = false; foreach (SampleValue sample in samples) { sample.Consume(null, 0, null, netlist, style); sumVolume += sample.Volume(); sumTemperature += sample.Volume() * sample.Temperature(); needLna = needLna || sample.stateMap.state.lna; } NumberValue volume = new NumberValue(sumVolume); NumberValue temperature = new NumberValue(sumTemperature / sumVolume); SampleValue result = new SampleValue(symbol, new StateMap(symbol, new List <SpeciesValue> { }, new State(0, lna: needLna)), volume, temperature, produced: true); foreach (SampleValue sample in samples) { result.stateMap.Mix(sample.stateMap, volume.value, sample.Volume(), style); // mix adding the means and covariances, scaled by volume result.AddReports(sample.RelevantReports(style)); } return(result); }
public Env ExtendValue <T>(List <Pattern> parameters, T argument, Netlist netlist, string source, Style style, int s) where T : Value // bounded polymorphism :) { if (parameters.Count != 1) { throw new Error("Different number of variables and values for '" + source + "'"); } return(this.ExtendValue <T>(parameters[0], argument, netlist, source, style, s + 1)); }
public static void PauseEquilibrate(Netlist netlist, Style style) { if (!netlist.autoContinue) { while ((!continueExecution) && Exec.IsExecuting()) { // if (!KGui.gui.GuiContinueEnabled()) KGui.gui.GuiOutputAppendText(netlist.Format(style)); KGui.gui.GuiContinueEnable(true); Thread.Sleep(100); } KGui.gui.GuiContinueEnable(false); continueExecution = false; //KGui.gui.GuiOutputSetText(""); // clear last results in preparation for the next, only if not autoContinue } }
public Env ExtendValues <T>(List <Pattern> parameters, List <T> arguments, Netlist netlist, string source, Style style, int s) where T : Value // bounded polymorphism :) { if (parameters.Count != arguments.Count) { throw new Error("Different number of variables and values for '" + source + "'"); } Env env = this; for (int i = 0; i < parameters.Count; i++) { env = env.ExtendValue <T>(parameters[i], arguments[i], netlist, source, style, s + 1); } return(env); }
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; }
// ==== OPERATOR DISPATCHING ==== // public Env Execute(Expressions expressions, Env env, Netlist netlist, Style style, int s) { List <Expression> arguments = expressions.expressions; if (this is ExecutorBinary ex2) { if (arguments.Count != 2) { Bad(arguments, style); } Value arg1 = arguments[0].EvalReject(env, netlist, style, s + 1); Value arg2 = arguments[1].EvalReject(env, netlist, style, s + 1); if (arg1 == Value.REJECT || arg2 == Value.REJECT) { return(Env.REJECT); } ex2.Execute2(arg1, arg2, style); return(env); } else if (this is ExecutorBinaryExt exExt2) { if (arguments.Count != 2) { Bad(arguments, style); } Value arg1 = arguments[0].EvalReject(env, netlist, style, s + 1); Value arg2 = arguments[1].EvalReject(env, netlist, style, s + 1); if (arg1 == Value.REJECT || arg2 == Value.REJECT) { return(Env.REJECT); } exExt2.Execute2(arg1, arg2, netlist, style, s); return(env); } else { throw new Error("Execute"); } }
public override void Execute2(Value arg1, Value arg2, Netlist netlist, Style style, int s) { if (arg1 is NetworkValue as1 && arg2 is ListValue <Value> as2) { ListValue <Value> .Each((Value e) => { Env extEnv = as1.ApplyReject(e, netlist, style, s); }, as2); }
public virtual Value ApplyPseudo3(Expression arg1, Expression arg2, Expression arg3, bool infix, Env env, Netlist netlist, Style style, int s) { throw new Error("OperatorPseudoTernary"); }
public virtual Value ApplyN(List <Value> argN, bool infix, Env env, Netlist netlist, Style style, int s) { throw new Error("OperatorEnnaryExt"); }
public virtual Value Apply3(Value arg1, Value arg2, Value arg3, bool infix, Env env, Netlist netlist, Style style, int s) { throw new Error("OperatorTernaryExt"); }
public static List <SampleValue> EquilibrateList(Env env, List <Symbol> outSymbols, List <SampleValue> inSamples, Noise noise, double fortime, Netlist netlist, Style style) { List <SampleValue> result = new List <SampleValue> { }; for (int i = 0; i < outSymbols.Count; i++) { result.Add(Equilibrate(env, outSymbols[i], inSamples[i], noise, fortime, netlist, style)); } return(result); }
public static List <SampleValue> Split(List <Symbol> symbols, SampleValue sample, List <NumberValue> proportions, Netlist netlist, Style style) { sample.Consume(null, 0, null, netlist, style); List <SampleValue> result = new List <SampleValue> { }; for (int i = 0; i < symbols.Count; i++) { NumberValue iVolume = new NumberValue(sample.Volume() * proportions[i].value); NumberValue iTemperature = new NumberValue(sample.Temperature()); SampleValue iResult = new SampleValue(symbols[i], new StateMap(symbols[i], new List <SpeciesValue> { }, new State(0, lna: sample.stateMap.state.lna)), iVolume, iTemperature, produced: true); iResult.stateMap.Split(sample.stateMap, style); iResult.AddReports(sample.RelevantReports(style)); result.Add(iResult); } return(result); }
public static List <SampleValue> Concentrate(List <Symbol> symbols, double volume, List <SampleValue> inSamples, Netlist netlist, Style style) { List <SampleValue> outSamples = new List <SampleValue> { }; for (int i = 0; i < symbols.Count; i++) { inSamples[i].Consume(null, 0, null, netlist, style); double temperature = inSamples[i].Temperature(); SampleValue outSample = new SampleValue(symbols[i], new StateMap(symbols[i], new List <SpeciesValue> { }, new State(0, lna: inSamples[i].stateMap.state.lna)), new NumberValue(volume), new NumberValue(temperature), produced: true); outSample.stateMap.Mix(inSamples[i].stateMap, volume, inSamples[i].Volume(), style); // same as Mix, but in this case we can also have volume < inSamples[i].Volume() outSample.AddReports(inSamples[i].RelevantReports(style)); outSamples.Add(outSample); } return(outSamples); }
// try this for multiparameter optimization: https://numerics.mathdotnet.com/api/MathNet.Numerics.Optimization.TrustRegion/index.htm // Golden Section Minimizer public static Value Argmin(Value function, Value lowerBound, Value upperBound, Value tolerance, Netlist netlist, Style style, int s) { if (!(lowerBound is NumberValue) || !(upperBound is NumberValue)) { throw new Error("argmin: expecting numbers for lower and upper bounds"); } double lower = (lowerBound as NumberValue).value; double upper = (upperBound as NumberValue).value; if (lower > upper) { throw new Error("argmin: lower bound greater than upper bound"); } if (!(function is FunctionValue)) { throw new Error("argmin: expecting a function as first argument"); } FunctionValue closure = function as FunctionValue; if (closure.parameters.parameters.Count != 1) { throw new Error("argmin: initial values and function parameters have different lengths"); } IScalarObjectiveFunction objectiveFunction = ObjectiveFunction.ScalarValue( (double parameter) => { List <Value> arguments = new List <Value>(); arguments.Add(new NumberValue(parameter)); bool autoContinue = netlist.autoContinue; netlist.autoContinue = true; Value result = closure.ApplyReject(arguments, netlist, style, s); if (result == null) { throw new Error("Objective function returned null"); } netlist.autoContinue = autoContinue; if (!(result is NumberValue)) { throw new Error("Objective function must return a number, not: " + result.Format(style)); } KGui.gui.GuiOutputAppendText("argmin: parameter=" + Style.FormatSequence(arguments, ", ", x => x.Format(style)) + " => cost=" + result.Format(style) + Environment.NewLine); return((result as NumberValue).value); }); try { ScalarMinimizationResult result = GoldenSectionMinimizer.Minimum(objectiveFunction, lower, upper); if (result.ReasonForExit == ExitCondition.Converged || result.ReasonForExit == ExitCondition.BoundTolerance) { KGui.gui.GuiOutputAppendText("argmin: converged with parameter=" + result.MinimizingPoint + " and reason '" + result.ReasonForExit + "'" + Environment.NewLine); return(new NumberValue(result.MinimizingPoint)); } else { throw new Error("reason '" + result.ReasonForExit.ToString() + "'"); } } catch (Exception e) { throw new Error("argmin ended: " + ((e.InnerException == null) ? e.Message : e.InnerException.Message)); } // somehow we need to recatch the inner exception coming from CostAndGradient }
// BFGF Minimizer public static Value Argmin(Value function, Value initial, Value tolerance, Netlist netlist, Style style, int s) { if (!(initial is ListValue <Value>)) { throw new Error("argmin: expecting a list for second argument"); } Vector <double> initialGuess = CreateVector.Dense((initial as ListValue <Value>).ToDoubleArray("argmin: expecting a list of numbers for second argument")); if (!(tolerance is NumberValue)) { throw new Error("argmin: expecting a number for third argument"); } double toler = (tolerance as NumberValue).value; if (!(function is FunctionValue)) { throw new Error("argmin: expecting a function as first argument"); } FunctionValue closure = function as FunctionValue; if (closure.parameters.parameters.Count != 1) { throw new Error("argmin: initial values and function parameters have different lengths"); } IObjectiveFunction objectiveFunction = ObjectiveFunction.Gradient( (Vector <double> objParameters) => { const string badResult = "argmin: objective function should return a list with a number (cost) and a list of numbers (partial derivatives of cost)"; List <Value> parameters = new List <Value>(); foreach (double parameter in objParameters) { parameters.Add(new NumberValue(parameter)); } ListValue <Value> arg1 = new ListValue <Value>(parameters); List <Value> arguments = new List <Value>(); arguments.Add(arg1); bool autoContinue = netlist.autoContinue; netlist.autoContinue = true; Value result = closure.ApplyReject(arguments, netlist, style, s); if (result == null) { throw new Error(badResult); } netlist.autoContinue = autoContinue; if (!(result is ListValue <Value>)) { throw new Error(badResult); } List <Value> results = (result as ListValue <Value>).elements; if (results.Count != 2 || !(results[0] is NumberValue) || !(results[1] is ListValue <Value>)) { throw new Error(badResult); } double cost = (results[0] as NumberValue).value; ListValue <Value> gradients = results[1] as ListValue <Value>; KGui.gui.GuiOutputAppendText("argmin: parameters=" + arg1.Format(style) + " => cost=" + style.FormatDouble(cost) + ", gradients=" + results[1].Format(style) + Environment.NewLine); return(new Tuple <double, Vector <double> >(cost, CreateVector.Dense(gradients.ToDoubleArray(badResult)))); }); try { BfgsMinimizer minimizer = new BfgsMinimizer(toler, toler, toler); MinimizationResult result = minimizer.FindMinimum(objectiveFunction, initialGuess); if (result.ReasonForExit == ExitCondition.Converged || result.ReasonForExit == ExitCondition.AbsoluteGradient || result.ReasonForExit == ExitCondition.RelativeGradient) { List <Value> elements = new List <Value>(); for (int i = 0; i < result.MinimizingPoint.Count; i++) { elements.Add(new NumberValue(result.MinimizingPoint[i])); } ListValue <Value> list = new ListValue <Value>(elements); KGui.gui.GuiOutputAppendText("argmin: converged with parameters " + list.Format(style) + " and reason '" + result.ReasonForExit + "'" + Environment.NewLine); return(list); } else { throw new Error("reason '" + result.ReasonForExit.ToString() + "'"); } } catch (Exception e) { throw new Error("argmin ended: " + ((e.InnerException == null) ? e.Message : e.InnerException.Message)); } // somehow we need to recatch the inner exception coming from CostAndGradient }
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); }
public Value Apply(Expressions expressions, bool infix, Env env, Netlist netlist, Style style, int s) { // arity/infix is assigned by the parser, and infix is supplied here from FunctionInstance->Apply // for infix operators known to the parser, arity = arguments.Count should be correct, but other function applications will not determine arity // the tricky case are "-" and observe, which are treated as Ennary operators, with arguments.Count = 1 or 2 List <Expression> arguments = expressions.expressions; if (this is OperatorUnary op1) { if (arguments.Count != 1) { Bad(arguments, style); } Value arg1 = arguments[0].EvalReject(env, netlist, style, s + 1); if (arg1 == Value.REJECT) { return(Value.REJECT); } return(op1.Apply1(arg1, infix, style)); } else if (this is OperatorBinary op2) { if (arguments.Count != 2) { Bad(arguments, style); } Value arg1 = arguments[0].EvalReject(env, netlist, style, s + 1); Value arg2 = arguments[1].EvalReject(env, netlist, style, s + 1); if (arg1 == Value.REJECT || arg2 == Value.REJECT) { return(Value.REJECT); } return(op2.Apply2(arg1, arg2, infix, style)); } else if (this is OperatorTernary op3) { if (arguments.Count != 3) { Bad(arguments, style); } Value arg1 = arguments[0].EvalReject(env, netlist, style, s + 1); Value arg2 = arguments[1].EvalReject(env, netlist, style, s + 1); Value arg3 = arguments[2].EvalReject(env, netlist, style, s + 1); if (arg1 == Value.REJECT || arg2 == Value.REJECT || arg3 == Value.REJECT) { return(Value.REJECT); } return(op3.Apply3(arg1, arg2, arg3, infix, style)); } else if (this is OperatorEnnary opN) { List <Value> argN = new List <Value>(); for (int i = 0; i < arguments.Count; i++) { Value argI = arguments[i].EvalReject(env, netlist, style, s + 1); if (argI == Value.REJECT) { return(Value.REJECT); } argN.Add(argI); } return(opN.ApplyN(argN, infix, style)); } else if (this is OperatorUnaryExt opExt1) { if (arguments.Count != 1) { Bad(arguments, style); } Value arg1 = arguments[0].EvalReject(env, netlist, style, s + 1); if (arg1 == Value.REJECT) { return(Value.REJECT); } return(opExt1.Apply1(arg1, infix, env, netlist, style, s)); } else if (this is OperatorBinaryExt opExt2) { if (arguments.Count != 2) { Bad(arguments, style); } Value arg1 = arguments[0].EvalReject(env, netlist, style, s + 1); Value arg2 = arguments[1].EvalReject(env, netlist, style, s + 1); if (arg1 == Value.REJECT || arg2 == Value.REJECT) { return(Value.REJECT); } return(opExt2.Apply2(arg1, arg2, infix, env, netlist, style, s)); } else if (this is OperatorTernaryExt opExt3) { if (arguments.Count != 3) { Bad(arguments, style); } Value arg1 = arguments[0].EvalReject(env, netlist, style, s + 1); Value arg2 = arguments[1].EvalReject(env, netlist, style, s + 1); Value arg3 = arguments[2].EvalReject(env, netlist, style, s + 1); if (arg1 == Value.REJECT || arg2 == Value.REJECT || arg3 == Value.REJECT) { return(Value.REJECT); } return(opExt3.Apply3(arg1, arg2, arg3, infix, env, netlist, style, s)); } else if (this is OperatorEnnaryExt opExtN) { List <Value> argN = expressions.EvalReject(env, netlist, style, s + 1); return(opExtN.ApplyN(argN, infix, env, netlist, style, s)); } else if (this is OperatorPseudoTernary opPara3) { if (arguments.Count != 3) { Bad(arguments, style); } return(opPara3.ApplyPseudo3(arguments[0], arguments[1], arguments[2], infix, env, netlist, style, s)); } else { throw new Error("Apply"); } }
private static void Execute_Worker(bool doParse, bool doAST, bool doScope, bool autoContinue, bool chartOutput) { KGui.gui.GuiBeginningExecution(); lastExecution = null; KGui.gui.GuiSaveInput(); KGui.gui.GuiOutputClear(); DateTime startTime = DateTime.Now; if (TheParser.Parser().Parse(KGui.gui.GuiInputGetText(), out IReduction root)) { if (doParse) { root.DrawReductionTree(); } else { Netlist netlist = new Netlist(autoContinue); try { Statements statements = Parser.ParseTop(root); if (doAST) { KGui.gui.GuiOutputAppendText(statements.Format()); } else { SampleValue vessel = Vessel(KControls.SelectNoiseSelectedItem != Noise.None); Env initialEnv = new ValueEnv("vessel", Type.Sample, vessel, new BuiltinEnv(new NullEnv())); Scope initialScope = initialEnv.ToScope(); Scope scope = statements.Scope(initialScope); if (doScope) { KGui.gui.GuiOutputAppendText(scope.Format()); } else { Style style = new Style(varchar: scopeVariants ? defaultVarchar : null, new SwapMap(), map: remapVariants ? new AlphaMap() : null, numberFormat: "G4", dataFormat: "full", // we want it full for samples, but maybe only headers for functions/networks? exportTarget: ExportTarget.Standard, traceFull: false, chartOutput: chartOutput); KChartHandler.ChartClear("", "s", "M", style); KChartHandler.LegendUpdate(style); KScoreHandler.ScoreClear(); KControls.ParametersClear(style); KDeviceHandler.Clear(style); KDeviceHandler.Sample(vessel, style); netlist.Emit(new SampleEntry(vessel)); DateTime evalTime = DateTime.Now; lastExecution = new ExecutionInstance(vessel, netlist, style, startTime, evalTime); lastExecution.environment = statements.EvalReject(initialEnv, netlist, style, 0); if (lastExecution.environment == null) { throw new Error("Top level reject"); } lastExecution.EndTime(); if (style.chartOutput) { foreach (ParameterEntry parameter in netlist.Parameters()) { KControls.AddParameter(parameter.symbol.Format(style), (parameter.value as NumberValue).value, parameter.distribution, style); } KGui.gui.GuiParametersUpdate(); // calls back KControls.ParametersUpdate, but only on Win/Mac } KGui.gui.GuiProcessOutput(); } } } catch (ExecutionEnded) { lastExecution.EndTime(); KGui.gui.GuiOutputAppendText(lastExecution.ElapsedTime()); } catch (ConstantEvaluation ex) { string cat = "Does not have a value: "; netlist.Emit(new CommentEntry(cat + ": " + ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, cat, ex.Message); } catch (Error ex) { netlist.Emit(new CommentEntry(ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, "Error", ex.Message); try { KGui.gui.GuiProcessOutput(); } catch { }; } catch (StackOverflowException ex) { netlist.Emit(new CommentEntry(ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, "Stack Overflow", ex.Message); } catch (Exception ex) { string cat = "Something happened"; netlist.Emit(new CommentEntry(cat + ": " + ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, cat, ex.Message); } } } else { KGui.gui.GuiInputSetErrorSelection(TheParser.Parser().FailLineNumber(), TheParser.Parser().FailColumnNumber(), TheParser.Parser().FailLength(), TheParser.Parser().FailCategory(), TheParser.Parser().FailMessage()); } EndingExecution(); }
public Env ExtendValue <T>(Pattern pattern, T argument, Netlist netlist, string source, Style style, int s) where T : Value // bounded polymorphism :) { Env env = this; if (pattern is SinglePattern) { SinglePattern parameter = pattern as SinglePattern; env = new ValueEnv(parameter.name, parameter.type, argument, netlist, env); } else if (pattern is ListPattern) { List <Pattern> subPatterns = (pattern as ListPattern).list.parameters; if (!(argument is ListValue <T>)) { throw new Error("A list pattern is bound to a non-list value: '" + source + "'"); } List <T> subArguments = (argument as ListValue <T>).elements; env = env.ExtendValues(subPatterns, subArguments, netlist, source, style, s + 1); } else if (pattern is HeadConsPattern) { List <Pattern> headPatterns = (pattern as HeadConsPattern).list.parameters; Pattern singlePattern = (pattern as HeadConsPattern).single; if (!(argument is ListValue <T>)) { throw new Error("A list pattern is bound to a non-list value: '" + source + "'"); } List <T> subArguments = (argument as ListValue <T>).elements; if (headPatterns.Count > subArguments.Count) { throw new Error("In a list pattern variables exceed values: '" + source + "'"); } List <T> headArguments = subArguments.Take(headPatterns.Count).ToList(); List <T> tailArguments = subArguments.Skip(headPatterns.Count).ToList(); env = env.ExtendValues(headPatterns, headArguments, netlist, source, style, s + 1); env = env.ExtendValue(singlePattern, new ListValue <T>(tailArguments), netlist, source, style, s + 1); } else if (pattern is TailConsPattern) { Pattern singlePattern = (pattern as TailConsPattern).single; List <Pattern> tailPatterns = (pattern as TailConsPattern).list.parameters; if (!(argument is ListValue <T>)) { throw new Error("A list pattern is bound to a non-list value: '" + source + "'"); } List <T> subArguments = (argument as ListValue <T>).elements; if (tailPatterns.Count > subArguments.Count) { throw new Error("In a list pattern variables exceed values: '" + source + "'"); } List <T> headArguments = subArguments.Take(subArguments.Count - tailPatterns.Count).ToList(); List <T> tailArguments = subArguments.Skip(subArguments.Count - tailPatterns.Count).ToList(); env = env.ExtendValue(singlePattern, new ListValue <T>(headArguments), netlist, source, style, s + 1); env = env.ExtendValues(tailPatterns, tailArguments, netlist, source, style, s + 1); } else { throw new Error("Pattern"); } return(env); }
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 virtual void Execute2(Value arg1, Value arg2, Netlist netlist, Style style, int s) { throw new Error("OperatorBinary"); }