[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Lecture 16 Notes



These are the notes for IDL Part I

-- 
Title: Math 481/581 Lecture 16: IDL Basics

Math 481/581 Lecture 16: IDL Basics

© 1998 by Mark Hays <hays@math.arizona.edu>. All rights reserved.


This document discusses the basics of IDL, the Interactive Data analysis Language.


Introduction

IDL is a (commercial) program that allows you to plot, process, and otherwise manipulate data. It is similar to matlab in many respects and can, in fact, be made to do just about anything that matlab can do. IDL is ideally suited for image and signal processing --- this reflects its roots in the geology and astronomy communities.

One nice thing about IDL is that you can download a "demo" version of it. In demo mode, there are a couple of limitations:

For most people, this is not a big deal. In fact, many people have used IDL exclusively to produce the figures for their dissertations. As long as you can generate a figure in 7 minutes, you're all set.

If the 7 minute thing gives you pause, you can also purchase the student version of IDL. It costs about $100 and provides all of the normal IDL features. The student version imposes the limit that no array can contain more than 65536 elements.

The full-blown-no-limitations-version costs around $1000 for a single PC node locked license.

Versions

As of this writing (20 Oct 1998), the latest version of IDL is 5.1.1. IDL 4.x and 5.0 are also commonly in use.

Supported Platforms

IDL 5.1.1 runs on the following platforms:

PlatformVendorHardware Operating
System
Supported
Versions
VMSDECAlpha AXPVMS6.2
UnixDECAlpha AXPDigital UNIX4.0
 HPPa RiscHP-UX10.1
 IBMRS/6000AIX4.1
 IntelIntel x86Linux2.0
 SGIR4000 and upIrix5.3/6.2
 SUNSparcSolaris 14.1.3
 SUNSparcSolaris 22.5
 SUNUltra 1 / 2Solaris 22.5
 SUNIntel x86Solaris 22.5
WindowsIntelIntel x86Windows 95 
 IntelIntel x86Windows NT4.0
 DECAlpha AXPWindows NT4.0
MacintoshAppleMotorola
Power PC
MacOS7.1.2

Note that IDL does not run on M68k-series based macs. IDL does not run under Windows 3.x, either.

IDL Home Page

The IDL home page is at:

http://www.rsinc.com

This site contains links to all sorts of useful IDL information.

IDL FTP Sites

You can FTP IDL binaries from the following sites: In general, the boulder.colorado.edu is faster than RSI's site.


Getting Started

Like maple and mathematica, IDL includes both terminal-based and gui-based interfaces. In what follows, we'll focus on the terminal-based version for clarity.

To start IDL on a UNIX system, simply type "idl" at your shell prompt. The following shows you what happens when IDL starts up in demo mode:

  > idl
  IDL Version 5.1 (linux x86). Research Systems, Inc.
  % Unable to open validation file: /usr/local/apps/idl/idl.genver.
    No such file or directory
  % Entering timed demo mode for IDL. Each session is limited to 7 minutes
    of operation. Printing and file saving is disabled.
  
    Contact your sales representative or Research Systems
    (303-786-9900, info@rsinc.com) if you are interested in
    evaluating a fully-functional version of this product.

  For basic information, enter "IDLInfo" at the IDL> prompt.

  IDL>
When you see the "IDL>" prompt, you can issue IDL commands for immediate execution.

To quit IDL, type "exit" at the IDL prompt.

There are two ways to get online help in IDL. First, you can type "?" at the IDL prompt. The problem with this method is that the help GUI dies after 7 minutes in demo mode, which can be annoying. To get a permanent help window, you can start the help GUI by itself before you start IDL:

  > idlhelp &
  > idl
  [... chatter ...]
  IDL>
The help available from the help GUI is very comprehensive; in fact, it contains everything that the full set of hardcopy documentation contains (RSI charges $$$ for printed manuals, these days). It is very nice of RSI to provide such comprehensive documentation (as well as a demo version of their product) for free.

NOTE: You must be in X-windows to get online help in the UNIX version of IDL.

Now that we know how to get it and out of IDL, let's see what it can do.


The Basics

Like matlab, IDL is an array based language. Unlike matlab, IDL supports several underlying data types, including: Having all of these different types allows you to optimize your memory usage; it also gives you a lot of flexibility when importing various binary data from external files.

There are special IDL functions to create arrays of each type. Each of them has the form:

  dst = xxxARR(D_1, ... , D_n)
where "xxx" is one of Up to eight dimensions can be specified. You can also create arrays in which each element is set to its index in the array by using the "indgen" family of functions:
  dst = yyyINDGEN(D_1, ..., D_n)
where "yyy" is one of This is similar to the matlab 0:n notation. Note that IDL arrays start at index 0. Also, IDL is not case sensitive.

IDL's syntax is not as clean as matlab's. This is partially due to the fact that IDL was originally coded in FORTRAN and developed by people who used FORTRAN. If you know FORTRAN, you'll recognize the tell-tale signs of crustiness in IDL.

IDL has two kinds of predefined subprogram entities: functions and procedures. In general, functions take some arguments and return a value (which can be any valid IDL object). Functions do not typically modify their arguments. IDL procedures do not return a value and they often modify their arguments (just like FORTRAN).

The "xxxARR" and "yyyINDGEN" functions that we met eariler are examples of IDL functions. One example of an IDL procedure is PRINT. It is used as follows:

  IDL> print, 3.14159
      3.14159
  IDL> print, findgen(3,2)
      0.00000      1.00000      2.00000
      3.00000      4.00000      5.00000
To summarize, functions take their arguments in parentheses and return a useful value. Procedures take their arguments as a comma separated list and do not return a value. There is a comma between the procedure name and the first argument.

IDL does not directly provide the matlab low:delta:high syntax. To do something like x = -2:.2:2, use this:

  x = 0.2*findgen(21) - 2

Many IDL procedures and functions also take optional keywords. For example, you can set the title of a plot like so:

  IDL> plot, x, sin(x), title='Sine Function'
  IDL>
Some keywords are boolean. Rather than using "keyword=1", you can use the shorthand "/keyword":
  IDL> plot, rdata, thetadata, /polar
  IDL>


Arrays and Array Operations

Building IDL arrays "by hand" is easy: you simply use square brackets:
  IDL> a = [1, 2, 3]
  IDL> print, a
         1       2       3
  IDL> b = [[1, 2], [3, 4]]
  IDL> print, cond(b)
  % Compiled module: NORM.
        21.0000
This example illustrates two things: first, it illustrates how to get the condition number of a matrix using the COND function. Second, it illustrates the fact that many builtin IDL routines are written in the IDL language and are loaded on demand -- in this case, the NORM routine was automagically loaded from an external file.

Array operations are handled in a natural way:

  IDL> a = [1,2,3]
  IDL> print, a + 1
         2       3       4
  IDL> print, a ^ 2
         1       4       9
  IDL> print, exp(a)
        2.71828      7.38906      20.0855

Matrix-matrix and matrix-vector multiplication are performed with the special "##" operator:

  IDL> a = [[1, 2], [3, 4]]
  IDL> x = [1, 1]
  IDL> print, a ## a
             7          10
            15          22
  IDL> print, a ## x
             3
             7
IDL forces you to choose how to solve linear systems (a number of methods are available). To solve Ax=[3,7], you'd do something like:
  IDL> b = [3, 7]
  IDL> ludc, a, perm
  IDL> print, lusol(a, perm, b)
        1.00000      1.00000
The perm argument is filled in by the LUDC procedure -- it contains the permutation matrix used for pivoting during the LU decomposition. This information is used during the back-substitution that occurs in LUSOL.

IDL can also perform singular value decompositions, Cholesky decompositions, Gauss-Seidel iterations, and solve triangular systems (using the highly optimized algorithm that is available for this case).

IDL uses routines derived from Numerical Recipes for many of its linear algebra operations. The routines that are used to compute eigenvalues and eigenvectors fall into this category.

The bad thing about IDL's linear algebra is that you cannot simply use A\b to solve "Ax = b". The good thing about it is that you have complete control over the algorithms used in the numerical solution -- because you have to specify precisely what you want to do.

Like matlab, IDL provides a syntax for slicing arrays:

Vector[i]ith element of vector
Array[i,j]Element at ith column and jth row
Vector[i:j]Elements i through j
Vector[i:*]Elements i through end of vector
Array[i,*]ith column of array
Array[i:j,m:n]Subarray consisting of columns i through j and rows m through n
Array[Array2]Convert Array2 to integer and interpret the result as a list of indices into Array
(Array_Expression)[i]ith element of expression

Multidimensional IDL arrays can be accessed in two ways. First, you can subscript them by using a list of dimensions (just like you'd think). You can also access them as "flat" one dimensional arrays, where the order of elements is row-major. This is extremely useful in conjuntion with IDL's WHERE function:

  IDL> a = [[1, -1], [4, -3]]
  IDL> print,a[0],a[1],a[2],a[3]
         1      -1       4      -3
  IDL> indices = where(a lt 0)
  IDL> print, indices
             1           3
  IDL> print, a[indices]
        -1      -3
  IDL> a[indices] = 0
  IDL> print, a
         1       0
         4       0
Normally, IDL does automatic type coercion of subexpressions. In other words, if one argument is an integer and the other argument is complex, the integer will be converted to a complex number and the result will be complex. Sometimes you will need to coerce things by hand. IDL provides the following explicit coercion functions:


Flow Control

IDL provides the usual flow control statements. In order to minimize programmer errors, I will present them in "full form" -- many of them support a terse "one liner" form but I recommend that you always go with the longer format.

Here is the for loop:

  FOR variable = expr1,expr2,incr DO BEGIN
    statements
  ENDFOR
The increment is optional and defaults to one.

The while loop works just like you'd think:

  WHILE expr DO BEGIN
    statements
  ENDWHILE

There is also a loop that performs the test at the bottom:

  REPEAT BEGIN
    statements
  ENDREP UNTIL expr

The "if" statement looks like:

  IF expr THEN BEGIN
    statements
  ENDIF ELSE BEGIN
    statements
  ENDELSE
There is no "elseif" in IDL -- to achieve this, you'll need to nest your if's.

Testing an N-way decision is so common that IDL provides a CASE statement:

  CASE expr OF
    expr1: statement
    expr2: statement
    ...
  ELSE: statement
  ENDCASE
If "statement" actually consists of multiple statements, you'll need to enclose the statements in a BEGIN...END block.

IDL provides the following boolean operators for use in expressions:

You can use parentheses to make them group the way you want. There are also several relational operators:

In general, you should avoid writing loops as much as possible. Instead, you should favor the highly optimized vector operations that IDL provides. For example, this code:

  a = fltarr(30)
  for i=0,29 do begin
    a[i] = sqrt(i + 1)
  endfor
is many orders of magnitude slower than the following:
  a = sqrt(findgen(30) + 1)
In fact, the "findgen" version is almost as fast as if you'd coded the thing in C or FORTRAN.

IDL lets you define your own procedures as follows:

  PRO proc_name, arg1, arg2, ..., argn
    statements
  END
for example:
  PRO add_three, obj1, obj2, obj3, result
    result = obj1 + obj2 + obj3
  END
You'd use it like this:
  IDL> ADD_THREE, 1, 3, 5, r
  IDL> PRINT, r
            9
  IDL>

You can also define your own functions:

  FUNCTION func_name, arg1, arg2, ..., argn
    statements
    RETURN, expr
  END
For example:
  FUNCTION add_three, obj1, obj2, obj3
    res = obj1+obj2+obj3
    RETURN, res
  END
You'd use it like this:
  IDL> print, add_three(1,3,5)
            9
  IDL>


Putting Programs into Files

In order to maximize confusion, IDL has two different input modes: the one in which you interactively type commands in response to the IDL prompt, and one in which IDL commands are read from a file.

When you provide input to the IDL prompt, a number of special commands are available. Also, each command you type must fit on a single line (so you cannot enter a long FOR loop, for example).

When IDL is reading commands from a file, you cannot use the special "executive" commands, but you can do things like enter multi-line loops, etc.

If you want to put a bunch of IDL commands into a file, simply open edit the file with your favorite editor. For reasons to be explained below, you should use a filename extension of .pro for all files containing IDL code.

Files containing IDL code consist of three sections:

In IDL, comments extend from a ";" character to the end of the current line.

Procedure and function definitions must be the first executable statements in the file, if such definitions are present.

The main section consists of a series of IDL statments. This list must terminate with the word "END".

Here is what such a file might look like:

; sample IDL program file
;

FUNCTION fadd3, obj1, obj2, obj3
  RETURN, obj1 + obj2 + obj3
END

PRO padd3, obj1, obj2, obj3, res
  res = obj1 + obj2 + obj3
END

PRINT, fadd3(1,2,3)

END
To load this file into IDL and execute it, type the following at the IDL prompt (assuming that the file is called exmpl.pro and exists in your CWD):
  IDL> .run exmpl
  % Compiled module: FADD.
  % Compiled module: PADD.
  % Compiled module: $MAIN$.
         3
         3
If there is a problem with your file (or if some piece of code make IDL croak in general), IDL will emit an error message and re-issue the prompt. The thing to remember is that all variables will usually be relative to the stack frame in which the error occurred. If you don't understand this, don't worry about it: just remember to type RETALL to unwind all the nested stack frames before typing your next IDL command.

A good way to program IDL procedures and functions is to put each one in a separate file whose name is composed of the procedure or function name and the .pro suffix. If you do this, you do not have to explicitly do a .run to load the code into IDL; instead, you can simply reference the procedure or function and IDL will load it for you.

However, IDL will only do this once. If you are editing the code for a function you've defined, you'll have to do an explicit .run to force IDL to reload your code.