计算函数限制的最佳方法是什么?

时间:2012-03-20 14:28:15

标签: c# c++ algorithm math limit

我打算开发一个可以计算用户给出的表达式(函数)限制的应用程序。

我已经有了一个功能表达式评估器,它肯定会派上用场。我的想法是像这样计算它:我给参数一些值越来越接近点,但没有达到这一点。最后,我看到两个连续结果之间的差异是否使得更小或更大更接近或远离0.如果它得到更小更近,这意味着限制是有限的,否则无限。在那之后,很容易估计结果。

有更好的方法吗?或者我应该选择这个?

应用程序将接受包含这些数学运算符的函数:+,-,*,/,%,^,函数(如floor,logarithms,trigonometry)和3个条件函数(abs,min,max)。 因此,例如,不接受具有整数值的特定值的函数,以及非整数值的另一个值。

5 个答案:

答案 0 :(得分:3)

在数学上你可以使用微积分。就像你只需要实现差异规则而你不必使用暴力

但你对wolframalpha的评论很棒: 例如:thats exactly what you need

答案 1 :(得分:2)

这个答案更多的是数学而不是编程,但它告诉你为什么你不能做你想要的东西(除非你添加更多关于功能的信息)。

我们将f定义如下:

  • f(x) = 0如果x是有理数
  • f(x) = 1如果x不是有理数

此功能在任何时候都没有限制,但是如果你使用你指定的方法,那么对于你使用的浮动(或双重)数字,f(x)将是0 ,差异将是0

您的方法会说f5的限制为0,但f根本没有限制。

答案 2 :(得分:1)

我只是写一个简短的评论,但我想的越多,我就越能得出结论,你的问题的答案是你不应该接受你的建议。您的提案中存在一个循环:找到函数的限制,您建议为系统提供一系列输入,这些输入的评估趋向于(假设的)函数限制。如果不知道限制是什么,你会如何开始?或者您是否想要实现一个程序来查找您已经知道的函数限制?一种永远比你少知道的人工白痴?

至于你应该做什么,首先要意识到这实际上是一个非常棘手的功能,并且没有适用于所有功能的通用解决方案,即使对于所有漂亮,行为良好的功能也是如此。您可能会发现Sage(http://www.sagemath.org/)或您知道的任何其他开源计算机代数系统是如何做到的,这是有益的。

答案 3 :(得分:0)

我这样做的方法是首先应用泰勒来找到给定函数的系数估计值,但将函数向左移动极限x。然后从它们的设定系数nan到0。然后只需在给定的x值处计算函数即可。

script

答案 4 :(得分:0)

尽管很难直接找到一个极限,但是您可以使用double.Epsilon常量在C#中很好地估计它们,以找到一个非常接近的值。该字段是一个常数,它表示可以用双浮点数表示的最小数字,因此我们将使用它来查找与x值非常接近的值,并将其插入函数中。

这里是一个例子:

using System;

namespace LimitsTest
{
    class Functions
    {
        public static double OneDividedByX(double x)
        {
            return 1 / x;
        }

        public static double XDividedByX(double x)
        {
            return x / x;
        }

        public static double OneDividedByXSquared(double x)
        {
            return 1 / Math.Pow(x, 2);
        }

        public static double XDividedByXPlusTwo(double x)
        {
            return x / (x + 2);
        }
    }

    class Program
    {
        static double LeftLimit(double x, Func<double, double> function)
        {
            return function(x - double.Epsilon);
        }

        static double RightLimit(double x, Func<double, double> function)
        {
            return function(x + double.Epsilon);
        }

        static double Limit(double x, Func<double, double> function)
        {
            double right = LeftLimit(x, function);
            double left = RightLimit(x, function);

            return (right == left) ? right : double.NaN;
        }

        static void ShowLimits(double x, string description, Func<double, double> function)
        {
            Console.WriteLine("{0} at {1}: {2}", description, x, function(x));
            Console.WriteLine("Limit of {0} as approached from the left of {1}: {2}",
                description, x, LeftLimit(x, function));
            Console.WriteLine("Limit {0} as approached from the right of {1}: {2}",
                description, x, RightLimit(x, function));
            Console.WriteLine("Limit of {0} as approached from {1}: {2}",
                description, x, Limit(x, function));
            Console.WriteLine();
        }

        static void Main(string[] args)
        {
            ShowLimits(0, "1 / x", Functions.OneDividedByX);
            ShowLimits(0, "x / x", Functions.XDividedByX);
            ShowLimits(0, "1 / x^2", Functions.OneDividedByXSquared);
            ShowLimits(-2, "x / (x + 2)", Functions.XDividedByXPlusTwo);

            Console.ReadLine();
        }
    }
}
相关问题