446,227 Members | 1,258 Online
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

# replacement for dynamic template parameter

 P: n/a I have a function that returns {sin(x),x,cos(x)} depending on a parameter k that can take only 3 integer values: -1, 0, 1. I am trying to do this with template specialization: enum curv { negative=-1, zero=0, positive=1 }; template double scurv(const double& x); template<> double scurv(const double& x) { return sin(x); } template<> double scurv (const double& x) { return x;} template<> double scurv (const double& x) { return cos(x); } curv guess_curv(const double& ym) { if (ym<0) return negative; if (ym>0) return positive; return zero; } Next, I would like to use this function in a class: class Yfunc { const curv k; const double& y; public: inpa(const double& M, const double& Y) : k(guess_curv(M+Y)), y(Y) {} double ez(const double& a) const { return scurv(x) * pow(y*a, 0.6) ; } }; Such that I construct Yfunc once, k is determined, and I do not test for k each time I call Yfunc::ez. Template parameters do note allow this dynamical parameter setting . Is there a smart way to overcome this, yet as performant as template specialization? I was thinking of function pointer but it was not as elegant. Thanks. Jul 23 '05 #1
6 Replies

 P: n/a On 2005-03-28, Marcel Sebbao wrote: Such that I construct Yfunc once, k is determined, and I do not test for k each time I call Yfunc::ez. Template parameters do note allow this dynamical parameter setting . Is there a smart way to overcome this, yet as performant as template specialization? I was thinking of function pointer but it was not as elegant. Function object + subclassing. Note that however you do runtime selection, if you are doing the selection at runtime there is inherent overhead in that (if you use polymorphism or function pointer, you have a pointer deref) So you don't get the same performance as you would with compile-time template selection. Cheers, -- Donovan Rebbechi http://pegasus.rutgers.edu/~elflord/ Jul 23 '05 #2

 P: n/a On 2005-03-28, Marcel Sebbao wrote: Such that I construct Yfunc once, k is determined, and I do not test for k each time I call Yfunc::ez. Template parameters do note allow this dynamical parameter setting . Is there a smart way to overcome this, yet as performant as template specialization? I was thinking of function pointer but it was not as elegant. btw, depending on your usage, it may help to have a member function that calls your function on a range, e.g. MyFunc(v.begin(),v.end(),result.begin()); Anyway, my point is that there might be a way to abstract the "making multiple calls" in a way that allows you to perform the indirection only once per usage. Cheers, -- Donovan Rebbechi http://pegasus.rutgers.edu/~elflord/ Jul 23 '05 #3

 P: n/a Marcel Sebbao wrote: I have a function that returns {sin(x),x,cos(x)} depending on a parameter k that can take only 3 integer values: -1, 0, 1. I am trying to do this with template specialization: [snip] Such that I construct Yfunc once, k is determined, and I do not test for k each time I call Yfunc::ez. Are you sure that computing transcendentals won't overwhelm any savings in avoiding the runtime comparison? -- Quidquid latine dictum sit, altum viditur. Jul 23 '05 #4

 P: n/a Thanks for the feedback. I thought the compiler was generating 3 functions and will call it appropriately only at runtime. I finally decided on the quickest change: make the Yfunc class a template class: template class Yfunc { const double& y; public: inpa(const double& Y) : y(Y) {} double ez(const double& a) const { return scurv(x) * pow(y*a, 0.6) ; } }; Then I call it within an if statement. What is "computing transcendentals"? Jul 23 '05 #5

 P: n/a Marcel Sebbao wrote: What is "computing transcendentals"? Carrying out a process that takes a given number into an approximation of its image under one of a certain class of mathematical functions -- to which sine and cosine belong. This can be quite computationally expensive, so the time the library calls take is likely to drown out some more comparisons unless your parameter k selects the identity map in most cases. Profile your code with runtime comparisons to find out if sin() and cos() are hot spots. If so, explore alternative implementations with your accuracy requirements in mind, and if you need help with that, visit sci.math.num-analysis. If you need help with profiling, visit comp.programming or a group about your development environment. http://mathworld.wolfram.com/Transce...lFunction.html -- Quidquid latine dictum sit, altum viditur. Jul 23 '05 #6

 P: n/a Well it looks like I had to get rid of the template stuff. I did some tests, and the computation of transcendental functions is more costly. I adopted for pointer to function :( static inline double identity(double x) { return x; } class Yfunc { const double& y; public: double (*Sc)(double x); Yfunc(const double& M, const double& Y): y(Y) { if (y+M<0) Sc = &sin; else if (y+M>0) Sc = &cos; else Sc = &identity; } double ez(const double& a) const { return Sc(a) * pow(y*a, 0.6); } }; Jul 23 '05 #7

### This discussion thread is closed

Replies have been disabled for this discussion.