Re: Expression template

2016-07-26 Thread Ilya Yaroshenko via Digitalmars-d-learn

On Tuesday, 26 July 2016 at 10:35:12 UTC, Etranger wrote:


I'll have time 2 months from now as I'm getting married in 2 
weeks :)


Congratulations!




Re: Expression template

2016-07-26 Thread Etranger via Digitalmars-d-learn

On Saturday, 23 July 2016 at 23:55:44 UTC, ag0aep6g wrote:

On 07/23/2016 01:05 PM, Etranger wrote:

[...]


To avoid the string mixin, you can let VecExpression take an 
alias of the mixin template (Vec_impl/VecSum_impl) and the list 
of arguments:


[...]


Thanks ! that's way much cleaner and the type strictness loss is 
not a problem since it is what I want.


Re: Expression template

2016-07-26 Thread Etranger via Digitalmars-d-learn

On Sunday, 24 July 2016 at 10:53:41 UTC, Ilya Yaroshenko wrote:

On Saturday, 23 July 2016 at 11:05:57 UTC, Etranger wrote:


[...]


Yes, but it is more complicated in terms of multidimensional 
and generic abstraction.
First we need to finish and test general matrix multiplication 
[2].


[...]


Thanks allot for your suggestions. I started looking into the 
ndslice and mir code. For me it seems that there is an urgent 
need to have a better benchmarking (like rust bench or google 
benchmark framework for cpp) framework than what is available. I 
can may be look into it.


I'll have time 2 months from now as I'm getting married in 2 
weeks :)


Re: Expression template

2016-07-23 Thread ketmar via Digitalmars-d-learn

On Saturday, 23 July 2016 at 23:36:40 UTC, Etranger wrote:
is there any good benchmarking lib like the #[bench] in rust 
that I can use ?)


dunno, i'm usually just using std.datetime.benchmark.


Re: Expression template

2016-07-23 Thread ag0aep6g via Digitalmars-d-learn

On 07/23/2016 01:05 PM, Etranger wrote:

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).


To avoid the string mixin, you can let VecExpression take an alias of 
the mixin template (Vec_impl/VecSum_impl) and the list of arguments:



struct VecExpression(alias mixinTemplate, mixinArgs ...)
{
  mixin mixinTemplate!mixinArgs;
  VecSum!(typeof(this), VecExpression!RHS) opBinary
(string op, RHS ...)(ref VecExpression!RHS rhs)
  {
/* ... */
  }
}
/* ... */
alias Vec(int n) = VecExpression!(Vec_impl, n);
/* ... */
alias VecSum(E1, E2) = VecExpression!(VecSum_impl, E1, E2);



Instead of mixing the fields into VecExpression, you could mix opBinary 
into distinct Vec/VecSum structs:



mixin template opBinaryMixin()
{
  VecSum!(typeof(this), RHS) opBinary(string op, RHS)(ref RHS rhs)
  {
static if (op == "+") return typeof(return)(, );
  }
}

struct Vec(int n)
{
  double[n] elems;

  /* ... */

  mixin opBinaryMixin!();
}

struct VecSum(E1, E2)
{
  E1 * e1;
  E2 * e2;

  /* ... */

  mixin opBinaryMixin!();
}


A bit of type strictness is lost here, since opBinary accepts anything, 
not just Vec/VecSum. If that strictness is needed, you could check 
specifically for Vec/VecSum, or maybe mix in a little identifier along 
with opBinary and check for that.



You can also try std.typecons.scoped [1] to put classes on the stack. 
That would get around any kind of mixin.



[1] https://dlang.org/phobos/std_typecons.html#.scoped


Re: Expression template

2016-07-23 Thread ketmar via Digitalmars-d-learn
2OP: sorry, i can barely read that code. this has nothing to do 
with your skills, it is the topic -- i've never seen clean lazy 
evaluation code. after all, this is a hack.


still, i think that such a library worth at least some work.

as for "is my code/approach is good enough", i know only two 
answers.

1. yes, 'cause it works.
2. no, 'cause it doesn't work.
so if your code works, it is good. ;-)

i mean that such hacks will be somewhat ugly anyway, so just 
write a brief explanation in comments and go on.


sorry, it is probably not what you wanted to hear... ;-)


Re: Expression template

2016-07-23 Thread ketmar via Digitalmars-d-learn

On Saturday, 23 July 2016 at 12:27:39 UTC, rikki cattermole wrote:
Either way I recommend you not worry about it. Compilers can be 
smart and dmd is mostly good enough in this department.


he has something to worry about. remember, this is scientific 
department, where ours 4x4 matrices are child's play. one removed 
temporary can save hours of calculations there.


Re: Expression template

2016-07-23 Thread Etranger via Digitalmars-d-learn

On Saturday, 23 July 2016 at 12:27:39 UTC, rikki cattermole wrote:


If you evaluate it as v = a + b + c instead of v = a + (b + c) 
you will still have a temporary value. Remember structs are 
just the values they carry and are basically optimized out. 
Either way I recommend you not worry about it. Compilers can be 
smart and dmd is mostly good enough in this department.


If you use dynamic arrays and not fixed sized arrays, they will 
go into the heap, so be careful with what you do with them. 
Fixed sized arrays like gl3n does is fairly cheap since it goes 
on to the stack and in some cases only in registers.


Usually if we solve it on IRC we post the solution that we come 
up with on the post.


For small matrices of fixed size, lazy evaluation may not be 
worth it, but for large matrices and vectors, it is worth it. For 
example, for testing purpose, I wrote 2 versions of and MLP 
(multi-layered perceptron) lib, one that uses openBLAS and one 
with Eigen. The one with Eigen was significantly faster than the 
one with openBLAS tanks to lazy evaluation. No wonder all the 
most known c++ linear algebra lib use this method (Eigen, 
Armadillo, Blitz++, Boost uBlas, ...).


This link http://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html 
explain better than me the advantages of this technique. Given 
the emphasize of D over generics, I think it is worth to explore 
this direction (I hope with better results than what I wrote !).


Re: Expression template

2016-07-23 Thread rikki cattermole via Digitalmars-d-learn

On 24/07/2016 12:09 AM, Etranger wrote:

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))(, );
}
}


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


If you evaluate it as v = a + b + c instead of v = a + (b + c) you will 
still have a temporary value. Remember structs are just the values they 
carry and are basically optimized out. Either way I recommend you not 
worry about it. Compilers can be smart and dmd is mostly good enough in 
this department.


If you use dynamic arrays and not fixed sized arrays, they will go into 
the heap, so be careful with what you do with them. Fixed sized arrays 
like gl3n does is fairly cheap since it goes on to the stack and in some 
cases only in registers.


Usually if we solve it on IRC we post the solution that we come up with 
on the post.


Re: Expression template

2016-07-23 Thread Etranger via Digitalmars-d-learn

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))(, );
}
}


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


Re: Expression template

2016-07-23 Thread rikki cattermole via Digitalmars-d-learn

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))(, );
}
}


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.


Re: Expression template in D struct

2009-05-06 Thread Trass3r

The Anh Tran schrieb:

One of my C++ struct is Vector3. It is a wrapper from D3DXVECTOR3.
I would like to use expression template to calculate where to point the 
gun. In C++, it is provided by boost::proto or boost::ublas.




You calculate where to point the gun at compile-time?