digitalmars.D - simple template metaprogramming example
- Paulo Herrera (55/55) Jan 06 2007 I've been experimenting with D's template capabilities to speed up some ...
- Deewiant (23/34) Jan 06 2007 Nice. Function templates make the code even nicer-looking, IMHO:
I've been experimenting with D's template capabilities to speed up some = = number crunching codes. In that process I adapted the evaluation of the dot product of two array= s, = originally in C++ and found at: = http://osl.iu.edu/~tveldhui/papers/techniques/. I think the D version is very concise and simple to understand, so it = could be added to the examples given in the templates documentation. On = = the other hand, this kind of examples could motivate people working on = numerical codes to try D. -------------------------------------------- /// Rational: /// Using a loop to compute the dot product of two small/medium size = float arrays, e.g. /// /// float s =3D 0.0; /// for (int i=3D0, i < size, ++i) /// s +=3D a[i]*b[i]; /// return s; /// /// can be very inefficient when compared to the hand written expressio= n /// /// return a[O]*b[0] + a[1]*b[1] + .....; /// /// Using template metaprogramming we can get the same effect without = explicitly writing /// code for different array size and type. struct dot_product(T, int N) { static T opCall (T[N] a, T[N] b) { return meta_dot!(N-1, N, T)(a,b); // expands to: a[0]*b[0] = + a[1]*b[1] + .... at compilation time } } struct meta_dot(int I, int N, T) { static T opCall(T[N] a, T[N] b) { static if (I =3D=3D 0) return a[0]*b[0]; else return a[I]*b[I] + meta_dot!(I-1, N, T)(a,b); } } // ------- // Usage: // ------- float[3] a; float[3] b; a[] =3D 0.5; b[] =3D 0.5; float dot =3D dot_product!(float, 3)(a, b); writefln("dot: %f", dot); // =3D 0.750000 --------------------------------------------- Paulo
Jan 06 2007
Paulo Herrera wrote:I've been experimenting with D's template capabilities to speed up some number crunching codes. In that process I adapted the evaluation of the dot product of two arrays, originally in C++ and found at: http://osl.iu.edu/~tveldhui/papers/techniques/. I think the D version is very concise and simple to understand, so it could be added to the examples given in the templates documentation. On the other hand, this kind of examples could motivate people working on numerical codes to try D.Nice. Function templates make the code even nicer-looking, IMHO: import std.stdio; T dot_product(T, size_t N)(T[N] a, T[N] b) { return meta_dot!(N-1, N, T)(a,b); } T meta_dot(size_t I, size_t N, T)(T[N] a, T[N] b) { static if (I == 0) return a[0]*b[0]; else return a[I]*b[I] + meta_dot!(I-1, N, T)(a,b); } void main() { float[3] a; float[3] b; a[] = 0.5; b[] = 0.5; float dot = dot_product(a, b); // note how implicit function template instantiation means we don't need to specify float and 3 writefln("dot: %f", dot); } -- Remove ".doesnotlike.spam" from the mail address.
Jan 06 2007