pass C++ random number distribution to a function - c++

I have looked for similar questions but haven't found them. I want to generate normally distributed random numbers. I used to code C and some C++98 but am now trying to go back and learn C++11.
I have a function to return a seeded RNG
auto seeded_rng () {
.... //do seeding.
std::default_random_engine Eng(/*seeds*/);
return Eng;
}
In my main function I bind the RNG to say a gaussian distribution
auto binded = std::bind(std::normal_distribution<double>{0,1.0},seeded_rng);
This function works fine. I can call "binded()" directly in main and it generates the numbers
I want to have a simulation object that needs random numbers to be created. My question related to how to pass in the "RNG_PART" below.
class sim
{
public:
sim( RNG_PART & rng, int_number_of sims ){ /* Do whatever */}
}
So if in main, I then want to create a simulation object
sim A(binded, 100);
it complains.
I tried declaring
sim::sim(std::default_random_engine &rng, int number_of_sims){}
but it is complaining. What type should I use to pass in the "binded" distribution to the constructor? Or am I going about this completely incorrectly. Should I just declare the RNG engine globally? I'd prefer not to do that.
Apologies if this is very basic!

The type of the argument to sim is not matching the type of binded. When you create binded, you avoid the issue by using auto instead of declaring the type, but you're going to need it later. How about the following in class sim instead of trying to figure out the type ahead of time. This also allows you to change the RNG or the random distribution without changing the sim class:
template<typename T>
class sim
{
public:
sim(T& rng, int_number_of sims ){ /* Do whatever */}
Note that the template definition must be visible to the place you use it, so you can't put it into a cpp file unless the only code that uses it is in that file. Typically, the template definition is in the same h file as where it was declared.
Then, you'd create sim as:
sim<decltype(binded)> A(binded,100);
the decltype(binded) is a way to tell the sim function template the type of binded.
Since binded can return different types depending upon the chosen random number distribution, obtaining the return type in the sim class template could be done with
using rnd_return_type = typename std::result_of<T()>::type; //in C++11, C++14
or
using rnd_return_type = std::invoke_result_t<T>; //C++17 and later
std::result_of is deprecated in C++17 and will be removed in C++20

Related

Two versions of the program depending on the input parameter without code duplication

I am solving the following problem. I am working on an optimization program in C ++ which, depending on the initial settings of the user, uses various regulations (standards) to calculate the target function. Suppose we have a method A based on some norm and a method B based on another norm to calculate the target function. The user is setting the right standard before starting the program. The rest of the code is the same. During optimization, the target function is iteratively called over and over again. Of course, there is a simple solution: each time the target function is called, the IF condition is used to decide which standard to use. But because the program has to make decisions in every iteration, it seems to be ineffective. The second option is to create 2 independent codes and run only the one with the required standard. This, in turn, is ugly in terms of duplicate code.
I imagined that I would create 2 different classes and use the selected class using the IF condition when constructing the object. This would make the program decide only once when creating the object, but during the iteration itself the object would be clearly defined. Unfortunately, this does not work because objects cannot be created in IF conditions.
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") Sensor_Uniaxial_025 sensor(data);
else if (data.sensors_tipe == "T_rosette_05") Sensor_T_rosette_05 sensor(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensor.rotate(element_index, orientation_angle);
Another way I would like is to set the correct method using a parameter in the constructor. Unfortunately, that probably isn't possible either.
I am a beginner and I did not find the answer anywhere. So maybe someone can help. Thanks
This is a good job for templates, which are "recipes" to generate code.
The end result will be duplicated machine code, but without the duplication in the source.
template<typename MethodT>
float optimize(const MethodT& method) {
float v = method();
// etc...
}
float methodA();
float methodB();
int main() {
auto a = optimize(methodA);
auto b = optimize(methodB);
}
First, the solution with if may be not that bad. It is branch on each function call, but the branch should be predicted well.
Second, if the functions that implement method A and method B are large enough to miss inlining, use function pointer.
Otherwise, use static polymorphism with templates, method A and method B may be passed via template parameter as functors.
In case, the user can change standard after programm compilation (for example, before each run) you can create interface and 2 child from it.
So, at startup you should create the instance (one of 2) you need through new. And then you can use it.
You can't use that algorithm with stack instances.
One way is to use inheritance.
class Sensor
{
public:
virtual void rotate(int, double) = 0;
};
class Sensor_Uniaxial_025 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
class Sensor_T_rosette_05 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
Sensor* sensorToUse;
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") sensorToUse = new Sensor_Uniaxial_025(data);
else if (data.sensors_tipe == "T_rosette_05") sensorToUse = new
Sensor_T_rosette_05(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensorToUse->rotate(element_index, orientation_angle);
The example above, with new, comes with serious memory management issues. But if you pre-allocate the sensor for each type, in a single instance, and use a look-up instead it works well.
The alternative is with template. See other answers for these approaches.

Pointer to function from another pointer

I'm new to c++ and I'm trying to make a generic switch (i.e. the device, not the C++ statement) that could be used to blink lights, turn beeps on and off, etc, in my Arduino project.
I could create a switchable interface and implement that in the classes that I want to "switch". But since I'm doing it as study purposes and I saw the pointer-to-functions ability in C++ (that is new to me since I come from C# and Java), I tough it would be a good opportunity to give it a try...
The problem is that I can pass the function in my code only if it's a local function but it won't work if I try to pass a function from another object like a led for example.
Some code to illustrate the problem. This is the switch.cpp, it recieves the On and Off functions in it's constructor and it has a update method that is called inside the loop method in the Arduino ino main class:
auto_switch.cpp
using switch_function = void(*)();
auto_switch::auto_switch(const switch_function on_function, const switch_function off_function, const int max_speed_count)
{
//sets all variables...
}
void auto_switch::update(const unsigned long millis)
{
//turn switch on and off...
}
And this is my ino file
ino file
#include <Arduino.h>
#include "led.h"
#include "auto_switch.h"
led* main_led;
auto_switch* led_switch;
int slow_speed;
//ugly code
void turn_led_on()
{
main_led->turn_on();
}
//ugly code
void turn_led_off()
{
main_led->turn_off();
}
void setup() {
main_led = new led(2, 3, 4, true, color::white);
//ugly code
led_switch = new auto_switch(turn_led_on, turn_led_off, 3);
slow_speed = led_switch->add_speed(100, 100, 3, 1000);
led_switch->set_active_speed(slow_speed);
led_switch->turn_on();
}
void loop() {
led_switch->update(millis());
}
It works but I had to make a local function (turn_led_on and turn_led_off) to be able to assign the inner functions as a parameter to the auto_switch constructor, the parts that I've wrote //ugly code
I wanted to do something like this, without the glue code in between:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
Is it possible? I've read something about static pointer to function and some std functions that help with that, if I get it right the glue code is necessary in this case so that the compiler can know where the functions are coming from I guess (from which object), but since the functions I need to call cannot be static I've discarded this option, and the std functions I believe it can't be used with the Arduino or could but shouldn't for performance limitations...
Anyway, does it make sense, can it be done using pointer to functions or should I create a interface or something different?
Before deciding how to do it, the qquestion is what do you want to do and why. Because, maybe there are better alternatives using simple C++ idioms.
Option 1: specialization with polymorphism
Do you want to specialize some functions of your switch, so instead of calling the function of the auto_switch you'd call dome more specialized ones ?
In this case you wouldn't do:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
but instead you would rely on polymorphism with virtual functions in the base class:
class auto_switch {
...
virtual void turn_on();
virtual void turn_off();
...
};
and write a specialized class for the leds:
class led_witch : public auto_switch {
...
void turn_on() override;
void turn_off() override;
...
};
In fact, the compiler will generate some function pointers behind the scene, but you don't have to care:
auto_switch s1=new auto_switch(...);
auto_switch s2=new led_switch(...); // no problem !!
s1->turn_on(); // calls auto_switch::turn_on()
s2->turn_on(); // calls led_switch::turn_on() since the real type of s2 is led_switch
But event if each object's behavior is dynamic on the the base of the real class of the object, the objects of the same class share a behavior that was predefined at compile time. If this is not ok, go to the next option.
Option 2: the member function pointer
The functions of another objects can only be invoked with that object at hand. So having a function pointer to a led function is not sufficient: you also need to know on which led it shall be applied.
This is why member function pointers are different and somewhat constraint: you can only invoke functions of class of your member function pointer. If polymorphism is sufficient (i.e. if derived class has a different implementation of a function already foreseen in the base classe) then you are lucky. If you want to use a function that only exists in the derived class and not in the base class, it won't compile.
Here a simplified version of auto_swith: I provide a function, but allso a pointer to the object on which the function has to be invoked:
class auto_switch{
void (led::*action)();
led *ld;
public:
auto_switch(void(led::*a)(), led*l) : action(a), ld(l) {}
void go () { (ld->*action)(); }
};
// usage:
auto_switch s(&led::turn_off, &l1);
s.go();
Online demo
Option 3 : the functional way (may that's what you're looking for ?)
Another variant would be to use the standard functional library to bind a member function and the object on which it shall be executed (as well as any need parameters):
class auto_switch{
std::function<void()> action;
public:
auto_switch(function<void()>a) : action(a) {}
void go () { action(); }
};
Here you can bind anything: any function of any class:
auto_switch s(bind(&led::turn_off, l1));
s.go();
auto_switch s2(bind(&blinking_led::blink, l2));
s2.go();
Online demo
Option 4 : command pattern
Now if you want to perform something on an object when you turn on and off the switch, but you need total flexibility, you can just implement the command pattern : this lets you execute anything on any object. And you don't even need a function pointer.

Is it possible to declare a variable of unknown type as a class member variable?

So I've been interested by the mersenne_twister engine and what it can do, so I decided to put the few lines of code required to initialize it inside my own class so that i simply have to create an instance of that class and can get any random numbers in any range i want without having to repeat those lines every time I need it.
I have suceeded so far but because I want my code to be as portble and efficient as possible I want to use the 64-bit engine depending on the architecture present.
I would like to avoid the way of using preprocessor macros defined by the compiler as that doesn't seem like the cleanest approach to me and would also require me to use the macros every time i mention the engine in my code.
My macro for the architecture l looks like this:
#define CPU_ARCH sizeof(nullptr)*8
And I declare the engine in the private space of the class so that i can init it in the constructor like this:
engine = mt19937(seed);
and use it in my random function like this:
double Random::giveRnd() {
return distribution(engine);
}
This looks fine right now but I have yet to find a way to implement both architectures with the same name "engine" in a way that the engine to be used is chosen at startup.
I have attempted the following:
Using a template to create a variable named engine that later gets
assigned either mt19337 or mt19337_64 which results in the compiler
complaining that
error: data member 'engine' cannot be a member template
with the following implementation:
class Random {
public:
[...]
private:
template<typename T>
T engine;
[...]
};
Using boost::variant which requires me to tell
my giveRnd() function which type to use when I use the engine which
is not possible since the type is not known at compile time
Not declaring the engine in the header file at all although this
results in the giveRnd() function not being able to use the engine
because it is not in the same scope.
Using preprocessor macros in the header file and then use typeid in
the source code to find out which engine was used, which doesn't seem
to be possible like this:
if(CPU_ARCH==32) { engine = mt19337(seed) }
because the compiler doesn't know that the engine will always be
32-bit in this case and complains that I cannot use the '=' operator
on two different types.
Does anyone have an idea on how to make this possible in a atleast somewhat clean way? Or do I need to fall back on the preprocessor macros?
You can implement behaviour that depends on CPU_BITS by making a class template that takes CPU_BITS as a template argument, and is specialized for expected values. For example:
#include <random>
template<size_t N> struct CpuOpts;
template<> struct CpuOpts<32> { using EngineType = std::mt19937; };
template<> struct CpuOpts<64> { using EngineType = std::mt19937_64; };
enum { CPU_BITS = sizeof(nullptr)*8 };
using CurrentCpuOpts = CpuOpts<CPU_BITS>;
struct Random
{
CurrentCpuOpts::EngineType engine;
};
int main()
{
Random r;
r.engine.seed(123456);
}

macro that defines entire derived class from one function and certain type specifiers?

I have a class called system. A system takes some object managers and changes all objects in them in some way.
For example there might be a system that draws all images in a imageManager.
Every derived class works somewhat like this (pseudo code):
class someChildClass : public System{
private:
someObjectManager &mang1; //these are used by the update method.
someOtherObjectManager &mang2;//the update method changes these somehow
public:
someChildClass(someObjectManager &mang1, someObjectManager &mang2)
:mang1(mang1),mang2(mang2){
}
virtual void update(){
//this is pure virtual in the System base class.
//Do something with the managers here
}
}
I feel like writing everything but the update method is a waste of time and a source of errors. I wanted to write a macro that basically makes a class like this like so:
QUICKSYSTEM(thisIsTheSystemName, someObjectManager, mang1, someOtherObjectManager, mang2, ... (infinite possible Managers. So a variadic macro?)){
//this is the update function
}
}//this is the end braked for the class declaration. Its ugly but I dont know how I could do the function differently?
well I am having some problems making the macro. Everything works fine until I need to split the variadic arguments into the names and the types. I dont know if this is even possible now, since I cant go back and forth in the arguments easily or apply a easy step to them to make sure that every 2nd is the name of the variable. I would be ok with omitting the possibility for names and just had the types with some sort of automatic naming (manager1,manager2,manager3 or something like that).
If this isnt possible using a macro, what would be a better way to avoid mistakes and cut some time in the constructor and class declaration part?
Yeah, macros are really, really not the way to do this. C++ has templates, which follow C++ syntax and support C++ expressions. Macros instead use their own preprocessor language, which is almost entirely unaware of C++.
You'll want to read up a bit on std::tuple as well. It's going to be rather tricky to handle all those managers with those names. Tuples are the Standard solution for that. managers.get<0> and managers.get<someObjectManager> both work.
Variadic templates are the tool you need here:
#include <iostream>
#include <tuple>
#include <functional>
struct System { void virtual update() = 0; };
template<class... Managers>
struct ManagedSystem : System
{
std::function<void(Managers&...)> _update;
std::tuple<Managers&...> _managers;
template<class F>
ManagedSystem(F update, Managers&... managers) : _update(update), _managers(managers...) {}
void update() override { _update(std::get<Managers&>(_managers)...); }
};
int main()
{
int n = 0;
double d = 3.14;
auto reset = [](int& a, double& d) { a = 0; d = 0.0; };
ManagedSystem<int, double> ms{reset, n, d};
ms.update();
std::cout << "n = " << n << ", d = " << d << "\n";
// n = 0, d = 0
}
The idea is to define a templated-class (ManagedSystem) taking as template-parameters multiple manager types. This class inherits from Systemand provides a constructor taking:
an update functor,
and references to manager whose type is defined by the template parameters of the class.
The said managers are registered internally in an std::tuple and (with a bit of parameter pack magic fed to the update functor.
From there, you can define an inherited class from System by providing an update function and a type list. This avoids the use of ugly and type-unsafe macros in favor of the not-less ugly but type-string templates ;)

std::generate - How do I use a random number generator?

In my programming I need to create a user-defined number of ublas vectors. I would like to do this with std::generate. However I get compiler errors that make it impossible for me.
The code I'm using:
for (size_t a_= 0; a_ < p_; a_++)
{
ublas::vector<double> next_vhat(size_of_vec);
std::generate(next_vhat.begin(), next_vhat.end(), mygen.give_rnd);
v_hat_.push_back(next_vhat);
}
I had to create a class specifically for the function call, since std::generate won't allow me to use a function with an argument as the third argument ("gen", see here. I need the numbers to be normal distributed, so the function call to the distribution function must contain, as an argument, the random number generator. Since it didn't allow me to call it with the argument, I had to write a class to do this for me.
The class I have written:
class RandGen
{
public:
RandGen()
: generator()
, norm_dist(0.0,1.0)
, random_seed(static_cast<unsigned>(std::time(NULL)))
{}
double give_rnd() { return (double) norm_dist(generator); }
private:
base_gen_t generator;
boost::random::normal_distribution<double> norm_dist; //Standard normal distribution
unsigned random_seed;
};
The error I'm getting
When trying to compile the whole thing, I get the following error:
error: cannot convert ‘RandGen::give_rnd’ from type ‘double (RandGen::)()’ to type ‘double (RandGen::*)()’
I have no idea what the compiler wants me to do here, or why it has so much trouble with this at all. Any advice is very appreciated.
You need to pass a callable object. That is, either a function pointer (not a member function pointer, which is what mygen.give_rnd is) or an object of a class that overloads operator(). You can just change your function give_rnd to this:
double operator()() { return (double) norm_dist(generator); }
And then, just pass your object directly to std::generate
std::generate(..., ..., mygen);
If, for some reason, you wanted to keep your RandGen class as it is, you would need to wrap it in another functor or lambda:
std::generate(..., ..., [&mygen]() { return mygen.give_rnd(); });