On Sat, 27 Feb 2010 04:56:00 -0500, Norbert Nemec <[email protected]> wrote:

Robert Jacques wrote:
That sounds sensible. However, extensive experience in Matlab has taught me that resorting to custom for-loop indicates you've failed to sufficiently think in arrays. :)

Indeed, most use cases are simple enough to be handled in array notation. I have worked with Matlab and Python and managed to come up with array notations in many non-trivial cases as well. However, once in a while, it just cannot be done. Typically, this happens when you have to handle non-linear terms or high order tensorial objects.

Of course, my examples were simple enough to permit alternative expressions, but I have encountered quite a number of cases where I could not avoid a loop in Python. I is hard to spontaneously construct something useful that I can describe in a few lines.

Imagine a charge density in one dimension:
        rho[r]
and then compute the coulomb energy
        sum(r1,r2)(rho[r1]*rho[r2]/(r1-r2))

Or an expression containing function calls

        sum(i,j)(f(i)*g(j)*A[i,j]))

Ultimately, 'sum' and other reduction would actually be just one use case. One could even use the same mechanism to construct arrays from expressions.

        auto A = array(a=0:10,b=0:20)(2*a + b%3)

(Disregard the exact syntax here...)

I will think further about this and try to come up with more specific use cases.

Greetings,
Norbert

Thank you. I understand the difficulty of finding good examples. I did take a look at my own research, but didn't find any good examples of complex, single line expressions. Somehow, this feels like a narrow problem area; simple things are easy to express using array ops, really complex things take multiple lines to express and should really be done with loops in the first place. Finding the middle ground and then finding a concise way of correctly expressing it both seem like difficult problems, though definitely ones worth investigating. Anyways, I've taken a look at the new examples:

Let Map create an infinite array whose elements are generated via function calls. (I've run into the function call issue before)
Let Index = Map!"a" or something similar
Let .B!D denote broadcasting an array along the D dimension
Let .* denote the element wise multiply. Practically, you might want to use .A and .M to switch between element-wise array and matrix style math. Practically, both Map and .B require the concept of one or more dimensions which are 'unbounded'. Unbounded dimensions become bounded when they interact with any operation that does bounds checking with a bounded dimension.

sum(r1,r2)(rho[r1]*rho[r2]/(r1-r2)) => sum( rho.B!1.*rho.B!0./( Index.B!1 - Index.B!0 ) )
sum(i,j)(f(i)*g(j)*A[i,j]))              => sum( Map!f.B!1.*Map!g.B!0.*A )
auto A = array(a=0:10,b=0:20)(2*a + b%3) => auto A = take([0,10],[0,20], 2*Index.B!1 + Index.B!0 % 3 ); auto A = take( Map!"2*a + b%3"[0..10,0..20] )

Although the ideal syntax is definitely shorter and a bit more readable than the array ops version, the array ops seems more concise than the delegate based alternative:

sum( Map!((int i, int j){ return rho(i)*rho(j)/(i-j); })[0..rho.length,0..rho.length] );

By the way, I'd recommend keeping all these examples for use in your documentation, as people don't naturally think in arrays and array ops.

Reply via email to