JMS1
JMS1

Reputation: 27

C++ Writing inline function to pass as argument

I'm writing a set of learning algorithms for a personal library. Learning Algorithms need two things, an input space to explore, and a way to compare one solution against another. Defining an input space is the most basic data transfer, however I'm having difficulty with passing it the rating function.

Currently my problematic code looks like this:

RankineGenerator generator(tempHotWater,tempColdWater);

int variablesSize = 2;
Range minMaxVaporizer = { tempColdWater,tempHotWater };
Range minMaxCondenser = { tempColdWater,tempHotWater };
Range minMax[] = {minMaxVaporizer, minMaxCondenser};

auto phi = [&generator] ( double * heatExchangerTemps ) -> double
{
generator.updateHeatExchangeTemps(heatExchangerTemps[0], heatExchangerTemps[1]);
generator.runSim();
return generator.getSpecificWork()/(generator.getColdWaterRelativeMass()+generator.getHotWaterRelativeMass());
};

Twiddle twiddle(variablesSize,phi,minMax,0.001);

And my constructor header looks like:

Twiddle(int size, double(*phi)(double*), Range minMax[], double minRatioDeltaPhi);

Where the "phi" lambda function is what I'm trying to pass to to the algorithm "twiddle"

It doesn't necessarily need to be a lambda function, any inline function will do.

Points of concern:

Learning algorithms tend to be computation intensive so a fast solution is preferable to an easy solution.

the function to be passed needs some way of accessing some of the information from the scope it was declared in.

The learning algorithm needs to be universal. Passing it problem specific data isn't an option, I need to be able to plug and play with any problem. Ideally the constructor should take a form like:

constructor( nVars, ratingFunction(vars[nVars]), ranges[nVars], minImprovementSpeed)

Update: It seems I've caused some confusion. My apologies.

Firstly I'm using the term inline meaning a function written in the middle of a program rather than as an independent entity. Not necessarily having anything to do with the keyword of the same name.

Secondly what I'm trying to do is pass a function with access to some local data. For example this:

double(*phi)(double*) = [](double* heatExchangerTemps) { /*do something*/ };

Twiddle twiddle(variablesSize,phi,minMax,.001);

with construction header:

Twiddle(int size, double (*phi)(double*) , Range minMax[], double minRatioDeltaPhi);

will compile but gives no access to the object "generator". However, when I try to capture the "generator" object in the lambda function:

double(*phi)(double*) = [&generator](double* heatExchangerTemps) { /*do something*/ };

or

auto phi = [&generator] ( double * heatExchangerTemps ) -> double { /*do something*/ };

I get an error.

I could do this:

double(*phi)(double*) = [](double* myArray)
{
    Generator generator(/*stuff*/);
    // do something
};

But then a new object of class "Generator" is created every time the function is called. Considering this function may be called 1000+ times that's not ideal. Plus now the "Twiddle" algorithm needs info specific to the Generator constructor which defeats the whole purpose of having a universal algorithm.

Ideally I need to be able access a local object (in this case generator) inside the function, and pass the function as a generic argument for a constructor.

Also it doesn't necessarily have to be a lambda function, that's just what first came to mind.

Upvotes: 0

Views: 327

Answers (1)

JMS1
JMS1

Reputation: 27

After poking around for a couple hours I found this:

std::function<double(double*)> phi = [&generator] ( double * heatExchangerTemps ) -> double
{ /*do someting*/ };
Twiddle twiddle(variablesSize,phi,minMax,1000000);

with constructor header:

Twiddle(int size, std::function<double(double*)> phi, Range minMax[], double maxResolution);

Not sure if it's the best answer, but it seems to work well.

basically my lambda function conforms to the type std::function<double(double*)> which allows me to keep the lambda capture capability while allowing my constructor to understand what it's receiving.

Upvotes: 1

Related Questions