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

Reply via email to