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 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.
However, I might want to do a grouping function, such as the avg and
sum functions, which create an (N-1) D piddle.
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]
]
and
print $a->myFreqDistrib(range => [0, 99], interval => 20)
[4 1 6 1 0]
and so on...
--
Puneet Kishor
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl