-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEvaluator.cs
More file actions
44 lines (40 loc) · 2.46 KB
/
Evaluator.cs
File metadata and controls
44 lines (40 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
namespace SymSharp;
/// <summary>
/// Utility class providing evaluation routines to convert expression trees into numeric values.
/// </summary>
public static class Evaluator
{
/// <summary>
/// Evaluates the given expression tree to a double value using optional variable definitions.
/// </summary>
/// <param name="expression">The expression tree to evaluate.</param>
/// <param name="variableDefinitions">Optional mapping of variable names to numeric values. May be null.</param>
/// <returns>The numeric result of evaluating the expression.</returns>
public static double EvaluateExpressionTree(IMathExpression expression, Dictionary<string, double>? variableDefinitions)
{
Dictionary<string, double> vardef = variableDefinitions ?? [];
if (expression is Scalar s)
return s.ToDouble();
if (expression is Variable v)
{
if (vardef.ContainsKey(v.Name)) return vardef[v.Name];
throw new Exception($"EvaluateExpressionTree: Undefined variable '{v.Name}'");
}
if (expression is AddOperator op0) { return EvaluateExpressionTree(op0.Left, vardef) + EvaluateExpressionTree(op0.Right, vardef); }
if (expression is SubtractOperator op1) { return EvaluateExpressionTree(op1.Left, vardef) - EvaluateExpressionTree(op1.Right, vardef); }
if (expression is MultiplyOperator op2) { return EvaluateExpressionTree(op2.Left, vardef) * EvaluateExpressionTree(op2.Right, vardef); }
if (expression is DivideOperator op3) { return EvaluateExpressionTree(op3.Left, vardef) / EvaluateExpressionTree(op3.Right, vardef); }
if (expression is PowerOperator op4) { return Math.Pow(EvaluateExpressionTree(op4.Left, vardef), EvaluateExpressionTree(op4.Right, vardef)); }
if (expression is LogOperator op5) { return Math.Log(EvaluateExpressionTree(op5.Inner, vardef)); }
throw new Exception("TILT: Should not get here");
}
/// <summary>
/// Parses and evaluates a textual numeric expression using the factory and returns a double.
/// This method is a convenience wrapper around <see cref="EvaluateExpressionTree(IMathExpression, Dictionary{string,double}?)"/>.
/// </summary>
/// <param name="expression">Textual expression to evaluate (e.g. "2+2").</param>
/// <returns>Numeric result of evaluation.</returns>
public static double Evaluate(string expression) =>
EvaluateExpressionTree(
SymFactory.FromString(expression), []);
}