I'm trying to write a numeric optimizer in C++ that allows the user to specify what type of input they want to use. The inputs all have the same "API" style, where all classes have methods of the same name. Example (only showing part of the code since the full detail doesn't matter):
OLS::OLS(int num_data_cols, float learning_rate, int num_epochs){
learningRate = learning_rate;
numEpochs = num_epochs;
numDataCols = num_data_cols;
// Generate Random Beta Start point
for (int i=0; i<numDataCols; i++){
beta.push_back( float(rand()%10)/float(rand()%10) );
}
intercept = float(rand()%10)/float(rand()%10);
}
void OLS::updateParameters(float target, vector<float> data)
{
float prediction = makePrediction(data);
float error = getError(target, prediction);
for (int i=0; i<numDataCols; i++){
beta.at(i) = beta.at(i) - learningRate*error*data.at(i);
}
intercept = intercept - learningRate*error;
}
...
There's another class called Hinge that has all the same methods. I want the user to be able to specify via command line which of these classes to use in the solver.
However, I'm unsure how to specify the variable that stores the "class to optimize on" object. At present I have this in as another class that wraps around the optimizers:
class GradientDescent {
private:
...
...
OLS* cost_function;
...
...
public:
GradientDescent(OLS objectHere);
GradientDescent(Hinge objectHere);
...
...
}
You can see two things - one I've overloaded to allow the user to choose which type of object to use. However, the cost_function is pre-specified as an OLS object. The behavior I'd like to have is cost_function is specified as a class object, but I don't want to pre-specify that it's OLS. I want to allow the user to tell me which of these optimizers they want, and then store that object and its substructure under the name cost_function.
How do I forward declare cost_function such that it will accept either a OLS or a Hinge object in the constructor for the class that uses the optimization the user requests? I have a method for using user input to choose which optimizer, I'm not worried about that, I just need to know how to handle the multiple possible types.