Expression template

Etranger via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jul 23 05:09:18 PDT 2016


On Saturday, 23 July 2016 at 11:19:34 UTC, rikki cattermole wrote:
> On 23/07/2016 11:05 PM, Etranger wrote:
> [snip]
>
>> ***************** start of code ******************
>> import std.stdio;
>> import std.traits;
>> import std.conv;
>>
>> struct VecExpression(alias mixins) {
>>   mixin (mixins);
>>   VecSum!(typeof(this), VecExpression!(RHS)) opBinary(string 
>> op, alias
>> RHS)(ref VecExpression!(RHS) rhs)
>> {
>>   static if (op == "+") return VecSum!(typeof(this),
>> VecExpression!(RHS))(&this, &rhs);
>> }
>> }
>>
>>
>> mixin template Vec_impl(int n) {
>>   double[n] elems;
>>
>>   @disable this();
>>
>>   this(double[n] e){
>>     elems=e;
>>   }
>>
>>   double opIndex(int i) {
>>     return elems[i];
>>   }
>> }
>>
>> alias Vec(alias n) = VecExpression!("mixin
>> Vec_impl!("~to!string(n)~");"); //Vec(int n) does not work
>>
>> mixin template VecSum_impl(E1, E2) {
>>   E1 * e1;
>>   E2 * e2;
>>
>>   @disable this();
>>
>>   this(E1 * ee1, E2 * ee2){
>>     e1=ee1;
>>     e2=ee2;
>>   }
>>
>>   double opIndex(int i) {
>>     return (*e1)[i]+(*e2)[i];
>>   }
>> }
>>
>> alias VecSum(E1, E2) = VecExpression!("mixin
>> VecSum_impl!("~fullyQualifiedName!E1~","~fullyQualifiedName!E2~");");
>>
>> void main()
>> {
>>   Vec!(3) v1 = Vec!(3)([5., 2., 3.]), v2 = Vec!(3)([1., 4., 
>> 3.]), v3 =
>> Vec!(3)([3., 2., 1.]);
>>   auto res = v1+v2;
>>   for(int i=0; i < 3; ++i){
>>     writefln("%f + %f = %f", v1[i], v2[i],  res[i]);
>>   }
>>   auto res2 = res+v3;
>>   for(int i=0; i < 3; ++i){
>>     writefln("%f + %f = %f", res[i], v3[i],  res2[i]);
>>   }
>>   writeln(res);
>>   writeln(res2);
>>
>>   // VecExpression!(Vec_impl!(3)) ve; // Error: template 
>> instance
>> Vec_impl!3 mixin templates are not regular templates
>> }
>>
>> ***************** end of code ******************
>>
>> My questions:
>>
>> 1- Is there a cleaner way to do it ? I had to use struct 
>> because I want
>> every thing to happen at compile time and on the stack 
>> (without gc). And
>> I had to use string mixins because template mixin does not 
>> work the way
>> I tried to use it ( see the error last line).
>>
>> 2- Is there a safer way to do it (without using pointers) ?
>>
>> 3- Do you think I'll hit a wall with this approach ?
>>
>> 4- Do you known any D libs that uses expression template for 
>> linear
>> algebra ?
>>
>> I thank you in advance for your help and wish you a nice 
>> weekend (and
>> apologize for my bad english) :)
>
> My goodness that code is awful.
>
> I have a fair idea what you are attempting to do here.
> So I'm going to point you directly to gl3n. Its meant for game 
> dev so won't provide you a 100% solution. But it should give 
> you ideas of how to do it.
>
> https://github.com/Dav1dde/gl3n/blob/master/gl3n/linalg.d#L49
>
> If you have any questions and want somebody to talk with you 
> instead of write, reply cycle. Please hop on to Freenode #d 
> channel.

Hi and thanks for your quick replay.

A looked to the gl3n code, although the code is clear and clean, 
it is not really what I want to do in my example.

The gl3n is eager evaluation. If I write "v = v1+v2+v3;", then it 
will create a temporary variable "tmp1=v1+v2;" then a second temp 
"tmp2=tmp1+v3;" and finally "v=tmp2;".

what I'm trying to do to use lazy evaluation in order to create 
only one tmp that will that will directly hold the result of 
v1[i]+v2[i]+v3[i]. That concept is then generalized in order to 
perform more optimization based on entire expression trees, no 
just tow operands.

And thanks for the suggestion regarding the channel, I'll try to 
use it as soon as I have the time. I feel on advantage of the 
forum is that it stays for other people and not just for me.

best regards


More information about the Digitalmars-d-learn mailing list