;---------------------------------------------------------------------------- ; $Id: lambda_log_disp.pro,v 1.6 2002/05/28 22:41:40 johnny Exp johnny $ ;+ ; NAME: ; LAMBDA_LOG_DISP ; ; PURPOSE: ; Calculate the time-dependent exponent and logarithmic displacement ; curves, as defined by Gao (1997), by calling a Fortran 90 sub-program ; lambda_log_disp using SPAWN. ; ; CATEGORY: ; Statistics. ; ; CALLING SEQUENCE: ; Result = LAMBDA_LOG_DISP(in_x, in_k, in_m, in_L, in_ie_value) ; ; INPUTS: ; in_x: Input scalar timeseries. Floating vector of N ; elements. Unchanged by routine. ; ; in_k: Evolution times at which to calculate time-depen- ; dent exponent and displacement curves. Integer ; vector of NK elements of equally spaced values of k, ; starting with 1. Unchanged by routine. ; ; in_m: Embedding dimension. Scalar integer. Unchanged by ; routine. ; ; in_L: Delay time. Scalar integer. Unchanged by routine. ; ; in_ie_value: Ruler initialization. This variable defines shells ; used in calculations and output in out_shells; each ; shell is defined as the interval: ; ( 2**[-(i+1)/2], 2**[-i/2] ) ; where i is an integer from ie_value to ie_value+8. ; Scalar integer. Unchanged by routine. ; ; KEYWORD PARAMETERS: ; F90_EXE: If defined, gives the directory path and executable ; name for the Fortran 90 program to be run. If not ; defined, the default is './lambda_log_disp_wrap'. ; String scalar. Unchanged by routine. ; ; LOG_DISP: If keyword set to a variable, the matrix of ; logarithmic displacement curves is returned as ; the variable. Each row is the logarithmic ; displacement at each evolution time k, for shells ; given by the shell interval (see Shells). Floating ; array dimensioned (NK,9). Created by routine. ; ; NORMALIZE_INPUT: If keyword set true, before using the input time- ; series in_x, the function normalizes it by: ; (in_x - min)/(max - min), where min and max are ; the maximum and minimum of in_x, respectively ; (i.e. normalize to unit interval [0,1]). Variable ; unchanged by routine. ; ; NPTS: If set to a variable, the variable returns the ; number of point pairs used for the ensemble aver- ; aging in each shell at each evolution time k, for ; shells given by the shell interval (see Shells). ; Long integer array dimensioned (NK,9). Created by ; routine. ; ; SHELLS: If set to a variable, the variable returns the ; shell upper boundaries for each row in Result and ; out_log_disp. The bounds for each i row in those ; output variables is the interval: ; ( out_shells(i+1), out_shells(i) ). ; The final row (i=9-1) corresponds to the interval: ; ( 0, out_shells(9-1) ) ; which is a "shell" that is actually a "ball." ; Floating array dimensioned (9). Created by ; routine. ; ; TAN_MOTION_LIM: If this is set to a variable, the criteria to ; remove tangential motion effects (i.e. ABS(i-j) ; must be greater than a value to be considered for ; calculations) is set to this keyword. If the ; keyword is undefined, the default value found in ; the f90 program called by this procedure is used ; (see the f90 LAMBDA_LOG_DISP routine in-code ; documentation). Variable unchanged by routine. ; ; OUTPUTS: ; Result: Time-dependent exponent (lambda). Each row is an ; NK-element vector giving the lambda at each evol- ; ution time, for shells given by the shell interval ; (see Shells). Floating array dimensioned (NK,9). ; Created by routine. ; ; FILE DEVICE I/O: ; Read/write to/from stdin/stdout. ; ; COMMON BLOCKS: ; None. ; ; EXAMPLE: ; None. ; ; MODIFICATION HISTORY: ; - 27 May 2002: Orig. ver. Johnny Lin, CIRES/University of Colorado. ; Email: air_jlin@yahoo.com. Passed minimally passably adequate tests. ; ; NOTES: ; - Written for IDL 5.5. ; - All keyword parameters are optional unless otherwise stated. ; - No procedures called with _Extra keyword invoked. ; - Fortran 90 executable defined by F90_Exe is called; no other user- ; written procedures are called. ; - See the in-code documentation and notes for the Fortran 90 routine ; LAMBDA_LOG_DISP for details on choosing parameters etc. The code and ; documentation are online at: http://www.johnny-lin.com/flib.html#lld. ; - There were some problems with IDL reading the array F90 write(*,*) ; statements if the writing was using an implicit do loop, so for all ; the read/writes to/from stdin/stdout, I use an explicit single element ; read/write, and equivalent IDL read/write on that single element. Note ; for the IDL read, this requires READF reads into a single string scalar ; variable, then moves the value into the array space. ; - Because this uses the SPAWN stdin/stdout pipe interface, numeric input ; and output will be truncated to the default formatting settings of ; stdin/stdout. ;- ; Copyright (c) 2002 Johnny Lin. For licensing, distribution conditions, ; and contact information, see http://www.johnny-lin.com/lib.html. ;---------------------------------------------------------------------------- FUNCTION LAMBDA_LOG_DISP, in_x, in_k, in_m, in_L, in_ie_value $ , F90_EXE = in_f90_exe $ , LOG_DISP = out_log_disp $ , NPTS = out_npts $ , SHELLS = out_shells $ , TAN_MOTION_LIM = in_tan_motion_lim $ , NORMALIZE_INPUT = normalize_input $ , _EXTRA = extra ; -------------------- Error Check and Parameter Setting -------------------- ; ; Selected variable key: x0, k, m, L, ie_value correspond to the same ; dummy arguments in the f90 subprogram LAMBDA_LOG_DISP. COMPILE_OPT IDL2 ON_ERROR, 0 x = in_x ;- protect input variables k = in_k m = in_m L = in_L ie_value = in_ie_value if (!VERSION.OS_FAMILY ne 'unix') then $ ;- check that the calling MESSAGE, 'error--must be unix' ; ver. of IDL is unix if (N_ELEMENTS(in_f90_exe) gt 0) then begin ;- set f90 executable path f90_exe = in_f90_exe ; and name endif else begin f90_exe = './lambda_log_disp_wrap' endelse if (N_ELEMENTS(in_tan_motion_lim) gt 0) then begin ;- set test to remove tan_motion_lim = in_tan_motion_lim ; tangential motion endif else begin ; effects tan_motion_lim = -1 endelse if (KEYWORD_SET(normalize_input) eq 1) then begin ;- set parameter to normalize_input0 = 1 ; determine whether endif else begin ; to normalize input normalize_input0 = 0 endelse if ( ((MAX(x) gt 1.0) or (MIN(x) lt 0.0)) and $ ;- check whether the (KEYWORD_SET(normalize_input) ne 1) ) then begin ; normalization key- MESSAGE, 'error--bad x range re normalization' ; word sld. be set endif NK = N_ELEMENTS(k) ;- number of evolution times N = N_ELEMENTS(x) ;- number of elements in scalar input time series if ((SIZE(k, /Type) ne 2) and (SIZE(k, /Type) ne 3)) then $ MESSAGE, 'error--bad k' ; ------------------- Create Arrays To Read In From Stdout ------------------ ; ; Stdout reads in as a string variable. Later on these variables will be ; converted back to the output type of this procedure. The variable tmp ; is used to read the diagnostic messages that are printed automatically ; by LAMBDA_LOG_DISP. out_lambda = STRARR(NK,9) ;- lambda values out_log_disp = STRARR(NK,9) ;- logarithmic displacement values out_npts = STRARR(NK,9) ;- number of points in shells out_shells = STRARR(9) ;- shell limits tmp = '' ;- temporary string ; --------------------------- Execute f90 Program --------------------------- SPAWN, [f90_exe] $ ;- run f90 program, est. pipe , Unit=iunit $ , /Sh PRINTF, iunit, N ;- send num pts in x vector to f90 prog. for i=0,N-1 do PRINTF, iunit, x[i] ;- send timeseries to f90 prog. PRINTF, iunit, NK ;- send num evolution times to f90 prog. for i=0,NK-1 do PRINTF, iunit, k[i] ;- send evolution times to f90 prog. PRINTF, iunit, m ;- send embedding dimension to f90 prog. PRINTF, iunit, L ;- send delay time to f90 prog. PRINTF, iunit, ie_value ;- send ruler initialization to f90 prog. PRINTF, iunit, tan_motion_lim ;- send tang. motion limiter to f90 prog. PRINTF, iunit, normalize_input0 ;- sent normalize_input flag to f90 prog. for i=1,9 do begin ;- read regular diagnostic messages READF, iunit, tmp & PRINT, tmp ; from the f90 routine endfor for j=0,9-1 do begin ;- read lambda values from f90 for i=0,NK-1 do begin READF, iunit, tmp out_lambda[i,j] = tmp endfor endfor for j=0,9-1 do begin ;- read log disp. values from f90 for i=0,NK-1 do begin READF, iunit, tmp out_log_disp[i,j] = tmp endfor endfor for j=0,9-1 do begin ;- read num of pts. in shells from f90 for i=0,NK-1 do begin READF, iunit, tmp out_npts[i,j] = tmp endfor endfor for i=0,9-1 do begin ;- read shell limits from f90 READF, iunit, tmp out_shells[i] = tmp endfor FREE_LUN, iunit ;- close pipe, kill f90 program ; --------------------------- Create Output Arrays -------------------------- out_lambda = FLOAT(out_lambda) ;- lambda values out_log_disp = FLOAT(out_log_disp) ;- logarithmic displacement values out_npts = LONG(out_npts) ;- number of points in shells out_shells = FLOAT(out_shells) ;- shell limits ; ------------------------------ Prepare Output ----------------------------- ; ; Note all out_* variables are already set to be returned by this point in ; the code. In this section we only set Result. Result = TEMPORARY(out_lambda) ;- return time-dependent exponent RETURN, Result END ;=== end of function === ; ========== end file ==========