www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - simple template metaprogramming example

reply "Paulo Herrera" <pauloh81 yahoo.ca> writes:
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
parent Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
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