On 8/27/2010 2:49 PM, P Kishor wrote:
> On Fri, Aug 27, 2010 at 3:08 PM, Derek Lamb<[email protected]>  wrote:
>    
>> On Fri, 2010-08-27 at 14:35 -0500, P Kishor wrote:
>>      
>>> I am enjoying all the fine tools that the masters have created. Like
>>> magic, with one command, I can apply the same function to millions of
>>> values.
>>>
>>> Now, I am itching to hit my head against the wall. I want to write my
>>> own function that can be applied to all the values in a piddle. So,
>>> following the convention, I envision
>>>
>>> $pdl->func to apply to the elements in the entire piddle and
>>> $pdl->function to apply to all the elements in the specified
>>> dimension. These are not necessarily grouping functions that result in
>>> an (n-1) D piddle, but they are more like sqrt that applies to every
>>> element.
>>>
>>> Where do I begin? Do I have write this in C? Or can I write a function
>>> in Perl and PDL-ify it?
>>>
>>>        
>> Hi Puneet,
>>
>> If you want to do $pdl->func, you just need to write a sub func{}, and
>> then export that into the PDL namespace.  So, yes, you can do it in
>> perl/PDL.  To see how to do this, look in the PDL source for some
>> function that you already do it with.  For example, I use $pdl->wfits to
>> write a FITS file, and in FITS.pm there's a line
>>
>> *wfits = \&PDL::wfits;
>>         and then
>> sub PDL::wfits { #code}
>>
>> I think you can also do it the other way:
>> *PDL::func = \&func;
>> sub func { #code}
>>
>>      
> When you say "the other way" above, I am guessing you mean without
> having to write my own PDL::MyModule, correct? The "other way" would
> be to just do it my own program, no?
>
>    
I guess that's the distinction.  You'll find it both ways in the PDL 
source tree.  You probably want the latter version, though.
>> I think you should think more about your desire for $pdl->function, and
>> what it will do for you.  If you're not grouping or reducing
>> dimensionality, could the same thing be accomplished with
>> $pdl->slice(#something)->func ? Saves you from having to write two subs.
>> "to apply to all elements in the specified dimension" doesn't really
>> make any sense--can you show us what you mean with an example like
>> sequence(3,4)?  For example, what if func() was just a shortcut for
>> squaring each element, what would function do?
>>
>>
>>      
> Your explanation and questions above are brilliant. They made me think
> through my problem. Many thanks. Here goes --
>
> sub add3 { return $_[0] * 3; }
>
> $a = sequence 3, 4;
> print $a;
> [
>   [ 0  1  2]
>   [ 3  4  5]
>   [ 6  7  8]
>   [ 9 10 11]
> ]
>
> print add3( $a->at(1, 2);
> 21
>
> print add3( $a)
> [
>   [ 0  3  6]
>   [ 9 12 15]
>   [18 21 24]
>   [27 30 33]
> ]
>
> print add3($a->slice(':,2'))
>
> [
>   [18 21 24]
> ]
>
> A style note -- how do I make chaining possible? I would like
> $a->at(1, 2)->add3 or $a->add3, which, currently gives me "Can't
> locate object method "add3" via package 'PDL'". I guess I have to
> "export it into the PDL namespace" as you state above. I will look at
> the source of FITS.pm and see if I can copy that.
>    
well, first you need to make sure that whatever your chaining returns a 
piddle, and not a perl scalar.  The '->' only works on piddles.  So 
basically that means never using 'at'.  Then if you have

sub PDL::add3 {#stuff}
then you could do $a->add3->some_other_func, because add3 is now in the 
PDL namespace.
> However, I might want to do a grouping function, such as the avg and
> sum functions, which create an (N-1) D piddle.
>    
As an example, I believe the way avg and average are implemented is that 
$pdl->avg is synonymous with $pdl->clump(-1)->average, so really all the 
work is in the dimension-reducing function average.
> Actually, here are a few concrete things that I want to do.
>
> 1. Create a frequency distribution of my piddle values. So, given
>
> print $a
> [
>   [ 67.099513  41.056771  58.605799]
>   [ 36.449405  17.962021  42.484533]
>   [ 57.186859   6.542282  6.1037422]
>   [ 58.814063   58.77334  12.803835]
> ]
>
> and a range, say, 0 .. 99, and a class interval of 10 like so
> 0: 0-19
> 1: 20-39
> 2: 40-59
> 3: 60-79
> 4: 80-99
>
> I want
>
> print $a->myRangeFunc(range =>  [0, 99], interval =>  20)
> [
>   [ 3  2  2]
>   [ 1  0  2]
>   [ 2  0  0]
>   [ 2  2  0]
> ]
>    
floor($a/20) ?

> and
>
> print $a->myFreqDistrib(range =>  [0, 99], interval =>  20)
> [4 1 6 1 0]
>
>    
hist(floor($a/20),0,100/20,1) ?
> and so on...
>
>
> --
> Puneet Kishor
>    
Derek

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

Reply via email to