=head1 NAME

PDL::Course - A journey through PDL's documentation, from beginner to advanced.

=head1 AUTHOR, DATE

This is written by David Mertens with edits by Daniel Carrera.

=head1 Preface

PDL's documentation is extensive. Some sections cover deep core magic
while others cover more usual topics like IO and numerical computation.
How are these related? Where should you begin?

This document is an attempt to pull all the key PDL documentation
together in a coherent study course, starting from the beginner level,
up to the expert.

I've broken down everything by level of expertise, and within expertise
I've covered documentation, library, and workflow modules. The
documentation modules are useful for what they tell you; the library
modules are useful for the functions that they define for you; the
workflow modules are useful for the way that they allow you to get your
work done in new and different ways.

=head1 Introductory

If you are new to PDL, these documentation modules will get
you started down the right path for using PDL.

=head2 Documentation

Modules that tell you how to start using PDL.  Many of these
are library modules technically, but they are included when
you C<use PDL>, so I've included them for their documentation.

After the first three, most of the docs listed below are rather
dry. Perhaps they would be better summarized by tables or better
synopses. You should at least scan through them to
familiarize yourself with the basic capabilities of PDL.

=over

=item * L<PDL::Philosophy>, L<PDL::QuickStart>

A couple of brief introductions to PDL. The second one is a bit more
hands-on. If you are new to PDL, you should start with these.

=item * L<PDL::Basic>

Covers basic ndarray-creation routines like C<sequence>,
C<rvals>, and C<logxvals> to name a random few.  Also covers
C<hist> and C<transpose>.

=item * L<PDL::Ufunc>

Explains a large collection of built-in functions which, given an
N-dimension ndarray, will create an ndarray with N-1 dimensions.

=item * L<PDL::NiceSlice>

PDL came of age right around the turn of the millennium and
NiceSlice came on the scene slightly after that.  Some of
the docs still haven't caught up.  NiceSlice is the 'modern'
way to slice and dice your ndarrays.  Read the Synopsis, then
scroll down to The New Slicing Syntax.  After you've read to
the bottom, return to and read the stuff at the top.

=item * L<PDL::Primitive>

Defines a whole slew of useful built-in functions.  These
are the sorts of things that beginners are likely to write to
the list and say, "How do I do xxx?"  You would be well
on your way to learning the ropes after you've gotten through
this document.

=item * Selections from L<PDL::Core>

Like PDL::Primitive, defines a large set of useful functions.
Unfortunately, some of the functions are quite esoteric, but
are mixed in with the rest of the simple and easy ones.  Skim
the whole document, skipping over the complicated functions
for now.  I would point out in particular the function
C<approx>.

=back

=head2 Workflow

=over

=item * The L<perldl> or L<pdl2|PDL::Perldl2> Shell

The Perldl Shell is a REPL (Read-Evaluate-Print-Loop, in other words,
a prompt or shell) that allows you to work with PDL (or any Perl, for
that matter) in 'real time', loading data from files, plotting,
manipulating... Anything you can do in a script, you can do in the PDL
Shell, with instant feedback!

=back

=head2 Libraries

=over

=item * L<PDL>

The main workhorse module. You'll include this in nearly every PDL
program you write.

=back

=head1 Normal Usage

The sorts of modules that you'll likely use on a normal basis in scripts
or from within the perldl shell.  Some of these modules you may never
use, but you should still be aware that they exist, just in case you
need their functionality.

=head2 Documentation

=over

=item * L<PDL::Slices>

In addition to explaining the original slicing and dicing functions -
for which you can usually use L<PDL::NiceSlice> - this also covers
many dimension-handling functions such as C<mv>, C<xchg>, and
C<reorder>.  This also thoroughly documents the C<range> function, which
can be very powerful, and covers a number of internal functions, which
can probably be skipped.

=item * L<PDL::Indexing>

This covers a lot of the deeper conceptual ground that you'll
need to grasp to really use PDL to its full potential.  It gets
more complex as you go along, so don't be troubled if you find
yourself loosing interest half way through.  However, reading
this document all the way through will bring you much closer to
PDL enlightenment.

=item * L<PDL::IO>

PDL has quite a few IO modules, most of which are discussed
in this summary module.

=item * L<PDL::Tips>

A collection of some of Tuomas's ideas for making good use of PDL.

=item * L<PDL::BadValues>

Explains what bad values are and how and why they are implemented.

=item * Selections from L<Inline::Pdlpp>

