I have a script (python symbolic toolbox) which auto-generates C++11 code to fill the entries of a matrix, like:
double J00(double a, double b) {return a+b;}
double J01(double a, double b) {return a-b;}
double J10(double a, double b) {return -a+b;}
double J11(double a, double b) {return -a-b;}
Now I could use an array of function pointers to store all the functions and fill the matrix, i.e.:
typedef double (*FillFunction) (double a, double b);
double J00(double a, double b) {return a+b;}
double J01(double a, double b) {return a-b;}
double J10(double a, double b) {return -a+b;}
double J11(double a, double b) {return -a-b;}
void main()
{
FillFunction J[2][2] = {{J00, J01}, {J10, J11}};
param0 = 0;
param1 = 1;
double Jresult[2][2];
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
Jresult[i][j] = J[i][j](param0, param1);
}
}
}
However, this is a performance critical part of my code and I would thus rather not use function pointers, especially since the size of the matrix and all functions are know at compile time. Is there a neat way to do this with templates or anything similar?
Note: I did not compile this code so I don't know if it would actually work, but I hope you get the idea.
If you are using external code generator anyway, just generate this:
double Jresult[2][2] = {
{J00(param0, param1), J01(param0, param1)},
{J10(param0, param1), J11(param0, param1)},
};
Related
I have a function my_func(), which takes 2 parameters a and b.
I want to define a function inside the solve_for_b_by_bisection() function, called f, such that I can just call f(b), which is my_func(a, b) for some fixed input a. How do I do that? Do I use a function pointer?
The reason I am doing this instead of calling f(a,b) directly is that in the actual thing I am working on, it has 10+ variables which are constants - it is not possible to repeat the variable list every time.
double my_func(const double a, const double b)
{
/* some arbitary function */
}
double solve_for_b_for_contant_a_by_bisection (const double a,
const double upperbound,
const double lowerbound)
{
double (*my_func_pointer)(const double b)
{
&my_func(a, b)
}
lowerboundvalue = *my_func(lowerbound)
upperboundvalue = *my_func(upperbound)
midpointvalue = *my_func(0.5 * (lowerbound+upperbound))
/* The rest of the implementation */
}
You might use lambda:
auto func = [a](double b) { return my_func(a, b); };
Just use lambda:
double solve_for_b_for_contant_a_by_bisection (const double a,
const double upperbound,
const double lowerbound)
{
auto f = [a]( double b ) { return my_func( a, b ); };
auto lowerboundvalue = f(lowerbound)
auto upperboundvalue = f(upperbound)
auto midpointvalue = f(0.5 * (lowerbound+upperbound));
/* The rest of the implementation */
}
You could either use a lambda function, as others have suggested, or std::bind. See how that will look and whether you like it better:
#include <functional>
double my_func(const double a, const double b)
{
/* some arbitary function */
}
double solve_for_b_for_contant_a_by_bisection (const double a,
const double upperbound,
const double lowerbound)
{
const auto f = std::bind(my_func, a, std::placeholders::_1);
const auto lowerboundvalue = f(lowerbound);
const auto upperboundvalue = f(upperbound);
const auto midpointvalue = f(0.5 * (lowerbound+upperbound));
/* The rest of the implementation */
}
Suppose the "standard" C++ inheritance paradigm:
struct GeneralFunc
{
/*..members..*/
virtual double value(double a, double b) { return 0; }
};
struct Func_classA : GeneralFunc
{
/*..members..*/
double value(double a, double b) { return a * b; }
};
struct Func_classB : GeneralFunc
{
/*..members..*/
double value(double a, double b) { return a + b; }
};
void main(){
double a = 1.0, b = 1.0;
std::vector<GeneralFunc*> my_functions;
//fill my_functions from input
for (auto& f : my_functions)
{
double v = f->value(a, b);
}
}
I would like an implementation that is most efficient for the iteration, i.e. minimizes indirect references, maximizes inline optimizations, ect. To constrain the problem, I know beforehand each specific "type" I want to implement (I can define only the "func" types I require, without having to allow other possibilities).
several options appear available:
boost::polycollection
#include <boost/poly_collection/base_collection.hpp>
//...rest the same
boost::base_collection<GeneralFunc> my_functions
//...rest the same
std::variant
#include <variant>
//...rts
using funcs = std::variant<Func_classA, Func_classB /*..possibly more../*>
std::vector<funcs> my_functions
or CRTP (Curiously Recurring Template Pattern)
Let me know the correct nomenclature for this, but here I "upcast" the base class based on the "type" -- a kind of manual dispatch.
template<typename T>
struct GeneralFunc
{
/*..members..*/
int my_type;
double value(double a, double b) {
switch (my_type){
case TYPE_A:
return static_cast<Func_classA*>(this)->value(a,b);
/*..you get the idea..*/
I'm okay sacrificing marginal efficiency for ease of development, but is there a consensus on the "best practice" in this case?
EDITS* fixed some typos; my current development is "in-development" of CRTP the last option.
SOLUTION:
After testing, both boost::polycollection and std::variant are valid approaches. However, this turned out to be far most efficient (from memory, may be slightly off).
enum ftype { A = 0, B, C };
struct GeneralFunc
{
ftype my_type;
GeneralFunc(ftype t) : my_type(t) {}
inline double value(double a, double b) const; // delay definition until derived classes are defined
}
struct Func_classA : GeneralFunc
{
Func_classA() : GeneralFunc(ftype::A) {}
inline double value(double a, double b) const { return a * b; }
}
/* define B, C (& whatever) */
inline double GeneralFunc::value(double a, double b)
{
switch(my_type){
case (ftype::A):
return static_cast<Func_classA*>(this)->value(a,b);
/* same pattern for B, C, ect */
}
}
void main(){
std::vector<std::unique_ptr<GeneralFunc>> funcs;
funcs.push_back(std::make_unique<Func_classA>());
funcs.push_back(std::make_unique<Func_classB>());
funcs[0]->value(1.0,1.0); // calls Func_classA.value
funcs[1]->value(1.0,1.0); // calls Func_classB.value
}
I'd be tempted to just use std::function as the container, rather than re-writing it.
using GeneralFunc = std::function<double(double, double);
struct Func_classA
{
/*..members..*/
double value(double a, double b) { return a * b; }
/*explicit*/ operator GeneralFunc () const { return [this](double a, double b){ value(a, b) }; }
};
struct Func_classB
{
/*..members..*/
double value(double a, double b) { return a + b; }
/*explicit*/ operator GeneralFunc () const { return [this](double a, double b){ value(a, b) }; }
};
void main(){
double a = 1.0, b = 1.0;
std::vector<GeneralFunc> my_functions;
//fill my_functions from input
for (auto& f : my_functions)
{
double v = f(a, b);
}
}
I think there's an option you didn't include (which is the one I'd use for performance critical code), that is to create a tuple of function objects and "iterate" over such tuple. Unfortunately there is no nice API to iterate over a tuple, so one has to implement his own. See the snippet below
#include <tuple>
#include <functional>
template<int ... Id, typename Functions>
auto apply(std::integer_sequence<int, Id ...>, Functions& my_functions, double& v, double a, double b){
([](auto a, auto b){a=b;}(v, std::get<Id>(my_functions)( a, b )), ...);
}
int main(){
auto fA = [](double a, double b){return a*b;};
auto fB = [](double a, double b){return a+b;};
//create the tuple
auto my_functions=std::make_tuple(fA, fB);
double v=0;
double a = 1.;
double b = 1.;
//iterate over the tuple
apply(std::make_integer_sequence<int, 2>(), my_functions, v, a, b);
}
This way you create a type safe zero overhead abstraction, since the compiler knows everything about the types you use (you don't need any type erasure mechanism). Also there's no need of virtual functions (same as in CRTP), so the compiler will probably inline the function calls. The snippet above uses C++17 generic lambdas, could be also implemented in C++14 or C++11 compliant way, but it would be more verbose. I would prefer this over CRTP because to me it looks more readable: no static cast to the derived class, and no artificial hierarchy of inheritance.
EDIT: from your answer looks like you don't really need the CRTP here, what you write using the CRTP solution is equivalent to this
enum ftype { A = 0, B, C };
auto fA = [](double a, double b){return a*b;};
auto fB = [](double a, double b){return a+b;};
int main(){
std::vector<ftype> types(2);
types[0]=A;
types[1]=B;
auto value = [&types](double a, double b, ftype i){
switch(i){
case (ftype::A):
return fA(a,b);
break;
case (ftype::B):
return fB(a,b);
break;
}
};
double v=value(1., 1., A);
v=value(1., 1., B);
}
Might be a matter of taste, but I think the version above is more readable (you don't really need a common base class, or static cast to the derived class).
I want to generate a function like this:
double apply_stencil(const double *u, const int i, const width,
const int *offset, const double *weight)
{
double t=0;
for(int j=0; j<width; j++)
t += u[i+offset[j]] * weight[j];
return t;
}
But I want to make sure that the width, the offsets, and possibly even the weights are compile/time constants.
That is possible to achieve by defining a type:
template <typename S>
double apply_stencil(const double *u, const int i)
{
double t=0;
for(int j=0; j<S::width; j++)
t += u[i+S::offset[j]] * S::weight[j];
return t;
}
// then:
struct Stencil {
const static double weight[];
const static int offset[];
const static unsigned int width = 3;
};
const double Stencil::weight[] = {1.0, 2.0, 1.0};
const int Stencil::offset[] = {-1, 0, 1};
However, this is not very pretty. I want a user to be able to specify the Stencil in their application code, and then call my apply_stencil function from my header file (this is really a simplification of something much more complicated).
Ideally, I would like to have the thing specified using expression templates, like so:
const Symbol u;
const Stencil<3> s (1*u[-1] + 2*u[0] + 1*u[1]);
Which uses this infrastructure:
struct Accessor {
int offset;
};
struct Symbol
{
Accessor operator[](int i) const {
return Accessor{i};
}
};
struct WeightedTerm
{
double weight;
int offset;
WeightedTerm()
: weight(1), offset(0) {}
WeightedTerm(double a, Accessor u)
: weight(a), offset(u.offset) {}
};
WeightedTerm operator*(double a, Accessor u) {
return WeightedTerm(a,u);
}
template <int n>
struct Sum
{
WeightedTerm terms[n];
Sum(WeightedTerm x, WeightedTerm y) {
terms[0] = x;
terms[1] = y;
}
Sum(Sum<n-1> x, WeightedTerm y) {
for(int i = 0; i < n-1; ++i)
terms[i] = x.terms[i];
terms[n-1] = y;
}
};
Sum<2> operator+(WeightedTerm x, WeightedTerm y) {
return Sum<2>(x,y);
}
template <int n>
Sum<n+1> operator+(Sum<n> x, WeightedTerm y) {
return Sum<n+1>(x,y);
}
template <int width>
struct Stencil
{
double weights[width];
int offsets[width];
Stencil(const Sum<width> s) {
for(int j = 0; j < width; ++j) {
weights[j] = s.terms[j].weight;
offsets[j] = s.terms[j].offset;
}
};
};
This looks nice, but now, the arrays are not necessarily compile time known. If I write it like I do above with literals in the expression, I have verified that the compiler can make the correct optimizations. But I want to make find a way to guarantee that they are always compile time constants.
I presume I could encode the offset as a template parameter in Accessor and WeightedTerm, but I can't see how I could do that and keep the desired expression syntax since operator() takes the offset as a regular argument.
So, the question is if there is a way to achieve this? I have a feeling that constexpr could be of use here which I am a bit unfamiliar with.
Use a std::integral_constant alias. If you want ease of use, use user defined literals.
constexpr int int_from_chars(){return 0;}
constexpr int k_pow(unsigned int x, unsigned int b=10){
return (x==0)?1:(k_pow(x-1,b)*b);
}
template<class...Chars>
constexpr int int_from_chars(char x, Chars...chars){
return k_pow(sizeof...(Chars))*(x-'0') + int_from_chars(chars...);
}
template<char...Cs>
constexpr auto operator""_kint(){
return std::integral_constant<int, int_from_chars(Cs...)>{};
}
or somesuch. Needs polish.
Now 7_kint is a compile time type encoding 7.
You can take the integral_constant<int, K> as a function argument, where K is a template non type argument.
Extending to octal/hex/binary left as an exercise.
template<int width>
double apply_stencil(const double *u, const int i, std::integral_constant<int,width>,
const int *offset, const double *weight)
{
double t=0;
for(int j=0; j<width; j++)
t += u[i+offset[j]] * weight[j];
return t;
}
Called via
apply_stencil( ptr, i, 7_kint, poffsets, pweights);
Similar (but more complex) techniques can be used to pass packs of offsets. Weights are a mess, as there is little compile time double support.
Suppose I have some value:
double x;
and I want to confine it to some range [a, b] such that the resulting value is within that range:
double confine(double x, double a, double b)
{
if (x < a) return a;
else if (x > b) return b;
return x;
}
Is there a single boost or STL function that can do this for me?
Yes, Boost Algorithm has clamp:
double clamped = clamp(x, a, b);
It requires only operator< or a custom comparator, and guarantees that it is called only once or twice. The documentation points out that with double and other floating-point types, NaN could cause unexpected results.
Apart from clamp(), you could also do this using a one liner in std::max() and std::min().
double confine(double x, double a, double b) {
return std::max(a, std::min(x, b));
}
I am writing a Matrix2D class. At the beginning I was using constructor as folows,
My code:
Matrix2D(float a,float b, float c,float d)
{
a_=a;
....
}
However, I have just realized that it would be a lot better if I could use multi dimensional array [2][2]. That's where the problem lies,
How do I write constructor for array ?
class Matrix
{
float matrix[2][2];
public:
Matrix2D(float a,float b,float c, float d)
{
matrix[2][2]={a,b,c,d} // not valid
}
}
Just to let you know, I don't ask for a complete code.
I just need someone to put me on a right track.
For C++11 you can do:
Matrix(float a,float b,float c, float d) :
matrix{{a,b},{c,d}}
{
}
There's no clean alternative for C++03.
matrix[0][0] = a; // initialize one element
and so on.
matrix[0][0] = value you want to matrix [n][n] = value you want but count up in a loop
so the matrix can be dynamic in size or you can reuse your code later.
for(int ii(0); ii < first dimension size; ++ii)
{
for(int ll(0); ii < second dimension size; ++ll)
{
matrix[ii][ll] = value you want;
}
}
this will make your code more extensible and more useful outside of this application and maybe it's not useful or maybe it is.
If it will be a matrix 2X2, then you can pass a float array and then loop through it.
for example
for(int x = 0;x<4;x++)
{
matrix[0][x] = myarray[x];
}
Luchian's version is best if you have a C++11 compiler. Here's one that works for all versions of C++:
struct matrix_holder { float matrix[2][2]; };
class Matrix : matrix_holder
{
static matrix_holder pack(float a,float b,float c, float d)
{
matrix_holder h = { {{a, b}, {c, d}} };
return h;
}
public:
Matrix(float a,float b,float c, float d) : matrix_holder(pack(a,b,c,d))
{
}
};
The optimizer will inline away the helper.