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

Reply via email to