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

janderson askme at me.com
Thu Apr 17 22:39:06 PDT 2008


Bill Baxter wrote:
> 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

Neat Stuff!



More information about the Digitalmars-d mailing list