public static void Main() { MathState s = new MathState(); foreach (string op in s.GetOperators()) { Console.Write(op + ","); } Console.WriteLine(""); while (true) { string ex = Console.ReadLine(); try { MathExpression expression = s.CreateExpression(ex); StaticStack<MathOperation> expressionStack = expression.ExpressionStack; bool assignment = false; if (expressionStack.Count > 1) { if (expressionStack.Pop() is MathEvaluator.MathOperations.Operators.Equals) { float newValue = (float) expressionStack.Pop().Calculate(expressionStack); if (expressionStack.Peek() is Variable) { Variable var = (Variable)expressionStack.Pop(); s.SetVariable(var.ToString(), newValue); Console.WriteLine(" " + var.ToString() + " -> " + newValue); assignment = true; } } } if(!assignment) { Console.WriteLine("Expression: " + expression.OriginalExpression); Console.WriteLine("PostFix: " + expression.PostFixExpression); MathExpression derived = expression.Derive(s); MathExpression dOptimized = derived; for(int i = 0;i< 5;i++) { dOptimized = dOptimized.Optimize(s); } Console.Write("Derived: "); derived.ExpressionTree.PrintInFix(); Console.Write("\nOptimized: "); dOptimized.ExpressionTree.PrintInFix(); Console.WriteLine("\n"); dOptimized.ExpressionTree.PrintPreFix(); Console.Write("\n"); Console.Write("Value: "); PrintDouble((float)expression.Calculate(), 20); } Console.WriteLine("Implicit: " + expression.IsImplicit); } catch (Exception exc) { Console.WriteLine(exc.Message); } } }
public void DeriveToStack(StaticStack<MathOperations.MathOperation> Stack,MathState State) { Value.DeriveToStack(this,State,Stack); }
public void Optimize(MathState State) { if(Value is Operator) { if (Left != null) Left.Optimize(State); if (Right != null) Right.Optimize(State); float LeftValue = (Left.Value is Number) ? ((Number)Left.Value).Value : float.NaN; float RightValue = (Right.Value is Number) ? ((Number)Right.Value).Value : float.NaN; switch (Value.ToString()) { case "-": case "+": if (LeftValue == 0) ReplaceWith(Right); else if (RightValue == 0) ReplaceWith(Left); else if (!(float.IsNaN(LeftValue) || float.IsNaN(RightValue))) { Number result; if (Value.ToString() == "+") result = LeftValue + RightValue; else result = LeftValue - RightValue; ReplaceWith(result); } else if (Left.Value is Plus || Left.Value is Minus) { // (a + b) + c float LeftLeftValue = (Left.Left.Value is Number) ? ((Number)Left.Left.Value).Value : float.NaN; float LeftRightValue = (Left.Right.Value is Number) ? ((Number)Left.Right.Value).Value : float.NaN; float mod = Left.Value is Plus ? 1 : -1; if (!(float.IsNaN(RightValue) || float.IsNaN(LeftLeftValue))) Left.Left.Value = (Number)(LeftLeftValue + RightValue * mod); else if (!(float.IsNaN(RightValue) || float.IsNaN(LeftRightValue))) Left.Right.Value = (Number)(LeftRightValue + RightValue * mod); else break; ReplaceWith(Left); } else if (Right.Value is Plus || Right.Value is Minus) { // a + (b + c) float RightLeftValue = (Right.Left.Value is Number) ? ((Number)Right.Left.Value).Value : float.NaN; float RightRightValue = (Right.Right.Value is Number) ? ((Number)Right.Right.Value).Value : float.NaN; float mod = Right.Value is Plus ? 1 : -1; if (!(float.IsNaN(LeftValue) || float.IsNaN(RightLeftValue))) Right.Left.Value = (Number)(RightLeftValue + LeftValue * mod); else if (!(float.IsNaN(LeftValue) || float.IsNaN(RightRightValue))) Right.Right.Value = (Number)(RightRightValue + LeftValue * mod); else break; ReplaceWith(Right); } break; case "*": if (LeftValue == 0 || RightValue == 0) { ReplaceWith(0); } else if (LeftValue == 1) ReplaceWith(Right); else if (RightValue == 1) ReplaceWith(Left); else if (!(float.IsNaN(LeftValue) || float.IsNaN(RightValue))) ReplaceWith( LeftValue * RightValue); else if (Left.Value is Variable && Right.Value is Variable) { // x * x if (Left.Value.ToString() == Right.Value.ToString()) ReplaceWith(Left.Value, State.GetOperator("^"), (Number)2); } else if (Left.Value is Exponentiation && Right.Value is Number) { // x^2 * x if (Left.Left.Value is Number && Left.Left.Value.ToString() == Right.Value.ToString()) { // x^2 -> x^2 + 1 Left.Right = new ExpressionTree(State.GetOperator("+")) { Left = Left.Right, Right = new ExpressionTree((Number)1) }; ReplaceWith(Left); } } else if (Right.Value is Exponentiation && Left.Value is Number) { throw new NotImplementedException("a*a^b not done yet :S"); // x^2 * x if (Right.Left.Value is Number && Right.Left.Value.ToString() == Left.Value.ToString()) { // x^2 -> x^2 + 1 Right.Right = new ExpressionTree(State.GetOperator("+")) { Left = Right.Right, Right = new ExpressionTree((Number)1) }; ReplaceWith(Right); } } else if (Left.Value is Multiplication) { // (a * b) * c float LeftLeftValue = (Left.Left.Value is Number) ? ((Number)Left.Left.Value).Value : float.NaN; float LeftRightValue = (Left.Right.Value is Number) ? ((Number)Left.Right.Value).Value : float.NaN; if (!(float.IsNaN(RightValue) || float.IsNaN(LeftLeftValue))) Left.Left.Value = (Number)(LeftLeftValue * RightValue); else if (!(float.IsNaN(RightValue) || float.IsNaN(LeftRightValue))) Left.Right.Value = (Number)(LeftRightValue * RightValue); else break; ReplaceWith(Left); } else if (Right.Value is Multiplication) { // a + (b + c) float RightLeftValue = (Right.Left.Value is Number) ? ((Number)Right.Left.Value).Value : float.NaN; float RightRightValue = (Right.Right.Value is Number) ? ((Number)Right.Right.Value).Value : float.NaN; if (!(float.IsNaN(LeftValue) || float.IsNaN(RightLeftValue))) Right.Left.Value = (Number)(RightLeftValue * LeftValue ); else if (!(float.IsNaN(LeftValue) || float.IsNaN(RightRightValue))) Right.Right.Value = (Number)(RightRightValue * LeftValue ); else break; ReplaceWith(Right); } break; case "/": if (LeftValue == 0) { ReplaceWith(0); } else if (RightValue == 1) ReplaceWith(Left); else if (!(float.IsNaN(LeftValue) || float.IsNaN(RightValue))) { ReplaceWith(LeftValue / RightValue); } break; case "^": if (RightValue == 1) ReplaceWith(Left); else if (LeftValue == 1) ReplaceWith(1); else if (!(float.IsNaN(LeftValue) || float.IsNaN(RightValue))) { ReplaceWith(Math.Pow(LeftValue,RightValue)); } break; default: break; } } else if (Value is MathEvaluator.MathOperations.Functions.Function) { foreach (var v in FunctionParameters) v.Optimize(State); switch(Value.ToString()) { case "ln": if(FunctionParameters[0].ToString() == "e") ReplaceWith(1); break; default: break; } } }
public override void DeriveToStack(MathEvaluator.ExpressionTree cur,MathState s, MathEvaluator.StaticStack<MathOperation> DeriveStack) { throw new MathEvaluator.Exceptions.UndefinedResultException(ToString() + " is not derivable"); }
public MathExpression Optimize(MathState state) { ExpressionTree tree = m_ExpressionTree; m_ExpressionTree.Optimize(state); StaticStack<MathOperation> stack = m_ExpressionTree.BuildExpressionStack(new StaticStack<MathOperation>()); Dictionary<string, float> var = new Dictionary<string, float>(m_Variables); for (int i = 0; i < stack.Count; i++) { if (stack[i] is Variable) { Variable v = (Variable)stack[i]; stack[i] = new Variable(v.ToString(), var); } } MathExpression optimized = new MathExpression(stack, var, OriginalExpression); UpdateExpressionTree(); return optimized; }
public MathExpression Derive(MathState state) { StaticStack<MathOperation> stack = m_ExpressionStack; StaticStack<MathOperation> derived = new StaticStack<MathOperation>(); ExpressionTree tree = new ExpressionTree(stack); tree.DeriveToStack(derived, state); Dictionary<string, float> var = new Dictionary<string, float>(m_Variables); for (int i = 0; i < derived.Count; i++) { if (derived[i] is Variable) { Variable v = (Variable)derived[i]; derived[i] = new Variable(v.ToString(), var); } } return new MathExpression(derived,var, "(" + OriginalExpression + ")'"); }