# A little challenge...

Robert Jacques sandford at jhu.edu
Sat Feb 27 11:30:18 PST 2010

```On Sat, 27 Feb 2010 04:56:00 -0500, Norbert Nemec
<Norbert at nemec-online.de> 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...)
>
> 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.

```