//Compiles the system into a FunctionVectorND private void Compile() { //Register the constant symbols with their current values parser.AddConst("k", () => k); parser.AddConst("m", () => m); parser.AddConst("b", () => b); //Evaluate the expressions udot_expr = parser.EvaluateExpression(udot); vdot_expr = parser.EvaluateExpression(vdot); //Generate function delegates and load them into the IVP ivp.F.funcs[0] = udot_expr.ToDelegate("t", "u", "v"); ivp.F.funcs[1] = vdot_expr.ToDelegate("t", "u", "v"); }
//Reads in parameters and adds them to the expression parser with their current values. //This is a helper function called by the parse functions above private void IncludeParameters() { foreach (KeyValuePair <string, double> p in parameters) { parser.AddConst(p.Key, () => p.Value); } }
public void EvaluatePhenotypeEquations(CreatureManager hManager) { parser.AddConst("A", () => GlobalGEPSettings.A_VAL); parser.AddConst("B", () => GlobalGEPSettings.B_VAL); chromosomePhenotypeChromoEquations = new List <string>(); chromosomePhenotypeGeneResults = new Dictionary <int, List <float> >(); chromosomePhenotypeChromoResults = new List <float>(); foreach (KeyValuePair <int, List <string> > chromosomeEquation in chromosomePhenotypeGeneEquations) { chromosomePhenotypeGeneResults.Add(chromosomeEquation.Key, new List <float>()); for (int i = 0; i < chromosomeEquation.Value.Count; i++) { //Evaluates the genes individually rather than linking them //If traits are on genes rather than chromosomes then no need to link all the genes and evaluate entire chromosomes together if (GlobalGEPSettings.TRAITS_ON_GENES) { Expression expressionResult = parser.EvaluateExpression(chromosomeEquation.Value[i]); float result = (float)expressionResult.Value; //Check to make sure only usable numbers are present. if (float.IsNaN(result) || float.IsInfinity(result) || float.IsNegativeInfinity(result)) { result = 0; } chromosomePhenotypeGeneResults[chromosomeEquation.Key].Add(result); } } if (!GlobalGEPSettings.TRAITS_ON_GENES) { string linkedEquation = LinkEquations(chromosomeEquation.Value, hManager.generator); Expression expressionResult = parser.EvaluateExpression(linkedEquation); float result = (float)expressionResult.Value; //Check to make sure only usable numbers are present. if (float.IsNaN(result) || float.IsInfinity(result) || float.IsNegativeInfinity(result)) { result = 0; } chromosomePhenotypeChromoResults.Add(result); } } }
//int debug_iter = 0; //Attempts to parse an expression. Sets invalidity flags and updates the status display //fieldNumber: X=1, Y=2, Z=3 public void ValidateExpression(int fieldNumber) { string expr; //Set the field we're looking at switch (fieldNumber) { case 1: expr = expressionXInput.text; //Debug.Log("Validation Field number" + fieldNumber + ". X equation input='" + expr + "'"); break; case 2: expr = expressionYInput.text; //Debug.Log("Validation Field number" + fieldNumber + ". Y equation input='" + expr + "'"); break; case 3: expr = expressionZInput.text; //Debug.Log("Validation Field number" + fieldNumber + ". Z equation input='" + expr + "'"); break; default: //shouldn't happen //Debug.Log("fieldNumber using default."); expr = expressionXInput.text; break; } //debug_iter += 1; //Debug.Log("Validating: Current expr at (" + debug_iter + "): <" + expr + ">"); //Validate try { //First check for empty expression if (expr == "") { //Debug.Log("Empty string detected. Current expr at (" + debug_iter + "): <" + expr + ">"); throw new EmptyExpressionException("Please enter all equations."); } ExpressionParser parser = new ExpressionParser(); //First, read in the user parameters as constants and give it test values int i = 1; foreach (KeyValuePair <string, double> p in parameters) { //each test value should be unique and nonzero to avoid divide by zero parser.AddConst(p.Key, () => 0.00013 * (i * 17)); i++; } //Next, try to evaluate the expression Expression tempExpr = parser.EvaluateExpression(expr); //If no ParseException was thrown, expression parsed correctly //This is where I'd check for custom functions, if that was handled. //Now let's check the parameters of the Expression foreach (KeyValuePair <string, Parameter> p in tempExpr.Parameters) { if (!(variablesAvailable.Contains(p.Key))) { throw new UnknownIdentiferException("Unknown identifier '" + p.Key + "'."); } } //Now for an invocation test: if (order == 1) { ExpressionDelegate deleg = tempExpr.ToDelegate("x", "y", "z", "t"); double[] values = { 0.125778, 0.13456928, 0.2944782, 0.41698793 }; deleg.Invoke(values); } else //order == 2 { ExpressionDelegate deleg = tempExpr.ToDelegate("x", "x'", "y", "y'", "z", "z'", "t"); double[] values = { 0.155926, 0.13562489, 0.2990285, 0.412947352, 1.8308463, 1.0329475, 2.7386352 }; deleg.Invoke(values); } //If no exception, then expression is validated. //Debug.Log("Expression validated: fieldNumber=" + fieldNumber); valid[(fieldNumber - 1)] = true; //All good in this expression. Check the other invalid flags CheckInvalidFlags(); UpdateStatusDisplay(validationStatusDisplay.text); } catch (ExpressionParser.ParseException ex) { //validation unsuccessful due to parsing error valid[(fieldNumber - 1)] = false; UpdateStatusDisplay(ex.Message); } catch (UnknownIdentiferException ex) { //validation unsuccessful due to unknown identifier valid[(fieldNumber - 1)] = false; UpdateStatusDisplay(ex.Message); } catch (EmptyExpressionException ex) { //validation unsuccessful due to empty expression valid[(fieldNumber - 1)] = false; UpdateStatusDisplay(ex.Message); } catch (Exception ex) { //validation unsuccessful on invocation test valid[(fieldNumber - 1)] = false; UpdateStatusDisplay("Unknown error. Check inputs."); Debug.Log(ex.Message); } }