So the problem you're running in to, Edward, is that non-affine
indexing is done with smoke and mirrors: each atomic operation is
done on the indexed sub-PDL and then the result is copied across to
the parent PDL. This means that redundantly indexed daughter PDLs
behave slightly unexpectedly on the LHS of in-place operators: the
result is calculated separately for each copy of each multiply indexed
elements, and the parent gets one arbitrarily-chosen version of the
result.
Fixing that conceptual wart would require refactoring the PP code
generator to carry out all operations in a parent/daughter pipeline in
the fastest loop, which nobody seems to want to touch - both because
the code generator is quite hairy and because inverting the thread
loops might slow down the majority of expression computations.
You can get the Right answer by declaring your own PP subroutine,
which isn't really as hard as the documentation would have you
believe. If you copy/paste the below into a file called "incdex.pdl"
in your autoload path (@PDLLIB), it will autoload an "incdex" function
that does what you want. If you take the trouble to parse and
understand the parts of the code you will see that it is quite simple:
you declare a name, a dimensionality of arguments, and a very brief
snippet of 'C' code that does What You Want.
Because the code is Inline, it will take a moment to compile the first
time you invoke it; after that, it will run at full C speed.
=
=
=
=
========================================================================
no PDL::NiceSlice;
use Inline Pdlpp=> <<'EOF'
pp_def('incdex',
# The Pars section declares the dimensionality we expect from our
arguments. Here,
# we are declaring a 1-D operator with two variables of different 1-D
sizes. Any
# additional dimensions get threaded over in the usual way.
Pars=>'src(n); dex(m)',
Code=>q{
// here inside the Code section we write in C with PP macros
long l;
loop(m) %{
// Retrieve the current element of "dex", bounds check it, and
// increment the corresponding element of "src".
l = $dex();
if(l >= 0 && l < $SIZE(n))
$src(n=>l)++;
%}
}
);
EOF
;
# the pp_def puts the newly declared PP subroutine into the 'PDL'
package;
# we want it in the current package, so copy the symbol over.
*incdex = \&PDL::incdex;
=
=
=
=
========================================================================
On Jul 1, 2009, at 6:46 PM, Hyer, Dr. Edward wrote:
> Hi PDL Wizards,
>
> perldl> $this=pdl(3,4,5,5,5,5,5,5,5,5)
> perldl> $that=pdl(0..10)
> perldl> $thisi=index($that,$this)
> perldl> $thisi += 1
> perldl> p $that
> [0 1 2 4 5 6 6 7 8 9 10]
>
> I was hoping for
> [0 1 2 4 5 13 6 7 8 9 10]
>
> Any suggestions for how I get this result?
>
> Thanks,
>
> --Edward H.
>
> _______________________________________________
> Perldl mailing list
> [email protected]
> http://mailman.jach.hawaii.edu/mailman/listinfo/perldl
>
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl