> Reading through the examples left me wondering about some
> technicalities:
>
> > @t[|i;|j] = @a[|j;|i]; # transpose 2-d @a
>
> Written like this it would require that @a is exact 2-dim, i.e. it would
> not just swap the first two dims of any n-dim array? I suppose if I'd
> want that I'd write
>
> @t[|i;|j;] = @a[|j;|i;]; # trailing ';' implies there might be
> trailing dims
I will confess, operations on general multidimensional arrays were not
something I had considered when I originally had this idea. The
problem I see with your @t[|i;|j;] example is that it isn't clear that
the trailing dims for @a and @t will have tied iterators. I.e., if @a
is defined with "my @a :bounds (3,3,3);", which of these two should be
considered equivilant?
@t[|i;|j;|k] = @a[|j;|i;|k]; # or...
@t[|i;|j;|k] = @a[|j;|i;|l];
Arguments could be made for either one.
> > #compute pairwise sum, pairwise product, pairwise difference...
> > @sum = @a[|i;|j;|k;|l] + @b[|i;|j;|k;|l];
> > @prod= @a[|i;|j;|k;|l] * @b[|i;|j;|k;|l];
> > @diff= @a[|i;|j;|k;|l] - @b[|i;|j;|k;|l];
>
> Hm, not sure if I am missing the point of these examples. Is that any
> different from the elementwise '+','*','-' apart from being possibly
> limited to 4D arrays?
It would be another way to do it, assuming that elementwise operators
are accepted. There does seem to be some resistance to the idea. In
which case, this would become the preferred way to do it.
> > #print lots of stuff to the screen.
> > sub foo { print join(',',@_),"\n"; return 0; }
> > $zero[|i;|j;|k;|l;|m;|n;|o;|p] = foo(|i,|j,|k,|l,|m,|n,|o,|p);
>
> Should that be '$zero' or '@zero'?
That's an interesting question. Based on the reasoning I had when I
wrote the RFC, it probably should be @zero. But... the $zero[...]
notation is more suggestive of what it's actually doing.
Would:
$zero[[|i,|j,|k,|l,|m,|n,|o,|p]] = foo(...);
be a good alternate or replacement for @zero[|i;|j;...]?
> > # Sneaky way to generate dot-product:
> > my $dotproduct;
> > { my @temp[|i] = $dotproduct += $a[|i] * $b[|i]; }
>
> Hm, how can this work with lazy evaluation? How is Perl supposed to know
> that @temp should be transiently created to increment $dotproduct as a
> side effect? Also, doesn't the above syntax seem to be conflicting with
> perl context rules since it essentially contains a statement
>
> @arr = $scalar
Hmmm, would {my @temp; $temp[|i] = $dotproduct += $a[|i] * $b[|i]; }
deal with the
@arr = $scaler issue?
As far as the transient creation of @temp, what would happen is that
the entire expression
"$temp[$i] = $dotproduct += $a[$i] * $b[$i]" would get wrapped in a
loop:
{ my @temp;
#generated loop
for my $i (scaler(@a)) {
$temp[$i] = $dotproduct += $a[$i] * $b[$i];
}
}
Perhaps a better way to do that would be:
(|i, $dotproduct += $a[[|i]] * $b[[|i]]);
Hmm... Would this work?:
Start with the smallest expression in the statement that includes all
the iterators.
If the expression is in void context, then simply wrap it in loops,
replacing each iterator with the appropriately lexically scoped
variable, renaming if necessary to avoid name-clashes:
$scalarproduct[|i;|j] = $i * $a[|i;|j];
gets transformed into:
for my $i_ (0..$#a[0]) {
for my $j (0..$#a[1]) {
$scalerproduct[$i_;$j] = $i * $a[|i;|j];
}
}
If the expression is in a list context, generate a temporary array of
dimension equal to the total number of (explicit or implicit)
iterators, assign the value of the expression evaluated at each
iteration of the inner loop to the corresponding element of the
temporary array, and finally return the array:
@tensorproduct = $a[[|i]] * $b[[|j]];
gets transformed into
@tensorproduct = do {
my @temp :bounds($#a[0],$#b[1]);
for my $i (0..$#a[0]) {
for my $j (0..$#b[1]) {
@temp[[$i,$j]] = $a[[$i]] * $b[[$j]];
}
}
@temp;
};
If the expression is in a scalar (lvalue) context expand the scope of
the iterators:
$dotproduct += $a[[|i]] + $b[[|i]];
$a[|i;|j] = rand();
In the first case, the RHS is the smallest expression containing all
the iterators, but it's in scalar context. Therefore, expand to
include the LHS as well, which puts us in void context, then transform
to:
for $i (0..$#a) {
$dotproduct += $a[[$]] + $b[[$i]];
}
In the second case, the LHS is the smallest expression containing all
the iterators, but it's in scalar lvalue context. Therefore, expand to
include the RHS as well, which puts us in void context, then transform
to:
for $i (0..$#a[0]) {
for $j (0..$#a[1]) {
$a[[$i,$j]] = rand();
}
}
I'm not sure what to do in list lvalue context. Are there any contexts
untouched (void lvalue?!?)?
And how do you lazily evaluate a dotproduct, anyway?
> Christian
--
Buddha Buck [EMAIL PROTECTED]
"Just as the strength of the Internet is chaos, so the strength of our
liberty depends upon the chaos and cacophony of the unfettered speech
the First Amendment protects." -- A.L.A. v. U.S. Dept. of Justice