Boost logo

Boost Users :

Subject: Re: [Boost-users] proto for array expressions
From: Daniel Oberhoff (daniel.oberhoff_at_[hidden])
Date: 2009-01-03 14:07:25


Sorry for the delay, the holidays, you know ...

Daniel Oberhoff wrote:
> On 2008-12-18 23:46:40 +0100, Eric Niebler <eric <at> boost-consulting.com> 
> said:
> 
>> Daniel Oberhoff wrote:
>>>
>>> Now with proto I was wondering how hard it would be to build an et
>>> engine for array math. Basically I am interested in general tensor
>>> notation, and the resulting expressions should be iteratable
>>> efficiently. think (advanced example):
>>>
>>> a_ij = b_i * (c_j - sum(d_ijk, k = [i-1,1])
>>
>> I don't understand your notation. What are a_ij et. al.?
> 
> Sorry, the underscripts where meant to be indices. So a is a 2d array, b 
> and c are 1d arrays, and d is a 3d array. The statement says: to 
> calculate a at a given index pair i,j (say 0,0) you substitute for i,j 
> on the right. And the sum sums over the third index of the 3d array d. 
> The notation further says that the bounds for the summation depend on 
> what you substitute for i. So to fill the array a like that you need to 
> substitute all values in the domian (say both indices run from 0 to 99 
> for a 100x100 array), and for efficiency it would be best if the right 
> hand side would result in an iterator that substitutes subsequent all 
> values in series.

OK, the syntax for your tensor expressions needs work, but I think what 
you're shooting for is certainly doable. How about a syntax like this:

     a[i][j] = b[i] * ( c[j] - sum( (d[i][j][k], k = (i-1,1)) ) )

This is a valid C++ expression, and I think there could be enough type 
information in it to make it do something useful. Here is a simple 
program that makes the above well-formed, and also defines a very 
rudimentary the grammar for tensor expressions, with transforms that 
calculate the expression's dimensionality. That's important because you 
don't want to assign a 2-D array to a 1-D array, for instance.

[...]

Hey, wow, a full implementation as a response :). Seems very lean and mean, and I will have to look at it further. What I just tried was defining two domains very similar to the calculator example, and then I was going to have syntax with round brackets like this:

a(i, j) = b(i) * ( c(j) - sum( d(i,j,k), k, i-1, 1) ) )
so one domain was to be for arrays (a,b,c,d) and one for the indices (i,j,k). But I could not get the grammar to check for the function syntax. somehow the proto extends mechanism just passed through all kinds of function call expressions, even though I explicitly specified only things like:

boost::proto::function< array_grammar, index_grammar >

and still things like a(a) compile. any ideas where I am going wrong?

next I will look at how to generate evaluators using fast iterators based on a simple array implementation.

Thx

daniel

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net