Although writing PDL::PP code is considered an Advanced topic, and is
covered in the next section, you should be aware that it is possible 
(and surprisingly simple) to write PDL-aware code.  You needn't read
the whole thing at this point, but to get some feel for how it works,
you should read everything up through the first example.  A copy of this
documentation is contained in L<PDL::PP-Inline>.

=item * L<PDL::Objects>

Explains how to subclass an ndarray object.

=item * L<PDL::Index>

This was discussed in the Preface. It is an automatically generated
file that lists all of the PDL modules on your computer. There are many
modules that may be on your machine but which are not documented here,
such as bindings to the FFTW library, or GSL. Give it a read!

=back

=head2 Libraries

=over

=item * L<PDL::FFT>

PDL's own Fast Fourier Transform.  If you have FFTW, then you
should probably make use of it; this is PDL's internal
implementation and should always be available.

=item * GSL

PDL does not have bindings for every sub-library in the GNU Scientific
Library, but it has quite a few. If you have GSL installed on your
machine then chances are decent that your PDL has the GSL bindings.
For a full list of the GSL bindings, check L<PDL::Index>.

=item * L<PDL::Func>

A somewhat uniform interface to the different interpolation modules in PDL.

=item * L<PDL::Bad>

Includes some basic bad-value functionality, including functions
to query if an ndarray has bad values (C<isbad>) and functions to
set certain elements as bad (C<setbadat> and C<setbadif>).  Among
other places, bad values are used in L<PDL::Graphics::PLplot>'s
xyplot to make a gap in a line plot.

=item * L<PDL::DiskCache>

A cool module that allows you to tie a Perl array to a collection of
files on your disk, which will be loaded into and out of memory as
ndarrays. If you find yourself writing scripts to process many data files,
especially if that data processing is not necessarily in sequential
order, you should consider using PDL::DiskCache.

=item * L<PDL::Char>

A PDL subclass that allows you to store and manipulate collections
of fixed-length character strings using PDL.

=item * L<PDL::Image2D>

A whole collection of methods for manipulating images whose image data
are stored in an ndarray.  These include methods for convolutions
(smoothing), polygon fills, scaling, rotation, and warping, among
others.

=item * L<PDL::ImageND>

Contains a few functions that are conceptually related to image
processing, but which can be defined for higher-dimensional data.  For
examples this module defines high-dimensional convolution and
interpolation, among others.

=item * L<PDL::ImageRGB>

Defines some useful functions for working with RBG image data.  It's
not very feature-full, but it may have something you need, and if not,
you can always add more!

=item * L<PDL::Transform>

Creates the transform class, which allows you to create various
coordinate transforms.  For example, if you data is a collection of
Cartesian coordinates, you could create a transform object to convert
them to Spherical-Polar coordinates (although many such standard
coordinate transformations are predefined for you, in this case it's
called C<t_spherical>).

=item * L<PDL::Opt::Simplex>

This package states that it "implements the commonly used simplex
optimization algorithm." I'm going to assume that if you need this
algorithm then you already know what it is.

=item * L<PDL::Math>

A collection of fairly standard math functions, like the inverse 
trigonometric functions, hyperbolic functions and their inverses, and
others.  This module is included in the standard call to C<use PDL>, but
not in the Lite versions.

=item * L<PDL::Matrix>

Provides a few functions that use the standard mathematical Matrix
notation of row-column indexing rather than the PDL-standard column-row.
It appears that this module has not been heavily tested with other
modules, so although it should work with other modules, don't be
surprised if something breaks when you use it (and feel free to offer
any fixes that you may develop).

=item * L<PDL::MatrixOps>

Provides many standard matrix operations for ndarrays, such as computing
eigenvalues, inverting square matrices, LU-decomposition, and solving
a system of linear equations.  Though it is not built on L<PDL::Matrix>,
it should generally work with that module.  Also, the methods
provided by this module do not depend on external libraries such as
Slatec or GSL.

=item * L<PDL::Reduce>

Implements an interface to all the functions that return ndarrays with
one less dimension (for example, C<sumover>), such that they can be
called by supplying their name, as a string.

=back

=head2 Workflow

=over

=item * L<PDL::AutoLoader>

Enables Matlab-style autoloading.  When you call an unknown
function, instead of complaining and croaking, PDL will go hunt
around in the directories you specify in search of a like-named
file.  Particularly useful when used with the Perldl Shell.

=item * L<PDL::Dbg>

Declares the C<px> function, which can be handy for debugging your
PDL scripts and/or perldl shell commands.

=item * L<PDL::Options>

