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.

questionAnswers(2)

yourAnswerToTheQuestion