Я новичок в 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.
Вы можете сделать эту работу с «функтором». Поэтому вместо определения функции для передачи определите класс, который переопределяет 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);
integrate
ожидает функцию в качестве первого аргумента, используйте лямбду или std::bind
:
double res2 = integrate([=](double x) { return ftest2(x, amplitude); }, 0., 2., 100, trapezium());
// Result 2: 5.05