长期浏览器,第一次在这里提问。我编写了许多脚本来执行各种 1D 数值积分方法并将它们编译到库中。我希望该库在能够集成的方面尽可能灵活。
这里我包含一个示例:一个非常简单的梯形规则示例,其中我将指针传递给要集成的函数。
// 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;
}
这很好用,但生成的库不是很独立,因为它需要在某处定义类模型。此外,理想情况下,模型应该能够从用户更改为用户,因此我不想在头文件中修复它。我尝试使用函数模板和仿函数来让它工作,但它不是很独立,因为模板应该在头文件中定义(除非你想显式实例化,我不这样做)。
所以,总结一下:有什么方法可以让我的集成函数接受具有可变数量输入参数的任意一维函数,同时仍然保持足够的独立性,可以将它们编译成一个独立的库?提前感谢您的建议。