数值积分:使模板函数仅采用函数名称或使用两个参数调用的函数

时间:2016-01-11 16:21:25

标签: c++ templates numerical-integration

我是C ++的新手,我试图编写/编辑一个使用梯形规则在数值上集成函数的代码。只要我只传递函数的名称,这样就可以正常工作。但是,如果我通过两个参数传递函数,这显然必须失败,因为" x" (见代码)未定义 如何更改代码才能使其正常工作?我是否必须改变课堂上的某些内容" trapezium"或仅在功能"整合"?

#include <iostream>

// Integration routine
template<typename Method, typename F, typename Float>
double integrate(F f, Float a, Float b, long steps, Method m)
{
    double s = 0;
    double h = (b-a)/steps;
    for (int i = 0; i < steps; ++i)
    s += m (f, a + h*i, h);
    return h*s;
}

// The method
class trapezium
{
public:
    template<typename F, typename Float>
    double operator()(F f, Float x, Float h) const
    {
        return (f(x) + f(x+h))/2;
    }
};

// Test function
namespace
{
    double ftest1(double x)
    {
        return (x < 1. ? 0. : 1.);
    }

    double ftest2(double x, double amplitude)
    {
        return x < 1. ? 0. : amplitude;
    }
}

int main()
{
    //This works:
    double res1 = integrate(ftest1, 0., 2., 100, trapezium());
    std::cout << "Result 1: " << res1 << std::endl;

    //This cannot work: 
    double amplitude = 5.;
    double res2 = integrate(ftest2(x, amplitude), 0., 2., 100, trapezium());
    std::cout << "Result 2: " << res2 << std::endl;

    return 0;
}

编辑:不幸的是,由于我无法影响的原因,我必须坚持使用C ++ 98标准。

2 个答案:

答案 0 :(得分:0)

integrate期望函数作为第一个参数,使用lambda或std::bind

double res2 = integrate([=](double x) { return ftest2(x, amplitude); }, 0., 2., 100, trapezium());
// Result 2: 5.05

答案 1 :(得分:0)

你可以使用&#34;仿函数&#34;来完成这项工作。因此,不是定义要传递的函数,而是定义一个覆盖operator()

的类
class func2{
private:
    double amp;
public:
    func2(double amp) : amp(amp) {}

    double operator()(double x){return amp * stepfunction(x);}
};

现在您可以传递func2的实例:

func2 myfunc2(5.0);
double res2 = integrate(myfunc2, 0.0, 2.0, 100.0, trapezium);