3

我在 C++ 中的自适应梯形规则算法存在问题——基本上,无论指定的容差如何,我都会得到相同的精确近似值。对于较大的公差,递归应该很早就停止(因为 abs(coarse-fine) 将小于 3.0*large tolerance 并且递归的 minLevel 约为 5)。

但是,此函数的作用是运行最大次数,而不管公差的选择如何。我哪里搞砸了?编辑:也许我的辅助函数有问题?

double trap_rule(double a, double b, double (*f)(double),double tolerance, int count)
{
    double coarse = coarse_helper(a,b, f); //getting the coarse and fine approximations from the helper functions
    double fine = fine_helper(a,b,f);

    if ((abs(coarse - fine) <= 3.0*tolerance) && (count >= minLevel))
        //return fine if |c-f| <3*tol, (fine is "good") and if count above
        //required minimum level
    {
        return fine;
    }
    else if (count >= maxLevel)
        //maxLevel is the maximum number of recursion we can go through
    {
        return fine;

    }
    else
    {
        //if none of these conditions are satisfied, split [a,b] into [a,c] and [c,b] performing trap_rule
        //on these intervals -- using recursion to adaptively approach a tolerable |coarse-fine| level
        //here, (a+b)/2 = c
        ++count;
        return  (trap_rule(a, (a+b)/2.0, f, tolerance/2.0, count) + trap_rule((a+b)/2.0, b, f, tolerance/2.0, count));
    }
}


EDIT: Helper and test functions:

//test function
double function_1(double a)
{
    return pow(a,2);
}

//"true" integral for comparison and tolerances




//helper functions

double coarse_helper(double a, double b, double (*f)(double))
{
    return 0.5*(b - a)*(f(a) + f(b)); //by definition of coarse approx
}


double fine_helper(double a, double b, double (*f)(double))
{
    double c = (a+b)/2.0;
    return 0.25*(b - a)*(f(a) + 2*f(c) + f(b)); //by definition of fine approx
}

double helper(double a, double b, double (*f)(double x), double tol)
{
    return trap_rule(a, b, f, tol, 1);
}

这是 main() 中的内容:

std::cout << "First we approximate the integral of f(x) = x^2 on [0,2]" << std::endl;

    std::cout << "Enter a: ";
    std::cin >> a;

    std::cout << "Enter b: ";
    std::cin >> b;

    true_value1 = analytic_first(a,b);

    for (int i = 0; i<=8; i++)
    {
        result1 [i] = helper(a, b, function_1, tolerance[i]);
        error1 [i] = fabs(true_value1 - result1 [i]);
    }

    std::cout << "(Approximate integral of x^2, tolerance, error )" << std::endl;
    for (int i = 0; i<=8; i++)
    {
        std::cout << "(" << result1 [i] << "," << tolerance[i] << "," << error1[i] << ")" << std::endl;
    }
4

1 回答 1

4

我发现与您建议的情况完全相反——算法仅在minLevel步骤后终止——原因是由于您使用了abs,而不是fabs在容差测试中。将abs其参数转换为 an int,因此任何小于 1 的错误都会被舍入为零。

abs就位后,我从一个非常相似的程序中得到了这个输出:

(0.333496,0.001,0.00016276)
(0.333496,0.0001,0.00016276)
(0.333496,1e-05,0.00016276)
(0.333496,1e-06,0.00016276)
(0.333496,1e-07,0.00016276)
(0.333496,1e-08,0.00016276)
(0.333496,1e-09,0.00016276)
(0.333496,1e-10,0.00016276)
(0.333496,1e-11,0.00016276)

替换为fabs我得到这个:

(0.333496,0.001,0.00016276)
(0.333374,0.0001,4.06901e-05)
(0.333336,1e-05,2.54313e-06)
(0.333334,1e-06,6.35783e-07)
(0.333333,1e-07,3.97364e-08)
(0.333333,1e-08,9.93411e-09)
(0.333333,1e-09,6.20882e-10)
(0.333333,1e-10,3.88051e-11)
(0.333333,1e-11,9.7013e-12)
于 2012-10-16T04:35:14.050 回答