Example #1
0
        /// <summary>
        /// Debugs the IsComplete function, which
        /// checks whether a given string of operators
        /// and operands can be computed.
        /// </summary>
        public static void DebugIsComplete()
        {
            Console.WriteLine("Debugging IsComplete method:");
            string func = "ln 2";

            bool testComplete = DerivativeCalculator.IsComplete(func);

            Console.WriteLine(testComplete);
        }
Example #2
0
        /// <summary>
        /// Calculates the limit as it approaches the value from both
        /// the left and right and averages between the two answers
        /// until either the x values get too close or the threshold
        /// is reached.
        /// </summary>
        /// <param name="func"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public static double EvaluateLimit(string func, double limit)
        {
            //Constants
            const double thresh   = 1e-3;
            const double thresh_x = 1e-5;
            const double delta    = 1e-4;

            //Initial step to initialize everything
            double x_l       = limit - 1;
            double x_r       = limit + 1;
            double left_ans  = Calculator.Calculate(func, x_l);
            double right_ans = Calculator.Calculate(func, x_r);
            double del       = Math.Abs(right_ans - left_ans);
            double del_x     = Math.Abs(x_l - x_r);
            double ans       = (left_ans + right_ans) / 2;

            //Infinite limits
            if (double.IsInfinity(limit))
            {
                //Deal with undefined fractions e.g. 1/inf with L'Hopital
                if (double.IsNaN(ans))
                {
                    //Get index of first outer division symbol
                    int index = StringFunctions.FindOuterSlash(func);

                    //Split into numerator and denominator
                    string num = func.Substring(0, index);
                    string den = func.Substring(index + 1, func.Length - 2);

                    //Take the derivate of the numerator and denominator
                    string numDer = DerivativeCalculator.Derivative(num);
                    string denDer = DerivativeCalculator.Derivative(den);

                    string tot = numDer + "/" + denDer;

                    return(EvaluateLimit(tot, limit));
                }
                else
                {
                    return(ans);
                }
            }

            //Loop until confident limit either converges or DNC
            while (true)
            {
                //If x values too close and still not converged, limit DNC
                if ((del < thresh) & (del_x < thresh))
                {
                    return(ans);
                }
                if (del_x < thresh_x)
                {
                    return(double.PositiveInfinity);
                }

                //Step to next values
                x_l += delta;
                x_r -= delta;

                //Calculate function at current step
                left_ans  = Calculator.Calculate(func, x_l);
                right_ans = Calculator.Calculate(func, x_r);

                //Get differences for break conditions
                del   = Math.Abs(right_ans - left_ans);
                del_x = Math.Abs(x_l - x_r);

                //Take average of two as current solution
                ans = (left_ans + right_ans) / 2;

                //Console.WriteLine(x_l + " " + x_r + " " + del_x + " " + left_ans + " " + right_ans + " " + del + " " + ans);
            }
        }
Example #3
0
        /// <summary>
        /// Debugs the derivative function, checking
        /// against solutions found from wolframalpha.com
        /// in order to compute L'Hopital's rule for
        /// taking limits that result in an indeterminate
        /// form.
        /// </summary>
        public static void DebugDerivative()
        {
            Console.WriteLine("Debugging derivative methods:");

            //Functions to test derivative of
            string[] funcList = { "(x+1)^(x+1)", "(x+2)^2",     "x^5",
                                  "2^(x+2)",     "x+x+x-x",     "ln(1/x)",
                                  "(x+2)/(x-5)", "(x*2)+(x/5)", "2+(x+2)^2+2^x",
                                  "e^x",         "cos(2)",      "cos(x)",       "cos(x^2)",
                                  "x",           "-x",          "-2^x",
                                  "sin(5)",      "sin(x)",      "sin(x^2)",
                                  "tan(5)",      "tan(x)",      "tan(x^2)",
                                  "log5(5)",     "log5(x)",     "log5(x^2)",
                                  "arccos(5)",   "arccos(x)",   "arccos(x^2)",  //Everything on and below this was done with x = 0.5
                                  "arctan(5)",   "arctan(x)",   "arctan(x^2)",
                                  "arcsin(5)",   "arcsin(x)",   "arcsin(x^2)",
                                  "sec(5)",      "sec(x)",      "sec(x^2)",
                                  "csc(5)",      "csc(x)",      "csc(x^2)",
                                  "cot(5)",      "cot(x)",      "cot(x^2)",
                                  "sqrt(5)",     "sqrt(x)",     "sqrt(x^2)",
                                  "abs(5)",      "abs(x)",      "abs(cos(x))",  };

            //From wolframalpha
            string[] correctAns = { "56.6625",  "8",         "80",
                                    "11.09035", "2",         "-0.5",
                                    "-7/9",     "2.2",       "10.7726",
                                    "7.38905",  "0",         "-0.90929",  "3.0272",
                                    "1",        "-1",        "-2.77258",
                                    "0",        "-0.416146", "-2.614574",
                                    "0",        "5.774399",  "9.36220048",
                                    "0",        "0.310667",  "0.621334",
                                    "0",        "-1.1547",   "-1.0328",   //Everything on and below this was done with x = 0.5
                                    "0",        "0.8",       "0.941176",
                                    "0",        "1.1547",    "1.0328",
                                    "0",        "0.622508",  "0.263535",
                                    "0",        "-3.81809",  "-15.8296",
                                    "0",        "-4.35069",  "-16.3375",
                                    "0",        "0.707107",  "1",
                                    "0",        "1",         "-0.479426", };

            //Run through test suite
            for (int i = 0; i < funcList.Length; i++)
            {
                //Attempt to calculate derivative, throw error if fails
                try
                {
                    string func = funcList[i];
                    string ans  = correctAns[i];

                    //Remove any whitespace for parsing
                    //func = "log_5(x)";

                    //Calculate limits and output answer
                    //double test = LimitCalc.EvaluateLimit(func, 2);
                    //Console.WriteLine("Limit as x->" + 2 + " of " + func + " = " + Math.Round(test, 3) + " ans: " + ans);

                    //Replace constants, convert to postfix, take derivative
                    string analytic_func = StringFunctions.ReplaceConstants(func, 0, false);
                    string funcPostFix   = Calculator.Convert2Postfix(analytic_func);
                    string test          = DerivativeCalculator.Derivative(funcPostFix);

                    //Choose what value to evaluate at based on function domain
                    int index = Array.IndexOf(funcList, "arccos(5)");
                    if (i < index)
                    {
                        Console.WriteLine(func + ": " + Calculator.Calculate(test, 2) + " ans: " + ans);
                    }
                    else
                    {
                        Console.WriteLine(func + ": " + Calculator.Calculate(test, 0.5) + " ans: " + ans);
                    }
                }
                catch
                {
                    string func = funcList[i];

                    Console.WriteLine("Error with derivative of: " + func);
                }
            }
        }