For example, there is hard logic inside function void Func(long param1, long param2, long param3, long param4, long param5).
It has a lot of statements inside depends on parameters, different checks, calculations depends on combinations and etc.
And that function is called many million times and takes serious amount of execution time. And I'd like to reduce that time.
All parameters are taken from config.ini file, so, they are unknown at compile time.
But I know, that param1 may be in diapason [1..3], param2 in diapason [0..1] and etc.
So, finally, there is maybe 200 combinations of those parameters.
And I'd like my compiler compile separated 200 combination, and at the beginning of run-time, when config.ini loaded, just choose one of them, and avoid run-time calculation of parameter's dependencies.
Is that possible to achieve in C++98? Or in C++11/14?
It is certainly possible to do this using templates, since templates
can have integers instead of type parameters. For instance, the
following function
template <int iParam1, int iParam2>
int sum()
{
return iParam1 + iParam2;
}
is a function in which iParam1 and iParam2 are fixed values for
a specific template instantiation. For example, function sum<1, 2> is
a function that always returns 3.
In you case, define Func with this prototype:
template <long Param1, long Param2, long Param3, long Param4, long Param5>
void Func()
Then, create a std::map that maps a combination of parameters to a function
in which these parameters are fixed. Something like this:
using ParamCombination = std::tuple<long, long, long, long, long>;
using ParamsToFunction = std::pair < ParamCombination, std::function<void()> >;
std::map< ParamCombination, std::function<void()> > map =
{
ParamsToFunction(std::make_tuple<long, long, long, long, long>(1, 2, 2, 2, 2), Func<1, 2, 2, 2, 2>),
...
// This map will contain pairs of all possible parameter combinations
// and their corresponding functions. This is a long list but it can be
// easily generated using a script.
};
These function will have all the benefits of compile time optimizations.
Finally, during runtime, all you need to do is create a tuple that represents
a parameter combination and call the function that this tuple maps to:
auto comb = ParamCombination(1, 2, 2, 2, 2);
map[comb](); // function call
I don't know if you have considered this but you could load the config at the beginning, calculate your 200 possible solutions and put them into a lookup table. This depends on the storage you can spare. Since your number of combination seems to be small, this should be no problem. You simple merge the parameter to an integer. E.g. ( x =[0...3]; y = [0...1]) => use first 2 bit for x 3rd bit for y and so on. Calculate all possibilities using loops. And store the result inside of an array. If you don't own parameter with the power of two. You can simply multiply the possibilities. E.g x =[0...3] y =[0...5] z =[0...2] => idx = x + y*(possibilites of x = 4) + z * (pos. x = 4) * (pos. y = 6)
Related
I have two tuples, each containing containers of different types.
std::tuple<containerA<typesA>...> tupleA;
std::tuple<containerB<typesB>...> tupleB;
So, as an example tupleA might be defined like this:
std::tuple<list<int>, list<float>> tupleA;
The two containers, containerA and containerB are different types. typesA and typesB do not intersect. I want to sort the containers inside the tuples by their sizes, and be able to access them by their type. So, as an example
std::tuple<list<int>, list<float>> tupleA {{2}, {3.3f, 4.2f}};
std::tuple<deque<double>, deque<uint8_t>> tupleB {{2.0, 1.2, 4.4}, {}};
auto sortedArray = sort(tupleA, tupleB);
sortedArray == {deque<uint8_t>, list<int>, list<float>, deque<double>};
sortedArray.get<list<float>>() == {3.3f, 4.2f};
std::get<list<int>>(tupleA).push_back(4);
std::get<list<int>>(tupleA).push_back(5);
std::get<list<int>>(tupleA).push_back(6);
sortedArray = sort(tupleA, tupleB);
sortedArray == {deque<uint8_t>, list<float>, deque<double>, list<int>};
The most important part is that I have to store sortedArray and that the sizes of the elements in the tuple may change. I have not been able to create such a sort function. The actual syntax of accessing the sortedArray is not important.
I tried to use naive indexes to the container data inside the sortedArray, such as using std::pair<A, 1> to refer to the second element in tuple A, however I can't access the information of the tuple through it because it is not a constexpr
This is possible but not easy.
First, you need to generate a compile-time list of every permutation of N elements (there are N factorial of them).
Write both a runtime and compile time permutation object (separate).
Make a runtime map from permutation to index. (map step)
Convert your tuple to a vector of (index, size). Sort this by size. Extract the permutation. Map this to the index of the set of permutations. (Sort step, uses map step)
Write a "magic switch" that takes a function object f and a permutation index, and invokes the f with the compile time permutation. (magic step)
Write code that takes a compile time permutation and reorders a tuple based on it. (reorder step)
Write code that takes a function object f and a tuple. Do (sort step). Do (magic step), feeding it a second function object g that takes the passed in permutation and the tuple and (reorder step), then calls f with it.
Call the function that does this bob.
std::tuple<list<int>, list<float>> tupleA {{2}, {3.3f, 4.2f}};
std::tuple<deque<double>, deque<uint8_t>> tupleB {{2.0, 1.2, 4.4}, {}};
bob(concat_tuple_tie(tupleA, tupleB), [&](auto&& sorted_array){
assert( std::is_same<
std::tuple<deque<uint8_t>&, list<int>&, list<float>&, deque<double>&>,
std::decay_t<decltype(sorted_array)>
>::value, "wrong order" );
sortedArray.get<list<float>>() == {3.3f, 4.2f};
});
std::get<list<int>>(tupleA).push_back(4);
std::get<list<int>>(tupleA).push_back(5);
std::get<list<int>>(tupleA).push_back(6);
bob(concat_tuple_tie(tupleA, tupleB), [&](auto&& sorted_array){
assert( std::is_same<
std::tuple<deque<uint8_t>&, list<float>&, deque<double>&, list<int>&>,
std::decay_t<decltype(sorted_array)>
>::value, "wrong order" );
});
Personally, I doubt you need to do this.
I could do this, but it might take me hours, so I'm not going to do it for a SO answer. You can look at my magic switch code for the most magic of the above. The other hard part is that permutation step.
Note that the code uses continuation passing style. Also note that every permutation of the lambda is instantiated, including the wrong ones, so your code must be valid for every permutation. This can result in an insane amount of code bloat.
An alternative solution could involve creating type-erasure wrappers around your containers and simply sorting those, but that is not what you asked for.
The problem you describe sounds very much like you want dynamic polymorphism, not static polymorphism — and your difficulty in solving it is because you're stuck on trying to express with tools for doing static polymorphism.
i.e. you need a type (hierarchy) for collections (or pointers to collections) that let you select the type of collection and the type of data at run-time, but still provides a unified interface to functions you need like size (e.g. by inheritance and virtual functions).
e.g. a beginning of a sketch might look like
struct SequencePointer
{
virtual size_t size() const = 0;
virtual boost::any operator[](size_t n) const = 0;
};
template <typename Sequence>
struct SLSequencePointer
{
const Sequence *ptr;
size_t size() const { return ptr->size(); }
boost::any operator[](size_t n) const { return (*ptr)[n]; }
};
In c++
I'm running an optimization algorithm to find a set of parameters for a given combination of temperature and humidity and I want a structure for efficient look-up and iteration time for further computation.
Example: I calculate all 5-parameters for a device across the range of Temperature[0k-300k] x Humidity[x-xxx]. I want to store these in memory and when I call a function at a given temperature and humidity, it should be able to quickly load the relevant 5 parameters using the tuple as a key.
I'm thinking of a multimap such as std::multimap<double, std::vector<double>>, but I'm iffy about the baggage that comes with vector.
Edit:
Ok an example will be like this (for one variable):
for x in range(Temperature){
parameterList[x] = (deviceClass.geneticAlgo(loss = 1, x));
deviceClass.setParameters(parameterList);
Then for that class I want:
double later_calc(temperature,humidity, x...){
return deviceSimulation(parameterList[(temperature, humidity, x...)]);
}
I want the later_calc function to quickly access the structure in the class accessed by the input of temperature, humidity, etc.
It seems to me you want to use a std::map with either a std::tuple as key or a custom class which holds the parameters, and a mapped type which stores the experiment result (here it is double, but you can also easily use a custom Result class):
struct ParameterType
{
int temperature;
int humidity;
int x;
bool operator<(ParameterType const& rhs) const
{
return std::tie(temperature, humidity, x) < std::tie(rhs.temperature, rhs.humidity, rhs.x);
}
};
using ResultType = double;
int main()
{
std::map<ParameterType, ResultType> params;
params[{263, 10, 1}] = 1.0;
std::cout<< params[{263, 10, 1}] <<std::endl;
}
DEMO
You should use a multimap if you want to repeat experiments, i.e. if you have multiple results for the same parameter set. (But you could also use a map with a std::vector<ResultType>).
Note that I've used integer values as a key, whereas in practice one is tempted to use floating point numbers. Those, however, might lead to problems in key comparison due to rounding errors. So better fix the decimal digits and decode real inputs as 263.53 as 26353.
I have the following expression:
A = cos(5x),
where x is a letter indicating a generic parameter.
In my program I have to work on A, and after some calculations I must have a result that must still be a function of x , explicitly.
In order to do that, what kind of variable should A (and I guess all the other variables that I use for my calculations) be?
Many thanks to whom will answer
I'm guessing you need precision. In which case, double is probably what you want.
You can also use float if you need to operate on a lot of floating-point numbers (think in the order of thousands or more) and analysis of the algorithm has shown that the reduced range and accuracy don't pose a problem.
If you need more range or accuracy than double, long double can also be used.
To define function A(x) = cos(5 * x)
You may do:
Regular function:
double A(double x) { return std::cos(5 * x); }
Lambda:
auto A = [](double x) { return std::cos(5 * x); };
And then just call it as any callable object.
A(4.); // cos(20.)
It sounds like you're trying to do a symbolic calculation, ie
A = magic(cos(5 x))
B = acos(A)
print B
> 5 x
If so, there isn't a simple datatype that will do this for you, unless you're programming in Mathematica.
The most general answer is "A will be an Expression in some AST representation for which you have a general algebraic solver."
However, if you really want to end up with a C++ function you can call (instead of a symbolic representation you can print as well as evaluating), you can just use function composition. In that case, A would be a
std::function<double (double )>
or something similar.
I was multiplying each container against another number so I did the following:
local_it begin = magnitudesBegin;
std::advance(begin , 2);
local_it end = magnitudesBegin;
std::advance(end, 14);
std::transform(begin, end, firstHalf.begin(),
std::bind1st(std::multiplies<double>(),100));
It worked wonders, problem is when doing the same to divide between another container. Here is a working example of my problem:
const std::size_t stabilitySize = 13;
boost::array<double,stabilitySize> secondHalf;
double fundamental = 707;
boost::array<double, stabilitySize> indexes = {{3,4,5,6,7,8,9,10,11,12,13,14,15}};
std::transform(indexes.begin(), indexes.end(), secondHalf.begin(),
std::bind1st(std::divides<double>(),fundamental));
It does divide the container. But instead of dividing each element in the array against 707 it divides 707 between each element in the array.
std::bind1st(std::divides<double>(),fundamental)
The code above takes a functor std::divides<double> that takes two arguments and fixes the value of the first argument to be fundamental. That is it fixes the numerator of the operation and you get the expected result. If you want to bind fundamental to be the denominator, use std::bind2nd.
you can try the following , divide has a completely different operation than multiply, it just divides a constant number by all your elements
std::bind1st(std::multiplies<double>(),1.0/707.0));
If the number 707.0 is something like a fundamental constant, and a division can be seen as a "conversion", let's call it "x to y" (I don't know what your numbers are representing, so replace this by meaningful words). It would be nice to wrap this "x to y" conversion in a free-standing function for re-usability. Then, use this function on std::transform.
double x_to_y(double x) {
return x / 707.0;
}
...
std::transform(..., x_to_y);
If you had C++11 available, or want to use another lambda-library, another option is to write this in-line where being used. You might find this syntax more readable like parameter binding using bind2nd:
std::transform(..., _1 / 707.0); // when using boost::lambda
I'm trying to get my head around tuples (thanks #litb), and the common suggestion for their use is for functions returning > 1 value.
This is something that I'd normally use a struct for , and I can't understand the advantages to tuples in this case - it seems an error-prone approach for the terminally lazy.
Borrowing an example, I'd use this
struct divide_result {
int quotient;
int remainder;
};
Using a tuple, you'd have
typedef boost::tuple<int, int> divide_result;
But without reading the code of the function you're calling (or the comments, if you're dumb enough to trust them) you have no idea which int is quotient and vice-versa. It seems rather like...
struct divide_result {
int results[2]; // 0 is quotient, 1 is remainder, I think
};
...which wouldn't fill me with confidence.
So, what are the advantages of tuples over structs that compensate for the ambiguity?
tuples
I think i agree with you that the issue with what position corresponds to what variable can introduce confusion. But i think there are two sides. One is the call-side and the other is the callee-side:
int remainder;
int quotient;
tie(quotient, remainder) = div(10, 3);
I think it's crystal clear what we got, but it can become confusing if you have to return more values at once. Once the caller's programmer has looked up the documentation of div, he will know what position is what, and can write effective code. As a rule of thumb, i would say not to return more than 4 values at once. For anything beyond, prefer a struct.
output parameters
Output parameters can be used too, of course:
int remainder;
int quotient;
div(10, 3, "ient, &remainder);
Now i think that illustrates how tuples are better than output parameters. We have mixed the input of div with its output, while not gaining any advantage. Worse, we leave the reader of that code in doubt on what could be the actual return value of div be. There are wonderful examples when output parameters are useful. In my opinion, you should use them only when you've got no other way, because the return value is already taken and can't be changed to either a tuple or struct. operator>> is a good example on where you use output parameters, because the return value is already reserved for the stream, so you can chain operator>> calls. If you've not to do with operators, and the context is not crystal clear, i recommend you to use pointers, to signal at the call side that the object is actually used as an output parameter, in addition to comments where appropriate.
returning a struct
The third option is to use a struct:
div_result d = div(10, 3);
I think that definitely wins the award for clearness. But note you have still to access the result within that struct, and the result is not "laid bare" on the table, as it was the case for the output parameters and the tuple used with tie.
I think a major point these days is to make everything as generic as possible. So, say you have got a function that can print out tuples. You can just do
cout << div(10, 3);
And have your result displayed. I think that tuples, on the other side, clearly win for their versatile nature. Doing that with div_result, you need to overload operator<<, or need to output each member separately.
Another option is to use a Boost Fusion map (code untested):
struct quotient;
struct remainder;
using boost::fusion::map;
using boost::fusion::pair;
typedef map<
pair< quotient, int >,
pair< remainder, int >
> div_result;
You can access the results relatively intuitively:
using boost::fusion::at_key;
res = div(x, y);
int q = at_key<quotient>(res);
int r = at_key<remainder>(res);
There are other advantages too, such as the ability to iterate over the fields of the map, etc etc. See the doco for more information.
With tuples, you can use tie, which is sometimes quite useful: std::tr1::tie (quotient, remainder) = do_division ();. This is not so easy with structs. Second, when using template code, it's sometimes easier to rely on pairs than to add yet another typedef for the struct type.
And if the types are different, then a pair/tuple is really no worse than a struct. Think for example pair<int, bool> readFromFile(), where the int is the number of bytes read and bool is whether the eof has been hit. Adding a struct in this case seems like overkill for me, especially as there is no ambiguity here.
Tuples are very useful in languages such as ML or Haskell.
In C++, their syntax makes them less elegant, but can be useful in the following situations:
you have a function that must return more than one argument, but the result is "local" to the caller and the callee; you don't want to define a structure just for this
you can use the tie function to do a very limited form of pattern matching "a la ML", which is more elegant than using a structure for the same purpose.
they come with predefined < operators, which can be a time saver.
I tend to use tuples in conjunction with typedefs to at least partially alleviate the 'nameless tuple' problem. For instance if I had a grid structure then:
//row is element 0 column is element 1
typedef boost::tuple<int,int> grid_index;
Then I use the named type as :
grid_index find(const grid& g, int value);
This is a somewhat contrived example but I think most of the time it hits a happy medium between readability, explicitness, and ease of use.
Or in your example:
//quotient is element 0 remainder is element 1
typedef boost:tuple<int,int> div_result;
div_result div(int dividend,int divisor);
One feature of tuples that you don't have with structs is in their initialization. Consider something like the following:
struct A
{
int a;
int b;
};
Unless you write a make_tuple equivalent or constructor then to use this structure as an input parameter you first have to create a temporary object:
void foo (A const & a)
{
// ...
}
void bar ()
{
A dummy = { 1, 2 };
foo (dummy);
}
Not too bad, however, take the case where maintenance adds a new member to our struct for whatever reason:
struct A
{
int a;
int b;
int c;
};
The rules of aggregate initialization actually mean that our code will continue to compile without change. We therefore have to search for all usages of this struct and updating them, without any help from the compiler.
Contrast this with a tuple:
typedef boost::tuple<int, int, int> Tuple;
enum {
A
, B
, C
};
void foo (Tuple const & p) {
}
void bar ()
{
foo (boost::make_tuple (1, 2)); // Compile error
}
The compiler cannot initailize "Tuple" with the result of make_tuple, and so generates the error that allows you to specify the correct values for the third parameter.
Finally, the other advantage of tuples is that they allow you to write code which iterates over each value. This is simply not possible using a struct.
void incrementValues (boost::tuples::null_type) {}
template <typename Tuple_>
void incrementValues (Tuple_ & tuple) {
// ...
++tuple.get_head ();
incrementValues (tuple.get_tail ());
}
Prevents your code being littered with many struct definitions. It's easier for the person writing the code, and for other using it when you just document what each element in the tuple is, rather than writing your own struct/making people look up the struct definition.
Tuples will be easier to write - no need to create a new struct for every function that returns something. Documentation about what goes where will go to the function documentation, which will be needed anyway. To use the function one will need to read the function documentation in any case and the tuple will be explained there.
I agree with you 100% Roddy.
To return multiple values from a method, you have several options other than tuples, which one is best depends on your case:
Creating a new struct. This is good when the multiple values you're returning are related, and it's appropriate to create a new abstraction. For example, I think "divide_result" is a good general abstraction, and passing this entity around makes your code much clearer than just passing a nameless tuple around. You could then create methods that operate on the this new type, convert it to other numeric types, etc.
Using "Out" parameters. Pass several parameters by reference, and return multiple values by assigning to the each out parameter. This is appropriate when your method returns several unrelated pieces of information. Creating a new struct in this case would be overkill, and with Out parameters you emphasize this point, plus each item gets the name it deserves.
Tuples are Evil.