Sorry for the slow response here.  

I inserted the offending fixes over the summer, which patched up a few 
consistency problems that arose because empty and null piddles were both 
implemented in an ad hoc manner.  In particular, there was never any 
documentation for how the empty set should be recognized, and the most natural 
way got adopted by default -- just use any old PDL with zero elements in it.  
The scalar case for whichND used that technique -- just returned a PDL with the 
same dimensions it would return anyway, but with 0 for one of the dimensions.  
If I recall right, that led to problems because sometimes the data pointer was 
allocated and sometimes it wasn't in the returned PDL (which is why it caused 
crashes occasionally).

Anyway, I regularized the empty PDL case to use a 1-D PDL with size 0, which is 
what index() was returning in the empty case.  That cleared up the bugs since 
everything could look for a specific case in the dimensions.  Little did I know 
that it would botch up someone else (of course -- without explicit 
documentation the code becomes the spec...)

Anyway, I'm open to moving back to a more general empty-PDL case that allows 
structured emptines -- though if we do that we should really do it right: 
regularize new_from_specification to accept specs for empty PDLs, and also make 
the empty stringifier return a dimension list as well as "Empty", as in 
"Empty(2x0)".

Given that we appear to have a use case now, I'd be willing to edit (by Friday):
        * whichND()
        * range()
        * new_from_specification()
        * the stringifier()
to use arbitrarily-dimensioned empty PDLs.  The most straightforward hack to 
avoid further crashes is to make sure that the data pointer is always valid 
even if there's nothing in particular for it to point at.

The threading engine needs to be thought about if full support is implemented 
for generic empty PDLs.  In particular, I believe empty dimensions should fail 
to match anything other than empty dimensions -- so, e.g., if $a is 2x0 and $b 
is 2x1, then "$a*$b" should throw an error, which it doesn't currently:

        $a = whichND(pdl(0))->(*2);
        $b = sequence(2,1);
        sub PDL::xdims { join("x",$_[0]->dims) }
        printf "%s * %s ==> %s\n", map { xdims $_ } ($a,$b,$a*$b);

yields
        2x0 * 2x1 ==> 2x0

rather than (more correctly) something like:
        PDL: PDL::Ops::mult(a,b,c): Parameter 'b':
        Mismatched implicit thread dimension 1: should be 0, is 1

Anyway, Chris, if you give the go-ahead I'll restore the fuller structured 
Empty behavior in those routines and put appropriate tests in place.  I'll dive 
into the threading engine to see just how simple it is to throw a mismatch 
error in the described case.  Otherwise I'll wait and update those routines 
later.




On Jan 3, 2012, at 12:45 PM, Chris Marshall wrote:

> Looking at the definition of whichND(), it seems like having
> it return a shape [nfound,0] piddle would be more consistent
> w.r.t. the principle of least surprise.  However, the question
> is whether it can be made to work with the range() and pdl
> constructor code and whether there are any other snags
> from that implementation.
> 
> Cheers,
> Chris
> 
> On Mon, Jan 2, 2012 at 4:06 AM, Bryan Jurish
> <[email protected]> wrote:
>> On 2011-12-30 13:53, chm wrote:
>>> On 12/27/2011 3:29 PM, Bryan Jurish wrote:
>>>> 
>>>>> From a more principled (as opposed to purely pragmatic) standpoint, I
>>>> think there are good reasons to allow size-0 dimensions across the
>>>> board
>> ...
>>>> to provide identity elements for glue().
>>> 
>>> The identity element argument seems like a plausible
>>> justification/motivation for the existence and meaning of
>>> such piddle shapes with 0-length dimensions.
>> 
>> ... just a note after the fact: it seems that the return value of
>> whichND(zeroes(4,3)) has changed in the 2.4.10 release candidate as
>> well. With $,=' '; I get:
>> 
>>  ##-- v2.4.7_001 (debian squeeze)
>>  print whichND(  ones(4,3))->dims; ##-- "2 12"
>>  print whichND(zeroes(4,3))->dims; ##-- "2 0"
>> 
>>  ##-- v2.4.9_015
>>  print whichND(  ones(4,3))->dims; ##-- "2 12"
>>  print whichND(zeroes(4,3))->dims; ##-- "0"
> 


_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl

Reply via email to