示例#1
0
        /// <summary>
        /// Converts a given postfix array to a infix expression.
        /// </summary>
        /// <param name="postfixExp"></param>
        /// <returns></returns>
        public static string Convert2Infix(string[] postfixExp)
        {
            Stack <string> tokenStack  = new Stack <string>();
            List <string>  postfixList = new List <string>();

            //Operator lists for different number of operands
            List <string> unaryOperators  = new List <string>();
            List <string> binaryOperators = new List <string>();

            OperatorFunctions.UnaryOperators(unaryOperators);
            OperatorFunctions.BinaryOperators(binaryOperators);

            //Recreate postfix list
            for (int i = 0; i < postfixExp.Length; i++)
            {
                postfixList.Add(postfixExp[i]);
            }
            postfixList.Reverse();

            //Iterate over all tokens in postfix expression
            foreach (string token in postfixList)
            {
                //Binary operators
                if (binaryOperators.Any(token.Contains))
                {
                    string x   = tokenStack.Pop();
                    string y   = tokenStack.Pop();
                    string exp = "(" + y + token + x + ")";

                    tokenStack.Push(exp);
                }
                //Unary operators
                else if (unaryOperators.Any(token.Contains))
                {
                    string x   = tokenStack.Pop();
                    string exp = "(" + token + "(" + x + ")" + ")";

                    tokenStack.Push(exp);
                }

                /*
                 * Add Numbers directly to string, the first
                 * one doesn't need a buffer space in-between
                 */
                else
                {
                    tokenStack.Push(token);
                }
            }

            return(tokenStack.Pop());
        }
示例#2
0
        /// <summary>
        /// Tests for finding the limit of many
        /// functions and comparing with results
        /// found from wolframalpha.com
        /// </summary>
        public static void DebugLimit()
        {
            Console.WriteLine("Debugging limit methods:");
            string limStr, limPostFix;
            double lim = 0;

            //Operator dictionary to define order of operations
            Dictionary <string, int> operators = new Dictionary <string, int>();

            OperatorFunctions.Operators(operators);

            //Test as many different operators I can think of - probably don't need test suite for this
            string[] funcList = { "-5 + (((sqrt(x) - x!)^2 / (x^2 * 5 + 3 * csc(cos(x)))) % 2) + abs(x) + ln(x) + arctan(x)",
                                  "-(x+5)",                                                                                  "x + -5","(-x)", "-x + 5", "log2(x)" };
            double[] correctAns = { 3.166983673,
                                    -10, 0, -5, 0, 0, };

            limStr = "5";
            for (int i = 0; i < funcList.Length; i++)
            {
                string func = funcList[i];
                double ans  = correctAns[i];

                //Create list of elements in limit to test for operators
                List <string> limList = new List <string>();
                limList = StringFunctions.Convert2List(limStr);

                //Check for operators in limit and convert appropriately
                if (limList.Any(operators.ContainsKey))
                {
                    limStr     = StringFunctions.ReplaceConstants(limStr);
                    limPostFix = Calculator.Convert2Postfix(limStr);
                    lim        = Calculator.EvaluatePostFix(limPostFix);
                }
                else
                {
                    limStr = StringFunctions.ReplaceConstants(limStr);
                    lim    = double.Parse(limStr);
                }

                //Remove any whitespace for parsing
                func = func.Replace(" ", "");

                //Calculate limits and output answer
                double test = LimitCalc.EvaluateLimit(func, lim);
                Console.WriteLine("Limit as x->" + lim + " of " + func + " = " + Math.Round(test, 3) + " ans: " + ans);
            }
        }
