By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,258 Online
Bytes IT Community
+ Ask a Question
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<curv k> double scurv(const double& x);
template<> double scurv<negative>(const double& x) { return sin(x); }
template<> double scurv<zero> (const double& x) { return x;}
template<> double scurv<positive> (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<k>(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
Share this Question
Share on Google+
6 Replies


P: n/a
On 2005-03-28, Marcel Sebbao <se****@yahoo.fr> 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 <se****@yahoo.fr> 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<curv k>
class Yfunc {

const double& y;

public:

inpa(const double& Y)
: y(Y) {}

double ez(const double& a) const {
return scurv<k>(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.