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