示例#3
0
        /// <summary>
        /// Takes a given postfix expression and evaluates it
        /// and returns the value to the main program to test
        /// for convergence.
        /// </summary>
        /// <param name="postfixExp"></param>
        /// <returns></returns>
        public static double EvaluatePostFix(string postfixExp)
        {
            string x, y, ans;

            string[]       postfixArray = postfixExp.Split(null);
            Stack <string> tokenStack   = new Stack <string>();

            //Operator lists for different number of operands
            List <string> unaryOperators  = new List <string>();
            List <string> binaryOperators = new List <string>();

            OperatorFunctions.UnaryOperators(unaryOperators);
            OperatorFunctions.BinaryOperators(binaryOperators);

            //Iterate over all tokens in postfix expression
            foreach (string token in postfixArray)
            {
                if (binaryOperators.Any(token.Contains))
                {
                    //Evaluate functions that take two arguments
                    y = tokenStack.Pop();
                    x = tokenStack.Pop();

                    ans = OperatorFunctions.EvaluateExp(x, y, token).ToString();

                    tokenStack.Push(ans);
                }
                else if (unaryOperators.Any(token.Contains))
                {
                    //Evaluate functions that only take a single argument
                    x = "temp";
                    y = tokenStack.Pop();

                    ans = OperatorFunctions.EvaluateExp(x, y, token).ToString();

                    tokenStack.Push(ans);
                }
                else
                {
                    tokenStack.Push(token);
                }
            }

            //Last thing on stack is the answer
            ans = tokenStack.Pop();
            return(double.Parse(ans));
        }
