long time browser, first time here. I wrote several scripts to execute various 1D methods of numerical integration and compiled them into a library. I would like this library to be as flexible as possible that it is able to integrate.
Here I include an example: a very simple example of a trapezoidal rule in which I pass a pointer to a function to be integrated.
// 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 = (ba)/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 *= (ba)/(2*N); return s; }
This works great for simple functions that take only one argument. Example:
double a = trap(sin,0,1);
However, sometimes I may need to integrate something that has more parameters, such as a quadratic polynomial. In this example, the coefficients will be determined by the user before integration. Code example:
Ideally, I could do something like this to integrate it:
double b = trap(quad(1,2,3),0,1);
But it is clear that this does not work. I ran into this problem by defining a class that has coefficients as members and a function of interest as a member function:
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); } };
However, then my integration function must change to take an object as an input instead of a function pointer:
// 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 = (ba)/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 *= (ba)/(2*N); return s; }
This works fine, but the resulting library is not very independent, since it requires a specific class model. In addition, ideally, the Model should be able to change from user to user, so I do not want to fix it in the header file. I tried using functional templates and functors to make this work, but it is not very independent, since again the template must be defined in the header file (if you do not want to explicitly create instances, but it is not).
So, to summarize: is there a way to make my integration functions accept arbitrary 1D functions with a variable number of input parameters, while remaining independent enough to be compiled into a standalone library? Thanks in advance for the suggestions.