Exemple #1
0
        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;
                }

            }
        }
Exemple #4
0
 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 + ")'");
        }