Suppose you define a powerful, versatile function.  Chances are good
that you'll accept the arguments in the form of a hash or hashref.  Now
you face the problem of processing that hashref.  L<PDL::Options>
assists you in writing code to process those options.  (You'd think
Perl would have tons of these sorts of modules lying around, but I
couldn't find any.)  Note this module does not depend on PDL for its
usage or installation.

=item * L<PDL::pdldoc>

Ever fired-up the perldl shell just to look up the help for a particular
function?  You can use C<pdldoc> instead.  This shell script extracts
information from the help index without needing to start the perldl
shell.

=back

=head1 Advanced Usage

The sorts of modules and documentation that you'll use if you write
modules that use PDL, or if you work on PDL maintenance.  These modules
can be difficult to use, but enable you to tackle some of your harder
problems.

=over

=item * L<PDL::Lite>, L<PDL::LiteF>

Lite-weight replacements for C<use PDL>, from the standpoint of
namespace pollution and load time.

=item * L<Inline::Pdlpp>

This was mentioned earlier.  Before you begin reading about L<PDL::PP>
(next), you should remind yourself about how to use this.
L<Inline::Pdlpp> will help you experiment with L<PDL::PP> without having
to go through the trouble of building a module and constructing
makefiles (but see L<PDL::pptemplate> for help on that).

=item * L<PDL::PP>

The PDL Pre-Processor, which vastly simplifies making you
C or Fortran code play with Perl and ndarrays.  Most of PDL's
basic functionality is written using PDL::PP, so if you're
thinking about how you might integrate some numerical
library written in C, look no further.

=item * L<PDL::pptemplate>

A script that automates the creation of modules that use L<PDL::PP>,
which should make your life as a module author a bit simpler.

=item * L<PDL::CallExt>

Allows you to call functions using external shared
libraries.  This is an alternative to using L<PDL::PP>.
The major difference between PDL::PP and PDL::CallExt is
that the former will handle threading over implicit thread
dimensions for you, whereas PDL::CallExt simply calls an
external function.  PDL::PP is generally the recommended
way to interface your code with PDL, but it wouldn't be Perl
if there wasn't another way to do it.

=item * PDL::Config

Defines the C<%PDL::Config> hash, which has lots of useful
information pertinent to your PDL build.

=item * L<PDL::Doc>

Explanation of the PDL documentation conventions, and an
interface to the PDL Documentation parser.  Following these
guidelines when writing documentation for PDL functions will
ensure that your wonderful documentation is accessible from
the perldl shell and from calls to C<barf>.  (Did you notice
that C<barf> used your documentation?  Time to reread
L<PDL::Core>...)

=item * L<PDL::Exporter>

A simple replacement for the standard L<Exporter> module.
The only major difference is that the default imported modules
are those marked ':Func'.

=item * L<PDL::Types>

Defines some useful functions for getting an ndarray's type, as well as
getting information about that type.

=back

=head1 Expert Usage

=over

=item * L<PDL::Core::Dev>

Provides some decently useful functions that are pretty
much only needed by the PDL Porters.

=item * L<PDL::API>

Explains how to make an ndarray I<by hand>, from Perl or your
C source code, using the PDL API.

=item * L<PDL::Internals>

Explains the nitty-gritty of the PDL data structures.  After reading
this (a few times :), you should be able to create an ndarray completely
from scratch (i.e. without using the PDL API).  Put a little
differently, if you want to understand how PDL::PP works, you'll need
to read this.

=back

=begin questionable

=head1 Other Documents

These documents are part of the PDL distribution but don't
seem to fit anywhere above.

=over

=item * L<PDL::Delta>

Explains how things changed from PDL 1.x to PDL 2.x

=item * L<PDL::Graphics2D>

Supposed to be a uniform interface to plotting 2D graphics.

=item * L<PDL::Dataflow>

Covers data flow, a cool feature to be sure, but from what I can tell
it is not currently supported.

=item * L<PDL::Lvalues>

PDL started before Perl 5.6, which introduce subs that could return
lvalues. I'm pretty sure that this module has been rolled into the core
and is no longer necessary.


=item * L<PDL::Tests>

Defines a few PDL::PP tests.  This code should be moved into the testing
suite, but hasn't been...

=item * L<PDL::Ops>

Defines the standard Perl-overloadable operators, like + and .=, for
example.  Since pretty much all of these operators and functions are
discussed elsewhere, there's usually no need to read this documentation
or use this module.

=item * L<PDL::Gaussian>

An apparently broken module to help generate and work with Gaussian
distributions.

=back

=end questionable


=head1 COPYRIGHT

Copyright 2010 David Mertens (dcmertens.perl@gmail.com). You can
distribute and/or modify this document under the same terms as the
current Perl license.

See: http://dev.perl.org/licenses/

