a=SIN(x) s=strmid("******long ****** string ****",18,6) print,alog10(5.e+3) a=tvrd()
print,last+space(5)+firstspace is a function that I defined. It takes one parameter, x, and returns a string containing x spaces.
function SPACE, x s=' ' return,strmid(s,0,x) endAs you can see, it takes the parameter, x, defines a very long string made up of spaces (in the actual code, it is even longer), and returns a substring of it, with length x. If you have any code after the RETURN command, it will not be executed. You can, on the other hand have multiple RETURN commands for different options:
if x gt 5 return,y print,'X is LE 5. Returning z.' return,zIn this example, y is returned and nothing printed if x is greater than 5. Otherwise, it prints a statement and returns z. Only one value can be returned in functions.
result = FUNCTION(Arg1, Arg2, KEYWORD = value)In this example, Arg1 and Arg2 are normal positional parameters, which are called arguments. The position of an argument establishes which variable in the function it corresponds to. KEYWORD is a keyword parameter, which is optional and specifies which variable is corresponds to. When defining a function:
FUNCTION Name,X, Y, KEYWORD = Z, TEST = TIn this definition, Name has two arguments and two keyword parameters. Calling Name(5, 7, TEST = "Gators") would result in X = 5, Y = 7, and T = "Gators" in the function. Z would be undefined since it was not specified. Keyword parameters can also be specified by Name(5,7,/KEYWORD). /KEYWORD is the same as saying KEYWORD = 1, and would result in X=5, Y=7, and Z=1.
.run filenameThis will compile all functions and procedures contained in the file. Functions and procedures MUST be compiled before calling them UNLESS they are in your IDL_PATH (like for instance gatorplot and space should be).
function factor2,x if x MOD 2 eq 1 then return,x return, factor2(x/2) endHere, you can see the base case is if x MOD 2 eq 1. In this case, the number is odd so it is returned. If the number is even though, it returns factor2(x/2), which will now check if (x/2) MOD 2 eq 1 and if not, keep recursively calling itself. Try typing this program in, and checking print, factor2(24) for instance, or several other numbers. This example is well-defined because each time you recurse, you cut x in half and are thus getting significantly closer to the base case. Both functions and procedures support recursion.
plot,x,y,title='Plot',psym=4 strput,s,'Fr.',6You have also seen user-defined procedures:
pro early_return,x,y if x gt 5 then return print,"X is less than 5" y=x*2 endHere, if x is greater than 5, nothing is done to it. Otherwise, a statement is printed and y is set to x*2. Unlike functions, procedures share variables with their caller. When you call a procedure:
early_return,a,ba and b are called actual parameters. For this particular example, b does not have to have been defined previously. When the procedure is executed, a and b are copied to the formal parameters, x and y in the procedures (x=a, y=b). On return or end, the formal parameters are copied back into the actual parameters, erasing any previous values. If you call a procedure with a literal instead of a variable as an actual parameter, there is no error, but no value can be copied back. Here are some examples:
a=6 early_return,a -> a=6 a=6 early_return,a,b -> a=6, b is undefined a=6, b=3 early_return,a,b -> a=6, b=3 early_return,6 -> nothing happens early_return,4 -> "X is less than 5" a=4 early_return,a -> "X is less than 5", a=4 early_return,4,b -> "X is less than 5", b=8 a=4, b=2 early_return,a,b -> "X is less than 5", a=4, b=8 early_return,3,2 -> "X is less than 5"Of course any parameters can be arrays as well as variables for both functions and parameters. For instance to write a procedure to return an array containing every other value in the original array:
pro every_other,x,y n=n_elements(x)/2 y=fltarr(n) for j=0,n-1 do y[j]=x[j*2] endIf you called this with every_other,a,b (and had already defined an array a), then b would end up being half as long as a and contain every other element of a. Note that unline functions, you can't use procedures in print statements. You have to just call the procedure_name,P1,...,Pn.
PRO XYZ, A, B, TEST=T ;define the procedure XYZ,3,X,TEST='Gators' ;call the procedureBoth procedures and functions can be called with fewer arguments than were defined in the procedure or function. Parameters that are not used in the actual parameter list are set to be undefined in the procedure or function. The number of actual parameters can be obtained by the function N_PARAMS():
if N_PARAMS() gt 3 then ...N_ELEMENTS can determine if a variable is defined or not without causing an error. If N_ELEMENTS(X) = 0 then X is undefined. If N_ELEMENTS(X) = 1 then it is a variable, and obviously if more than 1 then it is an array.
PRO plaw, X, A, F, pder F = A*X^A IF N_PARAMS() GE 4 then pder=[[X^A] ,[A*X^A*alog(X)]] END
PRO factor2,X if x MOD 2 eq 1 then return x=x/2 factor2,x endYou can see that for this case, a function would be better. This procedure does the same thing, but when calling it you have to do:
x = 24 factor2,x print,xinstead of just print,factor2(24). Remember, you have to call the procedure with a variable for the value to be returned to that variable. If you call it with a constant, it will still do the factoring, but will be unable to return the final value. Nonetheless, the point remains that recursion works will procedures too, and there are many times when a procedure is a better choice than a function, and recursion is necessary.
% Attempt to subscript A withLook at line 2 and see what is wrong in this case. If you are using functions and procedures, IDL will give you the line in the main program where the function was called in addition to the line in the function where the error occured, so you can track down if it was an error in that specific call (bad paramater maybe) or an error in the function/procedure in general. This is much better than languages like C++ and FORTRAN where you are not always even given a line number. Also note that because those other languages are compiled and not interpreted, you have no way of doing anything at a command line after an error, so you have to just put in a bunch of print statements to check the values of your variables.
is out of range. % Execution halted at: $MAIN$ 2
0 1 0 .5 1 where the middle point in z2 is calculated by 2 3 = 1 1.5 2 averaging all 4 points in the original array that 2 2.5 3 surround it. My procedure is 21 lines long.3. Write a program that prints the factorial of every number from 0 to 10. It should then create a 5x5 array z and read it in from a file. Copy the file ~warner/IDL5220/contour.dat to your directory and read it into z. x and y can both be findgens of length 5. Do a contour plot of z with the /follow keyword set so it labels every other contour. Call your linear interpolation procedure on x,y, and z. Open a second window and do a contour plot of the interpolated (now 9x9) array with the /follow keyword set. Interpolate this to produce a 17x17 array and do another contour plot in another new window. Notice how the contours get smoother the more interpolations you perform. My program is 14 lines long. You may put the function, procedure, and program all in the same file. You just have to put the program last in the file. So after the end statement for the procedure, just start typing your program, and finish that with another end statement. When you type .run name_HW5.pro, it will compile the function and procedure, but only run the program.