Числовая интеграция: сделать так, чтобы шаблонная функция принимала либо только имя функции, либо функцию, вызванную с двумя аргументами

Я новичок в C ++ и пытаюсь написать / отредактировать код, который численно интегрирует функцию с использованием правила трапеции. Это прекрасно работает, пока я передаю только имя функции. Однако, если я передаю функцию с двумя параметрами, это, очевидно, должно завершиться сбоем, поскольку «x» (см. Код) не определено.
Как я могу изменить код, чтобы он работал? Нужно ли что-то менять в классе «трапеция» или только в функции «интегрировать»?

#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.

-1

Решение

Вы можете сделать эту работу с «функтором». Поэтому вместо определения функции для передачи определите класс, который переопределяет 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);
0

Другие решения

integrate ожидает функцию в качестве первого аргумента, используйте лямбду или std::bind:

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

По вопросам рекламы [email protected]