Hi there,
I am writing an interpolator for multidimensional data that may be mixed integer and wanted some design advice. The user will know at compile-time what the number of integer and real dimensions is. The user will create a regular grid as the cartesian product of the various vectors of values for each dimension.
mixed_grid<3, 2> my_mixed_grid;
linear_interpolator<3, 2> f( my_mixed_grid); //3 real dimensions, 2 integer dimensions
The problem with the interpolator is that it needs to be used in a variety of ways. Sometimes the user knows the exact number of the integer or real along a particular dimension. Other times they know the exact index in the grid for a dimension (I am using this for my dynamic programming library, so things get a little crazy when the code is generic, and speed is essential since the interpolator is executed in the innermost loop and would be the main bottleneck if done wrong).
Ideal semantics:
- Would love the ability to specify the type of interpolation for each variable. interpolated as the default, exact, and by index. Exact would tell the interpolator implementation to find the exact value and to skip a dimension in the interpolation. Byindex would tell it to do the same but even skip the lookup in the list for that dimension.
- I want it to be relatively easy to call it with the default "interpolated" type.
- Having parameters out of order is not necessary, but if the solution is to use boost::parameter or something like that, then I would say that we might as well allow it.
Assuming that there is some sort of decoration class, I would love the semantics of the interpolator to allow something like this:
linear_interpolator<3, 2> f( my_mixed_grid);
cout << f(1.2, 3.4, 2.2, 1, 5); //normal. always ordered so integers at end.
cout << f(1.2, exact(3.4), 2.2, 1, 5); //normal
cout << f(1.2, exact(3.4), 2.2, 1, 5); //normal
cout << f(1.2, exact(3.4), 2.2, byindex(0), 5);
etc.
It is reasonable to have the type for the non-interpolated defaults. e.g.
cout << f(1.2, exact<real>(3.4), 2.2, byindex<int>(0), 5);
Although having a class that wraps the creation could be fine if the decoration needs template parameters
cout << f(1.2, get_exact(3.4), 2.2, get_by_index(0), 5);
Any idea on how to implement this or if this is the right approach? Should I be using boost parameter somehow to make life easier and not have to implement a huge number of overloaded operator()? I can't figure out what the decoration classes would look like, and I can't have this using a virtual function to extract a value.
And if boost::parameter is the solution: As gravy, it would be great if the user could positionally setup a bunch of boost parameter tags for their specific function (it is reasonable to expect them to put them in a namespace to avoid clashes).
i.e. support
f(_1 = 1.2, _3 = exact(2.2), _2 = 2.2, etc.);
but also to define some kind of macro that can be used by any :
FUNCTION_PARAMETER( _x, _1); //_x synonym for _1 used in the unpacking of the argpack
FUNCTION_PARAMETER( _y, _2); //etc.
so that they can call it like:
f(_x = 1.2, _y = exact(2.2), etc.);
I can't figure out in boost::parameter how I could have _x as a synonym for _1 which the interpolator implementation would use to unpack the argpack.
Thanks
Jesse