示例#4
0
        /// <summary>
        /// Takes in user input for a function and a value to evaluate the limit at
        /// and returns the value of the function if it converges or returns
        /// "inf" if it diverges.
        /// </summary>
        /// <param name="args"></param>
        private static void RunLimitCalc()
        {
            string func, limStr, limPostFix;
            double lim = 0, ans;

            //Operator dictionary to define order of operations
            Dictionary <string, int> operators = new Dictionary <string, int>();

            OperatorFunctions.Operators(operators);

            //Let user keep entering functions and limits as they desire
            while (true)
            {
                //User input
                Console.WriteLine("Input f(x): ");
                func = Console.ReadLine();
                Console.WriteLine("Input limit: ");
                limStr = Console.ReadLine();

                //Create list of elements in limit to test for operators
                List <string> limList = new List <string>();
                limList = StringFunctions.Convert2List(limStr);

                //Check for operators in limit and convert appropriately
                if (limList.Any(operators.ContainsKey))
                {
                    limStr     = StringFunctions.ReplaceConstants(limStr);
                    limPostFix = Calculator.Convert2Postfix(limStr);
                    lim        = Calculator.EvaluatePostFix(limPostFix);
                }
                else
                {
                    limStr = StringFunctions.ReplaceConstants(limStr);
                    lim    = double.Parse(limStr);
                }

                //Remove any whitespace for parsing
                func = func.Replace(" ", "");

                //Calculate limits and output answer
                ans = EvaluateLimit(func, lim);
                Console.WriteLine("Limit as x->" + lim + " of " + func + " = " + Math.Round(ans, 3));
                Console.ReadLine();
            }
        }
        /// <summary>
        /// Takes in a string that contains an expression and returns
        /// a boolean value if the expression is singular, i.e. it
        /// does not contain any operators.
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public static bool IsSingular(string[] func)
        {
            //Operator lists for different number of operands
            Dictionary <string, int> operators = new Dictionary <string, int>();

            OperatorFunctions.Operators(operators);

            //Skip placeholder strings
            if (func.Contains("temp"))
            {
                return(false);
            }

            //Check all tokens for operators
            foreach (string token in func)
            {
                if (operators.Any(p => p.Key == token))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#6
0
        /// <summary>
        /// This function takes an analytic expression and determines
        /// whether a "-" is a subtraction of two values or a negation
        /// of one value. Substitutes negations with 0 - value instead.
        /// </summary>
        /// <param name="Exp"></param>
        /// <returns></returns>
        public static List <string> ReplaceNegatives(List <string> Exp)
        {
            //Deep clone list for constant length to iterate over
            List <string> ExpOut = new List <string>();

            //ExpOut = DeepCloneList(Exp);
            ExpOut = Exp;
            int StrLen = Exp.Count();

            //Operator dictionary
            Dictionary <string, int> operators = new Dictionary <string, int>();

            OperatorFunctions.Operators(operators);

            for (int i = 0; i < ExpOut.Count() - 1; i++)
            {
                if ((operators.Any(p => p.Key == ExpOut[i])) & (ExpOut[i + 1] == "-"))
                {
                    //Case a + -b
                    //ExpOut.Insert(i + 1, "0");
                    ExpOut.Insert(i + 1, "(");
                    ExpOut.Insert(i + 2, "0");
                    ExpOut.Insert(i + 5, ")");
                    i += 3;
                }
                else if ((ExpOut[i] == "(") & (ExpOut[i + 1] == "-"))
                {
                    //Case (-a)
                    //ExpOut.Insert(i + 1, "0");
                    ExpOut.Insert(i + 1, "(");
                    ExpOut.Insert(i + 2, "0");
                    ExpOut.Insert(i + 5, ")");
                    i += 3;
                }
                else if ((i == 0) & (ExpOut[i] == "-"))
                {
                    //Case -a + b
                    //ExpOut.Insert(i , "0");
                    ExpOut.Insert(i, "(");
                    ExpOut.Insert(i + 1, "0");
                    ExpOut.Insert(i + 4, ")");
                    i += 2;
                }
                else if ((ExpOut[i] == "-") & (ExpOut[i + 1] == "(") & (i == 0))
                {
                    //Case -(a + b)
                    //ExpOut.Insert(i, "0");
                    ExpOut.Insert(i, "(");
                    ExpOut.Insert(i + 1, "0");
                    ExpOut.Insert(i, "0");
                    i += 2;
                }

                //Relic - might not be needed
                if (((ExpOut[i] == "-") & (ExpOut[i + 1] == "~")) |
                    ((ExpOut[i] == "~") & (ExpOut[i + 1] == "-")))
                {
                    //Case ~-a or -~a
                    ExpOut.RemoveRange(i, 2);
                }
                //Relic - might not be needed
                if (((ExpOut[i] == "~") & (ExpOut[i + 1] == "~")) |
                    ((ExpOut[i] == "-") & (ExpOut[i + 1] == "-")))
                {
                    //Case ~~a or --a
                    ExpOut.RemoveRange(i, 2);
                }

                /*
                 ################
                 ## Old Method ##
                 ################
                 ################
                 ################if ((operators.Any(p => p.Key == ExpOut[i])) & (ExpOut[i + 1] == "-"))
                 ################{
                 ################//Case a + -b
                 ################ExpOut[i + 1] = "~";
                 ################}
                 ################if ((ExpOut[i] == "(") & (ExpOut[i + 1] == "-"))
                 ################{
                 ################//Case (-a)
                 ################ExpOut[i + 1] = "~";
                 ################}
                 ################if ((i == 0) & (ExpOut[i] == "-"))
                 ################{
                 ################//Case -a + b
                 ################ExpOut[i] = "~";
                 ################}
                 ################if ((ExpOut[i] == "-") & (ExpOut[i + 1] == "(") & (i == 0))
                 ################{
                 ################//Case -(a + b)
                 ################ExpOut[i] = "~";
                 ################}
                 ################if (((ExpOut[i] == "-") & (ExpOut[i + 1] == "~")) |
                 ################((ExpOut[i] == "~") & (ExpOut[i + 1] == "-")))
                 ################{
                 ################//Case !-a or -!a
                 ################ExpOut.RemoveRange(i, 2);
                 ################}
                 ################if (((ExpOut[i] == "~") & (ExpOut[i + 1] == "~")) |
                 ################((ExpOut[i] == "-") & (ExpOut[i + 1] == "-")))
                 ################{
                 ################//Case !!a or --a
                 ################ExpOut.RemoveRange(i, 2);
                 ################} */
            }

            return(ExpOut);
        }
示例#7
0
        /// <summary>
        /// Converts a given infix expression to a postfix expression
        /// to calculate the values used for testing convergence of
        /// limits.
        /// </summary>
        /// <param name="infixExp"></param>
        /// <returns></returns>
        public static string Convert2Postfix(string infixExp)
        {
            List <string>  infixList  = new List <string>();
            string         postfixExp = "";
            Stack <string> tokenStack = new Stack <string>();

            tokenStack.Push("(");

            //Operator dictionary to define order of operations
            Dictionary <string, int> operators = new Dictionary <string, int>();

            OperatorFunctions.Operators(operators);

            //Convert infix expression to an array of strings
            infixList = StringFunctions.Convert2List(infixExp);
            infixList = StringFunctions.ReplaceNegatives(infixList);
            infixList.Add(")");

            //Iterate over all tokens in infix expression
            foreach (string token in infixList)
            {
                if (token == "(")
                {
                    tokenStack.Push(token);
                }
                else if (token == ")")
                {
                    /*
                     * Add operators to string until left paren reached,
                     * then pop left paren
                     */
                    for (int i = 0; i <= tokenStack.Count(); i++)
                    {
                        if (tokenStack.Peek() == "(")
                        {
                            tokenStack.Pop();
                            break;
                        }
                        else
                        {
                            postfixExp += " " + tokenStack.Pop();
                        }
                    }
                }
                else if (operators.Any(p => p.Key == token))
                {
                    /*
                     * Add operators in stack >= current operator to string,
                     * then push current operator to stack
                     */
                    for (int i = 0; i <= tokenStack.Count(); i++)
                    {
                        if (tokenStack.Peek() == "(")
                        {
                            break;
                        }
                        else if (operators[tokenStack.Peek()] >= operators[token])
                        {
                            postfixExp += " " + tokenStack.Pop();
                        }
                    }
                    tokenStack.Push(token);
                }
                else
                {
                    /*
                     * Add Numbers directly to string, the first
                     * one doesn't need a buffer space in-between
                     */
                    if (postfixExp.Length == 0)
                    {
                        postfixExp += token;
                    }
                    else
                    {
                        postfixExp += " " + token;
                    }
                }
            }

            return(postfixExp);
        }
        /// <summary>
        /// Takes in a reverse postfix array and recursively grabs
        /// an operator and two operands to be derivated such
        /// that they are all complete expressions.
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        private static string CompleteExpressions(string[] postfixArray)
        {
            //Operator lists for different number of operands
            List <string> unaryOperators  = new List <string>();
            List <string> binaryOperators = new List <string>();

            OperatorFunctions.UnaryOperators(unaryOperators);
            OperatorFunctions.BinaryOperators(binaryOperators);

            //Initialize
            int    i     = 0;
            string token = postfixArray[0];

            //Split between no, unary, and binary operators
            if (unaryOperators.Any(token.Contains))
            {
                string A = postfixArray[1];
                string B = "temp";

                bool completeA = IsComplete(A);

                //Loop until complete expressons
                while (!completeA)
                {
                    i++;

                    if (!completeA)
                    {
                        A += " " + postfixArray[i + 1];
                    }

                    //Recheck for completeness and increment
                    completeA = IsComplete(A);
                }

                string[] ArrA = A.Split(' ');
                string[] ArrB = B.Split(' ');
                return(EvaluateDerivative(ArrA, ArrB, token));
            }
            else if (binaryOperators.Any(token.Contains))
            {
                string B = postfixArray[1];
                string A = postfixArray[2];

                bool completeA = IsComplete(A);
                bool completeB = IsComplete(B);

                //Loop until complete expressons
                while ((!completeA) || (!completeB))
                {
                    //Try to fix completeness
                    if (!completeB)
                    {
                        B += " " + A;
                        A  = postfixArray[i + 3];
                    }
                    else if (!completeA)
                    {
                        A += " " + postfixArray[i + 3];
                    }

                    //Recheck for completeness and increment
                    completeA = IsComplete(A);
                    completeB = IsComplete(B);
                    i++;
                }

                string[] ArrA = A.Split(' ');
                string[] ArrB = B.Split(' ');
                return(EvaluateDerivative(ArrA, ArrB, token));
            }
            else
            {
                string[] tempList = { "temp" };
                return(EvaluateDerivative(tempList, postfixArray, "temp"));
            }
        }