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