【问题标题】:Passing generic function for numerical integration with trapezoidal rule使用梯形规则传递用于数值积分的通用函数
【发布时间】:2020-05-07 00:58:15
【问题描述】:

我有一种使用梯形法则计算函数积分的方法。它工作正常:

double trap_method(double a, double b, double n){

    int i = 1; double area = 0; double h = (b-a)/(n-1);
    double x = a+h;
    while(i <= n-2){

        area = area + exp(x)*h;
        x = x+h;
        i++;
    }
    area = area + (exp(a) + exp(b)) * h/2;

    return area;
}

但是,如您所见,它仅适用于 ex 或您硬编码到其中的任何内容。

我想知道如何向trap_method 添加一个参数,这样我每次都可以将我想要集成的表达式更改为我想要的任何内容。比如:

double trap_method(double a, double b, double n, function f){

    int i = 1; double area = 0; double h = (b-a)/(n-1);
    double x = a+h;
    while(i <= n-2){

        area = area + f(x)*h;
        x = x+h;
        i++;
    }
    area = area + (f(a) + f(b)) * h/2;

    return area;
}

【问题讨论】:

  • 请参阅Pointers to functions,除非您在某处输入了function,否则您所写的内容并未提供所需的语法。 (但是是的,你可以做你想做的事)另见Function pointer as parameter
  • 看看std::function,它可以很高兴地接受一个函数指针或一个lambda。
  • 如果你真的很懒,把function改成auto

标签: c++ numerical-methods generic-programming


【解决方案1】:

您可以使用函数指针或模板来传递 lambda 函数。

double f(double x){
    return x*x;
}

double trap_method(double a, double b, int n, double (*func)(double)){

    int i = 1; double area = 0; double h = (b-a)/(n-1);
    double x = a+h;
    while(i <= n-2){

        area = area + func(x)*h;
        x = x+h;
        i++;
    }
    area = area + (func(a) + func(b)) * h/2;

    return area;
}

template<typename FUNC>
double trap_method(double a, double b, int n, FUNC func){

    int i = 1; double area = 0; double h = (b-a)/(n-1);
    double x = a+h;
    while(i <= n-2){

        area = area + func(x)*h;
        x = x+h;
        i++;
    }
    area = area + (func(a) + func(b)) * h/2;

    return area;
}

主要

cout << trap_method(0, 1, 100, f) << endl;
cout << trap_method(0, 1, 100, [](double x){return x*x;}) << endl;

【讨论】:

  • 感谢您的回复。我假设前半部分是指针方法吗?在这种情况下,'double (*fp) (double)' 是否使它“指向”您之前创建的函数 'f'?如果该函数改为名称 'q' 它将是 'double (*qp) (double)' ?
  • @AlejandroMatos 不,参数名称不必相同。修改后的答案。
  • @AlejandroMatos 你的方法是正确的。我没有看到最后的金额。
【解决方案2】:
template<typename func_type>
double trap_method(double a, double b, double n, func_type f){

    int i = 1; double area = 0; double h = (b-a)/(n-1);
    double x = a+h;
    while(i <= n-2){

        area = area + f(x)*h;
        x = x+h;
        i++;
    }
    area = area + (f(a) + f(b)) * h/2;

    return area;
}

然后……

double result = trap_method(a, b, n, std::exp);

【讨论】:

  • 感谢您的回复。如果在“trap_method”中我放置了一个我之前声明过的函数“f”,那也可以吗?编辑:确实
  • 是的。因为它是一个模板,func_type 可以是任何东西。
  • 你试过编译这段代码吗? std::exp 命名函数的重载 setfunc_type 不能从该集合中推导出来。如果您只有一个非模板 std::exp 函数,这将起作用。
猜你喜欢
  • 2015-05-15
  • 2020-06-02
  • 1970-01-01
  • 2021-07-12
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多