Funktion an Funktion mit teilweise festen, teilweise variablen Parametern übergeben
-
Hallo zusammen,
ich wollte mal fragen, wie man am besten ein Interface für eine Mathematische Optimierungs-Funktion gestaltet. Ich habe also eine Funktion, die eine andere Funktion minimiert, zum Beispiel Gradientenabstieg. Jetzt will ich an diese Funktion eine (fast) beliebige Funktion übergeben, die minimiert werden soll.
Die Anforderungen an diese Funktion sollen sein: Rückgabewert vom typ double, Erster Parameter vom typ std::vector<double>. Darüber hinaus soll die zu minimierende Funktion aber auch noch beliebige weitere Parameter aufnehmen können. Das Ganze habe ich momentan so realisiert:
namespace fmin { template <typename T> std::vector<double> gradient_decent(std::function<double(std::vector<double> const &, T const &)>, std::vector<double> const & start_value_, T const &optional_paras_); } double cost_function(std::vector<double> const ¶s, int myint) { return paras.size() + myint; // Nur ein Beispiel } int _tmain(int argc, _TCHAR* argv[]) { std::vector<double> start_values{ 1 }; int optional_paras = 1; fmin::gradient_decent<int>(cost_function, start_values, optional_paras); }Das kommt schon ganz gut an das hin was ich will, ist aber noch nicht perfekt... Mich nervt zum Beispiel dass man in der Zeile 18 den Template-Parameter mit übergeben muss. Kann man dem Compiler nicht sagen dass er sich diesen aufgrund der übergebenen Kostenfunktion selbst raussucht?
In Matlab kann man ja sowas machen:
fminsearch(@(x)cost_function(x, optional_paras), start_values);Das heißt, cost_function wird über x minimiert. Die optionalen Parameter bleiben unverändert. Kann man in C++ etwas vergleichbar einfaches für den Anwender machen? Oder wie würdet ihr so ein Interface gestalten?
-
Das <int> sollte überflüssig sein.
Ich würde keine optionalen Parameter angeben lassen. Mal sind sie nutzlos, dann zu wenig. Außerdem kann deine Minimierungsfunktion den optionalen Parameter eh nicht benutzen. Also nur std::function<double(std::vector<double> const &)>. Sollte die Signatur mal nicht passen, dann kann man per Lambda oder std::bind die Signatur passen machen und damit mehr Parameter übergeben.
-
Hm stimmt, du hast recht.
Ich muss mir echt mal angewöhnen mehr mit lambdas zu machen, vielen Danke für den Hinweis
