Anyone come up with some cool algorithms/templates for D lately?

Bill Baxter dnewsgroup at billbaxter.com
Thu Apr 17 20:41:15 PDT 2008


janderson wrote:
> In the past people have posted these cool algorithms/templates they 
> figured out how to do in some neat way with D.  Things like wow, this 
> would take INF+ lines in C++ but I can do it in 2 in D.   This seems to 
> have died down a bit.   I always found these topics most interesting.
> 
> So I'm requesting people to post "cool stuff" they figured out how to do 
> in D.

I'm still flabbergasted by the cool things you can do inside 
fixed-length matrix/vector templates.

For instance (this is all from my matrix/vector classes in OpenMesh/D 
which are basically a complete rewrite of the original C++ versions)

struct MatrixT(T, int M, int N)
{
     alias T Scalar;

     union {
         Scalar[M*N] values_ = void;
         static if(M<=10 && N<=10) {
             mixin(_gen_elements!(M,N)("Scalar"));
         }
     }
}

// Generate the elements m00,m01,m02... elements
// For matrices with dimensions < 10 x 10 only.
private string _gen_elements(int M, int N)(string type) {
     static assert(M<=10);
     static assert(N<=10);
     char[] Num = "0123456789";
     string ret;
     for(int col=0; col<N; ++col) {
         ret ~= type ~ " ";
         for (int row=0; row<M; row++) {
             ret ~= "m" ~ Num[row] ~ Num[col];
             if (row!=M-1) ret ~=  ", ";
         }
         ret ~= ";\n";
     }
     return ret;
}

This creates aliases to each element of the matrix of the form m00, m01, 
m02, but only if the matrix is small enough.  I have no idea how you'd 
do that in C++.  I don't think it's really possible.


Here's another -- generating the unrolled code for multiplying two 
matrices together:

/// Multiply MxN matrix time NxP matrix
void mat_mult_ret(T,int M,int N,int P)(
     /*const*/ref MatrixT!(T,M,N) A,
     /*const*/ref MatrixT!(T,N,P) B,
     inout MatrixT!(T,M,P) ret)
{
     with(ret) {
         mixin(_gen_mat_mult_body!(M,N,P)("A","B"));
     }
}

private string _gen_mat_mult_body(int M, int N, int P)(string A, string B)
{
     string ret;
     for (int row=0; row<M; ++row) {
         for(int col=0; col<P; ++col) {
             ret ~= "        ";
             ret ~= "values_["~ctfe_itoa(col*M+row)~"] = ";
             for(int jj; jj<N; ++jj) {
                 string JJ = ctfe_itoa(jj);
                 string iA = ctfe_itoa( row+jj *M );
                 string iB = ctfe_itoa( jj +col*N );
                 ret ~= A ~ ".values_["~iA~"]*"~B~".values_["~iB~"]";
                 if (jj != N-1) { ret ~= " + "; }
                 else { ret ~= ";\n"; }
             }
         }
         ret ~= "\n";
     }
     return ret;
}


Wow.  The code generating function basically just looks like a standard 
triply-nested matrix multiply, but instead of doing multiplies it just 
splits out code that implements multiplies.

I think that's pretty sweet.

--bb



More information about the Digitalmars-d mailing list