C ++: funkcja pass z dowolną liczbą parametrów jako parametr
przeglądarka przez długi czas, pierwszy raz pyta tutaj. Napisałem wiele skryptów do wykonywania różnych metod integracji numerycznej 1D i skompilowałem je do biblioteki. Chciałbym, aby ta biblioteka była jak najbardziej elastyczna w odniesieniu do tego, co jest w stanie zintegrować.
Oto przykład: bardzo prosty przykład reguły trapezowej, w którym przekazuję wskaźnik do funkcji, która ma zostać zintegrowana.
// 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;
}
Działa to doskonale w przypadku prostych funkcji, które przyjmują tylko jeden argument. Przykład:
double a = trap(sin,0,1);
Jednak czasami mogę chcieć zintegrować coś, co ma więcej parametrów, takich jak wielomian kwadratowy. W tym przykładzie współczynniki zostałyby zdefiniowane przez użytkownika przed integracją. Przykładowy kod:
// arbitrary quadratic polynomial
double quad(double A, double B, double C, double x) {
return (A*pow(x,2) + B*x + C);
}
Idealnie byłbym w stanie zrobić coś takiego, aby go zintegrować:
double b = trap(quad(1,2,3),0,1);
Ale to oczywiście nie działa. Omówiłem ten problem, definiując klasę, która ma współczynniki jako członków i interesującą funkcję jako funkcję składową:
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); }
};
Jednak moja funkcja integracji musi zostać zmieniona, aby pobrać obiekt jako wejście zamiast wskaźnika funkcji:
// 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;
}
Działa to dobrze, ale wynikowa biblioteka nie jest bardzo niezależna, ponieważ potrzebuje gdzieś zdefiniowanego modelu klasy. Idealnie model powinien również być w stanie zmienić użytkownika na użytkownika, więc nie chciałbym go naprawiać w pliku nagłówkowym. Próbowałem użyć szablonów funkcji i funktorów, aby to zadziałało, ale nie jest to bardzo niezależne, ponieważ szablon powinien zostać zdefiniowany w pliku nagłówkowym (chyba że chcesz jawnie utworzyć instancję, której nie mam).
Podsumowując: czy jest jakiś sposób, w jaki mogę uzyskać moje funkcje integracji, aby zaakceptowały dowolne funkcje 1D ze zmienną liczbą parametrów wejściowych, zachowując jednocześnie niezależność, aby można je było skompilować w autonomiczną bibliotekę? Z góry dziękuję za sugestie.