PDL::FAQ (1)
Leading comments
Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) Standard preamble: ========================================================================
NAME
PDL::FAQ - Frequently asked questions about PDLVERSION
CurrentDESCRIPTION
This is version 1.008 of theABOUT THIS DOCUMENT
Q: 1.1 Where to find this document
You can find the latest version of this document at <pdl.perl.org/?docs=FAQ&title=Frequently%20Asked%20Questions> .Q: 1.2 How to contribute to this document
This is a considerably reworked version of theSimilarly, if you think parts of this document are unclear, please tell the
Send your comments, additions, suggestions or corrections to the
GENERAL QUESTIONS
Q: 2.1 What is PDL ?
The PDL concept is to give standard perl5 the ability to COMPACTLY store and SPEEDILY manipulate the large N-dimensional data sets which are the bread and butter of scientific computing. e.g. $a=$b+$c can add two 2048x2048 images in only a fraction of a second.
It provides tons of useful functionality for scientific and numeric analysis.
For readers familiar with other scientific data evaluation packages it may be helpful to add that
Q: 2.2 Who supports PDL? Who develops it?
As a Perl extension (see Q: 2.5 below) it is devoted to the idea of free and open development put forth by the Perl community.
Q: 2.3 Why yet another Data Language ?
There are actually several reasons and everyone should decide for himself which are the most important ones:- *
-
PDLis ``free software''. The authors ofPDLthink that this concept has several advantages: everyone has access to the sources -> better debugging, easily adaptable to your own needs, extensible for your purposes, etc... In comparison with commercial packages such asMATLABandIDLthis is of considerable importance for workers who want to do some work at home and cannot afford the considerable cost to buy commercial packages for personal use.
- *
-
PDLis based on a powerful and well designed scripting language: Perl. In contrast to other scientific/numeric data analysis languages it has been designed using the features of a proven language instead of having grown into existence from scratch. Defining the control structures while features were added during development leads to languages that often appear clumsy and badly planned for most existing packages with similar scope asPDL.
- *
-
Using Perl as the basis a PDLprogrammer has all the powerful features of Perl at his hand, right from the start. This includes regular expressions, associative arrays (hashes), well designed interfaces to the operating system, network, etc. Experience has shown that even in mainly numerically oriented programming it is often extremely handy if you have easy access to powerful semi-numerical or completely non-numerical functionality as well. For example, you might want to offer the results of a complicated computation as a server process to other processes on the network, perhaps directly accepting input from other processes on the network. Using Perl and existing Perl extension packages things like this are no problem at all (and it all will fit into your ``PDLscript'').
- *
-
Extremely easy extensibility and interoperability as PDLis a Perl extension; development support for Perl extensions is an integral part of Perl and there are already numerous extensions to standard Perl freely available on the network.
- *
-
Integral language features of Perl (regular expressions,
hashes, object modules) immensely facilitated development
and implementation of key concepts of PDL.One of the most striking examples for this point is probablyPDL::PP(see Q: 6.16 below), a code generator/parser/pre-processor that generatesPDLfunctions from concise descriptions.
- *
-
None of the existing data languages follow the Perl language
rules, which the authors firmly believe in:
-
- *
-
TIMTOWTDI:There is more than one way to do it. Minimalist languages are interesting for computer scientists, but for users, a little bit of redundancy makes things wildly easier to cope with and allows individual programming styles - just as people speak in different ways. For many people this will undoubtedly be a reason to avoidPDL;)
- *
- Simple things are simple, complicated things possible: Things that are often done should be easy to do in the language, whereas seldom done things shouldn't be too cumbersome.
-
All existing languages violate at least one of these rules.
-
- *
-
As a project for the future PDLshould be able to use super computer features, e.g. vector capabilities/parallel processing,GPGPUacceleration. This will probably be achieved by havingPDL::PP(see Q: 6.16 below) generate appropriate code on such architectures to exploit these features.
- *
- [ fill in your personal 111 favourite reasons here...]
Q: 2.4 What is PDL good for ?
Just in case you do not yet know what the main features of
Through the powerful pre-processor it is also easy to interface Perl to your favorite C routines, more of that further below.
Q: 2.5 What is the connection between PDL and Perl ?
Q: 2.6 What do I need to run PDL on my machine ?
Since To build
If you can (or cannot) get
Q: 2.7 Where do I get it?
Q: 2.8 What do I have to pay to get PDL?
We are delighted to be able to give you the nicest possible
answer on a question like this: Oh, before you think it is *completely* free: you have to invest some time to pull the distribution from the net, compile and install it and (maybe) read the manuals.
GETTING HELP/MORE INFORMATION
Q: 3.1 Where can I get information on PDL?
The complete The easiest way by far, however, to get familiar with
Even better, you can immediately try your newly acquired knowledge about
unix> pdl2 pdl> help < ... help output ... > pdl> help PDL::QuickStart < ... perldoc page ... > pdl> $a = pdl (1,5,7.3,1.0) pdl> $b = sequence float, 4, 4 pdl> help inner < ... help on the 'inner' function ... > pdl> $c = inner $a, $b pdl> p $c [22.6 79.8 137 194.2]
For further sources of information that are accessible through the Internet see next question.
Q: 3.2 Are there other PDL information sources on the Internet?
First of all, for all purely Perl-related questions there are
tons of sources on the net. Good points to start are
<www.perl.com> and <www.perl.org> .
The
- *
-
PDLdistributions
- *
- On-line documentation
- *
-
Pointers to an HTMLarchive of thePDLmailing lists
- *
-
A list of platforms on which PDLhas been successfully tested.
- *
- News about recently added features, ported libraries, etc.
- *
-
Name of the current pumpkin holders for the different PDLmodules (if you want to know what that means you better had a look at the web pages).
If you are interested in
A searchable archive and a hypertext version of the traffic on this list (1997-2004) can be found at <www.xray.mpe.mpg.de/mailing-lists/perldl> . More recent messages (since June 2005) can be found at
If you are interested in all the technical details of the ongoing
A searchable archive and a hypertext version of the traffic on this list (1997-2004) can be found at <www.xray.mpe.mpg.de/mailing-lists/pdl-porters> . More recent messages (since June 2005) can be found at
Cross-posting between these lists should be avoided unless there is a very good reason for doing that.
Q: 3.3 What is the current version of PDL ?
As of this writing (The most current (possibly unstable) version of
Q: 3.4 How can PDL-2.2 be older than PDL-2.007?
Over its development, Q: 3.5 I want to contribute to the further development of PDL. How can I help?
Two ways that you could help almost immediately are (1) participate
in To participate in
If you have a certain project in mind you should check if somebody else is already working on it or if you could benefit from existing modules. Do so by posting your planned project to the
Q: 3.6 I think I have found a bug in the current version of PDL. What shall I do?
First, make sure that the bug/problem you came across has not already been
dealt with somewhere else in this INSTALLATION
Q: 4.1 I have problems installing PDL. What shall I do?
First make sure you have read the file Next, check the file perldl.conf to see if by editing the configuration options in that file you will be able to successfully build
N.B. Unix shell specific: If you would like to save an edited perldl.conf for future builds just copy it as ~/.perldl.conf into your home directory where it will be picked up automatically during the
Also, check for another, pre-existing version of
If you still can't make it work properly please submit a bug report including detailed information on the problems you encountered to the perldl mailing list ( pdl-general@lists.sourceforge.net , see also above). Response is often rapid.
Q: 4.2 Are there configuration files for PDL I have to edit?
Most users should not have to edit any configuration files manually.
However, in some cases you might have to supply some information
about awkwardly placed include files/libraries or you might want
to explicitly disable building some of the optional If you had to manually edit perldl.conf and are happy with the results you can keep the file handy for future reference. Place it in ~/.perldl.conf where it will be picked up automatically or use "perl Makefile.PL PDLCONF=your_file_name" next time you build
Q: 4.3 Do I need other software for successful operation?
For the basicQ: 4.4 How can I install PDL in a non-standard location?
To install Q: 4.5 How can I force a completely clean installation?
To guarantee a completely clean installation ofBINARY DISTRIBUTIONS
Q: 4.5 What binary distributions are available?
Information about binary distributions ofIf someone is interested in providing binary distributions for other architectures, that would be very welcome. Let us know on the pdl-devel@lists.sourceforge.net mailing list. Also check your Linux distribution's package manager as many now include
Q: 4.6 Does PDL run on Linux? (And what about packages?)
Yes, Q: 4.7 Does PDL run under Windows?
CVS, GIT, AND ON-GOING DEVELOPMENT
Q: 4.8 Can I get PDL via CVS?
No. Q: 4.9 How do I get PDL via Git?
Assume you have Git installed on your system and want to download the
project source code into the directory "PDL". To get read-only access
to the repository, you type at the command line
git clone git://git.code.sf.net/p/pdl/code pdl-code
For official
git clone ssh://USERNAME@git.code.sf.net/p/pdl/code pdl-code
Q: 4.10 I had a problem with the Git version, how do I check if someone has submitted a patch?
The Sourceforge system contains a patch-manager which contains patches that have not yet been applied to the distribution. This can be accessed via the Tickets menu atIn addition, if you are not subscribing to the mailing list, check the archive of the "pdl-porters" and "perldl" mailing lists. See Question 3.2 for details.
Q: 4.11 I have gotten developer access to Git, how do I upload my changes?
The first thing you should do is to read the Git documentation and learn the basics about Git. There are many sources available online. But here are the basics:Before you upload your changes, commit them to
git add <file1> <file2> ... git commit
or combine these two with
git commit -a
Then pull in any changes others have made
git pull origin
Test the
Then update the shared repository (at
git push origin master
PDL JARGON
Q: 5.1 What is threading (is PDL a newsreader) ?
Unfortunately, in the context of - *
-
When mentioned in the INSTALLdirections and possibly during the build process we have the usual computer science meaning of multi-threading in mind (useful mainly on multiprocessor machines or clusters)
- *
-
PDLthreading of operations on piddles (as mentioned in the indexing docs) is the iteration of a basic operation over appropriate sub-slices of piddles, e.g. the inner product "inner $a, $b" of a (3) pdl $a and a (3,5,4) pdl $b results in a (5,4) piddle where each value is the result of an inner product of the (3) pdl with a (3) sub-slice of the (3,5,4) piddle. For details check PDL::Indexing
Q: 5.2 What is a piddle?
Well,TECHNICAL QUESTIONS
Q: 6.1 What is perldl? What is pdl2?
Sometimes "perldl" ("pdl2") is used as a synonym forQ: 6.2 How do I get on-line help for PDL?
Just type "help" (shortcut = ``?'') at the "pdl2" shell
prompt and proceed from there. Another useful command
is the "apropos" (shortcut = ``??'') command.
Also try the "demo" command in the "perldl" or "pdl2"
shell if you are new to MANIPULATION OF PIDDLES
Q: 6.3 I want to access the third element of a pdl but $a[2] doesn't work ?!
See answer to the next question why the normal Perl array syntax doesn't work for piddles.Q: 6.4 The docs say piddles are some kind of array. But why doesn't the Perl array syntax work with piddles then ?
I find when using the Perl Data Language it is most useful to think of standard Perl @x variables as "lists" of generic "things" and PDL variables like $x as "arrays" which can be contained in lists or hashes.
So, while piddles can be thought of as some kind of multi-dimensional array they are not arrays in the Perl sense. Rather, from the point of view of Perl they are some special class (which is currently implemented as an opaque pointer to some stuff in memory) and therefore need special functions (or 'methods' if you are using the
Finally, to confuse you completely, you can have Perl arrays of piddles, e.g. $spec[3] can refer to a pdl representing ,e.g, a spectrum, where $spec[3] is the fourth element of the Perl list (or array ;) @spec . This may be confusing but is very useful !
Q: 6.5 How do I concatenate piddles?
Most people will try to form new piddles from old piddles using some variation over the theme: "$a = pdl([$b, 0, 2])" , but this does not work. The way to concatenate piddles is to use the function "cat" (see also "append" and "glue"). Similarly you can split piddles using the command "dog" .Q: 6.6 Sometimes I am getting these strange results when using inplace operations?
This question is related to the "inplace" function. From the documentation (see PDL::QuickStart):
Most functions, e.g. log(), return a result which is a transformation of their argument. This makes for good programming practice. However many operations can be done "in-place" and this may be required when large arrays are in use and memory is at a premium. For these circumstances the operator inplace() is provided which prevents the extra copy and allows the argument to be modified. e.g.: $x = log($array); # $array unaffected log( inplace($bigarray) ); # $bigarray changed in situ
And also from the doc !!:
Obviously when used with some functions which can not be applied in situ (e.g. convolve()) unexpected effects may occur!
Q: 6.7 What is this strange usage of the string concatenation operator .= in PDL scripts?
See next question on assignment in Q: 6.8 Why are there two different kinds of assignment in PDL ?
This is caused by the fact that currently the assignment
operator "=" allows only restricted
overloading. For some purposes of Q: 6.9 How do I set a set of values in a piddle?
In Perl 5.6.7 and higher this assignment can be made using lvalue subroutines:
pdl> $a = sequence(5); p $a [0 1 2 3 4] pdl> $a->slice('1:2') .= pdl([5,6]) pdl> p $a [0 5 6 3 4]
see PDL::Lvalue for more info.
pdl> $a(1:2) .= pdl([5,6]) pdl> p $a [0 5 6 3 4]
With versions of Perl prior to 5.6.7 or when running under the perl debugger this has to be done using a temporary variable:
pdl> $a = sequence(5); p $a [0 1 2 3 4] pdl> $tmp = $a->slice('1:2'); p $tmp; [1 2] pdl> $tmp .= pdl([5, 6]); # Note .= !! pdl> p $a [0 5 6 3 4]
This can also be made into one expression, which is often seen in
pdl> ($tmp = $a->slice('1:2')) .= pdl([5,6]) pdl> p $a [0 5 6 3 4]
Q: 6.10 Can I use a piddle in a conditional expression?
Yes you can, but not in the way you probably tried first. It is not possible to use a piddle directly in a conditional expression since this is usually poorly defined. Instead
pdl> $a=pdl ( 1, -2, 3); pdl> print '$a has at least one element < 0' if (any $a < 0); $a has at least one element < 0 pdl> print '$a is not positive definite' unless (all $a > 0); $a is not positive definite
Q: 6.11 Logical operators and piddles - '||' and '&&' don't work!
It is a common problem that you try to make a mask array or something similar using a construct such as
$mask = which($piddle > 1 && $piddle < 2); # incorrect
This does not work! What you are looking for is the bitwise logical operators '|' and '&' which work on an element-by-element basis. So it is really very simple: Do not use logical operators on multi-element piddles since that really doesn't make sense, instead write the example as:
$mask = which($piddle > 1 & $piddle < 2);
which works correctly.
ADVANCED TOPICS
Q: 6.12 What is a null pdl ?
"null" is a special token for 'empty piddle'. A null pdl can be used to flag to a
sumover $a, $b=null;
which is equivalent to
$b = sumover $a;
If this seems still a bit murky check PDL::Indexing and
Q: 6.13 What is the signature of a PDL function ?
The signature of a function is an important concept in
'a(n); [o] b;'
this says that "maximum" takes two arguments, the first of which is (at least) one-dimensional while the second one is zero-dimensional and an output argument (flagged by the "[o]" qualifier). If the function is called with piddles of higher dimension the function will be repeatedly called with slices of these piddles of appropriate dimension(this is called threading in
For details and further explanations consult PDL::Indexing and
Q: 6.14 How can I subclass (inherit from) piddles?
The short answer is: read PDL::Objects (e.g. type "help PDL::Objects" in the perldl or pdl2 shell).The longer answer (extracted from PDL::Objects ): Since a
package FOO; @FOO::ISA = qw(PDL); sub initialize { my $class = shift; my $self = { creation_time => time(), # necessary extension :-) PDL => PDL->null, # used to store PDL object }; bless $self, $class; }
For another example check the script t/subclass.t in the
Q: 6.15 What on earth is this dataflow stuff ?
Dataflow is an experimental project that you don't need to concern yourself with (it should not interfere with your usual programming). However, if you want to know, have a look at PDL::Dataflow . There are applications which will benefit from this feature (and it is already at work behind the scenes).Q: 6.16 What is PDL::PP?
Simple answer: Slightly longer answer:
For further details check
Q: 6.17 What happens when I have several references to the same PDL object in different variables (cloning, etc?) ?
Piddles behave like Perl references in many respects. So when you say
$a = pdl [0,1,2,3]; $b = $a;
then both $b and $a point to the same object, e.g. then saying
$b++;
will *not* create a copy of the original piddle but just increment in place, of which you can convince yourself by saying
print $a; [1 2 3 4]
This should not be mistaken for dataflow which connects several *different* objects so that data changes are propagated between the so linked piddles (though, under certain circumstances, dataflown piddles can share physically the same data).
It is important to keep the ``reference nature'' of piddles in mind when passing piddles into subroutines. If you modify the input piddles you modify the original argument, not a copy of it. This is different from some other array processing languages but makes for very efficient passing of piddles between subroutines. If you do not want to modify the original argument but rather a copy of it just create a copy explicitly (this example also demonstrates how to properly check for an explicit request to process inplace, assuming your routine can work inplace):
sub myfunc { my $pdl = shift; if ($pdl->is_inplace) { $pdl->set_inplace(0) } else { # modify a copy by default $pdl = $pdl->copy } $pdl->set(0,0); return $pdl; }
MISCELLANEOUS
Q: 6.18 What I/O formats are supported by PDL ?
The current versions of - *
-
A home brew fast raw (binary) I/O format for PDLis implemented by the FastRaw module
- *
-
The FlexRaw module implements generic methods for
the input and output of `raw' data arrays. In particular, it is
designed to read output from FORTRAN 77 UNFORMATTEDfiles and the low-level C "write" function, even if the files are compressed or gzipped.
It is possible that the FastRaw functionality will be included in the FlexRaw module at some time in the future.
- *
-
FITS I/Ois implemented by the "wfits"/"rfits" functions inPDL::IO::FITS.
- *
-
ASCIIfile I/O in various formats can be achieved by using the "rcols" and "rgrep" functions, also in PDL::IO::Misc .
- *
-
PDL::IO::Pic implements an interface to the
NetPBM/PBM+ filters to read/write several popular image formats; also
supported is output of image sequences as MPEGmovies, animated GIFs and a wide variety of other video formats.
- *
-
On CPANyou can find the PDL::NetCDF module that works withPDL 2.007.
For further details consult the more detailed list in the
Q: 6.19 How can I stack a set of 2D arrays (images) into a 3D piddle?
Assuming all arrays are of the same size and in some format recognized by "rpic" (see PDL::IO::Pic ) you could say:
use PDL::IO::Pic; @names = qw/name1.tif .... nameN.tif/; # some file names $dummy = PDL->rpic($names[0]); $cube = PDL->zeroes($dummy->type,$dummy->dims,$#names+1); # make 3D piddle for (0..$#names) { # this is the slice assignment ($tmp = $cube->slice(":,:,($_)")) .= PDL->rpic($names[$_]); }
or
$cube(:,:,($_)) .= PDL->rpic($names[$_]);
for the slice assignment using the new PDL::NiceSlice syntax and Lvalue assignments.
The for loop reads the actual images into a temporary 2D piddle whose values are then assigned (using the overloaded ".=" operator) to the appropriate slices of the 3D piddle $cube .
Q: 6.20 Where are test files for the graphics modules?
This answer applies mainly to PDL::Graphics::TriD (
perl -Mblib Example/TriD/3dtest.pl perl -Mblib Example/TriD/line3d.pl
to try the two TriD test programs. They only exercise one TriD function each but their simplicity makes it easy to debug if needed with the Perl debugger, see perldbug.
The programs in the Demo directory can be run most easily from the "perldl" or "pdl2" interactive shell:
perl -Mblib perldl or perl -Mblib Perldl2/pdl2
followed by "demo 3d" or "demo 3d2" at the prompt. "demo" by itself will give you a list of the available
You can run the test scripts in the Demos/TriD directory manually by changing to that directory and running
perl -Mblib <testfile>
where "testfile" ; should match the pattern "test[3-9].p" and watch the results. Some of the tests should bring up a window where you can control (twiddle) the 3D objects with the mouse. Try using mouse button 1 for turning the objects in 3D space, mouse button 3 to zoom in and out, and 'q' to advance to the next stage of the test.
Q: 6.21 What is TriD or PDL::TriD or PDL::Graphics::TriD?
Questions like this should be a thing of the past with the
un*x> pdl2 pdl> apropos trid
Check the output for promising hits and then try to look up some of them, e.g.
pdl> help PDL::Graphics::TriD
Note that case matters with "help" but not with "apropos" .
Q: 6.22 PGPLOT does not write out PNG files.
There are a few sources of trouble with
C<make: *** No rule to make target `png.h', needed by `pndriv.o'. Stop.>
To fix this, find the line in the 'makefile' that starts with 'pndriv.o:' (it's near the bottom). Change, for example, ./png.h to /usr/include/png.h, if that is where your header files are (you do have the libpng and libz devel packages, don't you?). Do this for all four entries on that line, then go back and run "make".
Second, if you already have the
C<undefined symbol: png_create_write_struct>
This is because the
C<perl Makefile.PL EXLIB=png,z EXDIR=/usr/lib>
assuming that there exist files such as /usr/lib/libpng.so.*, /usr/lib/libz.so.*. Then do the standard "make;make test;make install;" sequence. Now you can write png files from
EXTENSIONS OF PDL
Q: 7.1 I am looking for a package to do XXX in PDL. Where shall I look for it?
The first stop is again "perldl" or "pdl2" and the on-line help
or the
pdl> apropos 'integral' ceil Round to integral values in floating-point format floor Round to integral values in floating-point format intover Project via integral to N-1 dimensions rint Round to integral values in floating-point format
Since the apropos command is no sophisticated search engine make sure that you search on a couple of related topics and use short phrases.
However there is a good chance that what you need is not part of the
Q: 7.2 Can I access my C/FORTRAN library routines in PDL?
Yes, you can, in fact it is very simple for many simple
applications. What you want is the The two functions you need to learn (at least first) are "pp_def" which defines the calling interface to the function, specifying input and output parameters, and contains the code that links to the external library. The other command is "pp_end" which finishes the
double eight_sum(int n) { int i; double sum, x; sum = 0.0; x=0.0; for (i=1; i<=n; i++) { x++; sum += x/((4.0*x*x-1.0)*(4.0*x*x-1.0)); } return 1.0/sum; }
We will here show you an example of how you interface C code with
The C code is shown above and is a simple function returning a double, and expecting an integer - the number of terms in the sum - as input. This function could be defined in a library or, as we do here, as an inline function.
We will postpone the writing of the Makefile till later. First we will construct the ".pd" file. This is the file containing
# # pp_def defines a PDL function. # pp_addhdr ( ' double eight_sum(int n) { int i; double sum, x; sum = 0.0; x=0.0; for (i=1; i<=n; i++) { x++; sum += x/((4.0*x*x-1.0)*(4.0*x*x-1.0)); } return 1.0/sum; } '); pp_def ( 'eight', Pars => 'int a(); double [o]b();', Code => '$b()=eight_sum($a());' ); # Always make sure that you finish your PP declarations with # pp_done pp_done();
A peculiarity with our example is that we have included the entire code with "pp_addhdr" instead of linking it in. This is only for the purposes of example, in a typical application you will use "pp_addhdr" to include header files. Note that the argument to "pp_addhdr" is enclosed in quotes.
What is most important in this example is however the "pp_def" command. The first argument to this is the name of the new function eight , then comes a hash which the real meat:
- *
-
This gives the input parameters (here "a") and the output parameters
(here "b"). The latter are indicated by the "[o]" specifier. Both
arguments can have a type specification as shown here.
Many variations and further flexibility in the interface can be specified. See "perldoc PDL::PP" for details.
- *
-
This switch contains the code that should be
executed. As you can see this is a rather peculiar
mix of C and Perl, but essentially it is just as
you would write it in C, but the variables that
are passed from PDLare treated differently and have to be referred to with a preceding '$'.
There are also simple macros to pass pointers to data and to obtain the values of other Perl quantities, see the manual page for further details.
Finally note the call to "pp_done()" at the end of the file. This is necessary in all
use PDL::Core::Dev; use ExtUtils::MakeMaker; PDL::Core::Dev->import(); $package = ["eight.pd",Eight,PDL::Eight]; %hash = pdlpp_stdargs($package); WriteMakefile( %hash ); sub MY::postamble {pdlpp_postamble($package)};
The code above should go in a file called Makefile.PL, which should subsequently be called in the standard Perl way: "perl Makefile.PL" . This should give you a Makefile and running "make" should compile the module for you and "make install" will install it for you.
Q: 7.3 How can I interface package XXX in PDL?
This question is closely related to the previous one, and as
we said there, the
However it is also possible to interface a package to
The
The following example will show you how to write a simple function that automatically allows threading. To make this concise the example is of an almost trivial function, but the intention is to show the basics of writing a
We will write a simple function that calculates the minimum, maximum and average of a piddle. On my machine the resulting function is 8 times faster than the built-in function "stats" (of course the latter also calculates the median).
Let's jump straight in. Here is the code (from a file called "quickstats.pd" )
# pp_def('quickstats', Pars => 'a(n); [o]avg(); [o]max(); [o]min()', Code => '$GENERIC(a) curmax, curmin; $GENERIC(a) tmp=0; loop(n) %{ tmp += $a(); if (!n || $a() > curmax) { curmax = $a();} if (!n || $a() < curmin) { curmin = $a();} %} $avg() = tmp/$SIZE(n); $max() = curmax; $min() = curmin; ' ); pp_done();
The above might look like a confusing mixture of C and Perl, but behind the peculiar syntax lies a very powerful language. Let us take it line by line.
The first line declares that we are starting the definition of a
The second line is very important as it specifies the input and output parameters of the function. a(n) tells us that there is one input parameter that we will refer to as "a" which is expected to be a vector of length n (likewise matrices, both square and rectangular would be written as "a(n,n)" and "a(n,m)" respectively). To indicate that something is an output parameter we put "[o]" in front of their names, so referring back to the code we see that avg, max and min are three output parameters, all of which are scalar (since they have no dimensional size indicated.
The third line starts the code definition which is essentially pure C but with a couple of convenient functions. $GENERIC is a function that returns the C type of its argument - here the input parameter a. Thus the first two lines of the code section are variable declarations.
The loop(n) construct is a convenience function that loops over the dimension called n in the parameter section. Inside this loop we calculate the cumulative sum of the input vector and keep track of the maximum and minimum values. Finally we assign the resulting values to the output parameters.
Finally we finish our function declaration with "pp_done()" .
To compile our new function we need to create a Makefile, which we will just list since its creation is discussed in an earlier question.
use PDL::Core::Dev; use ExtUtils::MakeMaker; PDL::Core::Dev->import(); $package = ["quickstats.pd",Quickstats,PDL::Quickstats]; %hash = pdlpp_stdargs($package); WriteMakefile( %hash ); sub MY::postamble {pdlpp_postamble($package)};
An example Makefile.PL
Our new statistic function should now compile using the tried and tested Perl way: "perl Makefile.PL; make" .
You should experiment with this function, changing the calculations and input and output parameters. In conjunction with the
BUGS
If you find any inaccuracies in this document (or dis-functional URLs) please report to the perldl mailing list pdl-general@lists.sourceforge.net.ACKNOWLEDGMENTS
Achim Bohnet (ach@mpe.mpg.de ) for suggesting CoolHTML as a prettypodder (although we have switched toCONTRIBUTORS
Many people have contributed or given feedback on the current version of theAUTHOR AND COPYRIGHT
This document emerged from a joint effort of severalPermission is explicitly not granted for distribution in book or any corresponding form. Ask on the