долгое время браузер, первый раз здесь. Я написал несколько сценариев для выполнения различных 1D методов численного интегрирования и скомпилировал их в библиотеку. Я бы хотел, чтобы эта библиотека была максимально гибкой в отношении того, что она может интегрировать.C++: функция пропуска с произвольным числом параметров в качестве параметра
Здесь я приведу пример: очень простой пример трапециевидного правила, где я передаю указатель на функцию, которая будет интегрирована.
// Numerically integrate (*f) from a to b
// using the trapezoidal rule.
double trap(double (*f)(double), double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += (*f)(xi); }
else { s += 2*(*f)(xi); }
}
s *= (b-a)/(2*N);
return s;
}
Это прекрасно работает для простых функций, которые принимают только один аргумент. Пример:
double a = trap(sin,0,1);
Однако иногда может потребоваться интегрировать то, что имеет больше параметров, как квадратичный полином. В этом примере коэффициенты будут определяться пользователем перед интеграцией. Пример кода:
// arbitrary quadratic polynomial
double quad(double A, double B, double C, double x) {
return (A*pow(x,2) + B*x + C);
}
В идеале, я бы смог сделать что-то вроде этого, чтобы интегрировать его:
double b = trap(quad(1,2,3),0,1);
Но ясно, что не работает. Я получил эту проблему, определив класс, который имеет коэффициенты в качестве членов и функции интереса как функции члена:
class Model {
double A,B,C;
public:
Model() { A = 0; B = 0; C = 0; }
Model(double x, double y, double z) { A = x; B = y; C = z; }
double func(double x) { return (A*pow(x,2)+B*x+C); }
};
Однако тогда моя функция интеграции необходимо изменить, чтобы взять объект в качестве входных данных вместо указатель функции:
// Numerically integrate model.func from a to b
// using the trapezoidal rule.
double trap(Model poly, double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += poly.func(xi); }
else { s += 2*poly.func(xi); }
}
s *= (b-a)/(2*N);
return s;
}
Это прекрасно работает, но в результате библиотека не очень независимы, так как она нуждается в классе модели быть определен где-то. Кроме того, в идеале Модель должна быть способна меняться от пользователя к пользователю, поэтому я не хочу исправлять ее в файле заголовка. Я попытался использовать функциональные шаблоны и функторы, чтобы заставить это работать, но он не очень независим, так как снова шаблон должен быть определен в файле заголовка (если вы не хотите явно создать экземпляр, которого я не знаю).
Итак, подытожим: есть ли способ, каким образом я могу получить свои интеграционные функции для принятия произвольных 1D-функций с переменным количеством входных параметров, при этом все еще оставаясь независимым, чтобы их можно было скомпилировать в автономную библиотеку? Заранее благодарим за предложения.
['std :: bind'] (http://en.cppreference.com/w/cpp/utility/functional/bind) –