MATRIX

Document Sample
MATRIX
MATRIX - Section 52



The B34S programming language capability is called with the command



b34sexec matrix;

/$ commands here

b34srun;



Example:



b34sexec matrix;

x=matrix(2,2:22. 33. 44. .02);

ix=inv(x);

test=ix*x;

call print(x,ix,test);

b34srun;





The MATRIX command provides a 4th generation language to process

selected calculations from B34S procedures and the ability to further

process data. Analysis is supported for real*8, real*16, complex*16 and

complex*32 data. Other data types such as character*1, character*8,

real*4 and integer*4 are supported. Calculation of the inverse of a

real*4 matrix, while supported, is not recommend due to accuracy loss.

High resolution graphics are available on all currently supported

platforms (Windows, RS/6000, Sun, Linux) and batch and interactive

operation is supported. Many string operations are available for

character*8 and character*1 data.



The MATRIX facility supports user PROGRAMS, SUBROUTINES and

FUNCTIONS. SUBROUTINES and FUNCTIONS have their own address space.

Variables are built using object oriented programming with analytic

statements such as:



y = x*2.;



where x is a variable that could be a matrix, 2D array, 1D array, vector

or a scalar. The use of the MATRIX command FORMULA and the SOLVE

subroutine allows recursive solution of an analytic statement over a

range of index values. This facility speeds up calculations that would

have had to use do loops which have substantial overhead. For intensely

recursive calculations, the user can call Fortran routines from within a

MATRIX command program or subroutine.



The MATRIX command recognizes variables of KIND complex*16, real*8,

real*4, real*16, complex*32, integer*4, character*1 and character*8. Due

to possible accuray loss only array math is supported for integer*4

objects. While the inv(real4object) is supported, due to accuracy loss

this is not recommended.



The KLASS of an object determines how it is processed. KLASS types are

scalar, 1D array, 2D array, vector and 2D matrix. For example the

assingment statement



y=2.0;



sets y to be a real*8 scalar, while



y=2;



sets y to be a integer*4 scalar.



If the commands



x=33.;

y=2;

test=x*y;



are given there will be a mixed-mode error message since the MATRIX

command processor does not know whether test should be integer*4 or

real*8. To create an integer*4 from a real*8 use



testint=idint(x)*y;



while to create a real*8 from an integer*4 variable y use



testr8 =x*dfloat(y);



Where possible Fortran names have been used for built-in functions to

reduce the learning curve.



To create a 2D array use



xarray=array(2,2: 1., 2., 3., 4.);



To create a 2D matrix use



xmatrix=matrix(2,2:1., 2., 3., 4.);



or



xmatrix=mfam(xarray);



There are a number of built in functions to convert the KIND and KLASS.

Key ones are:

SFAM( ) Create a scalar family.

MFAM( ) Convert an array to a matrix.

AFAM( ) Convert a matrix to an array.

VFAM( ) Convert a 1D array to a 1D vector.

DFLOAT( ) Convert integer to real*8.

IDINT( ) Convert real*8 to integer.

IQINT( ) Convert real*16 to integer.

IDNINT( ) Nearest integer from real*8.

IQNINT( ) Nearest integer from real*16

REAL( ) Obtain real*8 part of a complex*16

data type.

QREAL( ) Obtain real*16 part of complex*32 data

type.

IMAG( ) Obtain the real*8 imaginary part of a

complex*16 data type.

QIMAG( ) Obtain the real*16 imaginary part of a

complex*32 data type.

COMPLEX( , ) Build a complex*16 variable from two

real*8 variables.

QCOMPLEX( , ) Build a complex*32 variable from two

real*16 variables.

QNINT( ) Real*16 representation of nearest whole

number.

DNINT( ) Real*8 representation of nearest whole

number.

R8TOR16( ) Real*8 to real*16.

R16TOR8( ) Real*16 to real*8.

C16TOC32( ) Complex*16 to complex*32.

C32TOC16( ) Complex*32 to complex*16.

KINDAS(x,yy) Set a variable the kind of x, but value

of yy.



More detail on these features will be given below.



The B34S MATRIX language is very close to the Speakeasy language. In

MATLAB all 2D and 1D objects are assumed to be what B34S calls the

MATRIX KLASS. Assume x and y are 3 by 3 MATRIX objects in B34S and

MATLAB. In MATLAB for an element by element operation the command is



newobj=x.*y;



In B34S and Speakeasy the command for the same operation is:



newobj=afam(x)*afam(y);



If it is desired to place this back in a matrix:



newobj=mfam(afam(x)*afam(y));



Unlike MATLAB, B34S and Speakeasy are not case sensitive.



Assume xarray is an array and xmatrix is a matrix.



xxarray =2.+xarray;

xxmatrix=2.+xmatrix;



Speakeasy and B34S work the same. Here 2. is added to all elements

in xarray and only the diagonal elements in xmatrix.

In MATLAB 2+x adds 2 to all elements of the matrix.



The development of the MATRIX facility has been influenced closely

by Speakeasy. Wherever possible, the same command language has been used

to facilitate transfer of data to Speakeasy for further processing. The

MATRIX facility is NOT designed to run interactively but commands can be

given interactively in the MANUAL mode. In this mode scripts can be

edited and submitted. Output is written to the b34s.out file and error

messages are displayed in both the b34s.out and b34s.log files.



Under the Display Manager, the user can scroll the output files and run

the MATRIX command before and after other b34s commands.



The objective of the MATRIX facility is to give the user access to a

powerful object oriented programming language so that custom

calculations can be made. Of major interest is providing the ability to

estimate complex nonlinear least squares and maximum likelihood models.

Such models, which are specified in B34S MATRIX command programs, can be

solved using either other B34S subroutines or with the MATRIX nonlinear

commands NLLSQ, NL2SOL, MAXF1, MAXF2, MAXF3, CMAXF1, CMAXF2 and CMAXF3.

While the use of B34S subroutines would give the user TOTAL control of

the estimation process, speed would be given up.



In addition to specification of the model, in the B34S MATRIX language

it is also possible to write the model in a Fortran or C program and

call this user program from within a B34S MATRIX program. For recursive

systems where it is near impossible to vectorize the calculation, this

is may be the best way to proceed.



The B34S nonlinear solvers are based on time tested routines. The

objective of the b34s implementation is to facilitate their use in a way

whereby there is full knowledge of just what is being calculated. The

design of the MATRIX facility allows other libraries of routines to be

accessed from C or Fortran to provide other alternatives.



The MATRIX nonlinear commands give the user complete control of the

form of the estimated model which is specified in a MATRIX command

PROGRAM. Since these programs are called by compiled solvers, there is

a substantial speed advantage over a design that writes the solver in

a subroutine.



The file MATRIX2.MAC contains the subroutines DUD and MARQ which

illustrate the subroutine approach to nonlinear least squares and the

power of the MATRIX command language. While these subroutines can be

used, the NLLSQ and NL2SOL commands are substantially more powerful and

orders of magnitide faster.



The MATRIX command display routines OUTSTRING, OUTINTEGER and

OUTDOUBLE can be used to "instrument" the solution process such that

the user can see how the search is proceeding if B34S is running

in the Display Manager. These commands will not work for batch jobs

since the proper windows have not been opened unless the b34s2

procedure is used.



The B34S Matrix Language design allows DO loops and IF structures

to be in the command stream provided the commands are not given in

manual mode. This is not possible with Speakeasy. The command



call manual;



can be placed anywhere in the job to place the processor in manual mode

whereby commands could be entered or the process modified. The main

purpose of manual mode is to allow the user to take control of how a

subroutine is running. If call manual; is used in a MATRIX program under

the Display Manager, the user is placed in the IMATRIX mode where the

output to date can be seen, errors can be trapped and commands can be

given to see what has been calculated to date and scripts can be

submitted.



If the user is debugging a subroutine it is often useful to be able

to see what variables are active and possible modify the course of the

subroutines execution in a real-time mode. The command



call break('Are at position a');



can be used to trap execution in a loop. If any key has been hit prior

to call break being found, the program will stop. Otherwise the command

is ignored. This saves having the program checking for a key stroke as

each command is being executed which will slow speed. If call break is

executed, the user can then either allow execution to proceed or

terminate the process then and there. If the MATRIX workspace is saved

with the SAVE command, it can be restored after more B34S commands have

run. Unlike most other B34S commands, in many cases the MATRIX command

requires that commas be used. Unlike other B34S commands, errors are

written both in the LOG file and at the exact command that has caused a

problem. The command



call echooff;



can be used to reduce output when running a user SUBROUTINE, FUNCTION

or PROGRAM. If there is some question on how a certain section is

running, the command



call echoon;



can be used to echo commands as they are executed.



In Matlab commands that end with ; are not echoed, while commands that

do not end in ; are. This "design" requires the user to modify code

during the debug phase. As a result errors can creep in. The echoon

and echoff commands allow one tyo globally turn off output.



Every attempt has been made to increase the speed of execution.

Unlike Speakeasy, the CALL command is needed to execute PROGRAMS or

SUBROUTINES. By this design, a great deal of search time is saved.

To avoid I/O and to avoid possible unforseen conflicts over names, user

SUBROUTINES, PROGRAMS or FUNCTIONS must be loaded to be found. Automatic

loading of user commands slows execution substantially since the

processor would have to look in all libraries to see if a built-in

command had been replaced by a user subroutine, program or function. A

major reason automatic loading was not implemented was to avoid the

danger that the wrong subroutine could be loaded and a "wrong"

calculation be made and not caught.



A major objective of the MATRIX command is to give the user total

control over the processing of data. Users can develope extensions

and modifications of the statistics calculated by other B34S commands.

Over the years, more and more of the regular commands will be converted

to save data for later use in the matrix command. The library of

applications SUBROUTINES, FUNCTIONS and PROGRAMS in



c:\b34slm\matrix2.mac



will be inhanced. Since these procedures are written in the B34S MATRIX

language, they are self documenting. Facilities are provided whereby

users can add to these libraries. Since all procedures have to be

loaded, there is NO possibility that a user procedure can conflict with

a built-in command unless it is explicitly loaded. The only conflict

possible is with a MATRIX language command. This design prevents the

MATLAB problem of suddenly key commands not working because the order of

the library is changed due to a new toolkit being added.



The routines in matrix2.mac are of two types. General purpose routines,

such CFREQ which will calculate a cumulative frequency distribution, are

documented BOTH in the TOOLKIT section which lists all routines and

under the matrix command subroutine list. Commands such as this have

test problems of the same name in matrix.mac. Other programs in

matrix2.mac of less general interest for production jobs are only

documented in the TOOLKIT section. The library staging.mac contains

example files for the proposed subroutines in staging2.mac.



The MATRIX command can read and process a binary file. Reading can be

done in any order. This facility allows the system to process and change

a load module or recover data from a file that has a strange structure.

Character*1 processing allows the user to read and parse lines of a

file. This capability is of interest to the expert user.



For NLLSQ and maximum likelihood models that involve recursive models,

in many cases an alternative program may be RATS. Such models are slow

to estimate since there is a heavy parse overhead and the the vector

capability in the B34S MATRIX facility is not usuable. B34S is not

designed to replace RATS in this area.



In B34S NLLSQ and maximum likelihood estimation can be done where the

model is specified in the user's program using MATRIX commands. This

mode of operation combines the advantages of fast execution with the

flexibility of allowing the user to specify the model using a 4th

generation language. NLLSQ can also be done using subroutines DUD and

MARQ which were written in the B34S MATRIX command language. The

estimation of a ML model when a recursive system is not required is fast

and a number of routines from IMSL are supplied. Supported capability

includes constrained ML models. While recursive systems are possible,

due to the fact that DO loops or SOLVE/FORMULA commands are needed, the

speed is slower. The subroutine GARCH can be used to estimate a subset

of the ARCH/GARCH class of models without some of the recursive call

overhead. An even simplier command GARCHEST allows univariate estimation

for simple ARCH/GARCH models. Since B34S can estimate a nonlinear

programming model with nonlinear constraints, a fairly wide class of

models can be estimated. The BGARCH subroutine allows the user's PROGRAM

to estimate a bivariate GARCH model without the recursive overhead.



Note: In the above NLLSQ refers to nonlinear least squares. The B34S

MATRIX command has two commands for this calculation. NLLSQ uses

the Meeter (1964a, 1964b) routines that were first developed at

the University of Wisconsin and form the basis of much work in

time series analysis. The alternative routine NL2SOL uses the

Dennis-Gay-Welsch (1981) programs that have been widely used in

the literature. As of May 2004, the NLLSQ command can be run with

real*8 or real*16 data.



The maximization routines supported all come from various versions

of the IMSL library. The B34S MATRIX command subroutines DUD and

MARQ use the logic of the SAS Nonlin command but are written in

the B34S command language. These are supplied for research

interest. For nonlinear least squares, these would be a third

choice.









List of Built-In Matrix Command Subroutines



ABFSPLINE - Automatic Backfitting of a Spline Model

ACEFIT - Alternating Conditional Expectation Model Estimation

ACF_PLOT - Simple ACF Plot

ADDCOL - Add a column to a 2d array or matrix.

ADDROW - Add a row to a 2d array or matrix.

AGGDATA - Aggregate Data under control of an ID Vector.

ALIGN - Align Series with Missing Data

ARMA - ARMA estimation using ML and MOM.

AUTOBJ - Automatic Estimation of Box-Jenkins Model

BACKSPACE - Backspace a unit

BDS - BDS Nonlinearity test.

B_G_TEST - Breusch-Godfrey (1978) Residual Test

BGARCH - Calculate function for a BGARCH model.

BLUS - BLUS Residual Analysis

BPFILTER - Baxter-King Filter.

BREAK - Set User Program Break Point.

BUILDLAG - Builds NEWY and NEWX for VAR Modeling

CCFTEST - Display CCF Function of Prewhitened data

CHAR1 - Place a string is a character*1 array.

CHARACTER - Place a string in a character*1 array.

CHECKPOINT - Save workspace in portable file.

CLEARALL - Clears all objects from workspace.

CLEARDAT - Clears data from workspace.

CLOSE - Close a logical unit.

CLS - Clear screen.

CMAXF1 - Constrained maximization of function using zxmwd.

CMAXF2 - Constrained maximization of function using dbconf/g.

CMAXF3 - Constrained maximization of function using db2pol.

COMPRESS - Compress workspace.

CONSTRAIN - Subset data based on range of values.

CONTRACT - Contract a character array.

COPY - Copy an object to another object

COPYLOG - Copy file to log file.

COPYOUT - Copy file to output file.

COPYF - Copy a file from one unit to another.

CSPECTRAL - Do cross spectral analysis.

CSUB - Call Subroutine

CSV - Read and Write a CVS file

DATA_ACF - Calculate ACF and PACF Plots

DATAFREQ - Data Frequency

DATAVIEW - View a Series Under Menu Control

DELETECOL - Delete a column from a matrix or array.

DELETEROW - Delete a row from a matrix or array.

DES - Code / decode.

DESCRIBE - Calculate Moment 1-4 and 6 of a series

DF - Calculate Dickey-Fuller Unit Root Test.

DISPLAYB - Displays a Buffer contents

DIST_TAB - Distribution Table

DODOS - Execute a command string if under dos/windows.

DO_SPEC - Display Periodogram and Spectrum

DOUNIX - Execute a command string if under unix.

DQDAG - Integrate a function using Gauss-Kronrod rules

DQDNG - Integrate a smooth function using a nonadaptive rule.

DQDAGI - Integrate a function over infinite/semi-infinite

interval.

DQDAGP - Integrate a function with singularity points given

DQDAGS - Integrate a function with end point singularities

DQAND - Multiple integration of a function

DTWODQ - Two Dimensional Iterated Integral

ECHOOFF - Turn off listing of execution.

ECHOON - Turn on listing of execution.

EPPRINT - Print to log and output file.

EPRINT - Print to log file.

ERASE - Erase file(s).

EXPAND - Expand a character array

FORMS - Build Control Forms

FORPLOT - Forecast Plot

FREE - Free a variable.

FPLOT - Plot a Function

FPRINT - Formatted print facility.

GAMFIT - Generalized Additive Model Estimation

GARCH - Calculate function for a ARCH/GARCH model.

GARCHEST - Estimate ARCH/GARCH model.

GET - Gets a variable from b34s.

GETDMF - Gets a data from a b34s DFM file.

GETKEY - Gets a key

GETMATLAB - Gets data from matlab.

GET_FILE - Gets a File name

GET_NAME - Get Name of a Matrix Variable

GETRATS - Reads RATS Portable file.

GETSCA - Reads SCA FSAVE and MAD portable files.

GMFAC - LU factorization of n by m matrix

GMINV - Inverse of General Matrix using LAPACK

GMSOLV - Solve Linear Equations system using LAPACK

GRAPH - High Resolution graph.

GRAPHP - Multi-Pass Graphics Programing Capability

GRCHARSET - Set Character Set for Graphics.

GRREPLAY - Graph replay and reformat command.

GTEST - Tests output of a ARCH/GARCH Model

GWRITE - Save Objects in GAUSS Format using one file

GWRITE2 - Save objects in GAUSS format using two files

HEADER - Turn on header

HEXTOCH - Concert hex to a character representation.

HINICH82 - Hinich 1982 Nonlinearity Test.

HINICH96 - Hinich 1996 Nonlinearity Test.

HPFILTER - Hodrick-Prescott Filter.

ISEXTRACT - Place data in a structure.

IALEN - Get actual length of a buffer of character data

IBFCLOSE - Close a file that was used for Binary I/O

IBFOPEN - Open a File for Binary I/O

IBFREADC - Reads from a binary file into Character*1 array

IBFREADR - Reads from a binary file into Real*8 array

IBFSEEK - Position Binary read/write pointer

IBFWRITER - Write noncharacter buffer on a binary file

IBFWRITEC - Write character buffer on a binary file

IB34S11 - Parse a token using B34S11 parser

IFILESIZE - Determine number of bites in a file

IFILLSTR - Fill a string with a character

IGETICHAR - Obtain ichar info on a character buffer

IGETCHARI - Get character from ichar value

IJUSTSTR - Left/Right/center a string

ILCOPY - Move bites from one location to another

ILOCATESTR - Locate a substring in a string - 200 length max

ILOWER - Lower case a string - 200 length max

INEXTR8 - Convert next value in string to real*8 variable

INEXTR4 - Convert next value in string to real*4 variable

INEXTSTR - Extract next blank deliminated sub-string from a

string

INEXTI4 - Convert next value in a string to integer.

INTTOSTR - Convert integer to string using format

IR8TOSTR - Convert real*8 value to string using format

ISTRTOR8 - Convert string to real*8

ISTRTOINT - Convert string to integer

IUPPER - Upper case a string - 200 length max

I_DRNSES - Initializes the table used by shuffled generators.

I_DRNGES - Get the table used in the shuffled generators.

I_DRNUN - Uniform (0,1) Generator

I_DRNNOR - Random Normal Distribution

I_DRNBET - Random numbers from beta distribution

I_DRNCHI - Random numbers from Chi-squared distribution

I_DRNCHY - Random numbers from Cauchy distribution

I_DRNEXP - Random numbers from standard exponential

I_DRNEXT - Random numbers from mixture of two exponential

distributions

I_DRNGAM - Random numbers from standard gamma distribution

I_DRNGCT - Random numbers from general continuous distribution

I_DRNGDA - Random integers from discrete distribution alias

approach

I_DRNGDT - Random integers from discrete using table lookup

I_DRNLNL - Random numbers from lognormal distribution

I_DRNMVN - Random numbers from multivariate normal

I_DRNNOA - Random normal numbers using acceptance/rejection

I_DRNNOR - Random normal numbers using CDF method

I_DRNSTA - Random numbers from stable distribution

I_DRNTRI - Random numbers from triangular distribution

I_DRNSPH - Random numbers on the unit circle

I_DRNVMS - Random numbers from Von Mises distribution

I_DRNWIB - Random numbers from Weibull distribution

I_RNBIN - Random integers from binomial distribution

I_RNGET - Gets seed used in IMSL Random Number generators.

I_RNOPG - Gets the type of generator currently in use.

I_RNOPT - Selects the type of uniform (0,1) generator.

I_RNSET - Sets seed used in IMSL Random Number generators.

I_RNGEO - Random integers from Geometric distribution

I_RNHYP - Random integers from Hypergeometric distribution.

I_RNMTN - Random numbers from multinomial distribution

I_RNNBN - Negative binomial distribution

I_RNPER - Random perturbation of integers

I_RNSRI - Index of random sample without replacement

KEENAN - Keenan Nonlinearity test

KSWTEST - K Period Stock Watson Test

KSWTESTM - Moving Period Stock Watson Test

LAGMATRIX - Builds Lag Matrix.

LAGTEST - 3-D Graph to display RSS for OLS Lags

LAGTEST2 - 3-D Graph to display RSS for MARS Lags

LAPACK - Sets Key LAPACK parameters

LM - Engle Lagrange Multiplier ARCH test.

LOAD - Load a Subroutine from a library.

LOADDATA - Load Data from b34s into MATRIX command.

LPMAX - Solve Linear Programming maximization problem.

LPMIN - Solve Linear Programming minimization problem.

LRE - McCullough Log Relative Error

MAKEDATA - Place data in a b34s data loading structure.

MAKEGLOBAL - Make a variable global (seen at all levels).

MAKELOCAL - Make a variable seen at only local level.

MAKEMATLAB - Place data in a file to be loaded into Matlab.

MAKEMAD - Makes SCA *.MAD datafile from vectors

MAKERATS - Make RATS portable file.

MAKESCA - Make SCA FSV portable file.

MANUAL - Place MATRIX command in manual mode.

MARS - Multivariate Autoregressive Spline Models

MARSPLINE - Updated MARS Command using Hastie-Tibshirani code

MAXF1 - Maximize a function using IMSL ZXMIN.

MAXF2 - Maximize a function using IMSL DUMINF/DUMING.

MAXF3 - Maximize a function using simplex method (DU2POL).

MELD - Form all possible combinations of vectors.

MENU - Put up user Menu for Input

MESSAGE - Put up user message and allow a decision.

MINIMAX - Estimate MINIMAX with MAXF2

MISSPLOT - Plot of a series with Missing Data

MQSTAT - Multivariate Q Statistic

NAMES - List names in storage.

NLEQ - Jointly solve a number of nonlinear equations.

NLLSQ - Nonlinear Least Squares Estimation.

NL2SOL - Alternative Nonlinear Least Squares Estimation.

NLPMIN1 - Nonlinear Programming fin. diff. grad. DN2CONF.

NLPMIN2 - Nonlinear Programming user supplied grad. DN2CONG.

NLPMIN3 - Nonlinear Programming user supplied grad. DN0ONF.

NLSTART - Generate starting values for NL routines.

NOHEADER - Turn off header.

OLSQ - Estimate OLS, MINIMAX and L1 models.

OLSPLOT - Plot of Fitted and Actual Data & Res

OPEN - Open a file and attach to a unit.

OUTDOUBLE - Display a Real*8 value at a x, y on screen.

OUTINTEGER - Display an Integer*4 value at a x, y on screen.

OUTSTRING - Display a string value at a x, y point on screen.

PCOPY - Copy an object from one pointer address to another

PERMUTE - Reorder Square Matrix

PISPLINE - Pi Spline Nonlinear Model Building

PLOT - Line-Printer Graphics

POLYFIT - Fit an nth degree polynomial

POLYVAL - Evaluate an nth degree polynomial

POLYMCONV - Convert storage of a polynomial matrix

POLYMDISP - Display/Extract a polynomial matrix

POLYMINV - Invert a Polynomial Matrix

POLYMMULT - Multiply a Polynomial Matrix

PP - Calculate Phillips Peron Unit Root test

PRINT - Print text and data objects.

PRINTALL - Lists all variables in storage.

PRINTOFF - Turn off Printing

PRINTON - Turn on Printing (This is the default)

PROBIT - Estimate Probit (0-1) Model.

PVALUE_1 - Present value of $1 recieved at end of n years

PVALUE_2 - Present value of an Annuity of $1

PVALUE_3 - Present value of $1 recieved throughout year

QPMIN - Quadratic Programming.

QUANTILE - Calculate interquartile range.

READ - Read data directly into MATRIX workspace from a file.

REAL16INFO - Obtain Real16 info

REAL16OFF - Turn off Real16 add

REAL16ON - Turn on extended accuracy

REAL32OFF - Turn off Real32 add

REAL32ON - Turn on extended accuracy for real*16

REAL32_VPA - Turn on extended accuracy for real*16 using vpa

RESET - Calculate Ramsey (1969) regression specification test.

RESET77 - Thursby - Schmidt Regression Specification Test

RESTORE - Load data back in MATRIX facility from external save

file.

RTEST - Test Residuals of Model

RTEST2 - Test Residuals of Model - No RES and Y Plots

REVERSE - Test a real*8 vector for reversibility in Freq.

Domain

REWIND - Rewind logical unit.

ROTHMAN - Test a real*8 vector for reversibility in Time Domain

RMATLAB - Runs Matlab

RRPLOTS - Plots Recursive Residual Data

RUN - Terminates the matrix command being in "manual" mode.

SAVE - Save current workspace in portable file format.

SCHUR - Performs Schur decomposition

SCREENCLOSE - Turn off Display Manager

SCREENOPEN - Turn on Display Manager

SCREENOUTOFF - Turn screen output off.

SCREENOUTON - Turn screen output on.

SET - Set all elements of an object to a value.

SETCOL - Set column of an object to a value.

SETLABEL - Set the label of an object.

SETLEVEL - Set level.

SETNDIMV - Sets an element in an n dimensional object.

SETROW - Set row of an object to a value.

SETTIME - Sets the time info in an existing series

SETWINDOW - Set window to main(1), help(2) or error(3).

SIGD - Set print digits. Default g16.8

SIMULATE - Dynamically Simulate OLS Model

SMOOTH - Do exponential smoothing.

SOLVEFREE - Set frequency of freeing temp variables.

SORT - Sort a real vector.

SPECTRAL - Spectral analysis of a vector or 1d array.

STOP - Stop execution of a program.

SUBRENAME - Internally rename a subroutine.

SUSPEND - Suspend loading and Execuiting a program

SWARTEST - Stock-Watson VAR Test

SYSTEM - Issue a system command.

TABULATE - List vectors in a table.

TESTARG - Lists what is passed to a subroutine or function.

TIMER - Gets CPU time.

TRIPLES - Calculate Triples Reversability Test

TSAY - Calculate Tsay nonlinearity test.

TSLINEUP - Line up Time Series Data

TSD - Interface to TSD Data set

VAREST - VAR Modeling

VPASET - Set Variable Precision Math Options

VOCAB - List built-in subroutine vocabulary.

WRITE - Write an object to an external file.



Matrix Command Built-In Function Vocabulary



ACF - Calculate autocorrelation function of a 1d object.

AFAM - Change a matrix or vector to an array class object.

ARGUMENT - Unpack character argument at run-time

ARRAY - Define a 1d or 2d array.

BETAPROB - Calculate a beta probability.

BINDF - Evaluate Binomial Distribution Function

BINPR - Evaluate Binomial Probability Function

BOOTI - Calculate integers to be used with bootstrap.

BOOTV - Bootstraps a vector with replacement.

BOXCOX - Box-Cox Transformation of a series given lamda.

BSNAK - Compute Not a Knot Sequence

BSOPK - Compute optimal spline know sequence

BSINT - Compute 1-D spline interpolant given knots

BSINT2 - Compute 2-D spline interpolant given knots

BSINT3 - Compute 3-D spline interpolant given knots

BSDER - Compute 1-D spline values/derivatives given knots

BSDER2 - Compute 2-D spline values/derivatives given knots

BSDER3 - Compute 3-D spline values/derivatives given knots

BSITG - Compute 1-D spline integral given knots

BSITG2 - Compute 2-D spline integral given knots

BSITG3 - Compute 3-D spline integral given knots

C1ARRAY - Create a Character*1 array

C8ARRAY - Create a Character*8 array

CATCOL - Concatenates an object by columns.

CATROW - Concatenates an object by rows.

CCF - Calculate the cross correlation function on two

objects.

CHAR - Convect an integer in range 0-127 to character.

CHARDATE - Convert julian variable into character date dd\mm\yy.

CHARDATEMY - Convert julian variable into character data mm\yyyy.

CHARTIME - Converts julian variable into character date hh:mm:ss

CHISQPROB - Calculate chi-square probability.

CHTOR - Convert a character variable to a real variable.

CHTOHEX - Convert a character to its hex representation.

CFUNC - Call Function

COMB - Combination of N objects taken M at a time.

COMPLEX - Build a complex variable from two real*8 variables.

CSPLINEFIT - Fit a 1 D Cubic Spline using alternative models

CSPLINE - Calculate a cubic spline for 1 D data

CSPLINEVAL - Calculate spline value given spline

CSPLINEDER - Calculate spline derivative given spline value

CSPLINEITG - Calculate integral of a cubic spline

CUSUM - Cumulative sum.

CUSUMSQ - Cumulative sum squared.

CWEEK - Name of the day in character.

DABS - Absolute value of a real*8 variable.

DARCOS - Arc cosine of a real*8 variable.

DARSIN - Arc sine of a real*8 variable.

DATAN - Arc tan of a real*8 variable.

DATAN2 - Arc tan of x / y. Signs inspected.

DATENOW - Date now in form dd/mm/yy

DBLE - Convert real*4 to real*8.

DCONJ - Conjugate of complex argument.

DCOS - Cosine of real*8 argument.

DCOSH - Hyperbolic cosine of real*8 argument.

DDOT - Inner product to two vectors.

DERF - Error function of real*8/real*16 argument.

DERFC - Inverse of error function.

DERIVATIVE - Analytic derivative of a vector.

DET - Determinate of a matrix.

DEXP - Exponential of a real*8 argument.

DFLOAT - Convert integer*4 to real*8.

DGAMMA - Gamma function of real*8 argument.

DIAG - Place diagonal of a matrix in an array.

DIAGMAT - Create diagonal matrix.

DIF - Difference a series.

DINT - Extract integer part of real*8 number

DNINT - Extract nearest integer part of real*8 number

DIVIDE - Divide with an alternative return.

DLGAMMA - Natural log of gamma function.

DLOG - Natural log.

DLOG10 - Base 10 log.

DMAX - Largest element in an array.

DMAX1 - Largest element between two arrays.

DMIN - Smallest element in an array.

DMIN1 - Smallest element between two arrays.

DMOD - Remainder.

DROPFIRST - Drops observations on top or array.

DROPLAST - Drops observations on bottom of an array.

DSIN - Calculates sine.

DSINH - Hyperbolic sine.

DSQRT - Square root of real*8 or complex*16 variable.

DTAN - Tangent.

DTANH - Hyperbolic tangent.

EIGENVAL - Eigenvalue of matrix. Alias EIG.

EPSILON - Positive value such that 1.+x ne 1.

EVAL - Evaluate a character argument

EXP - Exponential of real*8 or complex*16 variable.

EXTRACT - Extract elements of a character*1 variable.

FACT - Factorial

FDAYHMS - Gets fraction of a day.

FFT - Fast fourier transform.

FIND - Finds location of a character string.

FLOAT - Converts integer*4 to real*4.

FPROB - Probability of F distribution.

FREQ - Gets frequency of a time series.

FRACDIF - Fractional Differencing

FYEAR - Gets fraction of a year from julian date.

GENARMA - Generate an ARMA series given parameters.

GETDAY - Obtain day of year from julian series.

GETHOUR - Obtains hour of the day from julian date.

GETNDIMV - Obtain value from an n dimensional object.

GETMINUTE - Obtains minute of the day from julian date.

GETMONTH - Obtains month from julian date.

GETQT - Obtains quarter of year from julian date.

GETSECOND - Obtains second from julian date.

GETYEAR - Obtains year.

GOODCOL - Deletes all columns where there is missing data.

GOODROW - Deletes all rows where there is missing data.

GRID - Defines a real*8 array with a given increment.

HUGE - Largest number of type

HYPDF - Evaluate Hypergeometric Distribution Function

HYPPR - Evaluate Hypergeometric Probability Function

INTEGER8 - Load an Integer*8 object from a string

I4TOI8 - Move an object from integer*4 to integer*8

I8TOI4 - Move an object from integer*8 to integer*4

ICHAR - Convect a character to integer in range 0-127.

ICOLOR - Sets Color numbers. Used with Graphp.

IDINT - Converts from real*8 to integer*4.

IDNINT - Converts from real*8 to integer*4 with rounding.

INFOGRAPH - Obtain Interacter Graphics INFO

IMAG - Copy imaginary part of complex*16 number into real*8.

INDEX - Define integer index vector, address n dimensional

object.

INLINE - Inline creation of a program

INT - Copy real*4 to integer*4.

INTEGERS - Generate an integer vector with given interval.

INV - Inverse of a real*8 or complex*16 matrix.

INVBETA - Inverse beta distribution.

INVCHISQ - Inverse Chi-square distribution.

INVFDIS - Inverse F distribution.

INVTDIS - Inverse t distribution.

IQINT - Converts from real*16 to integer*4.

IQNINT - Converts from real*16 to integer*4 with rounding.

ISMISSING - Sets to 1.0 if variable is missing

IWEEK - Sets 1. for monday etc.

JULDAYDMY - Given day, month, year gets julian value.

JULDAYQY - Given quarter and year gets julian value.

JULDAYY - Given year gets julian value.

KEEPFIRST - Given k, keeps first k observations.

KEEPLAST - Given k, keeps last k observations.

KIND - Returns kind of an object in integer.

KINDAS - Sets kind of second argument to kind first arg.

KLASS - Returns klass of an object in integer.

KPROD - Kronecker Product of two matrices.

LABEL - Returns label of a variable.

LAG - Lags variable. Missing values propagated.

LEVEL - Returns current level.

LOWERT - Lower triangle of matrix.

MCOV - Consistent Covariance Matrix

MAKEJUL - Make a Julian date from a time series

MASKADD - Add if mask is set.

MASKSUB - Subtract if mask is set.

MATRIX - Define a matrix.

MEAN - Average of a 1d object.

MFAM - Set 1d or 2d array to vector or matrix.

MISSING - Returns missing value.

MLSUM - Sums log of elements of a 1d object.

MOVELEFT - Moves elements of character variable left.

MOVERIGHT - Move elements of character variable right.

NAMELIST - Creates a namelist.

NEAREST Nearest distinct number of a given type

NCCHISQ - Non central chi-square probability.

NOCOLS - Gets number of columns of an object.

NOELS - Gets number of elements in an object.

NORMDEN - Normal density.

NORMDIST - 1-norm, 2-norm and i-norm distance.

NOROWS - Gets number of rows of an object.

NOTFIND - Location where a character is not found.

OBJECT - Put together character objects.

PDFAC - Cholesky factorization of PD matrix.

PDFACDD - Downdate Cholesky factorization.

PDFACUD - Update Cholesky factorization.

PDINV - Inverse of a PD matrix.

PDSOLV - Solution of a PD matrix given right hand side.

PI - Pi value.

PINV - Generalized inverse.

PLACE - Places characters inside a character array.

POIDF - Evaluate Poisson Distribution Function

POIPR - Evaluate Poisson Probability Function

POINTER - Machine address of a variable.

POLYDV - Division of polynomials.

POLYMULT - Multiply two polynomials

POLYROOT - Solution of a polynomial.

PROBIT - Inverse normal distribution.

PROBNORM - Probability of normal distribution.

PROBNORM2 - Bivariate probability of Nornal distribution.

PROD - Product of elements of a vector.

QCOMPLEX - Build complex*32 variable from real*16 inputs.

QINT - Extract integer part of real*16 number

QNINT - Extract nearest integer part of real*16 number

QREAL - Obtain real*16 part of a complex*326 number.

QRFAC - Obtain Cholesky R via QR method.

QRSOLVE - Solve OLS using QR.

RANKER - Index array that ranks a vector.

RCOND - 1 / Condition of a Matrix

REAL - Obtain real*8 part of a complex*16 number.

R8TOR16 - Convert Real*8 to Real*16

R16TOR8 - Convert Real*16 to Real*8

REAL16 - Input a Real*16 Variable

REC - Rectangular random number.

RECODE - Recode a real*8 or character*8 variable

RN - Normally distributed random number.

ROLLDOWN - Moves rows of a 2d object down.

ROLLLEFT - Moves cols of a 2d object left.

ROLLRIGHT - Moves cols of a 2d object right.

ROLLUP - Moves rows of a 2d object up.

RTOCH - Copies a real*8 variable into character*8.

SEIGENVAL - Eigenvalues of a symmetric matrix. Alias SEIG.

SEXTRACT - Takes data out of a field.

SFAM - Creates a scalar object.

SNGL - Converts real*8 to real*4.

SPACING - Absolute spacing near a given number

SPECTRUM - Returns spectrum of a 1d object.

SUBSET - Subset 1d, 2d array, vector or matrix under a mask.

SUBMATRIX - Define a Submatrix

SUM - Sum of elements.

SUMCOLS - Sum of columns of an object.

SUMROWS - Sum of rows of an object.

SUMSQ - Sum of squared elements of an object.

SVD - Singular value decomposition of an object.

TIMEBASE - Obtains time base of an object.

TIMENOW - Time now in form hh:mm:ss

TIMESTART - Obtains time start of an object.

TINY Smallest number of type

TDEN - t distribution density.

TPROB - t distribution probability.

TRACE - Trace of a matrix.

TRANSPOSE - Transpose of a matrix.

UPPERT - Upper Triangle of matrix.

VARIANCE - Variance of an object.

VECTOR - Create a vector.

VFAM - Convert a 1d array to a vector.

VOCAB - List built in functions.

VPA - Variable Precision Math calculation

ZDOTC - Conjugate product of two complex*16 objects.

ZDOTU - Product of two complex*16 objects.

ZEROL - Zero lower triangle.

ZEROU - Zero upper triangle.



**********************************************************************



Matrix Programming Language key words



CALL - Call a subroutine

CONTINUE - go to statement

DO - Starts a do loop

DOWHILE - Starts a dowhile loop

NEXT i - End of a do loop

ENDDO - End of a do loop

ENDDOWHILE - End of a dowhile loop

END - End of a program, function or Subroutine.

EXITDO - Exit a DO loop

EXITIF - Exit an IF statement

FOR - Start a do loop,

FORMULA - Define a recursive formula.

GO TO - Transfer statement

FUNCTION - Beginning of a function.

IF( ) - Beginning of an IF structure

ENDIF - End of an IF( )THEN structure

PROGRAM - Beginning of a program,

RETURN - Next to last statement before end.

RETURN( ) - Returns the result of a function.

SOLVE - Solve a recursive system.

SUBROUTINE - Beginning of subroutine.

WHERE( ) - Starts a where structure.



**********************************************************************



Commands listed by Function



Character & String Subroutines



CHTOHEX - Convert a character to its hex representation.

CONTRACT - Contract a character array

DISPLAYB - Displays a Buffer contents

EXPAND - Expand a character array

EVAL - Evaluate a Character Argument

HEXTOCH - Concert hex to a character representation.

IALEN - Get actual length of a buffer of character data

IBFCLOSE - Close a file that was used for Binary I/O

IBFOPEN - Open a File for Binary I/O

IBFREADC - Reads from a binary file into Character*1 array

IBFREADR - Reads from a binary file into Real*8 array

IBFSEEK - Position Binary read/write pointer

IBFWRITER - Write noncharacter buffer on a binary file

IBFWRITEC - Write character buffer on a binary file

IB34S11 - Parse a token using B34S11 parser

IFILESIZE - Determine number of bites in a file

IFILLSTR - Fill a string with a character

IGETICHAR - Obtain ichar info on a character buffer

IGETCHARI - Get character from ichar value

IJUSTSTR - Left/Right/center a string

ILCOPY - Move bites from one location to another

ILOCATESTR - Locate a substring in a string - 200 length max

ILOWER - Lower case a string - 200 length max

INEXTR8 - Convert next value in string to real*8 variable

INEXTR4 - Convert next value in string to real*4 variable

INEXTSTR - Extract next blank deliminated sub-string from a

string

INEXTI4 - Convert next value in a string to integer.

INTTOSTR - Convert integer to string using format

IR8TOSTR - Convert real*8 value to string using format

ISTRTOR8 - Convert string to real*8

ISTRTOINT - Convert string to integer

IUPPER - Upper case a string - 200 length max



Character Functions



CHAR - Convect an integer in range 0-127 to character.

CHTOR - Convert a character variable to a real variable.

DATENOW - Date now in form dd/mm/yy

EXTRACT - Extract elements of a character*1 variable.

FIND - Finds location of a character string.

ICHAR - Convect a character to integer in range 0-127.

INLINE - Inline creation of a program

MOVELEFT - Moves elements of character variable left.

MOVERIGHT - Move elements of character variable right.

NAMELIST - Creates a namelist.

NOTFIND - Location where a character is not found.

OBJECT - Put together character objects.

PLACE - Places characters inside a character array.

RTOCH - Copies a real*8 variable into character*8.

TIMENOW - Time now in form hh:mm:ss



Data Building, loading and Display Subroutines



ACF_PLOT - Simple ACF Plot

ADDCOL - Add a column to a 2d array or matrix.

ADDROW - Add a row to a 2d array or matrix.

AGGDATA - Aggregate Data under control of an ID Vector.

ALIGN Align Series with Missing Data

BUILDLAG - Builds NEWY and NEWX for VAR Modeling

CCFTEST - Display CCF Function of Prewhitened data

CHAR1 - Place a string in a character*1 array.

CHARACTER - Place a string in a character*1 array.

CHECKPOINT - Save workspace in portable file.

CLEARALL - Clears all objects from workspace.

CLEARDAT - Clears data from workspace.

CSUB - Call Subroutine

CONSTRAIN - Subset data based on range of values.

CSV - Read and Write a CVS file

DATA_ACF - Calculate ACF and PACF Plots

DATAVIEW - View a Series Under Menu Control

DATAFREQ - Data Frequency

DELETECOL - Delete a column from a matrix or array.

DELETEROW - Delete a row from a matrix or array.

DES - Code / decode.

DESCRIBE - Calculate Moment 1-4 and 6 of a series

DIVIDE - Divide with an alternative return.

DO_SPEC - Display Periodogram and Spectrum

GET_FILE - Get a File Name

GET_NAME - Get Name of a Matrix Variable

GTEST - Tests output of a ARCH/GARCH Model

GWRITE - Save Objects in GAUSS Format using one file

GWRITE2 - Save Objects in GAUSS Format using two files

FREE - Free a variable.

LAGMATRIX - Builds Lag matrix.

MELD - Form all possible combinations of vectors.

QUANTILE - Calculate interquartile range.

RTEST - Test Residuals of Model

RTEST2 - Test Residuals of OLS Model - No RES and Y Plots

SET - Set all elements of an object to a value.

SETCOL - Set column of an object to a value.

SETLABEL - Set the label of an object.

SETNDIMV - Sets an element in an n dimensional object.

SETROW - Set row of an object to a value.

SETTIME - Sets the time info in an existing series

SORT - Sort a real vector.

SUBRENAME - Internally rename a subroutine.



Data Building Functions



AFAM - Change a matrix or vector to an array class object.

ARRAY - Define a 1d or 2d array.

C1ARRAY - Create a Character*1 array

C8ARRAY - Create a Character*8 array

CATCOL - Concatenates an object by columns.

CATROW - Concatenates an object by rows.

CFUNC - Call Function

COMB - Combination of N objects taken M at a time.

COMPLEX - Build a complex variable from two real*8 variables.

CUSUM - Cumulative sum.

CUSUMSQ - Cumulative sum squared.

DABS - Absolute value of a real*8 variable.

DARCOS - Arc cosine of a real*8 variable.

DARSIN - Arc sine of a real*8 variable.

DATAN - Arc tan of a real*8 variable.

DATAN2 - Arc tan of x / y. Signs inspected.

DBLE - Convert real*4 to real*8.

DCONJ - Conjugate of complex argument.

DCOS - Cosine of real*8 argument.

DCOSH - Hyperbolic cosine of real*8 argument.

DDOT - Inner product to two vectors.

DEXP - Exponential of a real*8 argument.

DFLOAT - Convert integer*4 to real*8.

DGAMMA - Gamma function of real*8 argument.

DINT - Extract integer part of real*8 number

DNINT - Extract integer part of real*8 number

DLGAMMA - Natural log of gamma function.

DLOG - Natural log.

DLOG10 - Base 10 log.

DMAX - Largest element in an array.

DMAX1 - Largest element between two arrays.

DMIN - Smallest element in an array.

DMIN1 - Smallest element between two arrays.

DMOD - Remainder.

DROPFIRST - Drops observations on top or array.

DROPLAST - Drops observations on bottom of an array.

DSIN - Calculates sine.

DSINH - Hyperbolic sine.

DSQRT - Square root of real*8 or complex*16 variable.

DTAN - Tangent.

DTANH - Hyperbolic tangent.

EPSILON - Positive value such that 1.+x ne 1.

EXP - Exponential of real*8 or complex*16 variable.

FLOAT - Converts integer*4 to real*4.

FREQ - Gets frequency of a time series.

FYEAR - Gets fraction of a year from julian date.

GETIDIM - Obtain value from an n dimensional object.

GMFAC - LU factorization of n by m matrix

GMINV - Inverse of General Matrix using LAPACK

GMSOLV - Solve Linear Equations system using LAPACK

GOODCOL - Deletes all columns where there is missing data.

GOODROW - Deletes all rows where there is missing data.

GRID - Defines a real*8 array with a given increment.

HUGE - Largest number of type

INTEGER8 - Load an Integer*8 object from a string

I4TOI8 - Move an object from integer*4 to integer*8

I8TOI4 - Move an object from integer*8 to integer*4

ICOLOR - Sets Color numbers. Used with Graphp.

IDINT - Converts from real*8 to integer*4.

IDNINT - Converts from real*8 to integer*4 with rounding.

IMAG - Copy imaginary part of complex*16 number into real*8.

INDEX - Define integer index vector.

INFOGRAPH - Obtain Interacter Graphics INFO

INT - Copy real*4 to integer*4.

INTEGERS - Generate an integer vector with given interval.

IQINT - Converts from real*16 to integer*4.

IQNINT - Converts from real*16 to integer*4 with rounding.

ISMISSING - Sets to 1.0 if variable is missing

KEEPFIRST - Given k, keeps first k observations.

KEEPLAST - Given k, keeps last k observations.

KIND - Returns kind of an object in integer.

KINDAS - Sets kind of second argument to kind first arg.

KLASS - Returns klass of an object in integer.

LABEL - Returns label of a variable.

LAG - Lags variable. Missing values propagated.

LOWERT - Lower triangle of matrix.

MCOV - Consistent Covariance Matrix

MASKADD - Add if mask is set.

MASKSUB - Subtract if mask is set.

MATRIX - Define a matrix.

MFAM - Set 1d or 2d array to vector or matrix.

MISSING - Returns missing value.

NEAREST Nearest distinct number of a given type

NOCOLS - Gets number of columns of an object.

NOELS - Gets number of elements in an object.

NOROWS - Gets number of rows of an object.

NORMDIST - 1-norm, 2-norm and i-norm distance.

PI - Pi value.

QCOMPLEX - Build complex*32 variable from real*16 inputs.

QINT - Extract integer part of real*16 number

QNINT - Extract nearest integer part of real*16 number

QREAL - Obtain real*16 part of a complex*32 number.

RANKER - Index array that ranks a vector.

REAL - Obtain real*8 part of a complex*16 number.

R8TOR16 - Convert Real*8 to Real*16

R16TOR8 - Convert Real*16 to Real*8

REAL16 - Input a Real*16 Variable

REC - Rectangular random number.

RECODE - Recode a real*8 or chartacter*8 variable

RN - Normally distributed random number.

SEXTRACT - Takes data out of a field.

SFAM - Creates a scalar object.

SNGL - Converts real*8 to real*4.

SPACING Absolute spacing near a given number

SUBMATRIX - Define a Submatrix

SUBSET - Subset 1d, 2d array, vector or matrix under a mask.

SUM - Sum of elements.

SUMCOLS - Sum of columns of an object.

SUMROWS - Sum of rows of an object.

SUMSQ - Sum of squared elements of an object.

TIMEBASE - Obtains time base of an object.

TIMESTART - Obtains time start of an object.

TINY Smallest number of type

UPPERT - Upper Triangle of matrix.

VECTOR - Create a vector.

VFAM - Convert a 1d array to a vector.

ZDOTC - Conjugate product of two complex*16 objects.

ZDOTU - Product of two complex*16 objects.

ZEROL - Zero lower triangle.

ZEROU - Zero upper triangle.





Data Filtering Subroutines



CSPECTRAL - Do cross spectral analysis.

SPECTRAL - Spectral analysis of a vector or 1d array.

FFT - Fast fourier transform.

SPECTRUM - Returns spectrum of a 1d object.

VAREST - VAR Modeling



Date and Time Functions



CHARDATE - Convert julian variable into character date dd\mm\yy.

CHARDATEMY - Convert julian variable into character data mm\yyyy.

CHARTIME - Converts julian variable into character date hh:mm:ss

CWEEK - Name of the day in character.

FDAYHMS - Gets fraction of a day.

GETDAY - Obtain day of year from julian series.

GETHOUR - Obtains hour of the day from julian date.

GETMINUTE - Obtains minute of the day from julian date.

GETMONTH - Obtains month from julian date.

GETQT - Obtains quarter of year from julian date.

GETSECOND - Obtains second from julian date.

GETYEAR - Obtains year.

IWEEK - Sets 1. for monday etc.

JULDAYDMY - Given day, month, year gets julian value.

JULDAYQY - Given quarter and year gets julian value.

JULDAYY - Given year gets julian value.

MAKEJUL - Make a Julian date from a time series



Estimation and residual testing Subroutines



ARMA - ARMA estimation using ML and MOM.

AUTOBJ - Automatic Estimation of Box-Jenkins Model

BDS - BDS Nonlinearity test.

BPFILTER - Baxter-King Filter.

DF - Calculate Dickey-Fuller Unit Root Test.

GAMFIT - Generalized Additive Model Estimation

GARCHEST - Estimate ARCH/GARCH model.

KEENAN - Keenan Nonlinearity test

KSWTEST - K Period Stock Watson Test

KSWTESTM - Moving Period Stock Watson Test

LAGTEST - 3-D Graph to display RSS for OLS Lags

LAGTEST2 - 3-D Graph to display Rss for MARS Lags

LM - Engle Lagrange Multiplier ARCH test.

MINIMAX - Estimate MINIMAX with MAXF2

OLSQ - Estimate OLS, MINIMAX and L1 models.

OLSPLOT - Plot of Fitted and Actual Data & Res

POLYFIT - Fit an nth degree polynomial

POLYVAL - Evaluate an nth degree polynomial

PP - Calculate Phillips Peron Unit Root test

PROBIT - Estimate Probit (0-1) Model.

QUANTREG - Quantile Regression Program

RESET - Calculate Ramsey(1969) regression specification test.

RESET77 - Thursby - Schmidt Regression Specification Test

REVERSE - Test a real*8 vector for reversibility in Freq.

Domain

ROTHMAN - Test a real*8 vector for reversibility in Time Domain

RRPLOTS - Plots Recursive Residual Data

SIMULATE - Dynamically Simulate OLS Model

SMOOTH - Do exponential smoothing.

SWARTEST - Stock-Watson VAR Test

TRIPLES - Calculate Triples Reversability Test

TSAY - Calculate Tsay nonlinearity test.

TSD - Interface to TSD Data set



Estimation and residual testing and Spline Functions



BOOTI - Calculate integers to be used with bootstrap.

BOOTV - Bootstraps a vector with replacement.

BOXCOX - Box-Cox Transformation of a series given lamda.

MLSUM - Sums log of elements of a 1d object.



Spline Functions



ABFSPLINE - Automatic Backfitting of a Spline Model

ACEFIT - Alternating Conditional Expectation Model Estimation

BSNAK - Compute Not a Knot Sequence

BSOPK - Compute optimal spline know sequence

BSINT - Compute 1-D spline interpolant given knots

BSINT2 - Compute 2-D spline interpolant given knots

BSINT3 - Compute 3-D spline interpolant given knots

BSDER - Compute 1-D spline values/derivatives given knots

BSDER2 - Compute 2-D spline values/derivatives given knots

BSDER3 - Compute 3-D spline values/derivatives given knots

BSITG - Compute 1-D spline integral given knots

BSITG2 - Compute 2-D spline integral given knots

BSITG3 - Compute 3-D spline integral given knots

CSPLINEFIT - Fit a 1 D Cubic Spline using alternative models

CSPLINE - Calculate a cubic spline for 1 D data

CSPLINEVAL - Calculate spline value given spline

CSPLINEDER - Calculate spline derivative given spline value

CSPLINEITG - Calculate integral of a cubic spline

MARS - Multivariate Autoregressive Spline Models

MARSPLINE - Updated MARS Command using Hastie-Tibshirani code

PISPLINE - Pi Spline Nonlinear Model Building





Integration Subroutines



DQDAG - Integrate a function using Gauss-Kronrod rules

DQDNG - Integrate a smooth function using a nonadaptive rule.

DQDAGI - Integrate a function over infinite/semi-infinite

interval.

DQDAGP - Integrate a function with singularity points given

DQDAGS - Integrate a function with end point singularities

DQAND - Multiple integration of a function

DTWODQ - Two Dimensional Iterated Integral





IO routines Subroutines



BACKSPACE - Backspace a unit

CLOSE - Close a logical unit.

COPYLOG - Copy file to log file.

COPYOUT - Copy file to output file.

COPYF - Copy a file from one unit to another.

ECHOOFF - Turn off listing of execution.

ECHOON - Turn on listing of execution.

EPPRINT - Print to log and output file.

EPRINT - Print to log file.

ERASE - Erase file(s).

FORMS - Build Control Forms

FPRINT - Formatted print facility.

GET - Gets a variable from b34s.

GETDMF - Gets a data from a b34s DFM file.

GETKEY - Gets a key

GETMATLAB - Gets data from matlab.

GETRATS - Reads RATS Portable file.

GETSCA - Reads SCA FSAVE and portable portable files

HEADER - Turn on header

ISEXTRACT - Place data in a structure.

LOADDATA - Load Data from b34s into MATRIX command.

MAKEDATA - Place data in a b34s data loading structure.

MAKEMAD - Makes SCA *.MAD datafile from vectors

MAKEMATLAB - Place data in a file to be loaded into Matlab.

MAKERATS - Make RATS portable file.

MAKESCA - Make SCA FSV portable file.

MENU - Put up user Menu for input

MESSAGE - Put up user message and allow a decision.

NOHEADER - Turn off header

OPEN - Open a file and attach to a unit.

PRINT - Print text and data objects.

PRINTALL - Lists all variables in storage.

PRINTOFF - Turn off Printing

PRINTON - Turn on Printing (This is the default)

READ - Read data directly into MATRIX workspace from a file.

RESTORE - Load data back in MATRIX facility from external save

file.

REWIND - Rewind logical unit.

RMATLAB - Runs Matlab

SAVE - Save current workspace in portable file format.

TABULATE - List vectors in a table.

WRITE - Write an object to an external file.





Matrix Functions



DERIVATIVE - Analytic derivative of a vector.

DET - Determinate of a matrix.

DIAG - Place diagonal of a matrix in an array.

DIAGMAT - Create diagonal matrix.

EIGENVAL - Eigenvalue of matrix. Alias EIG.

INV - Inverse of a real*8 or complex*16 matrix.

KPROD - Kronecker Product of two matrices.

PDFAC - Cholesky factorization of PD matrix.

PDFACDD - Downdate Cholesky factorization.

PDFACUD - Update Cholesky factorization.

PDINV - Inverse of a PD matrix.

PDSOLV - Solution of a PD matrix given right hand side.

PERMUTE - Reorder Square Matrix

PINV - Generalized Inverse.

PROD - Product of elements of a vector.

QRFAC - Obtain Cholesky R via QR method.

QRSOLVE - Solve OLS using QR.

RCOND - 1 / Condition of a Matrix.

ROLLDOWN - Moves rows of a 2d object down.

ROLLLEFT - Moves cols of a 2d object left.

ROLLRIGHT - Moves cols of a 2d object right.

ROLLUP - Moves rows of a 2d object up.

SCHUR - Performs Schur decomposition

SEIGENVAL - Eigenvalues of a symmetric matrix. Alias SEIG.

SVD - Singular value decomposition of an object.

TRACE - Trace of a matrix.

TRANSPOSE - Transpose of a matrix.

ZDOTC - Conjugate product of two complex*16 objects.

ZDOTU - Product of two complex*16 objects.



Miscellaneous Subroutines



BREAK - Set User Program Break Point.

COMPRESS - Compress workspace.

COPY - Copy an object to another object

LAPACK - Sets Key LAPACK parameters

LOAD - Load a Subroutine from a library.

MAKEGLOBAL - Make a variable global (seen at all levels).

MAKELOCAL - Make a variable seen at only local level.

MANUAL - Place MATRIX command in manual mode.

NAMES - List names in storage.

LRE - McCullough Log Relative Error

PCOPY - Copy an object from one pointer address to another

REAL16INFO - Obtain Real16 info

REAL16OFF - Turn off Real16 add

REAL16ON - Turn on extended accuracy

REAL32OFF - Turn off Real32 add

REAL16ON - Turn on Real*32 extended accuracy

RUN - Terminates the matrix command being in "manual" mode.

SETLEVEL - Set level.

SETWINDOW - Set window to main(1), help(2) or error(3).

SIGD - Set print digits. Default g16.8

STOP - Stop execution of a program.

TESTARG - Lists what is passed to a subroutine or function.

TIMER - Gets CPU time.

VOCAB - List built-in subroutine vocabulary.



Miscellaneous Functions



ARGUMENT - Unpack character argument at run-time

FACT - Factorial

LEVEL - Returns current level.

POINTER - Machine address of a variable.

POLYROOT - Solution of a polynomial.

POLYDV - Division of polynomials.

POLYMULT - Multiply two polynomials

VOCAB - List built in functions.



Nonlinear Estimation Capability Subroutines



CMAXF1 - Constrained maximization of function using zxmwd.

CMAXF2 - Constrained maximization of function using dbconf/g.

CMAXF3 - Constrained maximization of function using db2pol.

BGARCH Calculate function for a BGARCH model.

GARCH - Calculate function for a ARCH/GARCH model.

GARCHEST - Estimate ARCH/GARCH model.

LPMAX - Solve Linear Programming maximization problem.

LPMIN - Solve Linear Programming minimization problem.

MAXF1 - Maximize a function using IMSL ZXMIN.

MAXF2 - Maximize a function using IMSL DUMINF/DUMING.

MAXF3 - Maximize a function using simplex method (DU2POL).

NLEQ - Jointly solve a number of nonlinear equations.

NLLSQ - Nonlinear Least Squares Estimation.

NL2SOL - Alternative Nonlinear Least Squares Estimation.

NLPMIN1 - Nonlinear Programming fin. diff. grad. DN2CONF.

NLPMIN2 - Nonlinear Programming user supplied grad. DN2CONG.

NLPMIN3 - Nonlinear Programming user supplied grad. DN0ONF.

NLSTART - Generate starting values for NL routines.

QPMIN - Quadratic Programming.

SOLVEFREE - Set frequency of freeing temp variables.





Random Number Generation and Testing - IMSL Names preserved



I_RNGET - Gets seed used in IMSL Random Number generators.

I_RNSET - Sets seed used in IMSL Random Number generators.

I_RNOPG - Gets the type of generator currently in use.

I_RNOPT - Selects the type of uniform (0,1) generator.

I_DRNSES - Initializes the table used by shuffled generators.

I_DRNGES - Get the table used in the shuffled generators.

I_DRNUN - Uniform (0,1) Generator

I_DRNNOR - Random Normal Distribution

I_RNBIN - Random integers from binomial distribution

I_DRNGDA - Random integers from discrete distribution alias

approach

I_DRNGDT - Random integers from discrete using table lookup

I_RNGEO - Random integers from Geometric distribution

I_RNHYP - Random integers from Hypergeometric distribution.

I_RNNBN - Negative binomial distribution

I_DRNBET - Random numbers from beta distribution

I_DRNCHI - Random numbers from Chi-squared distribution

I_DRNCHY - Random numbers from Cauchy distribution

I_DRNEXP - Random numbers from standard exponential

I_DRNEXT - Random numbers from mixture of two exponential

distributions

I_DRNGAM - Random numbers from standard gamma distribution

I_DRNGCT - Random numbers from general continuous distribution

I_DRNLNL - Random numbers from lognormal distribution

I_DRNNOA - Random normal numbers using acceptance/rejection

I_DRNNOR - Random normal numbers using CDF method

I_DRNSTA - Random numbers from stable distribution

I_DRNTRI - Random numbers from triangular distribution

I_DRNVMS - Random numbers from Von Mises distribution

I_DRNWIB - Random numbers from Weibull distribution

I_RNMTN - Random numbers from multinomial distribution

I_DRNMVN - Random numbers from multivariate normal

I_DRNSPH - Random numbers on the unit circle

I_RNPER - Random perturbation of integers

I_RNSRI - Index of random sample without replacement





Screen I/O and Plot Subroutines



CLS - Clear screen.

FPLOT - Plot a Function

GRAPH - High Resolution graph.

GRAPHP - Multi-Pass Graphics Programing Capability

GRCHARSET - Set Character Set for Graphics

GRREPLAY - Graph replay and reformat command.

OUTDOUBLE - Display a Real*8 value at a x, y on screen.

OUTINTEGER - Display an Integer*4 value at a x, y on screen.

OUTSTRING - Display a string value at a x, y point on screen.

PLOT - Line-Printer Graphics

SCREENCLOSE - Turn off Display Manager

SCREENOPEN - Turn on Display Manager

SCREENOUTOFF - Turn screen output off.

SCREENOUTON - Turn screen output on.



Statistical Functions



BETAPROB - Calculate a beta probability.

BINDF - Evaluate Binomial Distribution Function

BINPR - Evaluate Binomial Probability Function

BLUS - BLUS Residual Analysis

CHISQPROB - Calculate chi-square probability.

DERF - Error function of real*8/real*16 argument.

DERFC - Inverse of error function.

FPROB - Probability of F distribution.

HYPDF - Evaluate Hypergeometric Distribution Function

HYPPR - Evaluate Hypergeometric Probability Function

INVBETA - Inverse beta distribution.

INVCHISQ - Inverse Chi-square distribution.

INVFDIS - Inverse F distribution.

INVTDIS - Inverse t distribution.

MEAN - Average of a 1d object.vector.

NCCHISQ - Non central chi-square probability.

NORMDEN - Normal density.

POIDF - Evaluate Poisson Distribution Function

POIPR - Evaluate Poisson Probability Function

PROBIT - Inverse normal distribution.

PROBNORM - Probability of normal distribution.

PROBNORM2 - Bivariate probability of Nornal distribution.

TDEN - t distribution density.

TPROB - t distribution probability.

VARIANCE - Variance of an object.



System Subroutines



DODOS - Execute a command string if under dos/windows.

DOUNIX - Execute a command string if under unix.

SYSTEM - Issue a system command.





Time Series Functions



ACF - Calculate autocorrelation function of a 1d object.

CCF - Calculate the cross correlation function on two

objects.

DIF - Difference a series.

FRACDIF - Fractional Differencing.

GENARMA - Generate an ARMA series given parameters.

MAKEJUL - Make a Julian date from a time series



Variable Precision Math Subroutines and Functions



Subroutines



VPASET - Set Variable Precision Math Options



Functions



VPA - Variable Precision Math calculation





Listing of Alias function names



Name Replaced by

LOG DLOG

LN DLOG

LOG10 DLOG10

EXP DEXP

MOD DMOD

MAX DMAX

MAX1 DMAX1

MIN DMIN

INVERSE INV

SIN DSIN

COS DCOS

R4TOR8 DFLOAT

R8TOR4 FLOAT

SQRT DSQRT

SINH DSINH

GAMMA DGAMMA

COSH DCOSH

CONJ DCONJ

ATAN DATAN

ATAN2 DATAN2

ARSIN DARSIN

ARCOS DARCOS

ABS DABS





Index of Toolkit Routines contained in matrix2.mac



Index of programs, subroutines and Functions



ACF_PLOT - Simple ACF Plot

AUTOCOV - Autocovariance

BPF - Baxter - King MA Filter

BPFM - Baxter - King MA Filter with missing data

CFREQ - Determine Cumulative Frequency Distribution

COINT2 - Cointegration Tests of Two Series

COINT2LM - Cointegration Tests of Two Series, OLS, L1, MM

COINT2M - Moving Cointegration of Two Series

COINT2ME - Moving Cointegration of Two Series - Extended Args.

COINT2M2 - Moving Cointegration of Two Series OLS, L1, MM

COINT3 - Cointegration Tests of Three Series

COINT3ME - Moving Cointegration of Three Series

DATA_ACF - Calculate ACF and PACF Plots

DATAVIEW - View a Series Under Menu Control

DO_SPEC - Display Periodogram and Spectrum

DUD - Derivative Free Nonlinear Estimation

FDIFINFO - Fractional Differencing Information

FILTER - High Pass / Low Pass Filter using Real FFT

FILTERC - High Pass / Low Pass Filter using Complex FFT

FORPLOT - Forecast Plot using GRAPHP

GARCH2P - Two Pass GARCH Using ARMA Command

GARCH2PF - Two pass GARCH using ARMA Command with forecasting

GTEST - Tests output of a ARCH/GARCH Model

GWRITE - Save Objects in GAUSS Format using one file

GWRITE2 - Save Objects in GAUSS Format using two files

HP_BP_1 - Baxter-King & Hodrick-Prescott Filtering

HP_BP_2 - Baxter-King & Hodrick-Prescott Filtering Moving

Window

HP_2 - Hodrick & Prescott Filtering of a Moving Window

LMTEST - Engle (1982) test for ARCH for a range of lags

MARSPLOT - Automatically plot MARS Curves and Surface Plots

MCLEODLI - McLeod-Li (1983) Linearity test

MARQ - Estimation of a Nonlinear Model using Derivatives

MINIMAX - Estimate MINIMAX with MAXF2

MISSPLOT - Plot of a series with Missing Data

MQSTAT - Multivariate Q Statistic

MOVEAVE - Moving average of a vector

MOVEBJ - Moving Arima Forecast using AUTOBJ

MOVEH82 - Moving Hinich 82 test

MOVEH96 - Moving Hinich 96 test

MOVEOLS - Moving OLS Calculation

MOVEVAR - Moving Variance

NLVARCOV - Calculates NLLSQ Variance Covariance

OLSPLOT - Plot of Fitted and Actual Data & Res

PAD - Pad a 1D Real*8 Series on both ends

PVALUE_1 - Present value of $1 recieved at end of n years

PVALUE_2 - Present Value of an Annuity of $1

PVALUE_3 - Present value of $1 recieved throughout year

RTEST - Test Residuals of Model

RTEST2 - Test Residuals of Model - No RES and Y Plots

QUANTREG - Quantile Regression Program

RESET77 - Thursby - Schmidt Regression Specification Test

SUBSET - Subset 1d, 2d array, vector or matrix under a mask.





Running the Matrix Command:



The MATRIX command can be run in "batch mode" or interactively. When

run interactively, statements can be reloaded and scripts can be edited

and submitted. The file _imatrix.mac is the default name for the script

files. The first member _matrix is automatically run if the script is

submitted.



The B34S save file format is the same as used by Speakeasy and the

Speakeasy importall statement can be used to further process this file.

The MATRIX command can also read and write SCA and RATS portable files

and provides a bridge between these systems. The Display Manager

provides a number of options on how to use the system.



1. The MATRIX button on the Display Manager window gets B34S into

interactive MATRIX command mode. If the user wants to customize how the

matrix command will come up, the IMATRIX section in the MATRIX.MAC file

can be changed. In MANUAL mode one command at a time can be entered or

scripts can be edited and run. The user is encouraged to modify the

MATRIX file to load data etc. Interative use is intended for quick

commands. If the MATRIX member of the MATRIX.MAC file is modified, the

MATRIX button could be made to execute a matrix program, BEFORE going

into MANUAL mode. The MATRIX member of matrix.mac is:



/$ This shell can be modified to load data set if desired

b34sexec matrix;

call manual;

b34srun;



The _imatrix.mac file has a required member _matrix which can be edited

and submitted while under in the interactive matrix command mode. A

sample file is:



==_matrix

program _matrix;

/$ Lines above this are required

x=array(100:);

y=rn(x);

z=rn(y);

x=rn(x);

call graph(y,z);

call names(all);

call tabulate(x,y,x);

call olsq(y x:print);

call load(user '_imatrix.mac');

call user;

/$ Lines next are required

call manual;

return;

end;

==

==user

program user;

/$ this is a user program;

call print('I am in the user program user!!':);

return;

end;

==



2. The MATRIX command has been designed to run in "batch" mode from a

command file. This file is usually submitted from a FILE or from the

TASKS command of the Display Manager.



3. The LINEEDIT option under the MENU button allows multiple lines to

be entered. This way quick MATRIX jobs can be submitted. By use of the

MENU "RELOAD" facility, the commands just submitted can be recalled and

changed but are not saved in memory.



4. The MENU command provides two options. The MATRIX command gives the

user a screen where any MATRIX commands can be entered. In this mode a

"batch file" is interactively submitted. This mode is designed

for quick jobs that call user PROGRAMS, SUBROUTINES and FUNCTIONS. By

use of the RELOAD option, these commands can be modified and

resubmitted. The MENU command also allows access to the MATRIX command

which is the same as what is available with the IMATRIX Display Manager

command (see # 1 above).



In the middle of a MATRIX command section the command:



call save;



will save the workspace. Later in the session OR at a later session, the

command:



call restore;



will bring back what has been saved. The default name is



matrix.psv



A specific file can be given using the forms



call save(:file 'mystuff.psv');



which can be brought back with



call restore(:file 'mystuff.psv');



These save files can be read with Speakeasy(r) using the Speakeasy

IMPORTALL command. If b34s matrix command PROGRAMS, SUBROUTINES or

FUNCTIONS are present in the B34S MATRIX command workspace, the command



call save(:speakeasy);



will save only data objects. Because Speakeasy will not support

variables of the form %name, such variables are name _name. On

a restore these are converted back. The keyword checkpoint

can be used in the place of save to be compatible with Speakeasy.

If checkpoint is used, subroutines, functions and programs are

automatically not saved.



The MATRIX command interactive mode can be terminated by



call run;



and started later in the same job with



call manual;



This way a complex program can be debuged by looking an intermediate

values.



Since all output is written to the b34s output file in the usual manner,

View log and View output are always available to inspect results.



Help



The usual b34s help facility provides a discussion of all B34S MATRIX

commands. In addition the file matrix.mac provides an example of

virtually all MATRIX commands. These examples can be viewed with the

help facility, executed or saved in the B34S buffer where they can be

either run or further modified. The file matrix2.mac contains programs,

subroutines or fuctions that can be run provided that they are loaded

with the command



call load(somename);





Form of MATRIX command.



b34sexec matrix options parameters;



b34seend$



MATRIX Command Options





SAVEASVECTOR - Saves B34S variables as vectors. Default

is to save as an array. For the differences

between vector and array math, see below.

For a minor example, if the b34s variable

GASOUT is saved as an array. The statement

test=gasout**2.;



will square each element, If GASOUT is

saved as a vector, the command



test=gasout**2.;



will produce one observation which is the

sum of squared values of GASOUT.



SHOWUSE - Shows use of arrays. Indicates current

limits of the program.



HEADER - Turns on Header. Default is NOHEADER.

The commands



call noheader;



call header;



can turn the header off and on inside the

matrix step.



CBUFFER=n1 - Sets size of Command buffer. If a bigger

size is needed, a message will be

given. For further info see below.



SIGD=n2 - Sets number of significant digits in

variable printing. Default g16.8 for

real*8. This can also be set by



call sigd(i);



in open matrix language code. If i le 8

g16.i is used. If i > 8 then g16+(i-8).i

format is used. For example i = 10 uses

g18.10.



SOLVEFREE=n3 - Sets frequency of cleaning temp variables

with SOLVE command. Default = 50. If

error message on exceeding temp variables

is seen, set number smaller. A larger

n2 value can reduce CPU time. The

subroutine SOLVEFREE can be used to

test your code.



DSEED=r - Sets the seed for GGNML and GGUBS and

other routines. This seed works the same

but can be set to a different value than

the seed set set under the OPTIONS command.

The exact random number routine used is

set on the OPTIONS command with the

command RECVER and RNVER. Consult help

files for this command for further

detail. Default = 123457.0d+00 or the

seed set with SETSEED on the OPTIONS

command. The possibly of a different seed

for the MATRIX command isolates how this

command runs in relation to a default

seed set with SETSEED in a user

AUTOEXEC.B34 file. Since not all random

number generators are equal, users should

use caution. Empirically it was found that

if 3000 random normal deviates are

generated using the default (IMSL) seed,

the BDS statistic flags the series as

"nonlinear." This finding is strange

to say the least. Using I_RNOPT command

the exact uniform generator for IMSL

random number routines can be selected.



The MATRIX command RN( ) and REC( )

have optional switches that allow the

default random number routines to be

replaced by IMSL version 10 routines.



DISPLAY=key - Sets accuracy and number of Cols to

print matrix output. Key can be set:



COL80FIXED f18.5

COL80MEDIUM g15.6

COL80HIGH g25.16

COL129FIXED f18.5

COL129MEDIUM g15.6

COL129HIGH g25.16



The default is COL129MEDIUM.



This can be set globally with the options

commands linesize and sigd



LINESIZE SIGD DISPLAY

80 8 COL80HIGH

132 8 COL129HIGH





Size of problems:



The maximum size of any problem is limited by the maximum

number of sentences in the parse table (MAXNSENT) and the maximum

number of tokens (MAXNTOKEN). These can be increased in the

autoexec.b34 file on the PC, or in an OPTIONS command such as



b34sexec options maxnsent(600) maxntoken(5000); b34srun;

Other current constraints are:



Max number of objects in memory 10000.

Max number of arguments to a function or subroutine 2500.



These constraints may change in the future. For other limitations

see the SHOWUSE command of the MATRIX sentence.



Overview of the Matrix Language Cont.



The goal of the MATRIX command is to provide a high-level programing

language that will allow the user to easily customize a B34S

application. The MATRIX command consists of analytic statements that

that can be reduced to assingment statements and keywords. In contrast

to address oriented programing languages such as FORTRAN, the B34S

matrix language is object oriented. Assuming X was a vector of 20

numbers, the command



ameanx=mean(x);



places the mean of the x vector in the variable ameanx.



Keywords such as PRINT are used in the form



call print('This will print x',x);



which will print the statement and the object x. The PRINT command will

allow up to 400 arguments or objects to be passed in one call.



Keywords are built into the language or can be user written SUBROUTINES,

FUNCTIONS or PROGRAMS. User SUBROUTINES and FUNCTIONS pass objects as

arguments and calculate in a protected workspace. This means that a

variable X can be defined at both the base level and in the SUBROUTINE

to mean different things. The difference between PROGRAMS and

SUBROUTINES is that SUBROUTINES pass arguments and work in a protected

space while PROGRAMS do not pass arguments. PROGRAMS use the current

level as their name domain. Hence if a PROGRAM is called from the base

level, it can access objects known at that level. If the same programn

is called from a SUBROUTINE, it will access data known at that level

only. User SUBROUTINES and FUNCTIONS also have access to GLOBAL

variables.



Recursive Notes: User SUBROUTINES and FUNCTIONS can be called

recursively up to the MAXSTAK limit currently 5000, although CBUFFER

will have to be increased to handle saving the open arguments. Recursive

calls are very very slow but are useful in some situations. Job

RECURSIVE in matrix.mac shows that for the same task, a DO loop is 100

times faster than a recursive function or subroutine call. A DO loop

itself is slow relative to object calculations. FORMULA & SOLVE

statements are from 4 - 10 times faster than DO loops. The speed gain

depends on: 1. the length of the vectors, 2: the complexity

of the problem and 3. the SOLVEFREE setting which sets how frequently

temp variables are freed in the workspace. If recursive calls are a

major problem, a brach to an externallu compiled Fortran program might

be a good solution. For further detail, see section 14 of this help

file.



User SUBROUTINES, PROGRAMS and FUNCTIONS must have names of 8 or

less characters. A simple example of a user subroutine is DESC



subroutine desc(name,mean1,var);

mean1=mean(name);

var=variance(name);

return;

end;



The following code fragment uses DESC



x=array(5:1 2 3 4 5);

call desc(x,m,v);

call print(Variable mean var',x,m,v);





A PROGRAM for the same result would be



program desc2;

m=mean(x);

v=variance(x);

return;

end;



The following code fragment uses DESC2.



x=array(5:1 2 3 4 5);

call desc2;

call print(Variable mean var',x,m,v);



Note that in this case the actual names are needed to be used inside

DESC2 since the name domain is at the global level.



A simple user function DESF will return the mean although in this

case it makes little sense since we have the built-in function mean.



function desf(x);

m=mean(x);

return(m);

end;





The following code fragment uses desf



x=array(5:1 2 3 4 5);

amean=desf(x);



MATRIX command built-in FUNCTIONS and SUBROUTINES in addition to

allowing name arguments, also allow passing character strings subject

to a limitation shown below.



Given

subroutine printit(c);

call print(c);

return;

end;



If the string is LE 8 characters the form



call printit('less8');



can be used. If the string is greater that 8, then the correct form is



call character(c,'This is greater than 8');

call printit(c);



must be used. This is illustrated in the job char_4 in the matrix.mac

file. What is happening is that the form



call printit('aa');





places the string 'aa' in a chararacter*8 variable.



The form



call character(cc,'aa');

call printit(cc);



places the string 'aa' in a two element character*1 array.



Thus the statement



name='J';



creates a character*8 variable. If this is used in an assingment

statement to a character*1 variable, the character*1 variable will be

redefined which may not be what is wanted. This is illustrated in the

job char_5 which is listed next:



b34sexec matrix;

call echooff;

x=rn(matrix(30,30:));

call character(ii,'Element (1, ');

call character(ii2,' ');

jj=integers(12,17);

do i=1,30;

call inttostr(i,ii2,'(i6)');

ii(jj)=ii2(jj-11);

call character(rp,')');

/$ **********************************************************

/$ Warning the statement

/$ ii(18)=')';

/$ does not work since it will be redefined to be character*8

/$ and will be outside the 132 range and not printed

/$ **********************************************************

ii(18)=rp;

call print(ii,x(1,i) :line);

next i;

call names(all);

b34srun;



Summary. Since the MATRIX command supports character*8 and character*1

data added care must be used to pass just what is desired to a user

routine. Built-in subroutines and functions can detect just what has

been passed and take the appropriate path.



The command character or char1 can be used to build a multi-line 2D

character*1 array.



call character(text,'This is line one'

'This is line two which is longer'

'This is line three'

'This is 4');



produces a 2d character*1 array of size 4,132 where 132 is the max

length of a line.



Strings to the character command can be up to 132 in length.



Advanced concepts.



Note: If a MATRIX command variable name is passed to a user SUBROUTINE

or FUNCTION, it is possible to return a changed value. If a

structured object is passed, it is NOT possible to return

a value. This follows the Speakeasy convention but is not the

usual case in Fortran. The reason for this is that the structured

object may repackage the data, which is not the case in Fortran.

For example assume matrix A defined as



n=10;

a=rn(matrix(n,n:));



if we call desc (see routine listed above) as



call desc(a(1,),m,v);

mm(1)=m;

vv(1)=v;

call desc(a(2,),m,v);

mm(2)=m;

vv(2)=v;



we have the desired result since DESC does not change the first

argument. However the code



call desc(a(1,),m(1),v(1));

call desc(a(2,),m(2),v(2));

will not work as intended because in the parsing

process, m(1), m(2), v(1), and v(2) are replaced by

temporary variables. After returning the temp values

not the real values are saved. One would think that this

could be taken care of by the compiler BUT this is not

possible. The reason relates to how stuctured objects are

handled. Consider the following code.



x=rn(matrix(10,10:));

row2=x(2,);



In the matrix the elements of row 2 differ by 10 memory

positions since Fortran saves by column. However the

command row2=x(2,); "repackages" these elements so that

they are next to each other. Hence putting them back into

the matrix X is not just a copy operation. For this reason

users have to be careful when passing structured objects.

B34S MATRIX USER SUBROUTINES and FUNCTIONS pass structured

objects by value NOT by address! More detail on this is

provided below.



In other languages such as MATLAB arguments cannot be changed at all.

In MATLAB if the user has a function myfun that takes three arguments

and returns two, the MATLAB calling form is



[back1,back2]=myfun(in1,in2,in3);



where in matlab the function is defined by



function[bb,cc]=myfun(aa1,aa2,aa3)



The B34S MATRIX command follows the Speakeasy conventions and allows a

bit more flexibility. However users have to be careful.



The MATRIX language recognizes the following types of objects which

are given kind and klass numbers.





kind

character*1 -1

real*4 4

real*8 8

real*16 -16

complex*16 16

complex*32 32

program 1

subroutine 2

function 3

formula 33

character*8 -8

integer*4 -4

integer*8 -88

vpa real 88

vpa real packed 888

vpa integer -44

vpa integer packed -444

vpa complex 160

vpa complex packed 1600

not defined -99



Klass

scalar 0

vector 1

matrix 2

1 dim array 5

2 dim array 6



The matrix language recognizes structured objects.



Define a as matrix 1. 2. 3.

4. 5. 6.

7. 8. 9.



with the command



a=matrix(3,3:1 2 3 4 5 6 7 8 9);



The matrix, array and vector commands are the only ones that

automatically convert integer input to real*8. If an integer*4 matrix

is desired use



a=idint(matrix(3,3:1 2 3 4 5 6 7 8 9));



The command



call print(a(2,));



prints row 2 while



call print(a(,3))



prints column 3.



After defining an integer vector i of two elements 1 and 3



i=integers(1,3,2);



the commands



call print('This is row 1 and 3',a(i,));

call print('This is col 1 and 3',a(,i));



will pull off rows 1 & 3 and columns 1 & 3 respectively.



Remember structured objects pass as values NOT addresses.



Structured objects can be used as arguments but cannot be used for

output. On the left of an = sign assingments are possible. This is

contrary to Fortran which passes by address. B34S "repackages" the

structured object data and passes the values leaving the original array

intact. Internally the matrix is saved by columns following Fortran.

Hence both x(2,) and x(,2) pass contiguous values although the

underlying storage is NOT contiguous for x(2,). What is happening is

that the B34S parser "repackages" the second row, which was not saved as

contiguous values, into a vector. For this reason it is not possible to

return back values from a structured variable address such as x(,i),

x(i) or x(3,) etc. In a sense this "limitation" of returning values

in a structured object frees the user from having to remember the

underlying storage of the matrix object. Here the vector is an object in

its own right. That is how we think of it in mathmatics. The goal of the

MATRIX design is to think in mathematics, not in computer storage

conventions.



Speed design considerations:



Code such as



i=integers(2,20);

j=i-1;

a(j) = b(i);



involves repetitive expansion of A which has not been defined to

the correct size and therefore has to be expanded on the fly. While

such code will work, a better approach is



b34sexec matrix;

b=rn(array(30:));

i=integers(2,20);

j=i-1;

a=array(dmax(j):);

a(j) = b(i);

call tabulate(a,b);

b34seend$



which will run substantially faster.



The following code illustrates some of these concepts.



x=rn(matrix(3,3:));

a(1,1)= mean(x);

v=vector(3:1 2 3);

a(2,)=v;

i=idint(array(2:1,3));

* place terms 1 3 of v in newv;

newv=v(i);

x=matrix(3,3:integers(1,9));

* places rows 1 and 3 of x or



1 2 3

7 8 9

in newx;

newx=x(i,);



The mean of x is now in a(1,1), 1 2 3 is in row 1 of newx and 7 8 9 are

in row 2. 1.0 and 3.0 are in variable newv.



Data can be placed in structured objects a number of ways.



To put 6.0 in col 3 of x at all locations:



call setcol(x,3,6.0);



To put 7.0 in row 6 of x at all locations:



call setrow(x,6,7.0);



another way would be



x(6,)=(array(nocols(x):)+7.0);



assuming x is a 2d array. Or



x(6,)=7.;



Object expansion is possible. The command



a(6,)=v;



would place v in a new row 6 of x.



Due to possible ambiguity, if v is a vector and i and j are vectors, the

statement



x(i,j)=v;



is not allowed.



The command



newx=matrix(n,n:)+8.0;



will build a n by n matrix with 8.0 on the diagonal



while



newx=array(n,n:)+8.0;



will put 8.0 in all elements. These statements illustrate the difference

between "matrix math" and "array math."



The operators .EQ. .LT. .GT. .NE. .GE. .LE. .OR. .AND. can be used in

expressions as well as IF and WHILE statements.



Given

x=2.0; y=3.0; test1=x.eq.y; test2=x.ne.y;



returns test1=0.0 and test2=1.0



If x=array(:1 2 3); y=array(:1 2 4);



the commands



test1=x.eq.y; test2=x.ne.y;



imply



test1=array(:1.0 1.0 0.0) since x(3) ne y(3)



test2=array(:0.0 0.0 1.0) since x(1)=y(1) and x(2)=y(2)



Note: That in an IF statement the arguments must be scalars while

analytic statements of the form



x=



will create a scalar or vector depending on the inputs. If one input is

a vector, the other input must be a scalar or a vector of the same size.



Warning: The logical operators .and. and .or. can be used to compare

0.0 and 1.0 values only.



Names of Objects and commands.



B34S MATRIX commands that do not return an argument across an equals

are executed by the CALL sentence. The CALL sentence first looks in

named storage for a routine with this name. If this is not found, then

the built in routines are used. While it is possible to have a user

routine with the same name as a built in routine, this is not a good

idea. For example assume you have loaded the series GASOUT. The command



acf=acf(gasout,24);



will place 24 autocorrelations of the GASOUT series in the structured

variable ACF. The result is that the ACF command is no longer available.

If the command



acf2=acf(gasin,24);



is given later in the job, B34S will object that ACF is not a 2D object.

The solution is to use FREE to "turn on" the built-in command ACF.



call free(acf);

acf2=acf(gasin,24);



or better still resist using an internal command name as a variable

name.

Math using the MATRIX Command.



The MATRIX command allows math between 1 and 2 dimensional arrays

and between vectors (1 dimensional) and matrices (2 dimensional)

for real*8 and complex*16 objects.



Array math can be done between real*8, real*4, real*16, integer*4 and

complex*16 objects. Objects of different types cannot be mixed. If this

is attempted, B34S will give a "mixed mode" error message. The reason

for this is given below.



Warning. Only in the most extreme cases should variables be saved as

real*4. The real*4 data type is for some graphic applications and for

variable storage in cases where memory is low. While array and matrix

math is possible for real*4, other functions such as sin will not work

to prevent users from making calcualtios that have accyracy loss.



Matrix and vector math can be done only with real*4 real*8, real*16,

complex*16, complex*32 variables and vpa real and complex objects.



Assume r8 is real*8.



newr=r8*2.0;



is allowed but



newr=r8*2;



is not allowed since 2 is an integer. The error message will refer to

"mixed mode" operations. The logic behind not allowing r8*2 is that it

is not clear whether an integer*4 or real*8 result is desired. This

convention is not followed in Speakeasy which tries to make everything

real*8. The reason for this "restriction" is illustrated by the

following example. Assume the commands



x=10.;

y=x*2;



where given. The parser would not know if Y should be integer*4 20

or real*8 20.





Note: The functions DBLE, SNGL, DINT, IDINT, INT, FLOAT, DFLOAT, REAL,

IMAG, COMPLEX, r8tor16, r16tor8, c16toc32, c32toc16 i4toi8, i8toi4

and vpa can be used to convert the storage of a variable.



Speed considerations:



To increase run-time speed the CALL command is used in place of just

naming the SUBROUTINE as is done with some other programming systems

such as Speakeasy and MATLAB. B34S follows the Fortran convention.



Arguments passed to subroutines and functions must be inside ( ).

Built in Matrix Commands called with CALL must not be mixed.

For example



call names;



is allowed. but



call names names(all);



is not allowed since the command NAMES(ALL) is not the first key word

in the call sentence.



Matrix Command Files:



The file c:\b34slm\matrix.mac contains a number of complete matrix

command examples. These can be executed, loaded into the program buffer

under TASKS, or viewed using the help facility. There are working

examples for virtually every matrix command. Users should customize

these examples.



The file c:\b34slm\matrix2.mac contains matrix command SUBROUTINES,

PROGRAMS and FUNCTIONS. These can be loaded as run time with the

command



call load(somename);



or loaded into the program buffer, or viewed with the help facility.

Each file cannot contain anything except, SUBROUTINES, PROGRAMS or

FUNCTIONS. The advantage of loading a routine with a CALL LOAD

statement, rather than having the routine in the command file, is that

parse space is saved and execution speed is also increased. If the

user adds routines to the library, it is important that the code be

"clean" since the parser will not check the code in the same manner

as would be the case if the routine were loaded. Unless the routine

produces output, most routines are called inside CALL ECHOOFF;

CALL ECHOON; statements so that the statements executed will not echo

to the output file.



The files staging.mac and staging2.mac are like matrix.mac and

matrix2 except that they are for prospective commands. These commands

are documented inside the routine and not in the b34shelp.dat file.



Basic rules of the B34S Matrix Command:



1. All matrix statements MUST end in $ or ;.



x=dsin(q);



2. Mixed mode math is not allowed. For example assuming x is real*8



x=x*2;



is not allowed because x is real*8 and 2 is an integer. The reason

mixed mode is not allowed is that the processor would not know what

to do with the result.



The correct form is



x=x*2.;



or



x=idint(x)*2;



if you want an integer result and x was real*8 before the command.



3. Structured objects can only be used on the right of an expression

or in a subroutine call as input. For example



mm=mean(x(,3));



calculates the mean of col 3 while



nn=mean(x(3,));



calculates the mean of row 3.





4. Structured objects can be used on the left of an assignment statement

to load data.



The commands



x=3.0;

x(2)=4.0;



add another element to x.



x=rn(matrix(4,4:));

x(,2)=0.;



places 0.0 in col 2 while



x(3,)=99.;



places 99.0 in row 3.



The following code shows advanced structured index processing. This

code is available in matrix.mac at overview_2



/$ Illustrates Structural Index Processing

b34sexec matrix;



x =rn(matrix(6,6:));

y =matrix(6,6:);

yy =matrix(6,6:);

z =matrix(6,6:);

zz =matrix(6,6:);

i=integers(4,6);

j=integers(1,3);

xhold=x;



hold=x(,i);

call print('cols 4-6 x go to hold',x,hold);



y(i, )=xhold(j,);

call print('Rows 1-3 xhold in rows 4-6 y ',xhold,y);

y=y*0.0;

j2 =xhold(j,);

y(i, )=j2 ;

call print('Rows 1-3 xhold in rows 4-6 y ',xhold,y);



z(,i)=xhold(,j);

call print('cols 1-3 xhold in cols 4-6 z ',xhold,z);

j55 =xhold(,j);

z=z*0.0;

z(,i)=j55;

call print('cols 1-3 xhold in cols 4-6 z ',xhold,z);



yy=yy*0.0;

yy(i,)=xhold;

call print('rows 1-3 xhold in rows 4-6 yy',xhold,yy);



zz=zz*0.0;

do ii=1,3;

jj=ii+3;

zz(,jj)=xhold(ii,);

enddo;



call print('Note that zz(,j)=xhold(i,) will not work');

call print('rows 1-3 xhold in cols 4-6 zz',xhold,zz);



zz=zz*0.0;

do ii=1,3;

jj=ii+3;

zz(jj,)=xhold(,ii);

enddo;



call print('Note that zz(j,)=xhold(,i) will not work');

call print('cols 1-3 xhold in rows 4-6 zz',xhold,zz);



oldx=rn(matrix(20,6:));

newx= matrix(20,5:);

i=integers(4);

newx(,i)=oldx(,i);

call print('Col 1-4 in oldx goes to newx',oldx,newx);



oldx=rn(matrix(20,6:));

newx= matrix(20,5:);

i=integers(4);



newx(1,i)=oldx(1,i);

call print('This puts the first element in col ',oldx,newx);

newx=newx*0.0;



newx(i,1)=oldx(i,1);

call print('This puts the first element in row ',oldx,newx);

newx=newx*0.0;



newx( ,i)=oldx( ,i);

call print('Whole col copied here',oldx,newx);



oldx=rn(matrix(10,5:));

newx= matrix(20,5:);

i=integers(4);



newx(i,1)=oldx(i,1);

call print('This puts the first element in row ',oldx,newx);



newx=newx*0.0;

newx(i,)=oldx(i,);

call print('Whole row copied',oldx,newx);



* we subset a matrix here ;

a=rn(matrix(10,5:));

call print('Pull off rows 1-3, cols 2-4',

a,a(integers(1,3),integers(2,4)));

b34srun;



5. Functions or math expressions are not allowed on the left hand side

of an equation. Assume the user wants to load another row. The

command x(norows(x)+1,)=v; in the sequence



x=matrix(3,3:1 2 3 4 5 6 7 8 9);

v=vector(3:22 33 44);

x(norows(x)+1,)=v;



will not work. The correct way to proceed is:



x=matrix(3,3:1 2 3 4 5 6 7 8 9);

v=vector(3:22 33 44);

n=norows(x)+1;

x(n,)=v;



to produce



1. 2. 3.

4. 5. 6.

7. 8. 9.

22. 33. 44.



The command



x(i+1)=value;



will not work since there is a calculation implicit on the left.

The correct code is:



j=i+1;

x(j)=value;



6. Matrix and array math is supported. If x is a 3 by 3 matrix,

the command



x=afam(x);



will create the 3 by 3 array x. If x is a 3 by 1 array. The command



mx=vfam(x);



will create a matrix mx containing columns of x.



If

x=rn(array(3,3:));

vv=vfam(x);



vv is a 3 by 3 matrix. To convert x to a vector column by column

use



vvnew=vector(:x);



7. Keywords should not be used as variable names. If they are

the command with this name is "turned off." This can cause

unpredictable results with user PROGRAMS, SUBROUTINES

and FUNCTIONS. Keywords cannot conflict with user program,

subroutine or function names since the users code is not loaded

unless a statement of the form



call load(name);



8. MATRIX command SUBROUTINES and FUNCTIONS allow passing

arguments. For example:



call myprog(x,y);



y=myfunc(x,y);



Character values can be passed and optionally changed.





b34sexec matrix;



subroutine test(a);

call print('In routine test A= ',a);

call character(a,'This is a very long string');

return;

end;



/$ pass in character*8

call test('junk');



call character(jj,'some junk going in');

call print(jj);



/$ pass in a character*1 array



call test(jj);

call print(jj);

b34srun;



Special characters such as : and | are not allowed in USER

SUBROUTINES or FUNCTION calls because of the difficulty of

parsing these characters in the user routine. This restriction

may change in future versions of the MATRIX command if there

is demand.



9. Coding assumptions. Statements such as:



y = x-z;



are allowed. Statements such as



y = -x+z;



will not work as intended. The error message will be

"Cannot classify sentence Y ...". The command should be given as



y = -1.*x + z;



or better still



y = (-1.*x) + z;



A statement



y = x**2;



where x is real*8 will get a mixed mode message and should be given

as



y = x**2.;



Complex statements such as



yhat = b1*dexp(-b2*x)+ b3*dexp(-(x-b4)**2./b5**2.)

+ b6*dexp(-(x-b7)**2./b8**2.);



will not work and should have ( ) around the power expressions

and -1.* .



yhat = b1*dexp(-1.0*b2*x)+ b3*dexp(-1.0*((x-b4)**2.)/(b5**2.))

+ b6*dexp(-1.0*((x-b7)**2.)/(b8**2.));

Examples of MATRIX language statements:



The statement



y=dsin(x);





is an analytic statement that creates the stuctured object y by

taking the sin of structured object x.



The statements below defines a user subroutine moveaver to calculate

a moving average.



subroutine moveaver(x,nterms,moveaver);



10. The following code illustrates automatic expansion.



x(1)=10.;

x(2)=20.;



The array x contains elements 10. and 20.



Warning:



The commands



x(1)=10.;

x(2)=20;



produces an array of 0 20 since the statement x(2)=20 redefines

the x array to be integer! This is an easy mistake to make!

Computers do what we tell them to do!



Statements such as



x(0) = 20.;



x(-1)= 20.;



x(1) = 20.;



all set element 1 of x to 20. The x(0) and x(-1) statements

will generate a message warning the user.



11. Memory Management Issues.



Warning: Automatic expansion inside a subroutine, program, DO

loop, dowhile loop, or function can cause the program to "waste"

memory since newer copies of the expanded variable will not fit into

the old location. The matrix command will have to allocate a new

space which will leave a "hole" in memory. B34S provides the

capability of the user programming memory management as needed.

The command



call compress;



can be used to compress the workspace in this situation.



A better solution is to allocate the variable to the max shape

outside the loop. In addition to space requirements, prior

allocation will substantially speed up execution. If memory problems

are encountered, the command



call names(all);



can be used to see how the variables are saved in memory and

whether as the loop proceeds more space is used. In some situations

the max temp number message may be reached if temps cannot be

automatically freed. For example compare the following code;



n=10;

x=array(n:);

call names(all);

do i=1,n;

x(i)=dfloat(i);

call names(all);

enddo;





with



n=10;

call names(all);

do i=1,n;

x(i)=dfloat(i);

call names(all);

enddo;



The first job will run faster and not use up memory. This job can be

found in the file matrix.mac under MEMORY and should be run by users

wanting to write efficient subroutines.



The command



n=10;

call compress(n);



allows the user to compress every n times call compress is called.

For example:



do i=1,nn;

* statements here;

call compress(100);

enddo;



Compresses every 100 times the loop calls

compress.



An alternative is to use the solvefree command as



do i=1,2000;

call solvefree(:alttemp);

* many commands here ;



call solvefree(:cleantemp);

enddo;



Due to enhancements to the memory management in B34S

that were part of the 8.10G version, this option only

has use if memory management is needed as part of a

user model that is called by one of the nonlinear

commands. For added detail on this use, see below.



In the above example the first call with

:alttemp sets %%____ style temp variables in place of the

default ##____ style. The command :cleantemp resets the temp

style to ##____ and cleans all %%____ temps, leaving the

##_____ style temps in place. If this capability is used

carefully, substantial speed gains can be made. In addition

the max number of temps will not be reached. Use of this

feature slows down processing and is usually not needed.



The command



call solvefree(:cleantemp2);



cleans user temps at or above the current level. This can be

useful within a nested call to clean work space.



The dowhile loop usually is cycled many times and needs active

memory management. An example is:



b34sexec matrix;

sum=0.0;

add=1.;

ccount=1.;

count=1.;

tol=.1e-6;



/$ outer dowhile does things 2 times



call outstring(2,2,'We sum until we can add nothing!!');

call outstring(2,4,'Tol set as ');

call outdouble(20,4,tol);



call echooff;



call solvefree(:alttemp);



dowhile(ccount.ge.1..and.ccount.le.3.);

sum=0.0;

add=1.;

count=1.;



dowhile(add.gt.tol);

oldsum=sum;

sum=oldsum+((1./count)**3.);

count=count+1.;

call outdouble(2,6,add);

add=sum-oldsum;



/$ This section cleans temps



if(dmod(count,10.).eq.0.)then;

call solvefree(:cleantemp);

call solvefree(:alttemp);

endif;



enddowhile;



ccount=ccount+1.;



call print('Sum was ',sum:);

call print('Count was ',count);



enddowhile;



b34srun;





Note: The command call compress; will be ignored if it is used in a

program, function or subroutine that is called as part of a

nonlinear estimation command such as NLLLSQ, CMAX2 etc.

The reason for this restriction is to avoid the possibility

of data movement that is not known to the calling command.

If memory management is needed in this case, use the

solvefree command.



12. Missing data



Handling missing data often causes problems. Assume the following

code:



x=rn(array(10:));

lagx=lag(x,1);

y=x-(10.*lagx);

goody=goodrow(y);

call tabulate(x,lagx,y,goody);



Y will contain missing data in row 1. The variable goody will

contain 9 non missing value observations.



13. Recursive solutions

In many cases the solution to a problem requires recursive

evaluation of an expression. While the use of recursive function

calls is possible, it is not desirable since there is great overhead

in calling the function or subroutine over and over again. The DO

loop, while still slow, is approximately 100 times faster than the

recursive function call. The test problem RECURSIVE in

c:\b34slm\matrix.mac documents how slow the recursive function call

and do loop are for large problems. Another reason that a recursive

function call is not recommended is that the stack must be saved.



One way to handle a recursive call is to use the SOLVE statement

to define the expression that has to be evaluated one

observation at a time. If the expression contains multiple

expressions that are the same, a FORMULA can be defined and used in

the SOLVE statement. The FORMULA and SOLVE statements evaluate an

expression over a range, ONE OBSERVATION AT A TIME. This in contrast

to the usual analytic expression which is evaluated completely on

the right BEFORE the copy is made. Unlike an expression, a formula

or SOLVE statement can refer to itself on the right. The BLOCK

keyword determines the order in which the formulas are evaluated. If

the expression in the SOLVE statement does not have duplicate code,

it is faster not to define a FORMULA. Examples of both approaches

are given next. The code:



test=array(10:);

test(1)=.1;

b=.9;

solve(test=b*test(t-1)+rn(1.)

:range 2 norows(test)

:block test);

call print(test);



works but



test = b*lag(test,1)+rn(1.);



will not get the "correct" answer since the right hand side is built

before the copy is done.



More complex expressions.



The FORMULA statement requires use of the subscript t unless

the variable is a scalar. The use of the FORMULA and SOLVE

statements are illustrated below:



Example 1.



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix ;

double=array(norows(gasout):);

formula double = dlog(gasout(t)*2.);

call names;

call print(double);

test2=array(norows(gasout):);

solve(test2=test2(t-1)+double(t)+double(t-1)

:range 2, norows(gasout)

:block double);

call print(mean(test2));



b34srun;



Example 2. The following two statements are the same



do i=1,n;

x(i)=y(i)/2.;

enddo;



solve(x=y(t)/2. :range 1 n);



Note: The SOLVE and FORMULA statements cannot use user functions.

A DO loop can use user functions.



More detail on the SOLVE and FORMULA statements are given below.



An alternative to the FORMULA/SOLVE approach is to call a Fortran

or other execuitable directly for the recursive calculation from

inside a B34S Matrix command program. For an example of this

approach see section 22 below and the examples FORTRAN and FORTRAN2

in the file matrix.mac. This method is very fast and is the best way

to go.



14. User defined data structures



The B34S MATRIX command allows users to build custom data types.

The below example shows the structure PEOPLE consisting of a

name field (PNAME), a SSN field (SSN), an age field (AGE), a

race field (RACE) and an income field (INCOME).



The built in function SEXTRACT( ) is used to take out a

field and the built in SUBROUTINE ISEXTRACT is used to place data

in a structure. Both SEXTRACT and ISEXTRACT allow a third argument

that operates on an element. The name SEXTRACT is "structure

extract" while ISEXTRACT is "inverse structure extract." Use of

these commands is illustrated below:



b34sexec matrix;

people=namelist(pname,ssn,age,race,income);

pname =namelist(sue,joan,bob);

ssn =array(:20,100,122);

age =idint(array(:35,45,58));

race =namelist(hisp,white,black);

income=array(:40000,35000,50000);

call tabulate(pname,ssn,age,race,income);

call print('This prints the age vector',sextract(people(3)));

call print('Second person',sextract(people(1),2),

sextract(people(3),2));

* make everyone a year older ;

nage=age+1;

call isextract(people(3),nage);

call print(age);

* make first person 77 years old;

call isextract(people(3),77,1);

call print(age);

b34srun;



Data structures are very powerful and, in the hands of an expert

programmer, can be made to bring order to complex problems.



15. Advanced programming Concepts and Techniques for Large Problems



Programs such as Speakeasy which are meant to be used interactively

have automatic workspace compression. As a result a Speakeasy

LINKULE programmer has to check for movement of defined objects

anytime an object is created or freed. So as to increase speed,

B34S does not move the variables inside the allocator unless

told to do so. If a DO loop terminates and the user is not in a

SUBROUTINE, temp variables are freed. If a new temp variable is

needed, B34S will try to place this variable in a free slot. If a

variable is growing, this may not be possible. Hence it is good

programming practice to create arrays and not rely on automatic

variable expansion.



In a subroutine call, a variable passed in is first copied to

another location and set to the current level + 1. Thus there are

names storage implications of a subroutine call.



In a large program the command



call compress;



will manually clean out all temp variables and compress the

workspace. While this command takes time, in a large job it may be

required to save time and space. For example: temp variables

are named ##1 ...... ##999999. If the peak number of temp

variables gets > 999999, then B34S has to reuse old names and

as a result slows down checking to see if a name is currently being

used. A call to COMPRESS will reset the temp variable counter as

well as free up space.



If compress is called from a place it cannot run, say in a program

subroutine or function that is being called by a b34s command

such as cmax2, it will be ignored and no message will be given.

The compress command will also be ignored if it is called under a

running function, directly or indirectly. This means that a call to

compress from a subroutine may or may not compress depending on

whether the subroutine was called from a user function.



The MATRIX command termination message gives space used, peak space

used and peak and current temp # usage. Users can monitor their

programs with these measures to optimize performance.

In the opinion of the developer, the B34S MATRIX command DO loop is

too slow. The problem is that the DO loop will start to run

without knowing the ending point because it is supported at the

lowest programming level. In contrast, Speakeasy requires that

the user have a DO loop only in a SUBROUTINE, PROGRAM or FUNCTION

where the loop end is known in theory. Ways to increase DO loop

speed are high on the "to do" list. Faster CPU's may be the answer.

The LF95 compiler appears to make faster DO loops than the older

LF90 compiler. This suggests that the cache may be part of what is

slowing things down. The test problem SOLVE6 illustrates some of

these issues. Times and gains from the SOLVE statement vary based on

the compiler used to build the B34S. On a Gateway P6 400 machine





LF90 4.50i LF95 5.5b

SOLVE time 9.718 9.22

DO time 41.69 13.73

Gain of SOLVE 4.3897 1.49





LF90 appears to make a very slow DO loop!! LF95 is faster.



In simple formulas the FORMULA and SOLVE commands are useful. With

large complex sequences of commands, the DO loop cost may have to

be "eaten" by the user since it is relative low in comparison to the

cost of parsing the expression. A major advanatge of the DO loop is

that the logic is 100% clear is most cases.



Speed can be increased by using variables for constants. This is

because at parse time all scalars are made temps. Doing this outside

the loop speeds things.



Slow code



do i=3,1000;

x(i)=x(i)*2.;

enddo;



better code



two=2.0;

do i=3,1000;

x(i)=x(i)*two;

enddo;



Vectorized code



i=integers(3,1000);

x=x(i)*2.;



Compact vectorized code



x=x(integers(3,1000))*2.;

If all elements need to be changed the fastest code is



x=x*2.;



In the vectorized examples parse time is the same no matter whether

there are 10 elements in x or 10,000,000.



For speed gains from the use of masks, see # 18 below.



16. DO, IF and DOWHILE nested statement limits



Do loop, dowhile loop and if statement termination should be hit. If

this is not done, the max if statement limit or do statement limit

can be exceeded depending on program logic. This "limitation" comes

from having IF and DO loops outside programs, subroutines or

functions. When the do loop or if structure starts to run the

program does not know the end. The code





loop continue;

if(dabs(z1-z2).gt.1.d-13)then;

z2=z1;

z1=dlog(z1)+c;

go to loop;

endif;



will never hit endif; The b34s parser will not know the position of

this statement and the max IF statement limit could be hit if the

IF structure was parsed many times. A better approach is not to

use an IF structure in this situation. The correct code is:



loop continue;

if(dabs(z1-z2).le.1.d-13)go to nextstep;

z2=z1;

z1=dlog(z1)+c;

go to loop;



nextstep continue;



17. Mask Issues



Assume an array x where for x 0 if U(i,i)=0. GMFAC uses the LAPACK routines

DGETRF/ZGETRF and DGETRI/ZGETRI. GMFAC will noty run on real*16

and complex*32 data types. The commands





call gminv(x,xinv);

call gminv(x,xinv,info);

call gminv(x,xinv,info,rcond);



invert a general matrix using LAPACK. This code may be faster than

inv( ) if the rank of the matrix is greater than 200 by 200.

If the optional argument info is present, the routine will not stop

if there is a problem. This allows the user to take automatic

corrective action. The routine gminv is the fastest large general

matrix routine. It does not do refinement by default. The rcond

option takes time and usually is not needed. The rcond value from

LAPACK is not the same as LINPACK. The routine GMINV uses LAPACK

DGETRF/ZGETRF and DGETRI/ZGETRI and optionally DGECON/DGECON if the

condition is needed.



The command

call gmsolv(x,b,ans,info);



where x is a n by n matrix, b a n by k matrix solves the system

ans*x=b. If the optional argument info is present, the program will

not stop if there is a rank problem. The LAPACK routines

DGETRF/DGETRS and ZGETRF/ZGETRS are usually used. If the key words

:refine or :refinee are present, the LAPACK routines DGESVX and

ZGESVX will be used to refine the solution. This will take

substantially more time. Unless the optional key words are

used, gmsolv is the fastest way to solve the general system ans*x=b

where x is greater than or equal to 200 by 200. The larger b, the

more the gain in speed.



The command



s=svd(x,ibad,job,u,v);



Calculates singular value decomposition of x which must be real*8 or

real*16, complex*16 or complex*32. LINPACK routines DSVDC and ZSVDC

are used. For real*16 and complex*32, these have been converted to

QSVDC and CQSVDC respectively.



For added detail on these options, please look at the help files and

the example files. Inversion options under the matrix command have

been designed to be both easy to use and flexible.



If the series are real*16 or complex*32, only the LINPACK routines

are available since LAPACK is not currently available for these data

types.



The inv( ) command also works for VPA data. Substantial accuracy

gains can be obtained. For further detail, see sections 23 & 24

below.



21. Fortran and other Language Interfaces



While the B34S Matrix language is "vectorized" and can easily handle

most tasks, recursive systems that involve DO and DOWHILE loops are

quite slow. An alternative is to code the desired calculation

in the user language of choice and link to this program inside

a B34S matrix command subroutine. While one possible implementation

of this facility might be via a W2K DLL, this approach was rejected

as being not portable and overly complex. The implementation

discussed below allows the user to use any language to develop the

program and communicate with the b34s processor with files. The

below listed examples illustrate this technique. If there is

sufficient user demand, at a later point a user DLL for the matrix

command might be developed. The downside is that such an

implementation would require the user directly access the matrix

commmand named storage array. It is the experience of the developer

of B34S that only the most experienced programmers are capable of

this complexity. A programmer without the proper training could

easily "kill" or worse still, damage the B34S MATRIX command

resulting in a hard-to-detect error being generated. The file IO

approach will not allow direct access to the B34S matrix command

arrays and is safer but slower. If most of the cpu time is in the

calculation, not in passing the data, this cost will be minimal.



Example of a user fortran program being called.



The below listed example calls the program _test.exe on W2K which in

turn writes a file of 1000 sin values. These are read into the

matrix command. Except for the compile command this job is

100% portable between Linux and W2K. The user is NOT required

to write in FORTRAN. Any user programming language or user external

program is allowed provided it can read and make files for the IO

into the B34S matrix command.



Simple Example Program logic:



1. Open file _test.f

2. Copy lines in the 2-D character*1 array test into this file.

3. Compile the fortran.

4. Run the program _test and place output in testout

5. Open testout in the B34S matrix command and read

the character first line.

The number of elements line into valiable n.

Allocate a 1d array testd of length n.

Read data into testd.

Print testd.



b34sexec matrix;

call open(70,'_test.f');

call rewind(70);

/$ 1234567890

call character(test," write(6,*)'This is a test # 2'"

" n=1000 "

" write(6,*)n "

" do i=1,n "

" write(6,*) sin(float(i)) "

" enddo "

" stop "

" end ");

call write(test,70);

call close(70);



call dodos('lf95 _test.f');

call dounix('lf95 _test.f -o_test');

call dodos('_test > testout':);

call dounix('./_test > testout':);

call open(71,'testout');

call character(test2,' ');

call read(test2,71);

call print(test2);

testd=0.0;

n=0;

call read(n,71);

testd=array(n:);

call read(testd,71);

call print(testd);



call close(71);

call dodos('erase testout');

call dodos('erase _test.f');

call dounix('rm testout');

call dounix('rm _test.f');



b34srun;





Complex Example Program Logic



1. Fortran program logic:



Read data from data.dat into array data1.

Read number of parameters in the model into npar.

Read Model npar parameters into array parm.

Calculate the function value and write to

file testout.



2. Matrix program test writes the parameters as they change

to a file and calls the compiled fortran program

which will return with a new func value.



Things to be aware of:



The commands



call dodos(' ');

call dounit(' ');



were not given in the form



call dodos(' ':);

call dounit(' ':);



since there is no screen writting. By not using the

: the flash is avoided.



The matrix command write used for data was



call write(y,72,'(3e25.16)');



in place of the more general



call write(y,72);



because the line got too long on Linux.



The lines

call out....



were added to show progress. These are only seen if the

program is running in the Display Manager.



b34sexec options ginclude('b34sdata.mac') member(lee4);

b34srun;



b34sexec matrix ;

call loaddata ;



* The data has been generated by GAUSS by with settings $

* a1 = GMA = 0.09 $

* b1_n = GAR = 0.5 ( When Negative) $

* b1 = GAR = 0.01 $



* call echooff ;



/$ Setup fortran



call open(70,'_test.f');

call rewind(70);

call character(fortran,

/$234567890

" implicit real*8(a-h,o-z) "

" parameter(nn=10000) "

" dimension data1(nn) "

" dimension res1(nn) "

" dimension res2(nn) "

" dimension parm(100) "

" call dcopy(nn,0.0d+00,0,data1,1)"

" call dcopy(nn,0.0d+00,0,res2 ,1)"

" open(unit=8,file='data.dat') "

" open(unit=9,file='tdata.dat') "

" read(8,*)nob "

" read(8,*)(data1(ii),ii=1,nob) "

" read(9,*)npar "

" read(9,*)(parm(ii),ii=1,npar) "

" read(9,*) res2(1) "

" close(unit=9) "

" "

" do i=1,nob "

" res1(i)=data1(i)-parm(3) "

" enddo "

" "

" func=0.0d+00 "

" do i=2,nob "

" res2(i) =parm(1)+(parm(2)* res2(i-1) ) +"

" * (parm(4)*(res1(i-1)**2) ) "

" func=func+(dlog(dabs(res2(i))))+ "

" * ((res1(i)**2)/res2(i)) "

" enddo "

" func=-.5d+00*func "

" close(unit=8) "

" open(unit=8,file='testout') "

" write(8,fmt='(e25.16)')func "

" close(unit=8) "

" stop "

" end ");



call write(fortran,70);

call close(70);



maxlag=0 ;

y=doo1 ;

y=y-mean(y) ;



* compile fortran and save data;



call dodos('lf95 _test.f' );

* call dounix('lf95 _test.f -o_test');

call dounix('fortlc _test');

call open(72,'data.dat');

call rewind(72);

call write(norows(y),72);

call write(y,72,'(3e25.16)');

call close(72);





v=variance(y) ;

arch=array(norows(y):) + dsqrt(v);



i=2;

j=norows(y);



* parm=array(:.0001 .0001 .0001 .0001);

* parm(1)=v;

* parm(3)=mean(y);



count=0.0;



call echooff;



program test;



call open(72,'tdata.dat');

call rewind(72);

npar=4;

call write(npar,72);

call write(parm,72,'(e25.16)');

arch(1)=0.0d+00 ;

call write(arch(1),72,'(e25.16)');

call close(72);



call dodos('_test');

call dounix('./_test ');

call open(71,'testout');

func=0.0;

call read(func,71);

call close(71);



count=count+1.0;

call outdouble(10,5 ,func);

call outdouble(10,6 ,count);

call outdouble(10,7, parm(1));

call outdouble(10,8, parm(2));

call outdouble(10,9, parm(3));

call outdouble(10,10,parm(4));



return;

end;



ll =array(4: -.1e+10, .1e-10,.1e-10,.1e-10);

uu =array(4: .1e+10, .1e+10,.1e+10,.1e+10);



rvec=array(4: .1 .1, .1, .1);



parm=rvec;



* call names(all);



call cmaxf2(func :name test

:parms parm

:ivalue rvec

:maxit 2000

:maxfun 2000

:maxg 2000

:lower ll

:upper uu

:print);

*call dodos('erase testout');

*call dodos('erase _test.exe');

*call dounix('rm testout');

*call dounix('rm _test');



b34srun;



22. Polynomial Matrix Operations



A polynomial matrix is one where the coeffiients are themselves

coefficients. A two by two system with max order 3 could be saved

in form



B(1,1)(L) B(1,2)(L)

B(2,1)(L) B(2,2)(L)



where the zero order terms (constant) are saved in the term. The

VAREST command saves the matrix in a form where the constant is

placed last. This is NOT :BYVAR format which would have occured if

call olsq(y y{1 to maxlag} x{1 to maxlag} were used.



B(1,1)(L) B(1,2)(L) c(1)

B(2,1)(L) B(2,2)(L) c(2)



For a two variable system with 6 lags the coefficients are saved in

a 2 by ((2*6)+1) matrix.



VAREST also saves [I - B(L)] which when inverted gives

the phi weights.





The matrix polynomial routines POLYMINV (used to calculate the

inverse of a matrix), POLYMMULT (used to calculate a

multiplication) and POLYMDISP (used to print or display such a

matrix) use the convention:



B(1,1)(0) B(1,2)(0) B(1,1)(k) B(1,2)(k)

B(2,1)(0) B(2,2)(0) B(2,1)(k) B(2,2)(k)



which is termed :BYORDER



The command POLYMCONV can be used to convert from one system to

another. Each matrix in :BYORDER form has a three element integer

variable of the form (nrow,ncol,degree+1) that allows it to be

decoded. If nrow=ncol then the matrix can be inverted. A matrix in

:BYVAR form does not need an index to decode it but must be saved

as a n by ((n*order)+1) system. For example a 2 variable VAR with

mar order 5 could be saved as a 2 by 11. The first row would be 5

lags of x(1) and 5 lags x(2) plus the constant.



For further detail see the VAREST command example. A simple setup

is:





b34sexec matrix;

call loaddata;

call load(buildlag);

call load(varest);

call echooff;



ibegin=1;

iend=296;

nlag=2;

nterms=10;

x=catcol(gasin,gasout);



call varest(x,nlag,ibegin,iend,beta,t,sigma,corr,residual,1,

a,ai,varx,varxhat,rsq);

call print(beta,t,sigma,corr);

call tabulate(varx,varxhat,rsq);

call polymdisp(:display a ai);

call polyminv(a ai psi ipsi nterms);

call polymdisp(:display psi ipsi);

b34srun;



23. Real*16 and Complex*32 Data types

While the usual data types in the MATRIX command are real*8 and

complex*16, there is a limited real*16 and complex*32 capability.

In addition there are improvements to accuracy in real*8, real*16,

complex*16 and complex*32 by modification the the BLUS routines.

If extream accuracy is needed, the VPA option dicussed in the

next section can be used.



Until this message is removed, this capability is assumed to be

in "beta" form. Many commands have been converted to support these

increased accuracy data types.



Examples:



Option 1. Works for all commands that use routines that involve

BLUS routines.



The command



call real16on(:real16math);



will perform math with real*8 objects using real*16 math and

complex*16 objects using complex*32 math. The command



call real16on;



uses the IMSL routines dqadd and dqmult to increase accuracy. It

is faster than



call real16on(:real16math).



These options can be turned off with the command



call real16off;



For example the default test case takes 2.04, with real16on

it takes 3.14 while with real16on(:real16math) the time is

5.95. In most cases this added accuracy is not needed.



For real*16 and complex*32 objects, the command



call real32on;



uses added accuracy for qdot, qsum, qasum, qaxpy and qscal

and added accuracy for cqdot, cqsum, cqasom, cqaxpy and cqscal



call real32off;



turns off this feature.



The command



call real32_vpa;

uses vpa math to increase real*16 accuracy. This will run slowly

but variable precision math is supported. This allows vpa math

to support a number of otherwise real*16 commands. At a later

date this may enhance complex*32 objects. For not it is

experomental.



Option 2.



Real*16 and complex*32 variables can be created from real*8 and

complex*16 variables with the r8tor16 and c16toc32 commands.

The commands r16tor8 and c32to16 can be used to convert

series back to the default datatypes. A series can be created to

be a specific data type with the command kindas( ). Assume

x is real*8 and xr16 is real*16. The user wants one_r8 to be

real*8 and oner_16 to be real*16. The following commands can be

used.



one_r8=kindas(x,1.0);



oner_16=kindas(xr16,1.0);



While array and matrix math is 100% available, only a subset of

commands are available. More detail is available under the help

commands of the specific commands. See the matrix example r16c32

and the examples math5 and math6 for applications. As of 24 June

2003, INV, EIG, SEIG, SVD and a number of production commands such

as DEXP, DLOG, SUMSQ, SUM etc have been converted. While LINPACK,

and EISPACK have been converted to support real*16 and complex*32,

FFTPACK and LAPACK have not.



Warning: While real*8 and compolex*16 data can be converted to

real*16 and complex*32 with the commands r8tor16( ) and

c16toc32 respectively, much accuracy will be lost. For

more accuracy it is it necessary to ready into real*16

or complex*32 directly. For an exampe, of how this id

done see the Filippelli (filippelli.dat) data which is

in stattest.mac.



24. Variable Precision Arithmetic.



The B34S has the capability of variable precision math where

the number of digits calculated is up to 1780. For more detail on this

facility see the help documents for subroutine VPASET and function VPA

that provide the interface into this facility. Full matrix and array

math is provided as well as the inverse or real and complex VPA objects.

Unlike a numnber of other software systems, this facility is 100%

integrated in the b34s system. For example, once a vpa number is built

with the vpa(function), calculations can be made in the usual manner

as will be illustrated below. Real, integer and complex objects have

been implemented. The facility allows hugh numbers, both real and

integer, to be used in calculations. Given the default settings

of MBASE is 10**7 and NDIGMX = 256, integers less than 10**1792

can be used. In contrast, the range for integer*4 is

-2,147,483,648 - 2,147,483,647. For integer*8 these become

-9,223,372,036,854,775,808 - 9,223,372,036,854,775,807.





This facility was built with the FM_ZM Library version 1.2 built by

David M. Smith. The basic reference is:



Algorithm 693, ACM Transactions on Mathematical Software,

Vol. 17, No. 2, June 1991, pages 273-283.



although a newer version of the libraty was obtained from the web.



The below listed program calculates 2.0/4.11 a number of ways and

shows the various accuracy obtained.





b34sexec matrix;

call echooff;

* Accuracy differences depending on data precision;

call print(' 2.0/4.11 using different precisions':);

call fprint(:clear :col 32

:string ' 10 20 30 40 50' :print

:clear :col 32

:string '12345678901234567890123456789012345678901234567890' :print);



call fprint(:clear :col 1 :string 'str => vpa'

:col 30 :display vpa('2. ')/vpa('4.11') 'e70.52'

:print :clear

:col 30 :display vpa('2.00')/vpa('4.11') 'e50.32'

:print);



call fprint(:clear :col 1 :string 'real*8 => vpa'

:col 30 :display vpa(2.00)/vpa(4.11) 'e50.32'

:print);





call fprint(:clear :col 1 :string 'real*8 => real*16'

:col 18 :display r8tor16(2.)/r8tor16(4.11)

'(e50.32)' :print);



call fprint(:clear :col 1 :string 'str => real*16'

:col 18 :display real16('2.00')/real16('4.11')

'(e50.32)' :print);

call fprint(:clear :col 1 :string 'real*8 => real*8'

:col 18 :display array(:2.00/4.11)

'(e50.32)' :print);

call fprint(:clear :col 1 :string 'real*4 => real*4'

:col 18 :display sngl(2.00)/sngl(4.11)

'(e50.32)' :print);

b34srun;





The Above job shows 2./4.11 using various precisions. The VPA result to

52 digits is:

.4866180048661800486618004866180048661800486618004866M+0

and shows the repeating pattern that will continue. When the data (2.0

and 4.11) was read with a string input, no accuracy was lost with

real*16 given the format e50.32. This degree of accuracy was not

obtained with real*16 if the data was read as real* firsdt anf then

converted to real*16.



The above job was edited to display only 72 columns and is listed below.



2.0/4.11 using different precisions

10 20 30 40

1234567890123456789012345678901234567890

str => vpa .4866180048661800486618004866180048661800

.48661800486618004866180048661800M+0

real*8 => vpa .48661800486618001080454992664677M+0

real*8 => real*16 0.48661800486618001080454992664677E+00

str => real*16 0.48661800486618004866180048661800E+00

real*8 => real*8 0.48661800486618000000000000000000E+00

real*4 => real*4 0.48661798200000000000000000000000E+00



Even for this simple case, the real*4 result began to differ at the 6th

digit (although with rounding the failure was at 10). The real*8 result

failed at digit 17 as expected. When the real*16 data input was by

string there was no loss of accuracy up to the 32nd digit. However, when

the data was first read as real*8 and converted to real*16 accuracy

problems emerged by the 17th digit. The calculation was limited by the

precision of the data read. This finding was verified when we moved

real*8 data into VPA and got the same result as the real*8 into real*16.

The str into vpa is the "true" answer.



The next example show inverse gains:



/;

/; Shows gains in accuracy of the inverse with vpa

/;

b34sexec matrix;



call echooff;

n=3;

call vpaset(:ndigits 1750);

x=rn(matrix(n,n:));

r16x=r8tor16(x);

vpax=vpa(x);

call print('Real*4 tests',sngl(x),inv(sngl(x)),sngl(x)*inv(sngl(x)));

call print('Real*8 tests',x, inv(x), x*inv(x));

call print('Real*16 tests',r16x,inv(r16x),r16x*inv(r16x));

call print('VPA tests',vpax,inv(vpax),vpax*inv(vpax));



b34srun;



Edited output produces:



Real*4 tests

Matrix of 3 by 3 elements (real*4)





1 2 3

1 2.05157 1.27773 -1.32010

2 1.08325 -1.22596 -1.52445

3 0.825589E-01 0.338526 -0.459242





Matrix of 3 by 3 elements (real*4)





1 2 3

1 0.521061 0.675528E-01 -1.72205

2 0.179445 -0.402323 0.819689

3 0.225948 -0.284424 -1.88285





Matrix of 3 by 3 elements (real*4)





1 2 3

1 1.00000 0.919681E-08 0.759197E-07

2 0.585772E-07 1.00000 0.822609E-07

3 0.878866E-08 0.560976E-08 1.00000







Real*8 tests



X = Matrix of 3 by 3 elements



1 2 3

1 2.05157 1.27773 -1.32010

2 1.08325 -1.22596 -1.52445

3 0.825589E-01 0.338525 -0.459242





Matrix of 3 by 3 elements



1 2 3

1 0.521061 0.675528E-01 -1.72204

2 0.179445 -0.402323 0.819689

3 0.225948 -0.284424 -1.88285





Matrix of 3 by 3 elements



1 2 3

1 1.00000 -0.555112E-16 0.00000

2 0.00000 1.00000 0.00000

3 -0.138778E-16 -0.277556E-16 1.00000

Real*16 tests



R16X = Matrix of 3 by 3 elements (real*16)



1 2 3

1 2.05157 1.27773 -1.32010

2 1.08325 -1.22596 -1.52445

3 0.825589E-01 0.338525 -0.459242





Matrix of 3 by 3 elements (real*16)



1 2 3

1 0.521061 0.675528E-01 -1.72204

2 0.179445 -0.402323 0.819689

3 0.225948 -0.284424 -1.88285





Matrix of 3 by 3 elements (real*16)



1 2 3

1 1.00000 -0.144445E-33 0.00000

2 0.00000 1.00000 0.00000

3 0.00000 -0.240741E-34 1.00000







VPA tests



VPAX = Matrix of 3 by 3 elements VPA - FM



1 2 3

1 .205157M+1 .127773M+1 -.132010M+1

2 .108325M+1 -.122596M+1 -.152445M+1

3 .825589M-1 .338525M+0 -.459242M+0





Matrix of 3 by 3 elements VPA - FM



1 2 3

1 .521061M+0 .675528M-1 -.172205M+1

2 .179445M+0 -.402323M+0 .819689M+0

3 .225948M+0 -.284424M+0 -.188285M+1





Matrix of 3 by 3 elements VPA - FM



1 2 3

1 .100000M+1 -.139488M-1757 .000000M 0

2 .168219M-1758 .100000M+1 .000000M 0

3 -.138187M-1758 .173950M-1758 .100000M+1



and shows the worse accuracy of the off diagonal of the real*4 case was

0.822609E-07 while the worse VPA error was .168219e-1758. The problem

consists of random numbers and is designed to be easy.





Matrix Programming Language key words



CALL Call a subroutine



call print('This is a string');



calls the print command. B34S MATRIX commands that

do not return an argument across an equals are executed

by the CALL sentence. The CALL sentence first looks in

named storage for a routine with this name. If this is

not found, then the built in routines are used. While

it is possible to have a user routine with the same name

as a built in routine, this is not a good idea.



CONTINUE go to statement



name continue;



is a go to statement target.



Note name must be le 8 characters



Example:



if(x.eq.0.0)go to test;

call print('x is greater than 0.0');

test continue;



DO Starts a do loop



do i=1,10;



Begins a DO loop. An alternative is:



do i=1,10,1;



Another alternative is



for i=1,10;





Notes on do loops:



The code:



do i=1,10;

do j=i,10;

s(i,j)=b(i)*a(j);

enddo;

enddo;

is valid. As written, both do loops will

completely execute. If in place of the above,

the code had been:



do i=1,10;



do j=i,10;

s(i,j)=b(i)*a(j);

if(s(i,j).le..0001)go to done;

enddo;



done continue;

call print('This is the end of loop one');

enddo;



the results would not be as intended since B34S does not know

to return to the statement



do i=1,10;



and will instead try to continue with the statement



do j=i,10;



since it may not "know" the exact location of the inner loop

enddo; statement because it may not have found it. The solution

is to manually terminate the inner loop by setting j outside

the range. Corrected code would be:



do i=1,10;



do j=i,10;

s(i,j)=b(i)*a(j);

if(s(i,j).le..0001)go to done;

enddo;



done continue;

j=0;

call print('This is the end of loop one');

enddo;



Example:



do i=1,n;

x(i)=y(i+1);

enddo;



A faster code would be



i=integers(1,n);

j=i+1;

x(i)=y(j);

Notes on do loop variables. In Fortran it is not recommended

that DO loop variables be used outside the loop.



In B34S



b34sexec matrix;

do i=1,2;

call print('in loop i = ',i);

enddo;

call print('out of loop i =,i);

b34srun;



Produces i=3 at the "out of loop" position.



This is the same as Fortran. To check compile



c test fortran

do i=1,2

write(6,*)'In loop i was ',i

enddo

write(6,*)'Out of loop i was ',i

end



Note how closely B34S follows the Fortran standard and the

language.



DOWHILE Starts a dowhile loop



dowhile(x.gt.0.0);



Starts a DOWHILE loop.



Example:



b34sexec matrix;

sum=0.0;

add=1.;

count=1.;

tol=.1e-6;



dowhile (add.gt.tol);

oldsum=sum;

sum=oldsum+((1./count)**3.);

count=count+1.;

add=sum-oldsum;

enddowhile;



call print('Sum was ',sum:);

call print('Count was ',count);

b34srun;



Warning: Be sure you do not have an infinate loop.



ENDDO ENDS a do loop

enddo;



Ends a DO loop.



next i;



Can be used in place of enddo;



Example:



do i=1,n;

x(i)=y(i+1);

enddo;



ENDDOWHILE ENDS a dowhile loop



enddowhile;



Ends a DOWHILE loop.



Example:



b34sexec matrix;

sum=0.0;

add=1.;

ccount=1.;

count=1.;

tol=.1e-6;



/$ outer dowhile does things 2 times



call outstring(2,2,'We sum until we can add nothing!!');

call outstring(2,4,'Tol set as ');

call outdouble(20,4,tol);



call echooff;



dowhile(ccount.ge.1..and.ccount.le.3.);



sum=0.0;

add=1.;

count=1.;



dowhile(add.gt.tol);

oldsum=sum;

sum=oldsum+((1./count)**3.);

count=count+1.;

call outdouble(2,6,add);

add=sum-oldsum;

enddowhile;



ccount=ccount+1.;

call print('Sum was ',sum:);

call print('Count was ',count);



call compress(1000);

enddowhile;



b34srun;





END End of a program, function or Subroutine.



end;



Ends a PROGRAM, SUBROUTINE or FUNCTION.



Example:



subroutine test(x);

call print('The mean of x is',mean(x));

return;

end;



EXITDO Exit a DO loop



exitdo;



Exits a do loop.



Example:



b34sexec matrix;

call echooff;

do j=1,4;

do i=1,10;

if(i.eq.8)exitdo;



if(i.ge.0)then;

call print('at 1 in if i was ',i:);

if(i.ge.4)exitif;

call print('at 2 in if Should never be gt 3 i was ',i:);

endif;



call print('in do loop ',i);

enddo;

enddo;

b34srun;

EXITIF Exit a IF loop



exitdo;



Exits a do loop.



Example:

b34sexec matrix;

call echooff;

do j=1,4;

do i=1,10;

if(i.eq.8)exitdo;



if(i.ge.0)then;

call print('at 1 in if i was ',i:);

if(i.ge.4)exitif;

call print('at 2 in if Should never be gt 3 i was ',i:);

endif;



call print('in do loop ',i);

enddo;

enddo;

b34srun;

FORMULA Defive a recursive formula.



formula x=y(t-1);



Defines a formula. Formulas are only executed for

observation t in a SOLVE statement. Formula definations

are saved at level 2. Formula results are saved at the

current level and can be used in the usual analytical

statements provided that they have been executed by a

solve statement. More extensive help in given later

in the help document.



Brief example:



* archvar and resid start out as variables =0.0;

* formula statement updates ONLY for obs t;

* For t=2, this value of u is used to get archvar;

archvar=array(norows(y):);

resid =array(norows(y):);

formula archvar = a0 + a1 * (resid(t-1)**2.) ;

formula resid=y(t) - b1 - b2*x1(t) - b3*dsqrt(archvar(t));

solve(

archlogl=(-.5)*(dlog(archvar(t))+((resid(t)**2.)/archvar(t))

:range 2 norows(y) :block archvar resid);







FOR Start a do loop



for i=1,10;



Alternate do loop setup.



Example:



for i=1,n;

x(i)=y(i+1);

next i;

is the same as



do i=1,n;

x(i)=y(i+1);

enddo;

NEXT i End of do loop



next i;



Alternate end of DO loop



Example:



for i=1,n;

x(i)=y(i+1);

next i;



GO TO Transfer statement



go to n;



Transfers control to statement



n CONTINUE;



Note n must be le 8 characters



Example:



if(x.eq.0.0)go to test;

call print('x is greater than 0.0');

test continue;



Note: Statements such as



if(k.eq.0)then;

* statements here ;

if(jj.gt.0)go to done;

endif;



should be avoided since the statement



endif;



will not be found and the # of if statements will be exceeded.



Better code is



bad=0;



if(k.eq.0)then;

* statements here;

bad=1;

endif;



if(bad.eq.1)go to done;



or



if(k.eq.0)then;

* statements here;

if(jj.gt.0)exitif;

endif;



FUNCTION Beginning of a function.



function somename(args);



is the first line of a user function.



Functions can have functions as arguments and themselves

can be used as arguments. The command



call compress;



will be ignored if found in a function or a subroutine or a

program called by a running function.



Examples:



function tt(y);

t=sum(y);

return(t);

end;



testmean=tt(y)/dfloat(norows(y));



call mysub(tt(y),x,z);







IF( ) Beginning of an IF structure



Note: The WHERE statement operates on non scalar objects while

the IF statement operates on scalar objects.



if(x.eq.9)y=dabs(x);



Simple IF statement. X must be a scalar.



If the mask JJ (must be 0.0 or 1.0) was set the code:



jj(1)=0.0;

jj(2)=1.0;

if(jj(i))call print('i was 2');



can be used.

The commands NLPMIN1, NLPMIN2 and NLPMIN3 use mask technology.



The statements:



if(x.eq.9)then;

call stop;

endif;



will STOP the program and get out of the MATRIX command if x=9.



Note that IF statements ( ) must resolve to 0.0 or 1.0.



A check for 0.0 of the form



if(x.ne.0.0)y=p/x;



will work in versions of B34S since November 7, 2004. An

alternative is:



if(x.ne.0.0)then;

y=p/x;

endif;



MASKS are a feature related to IF statements but much faster.

Since a logical expression resolves to be 0.0 or 1.0, a mask

can be built with a expression such as



mask = x .gt. 1.0 ;



Masks are a way to vectorize what would be an IF.



For example:



b34sexec matrix;

call print('If X GE 0.0 y=20*x. Else y=2*x':);

x=rn(array(20:));

y= (x.lt.0.0)*(x*2.0) + (x.ge.0.0)*(x*20.);

call tabulate(x,y);

b34srun;



will run faster than



b34sexec matrix;

call print('If X GE 0.0 y=20*x. Else y=2*x':);

x=rn(array(20:));

do i=1,norows(x);

if(x(i).lt.0.0)y(i)=x(i)*2.0;

if(x(i).ge.0.0)y(i)=x(i)*20.;

enddo;

call tabulate(x,y);

b34srun;



due to DO loop overhead.

Note: Statements such as



if(k.eq.0)then;

* statements here ;

go to done;

endif;



should be avoided since the statement



endif;



will not be found and the # of if statements will be exceeded.



Better code is



bad=0;



if(k.eq.0)then;

* statements here;

bad=1;

endif;



if(bad.eq.1)go to done;



Examples of code to change an element of an array using a mask.





x=integers(1,10);

xx=x;



/$

/$ Note that Where sets one element to 99 rest to 0.0;

/$

where(x.eq.5)x=99;



/$ This may not be what is desired.

/$ This is the right way to do calculation using masks



xx=(xx.eq.5)*99+(xx.ne.5)*xx;

call print(x,xx);



ENDIF End of an IF( )THEN structure



endif;



Must be the end of an if( )then; structure.



Example:



if(x.eq.0.0)then;

y=10.;

v=y*dsin(q);

endif;

PROGRAM Beginning of a program,



program somename;



begins a program. Programs use global variables.



Example:



program doit;

call loaddata;

call olsq(x,y :print);

call graph(%res);

return;

end;

RETURN( ) Returns the result of a function.



return(result);



Next to last statement in a user function.



Example:



function tt(y);

t=sum(y);

return(t);

end;





RETURN Next to last statement before end.



return;



must be the next to last statement in a PROGRAM, SUBROUTINE or

FUNCTION.



Example:



program doit;

call loaddata;

call olsq(x,y :print);

call graph(%res);

return;

end;



SOLVE Solve a recursive system of equations.



solve( );



solves a recursive system.



solve(vv=x(t) :range 1 10);



Solves recursively an expression.

If formulas are involved, the form is



solve(vv=x(t) :range 1 10 :block x);



Note:



:range i j is OK

:range i, j is OK

:range i, norows(gasout) is ok

:range (i+6), j is not ok





For more detail see extensive example below:



b34sexec matrix;

/$ Unlike RATS, SOLVE and FORMULA statements can

/$ refer to themselves recursively

n=1000;

v=1.0;

ar1=array(n:)+missing();

ar1(1)=99.+rn(v);

solve(ar1=ar1(t-1)+rn(v):range 2 n);

call graph(ar1);

call tabulate(ar1);

b34srun;



SUBROUTINE Beginning of subroutine.



subroutine somename(args);



is the start of a subroutine. Subroutines use local variables.



Example:



subroutine test(x);

call print('The mean of x is',mean(x));

return;

end;



WHERE( ) Starts a where structure.





Note: The WHERE statement operates on non scalar objects while

the IF statement operates on scalar objects.



where(x.gt.0.0)y=x;





Assuming x exists. where elements of x > 0.0 y=x, otherwise

y=oldvalue. Variables x and y must be the same structure. The

"mask" is done at the copy step. Commands of the form



where(s.gt.0.0)y=dsqrt(s);

will not work as intended since the dsqrt(s) is done BEFORE the

mask is applied. Only simple replacement is allowed.

Statements such as



where(x.ge.0.0)z(,1)=q;



are not allowed since z(,1) is a temp variable.



The statements



where(x.ge.0.0)x=missing();

where(x.ge.10.)x=dqsrt(20.);



are allowed but care must be used. Since x and missing() and

dsqrt(20.) are not the same structure, here if ( ) is "false"

x is set = 0.0. For example, in the first statement where

x ge 0.0, x is set to missing(). If x lt 0, x is set to 0.0.



The second statement sets x to dsqrt(20.) if x was ge 10.

Otherwise x is set to 0.0.



Note that depending on whether x existed or not the statement

does not return the same vector. This is an explicit design

decision. Like Speakeasy, where( ) returns the existing

value if the logical statement is false and zero if the

variable did not exist! Assume x does not exist. Given



where(x.ge.0.0)newx=missing();



Here if x ge 0.0, then newx = missing(), otherwise newx = 0.0.



Logical masks are an alternative to some of the where

capability.



For example:



x=a.gt.y;



Here where a is > y, x = 1.0, x = 0.0 otherwise.





Example:



/; Here for the first where( ) the two objects

/; across the equals sign are not the same structure

/; If the ( ) is false x2bad resolves to 0.0 whether or

/; not it existed prior to the where( ) being found.

/;

/; The second where( ) has objects the same structure across

/; the =. Both objects exist. Here the old x value is

/; maintained. The logic here is

/; test = x*(x.ne.y)+dummy*(x.eq.y)

b34sexec matrix;

x=array(:1,-2,3,-4,5,-6,7,-8,9,-10);

y=array(:0,-2,1,-4,6,-6,2,-8,5,-10);

x2bad=x;

x2good=x;

dummy=array(norows(x):)+ -9999.;

where(x.eq.y)x2bad =-9999.;



where(x.eq.y)x2good =dummy;

test = (x*(x.ne.y))+ (dummy*(x.eq.y));

call tabulate(x,y,dummy,x2bad,x2good,test);

b34srun;



Edited Results are:



=> X=ARRAY(:1,-2,3,-4,5,-6,7,-8,9,-10)$

=> Y=ARRAY(:0,-2,1,-4,6,-6,2,-8,5,-10)$

=> X2BAD=X$

=> X2GOOD=X$

=> DUMMY=ARRAY(NOROWS(X):)+ -9999.$

=> WHERE(X.EQ.Y)X2BAD =-9999.$

=> WHERE(X.EQ.Y)X2GOOD =DUMMY$

=> TEST = (X*(X.NE.Y))+ (DUMMY*(X.EQ.Y))$

=> CALL TABULATE(X,Y,DUMMY,X2BAD,X2GOOD,TEST)$





Obs X Y DUMMY X2BAD X2GOOD TEST

1 1.000 0.000 -9999. 0.000 1.000 1.000

2 -2.000 -2.000 -9999. -9999. -9999. -9999.

3 3.000 1.000 -9999. 0.000 3.000 3.000

4 -4.000 -4.000 -9999. -9999. -9999. -9999.

5 5.000 6.000 -9999. 0.000 5.000 5.000

6 -6.000 -6.000 -9999. -9999. -9999. -9999.

7 7.000 2.000 -9999. 0.000 7.000 7.000

8 -8.000 -8.000 -9999. -9999. -9999. -9999.

9 9.000 5.000 -9999. 0.000 9.000 9.000

10 -10.00 -10.00 -9999. -9999. -9999. -9999.





***********************************************



Documentation of built-in commands called by CALL command.



For futher examples, see problems in matrix.mac

ABFSPLINE - Automatic Backfitting of a Spline Model



call abfspline(y x1 x2 :print);



Controls estimation of adaptive backfitting Model following

methods suggested by Hastie-Tibshirani (1990 page 262).



The above specification assumes a degree = 3 fit to each

term. Alternative setups are:

call abfspline(y x1[order,2] x2 :print);

call abfspline(y x1[predictor,2] x2 :print);



for a degree 2 fit on x1.



call abfspline(y x1[order,1] x2 :print);



for no smoothing on x1



call abfspline(y x1[logit,0] x2 :print);



if x1 is of the 0_1 type.



The Hastie and R. J. Tibshirani GPL R MDA Fortran library was

extensively modified to improve performance and add features

and is contained in sourc18.f. The developer of B34S released

the library utility.f as GPL to allow stand alone use of

some B34S utility routines. With the addition of the linpack

library, the Hastie-Tibshirani routines can be run stand alone

provided the user write a very small main program to read data.

Some LINPACK routines are included both in sourc3.f and

utility.f. Needed BLAS routines are given only in sourc3.f.The

sourc18.f library contains the routines for the b34s matrix

commands MARSPLINE, GAMFIT, ACEFIT and ABFSPLINE. Sone routines

that are needed for B34S but not needed for stand alone use are

disabled in utility2.f that should be linked in.



MARS, MARSPLINE, GAMFIT, ACEFIT and ABFSPLINE are all related

models that attempt to model nonlinear data with various spline

procedures.



For further detail see the MARS, ACEFIT, GAMFIT and MARSPLINE

commands.



Lags can be entered as



x{1} or x{1 to 20}



Basic references of these techniques.:



- Hastie-Tibshirani "Generalized Additive Models," Chapman &

Hall 1990.



- Stokes, Houston H. "Specifying and Diagnostically Testing

Econometric Models," second edition 1997 Quorum Books.

Chapter 14. Third edition in draft form as of 2006.



- Stokes, Houston H and Hugh Neuburger, "New Methods in

Financial Modeling," 1998 Quorum Books. Chapter 4.







:print Print header and minimal output.

:trace Trace solution. This is usually not needed.



:thresh r8 Sets threshold for Forwartd selection.

Default= .001



:maxit i4 Sets maximum iterations.



:rankto r8 Sets threshold for prune of

a multicolinear basis. Default

.1d-12



:sample mask - Specifies a mask real*8 variable that

if = 0.0 drops that observation.

Unless the mask is the number of obs

after any lags, an error message will

be generated. The sample variable

must be used with great caution when there

are lags. A much better choice is the

:holdout option.



:holdout n - Sets number of observations to hold out



Note: :sample cannot be used with :holdout.



:mi i1 Sets maximum number of variables per basis

function. Max = 3.



MI=1 => additive model.

MI > 1 => up to MI-variable interactions

allowed. Default = 1



:nk i2 Sets maximum number of basis functions.

Default = 5.









:df r1 Sets the number of degress of freedom charged

for unrestricted knot optimization. Default=2.





:weight Uses the last series on the model sentence as

a weight variable vector.





:forecast xmatrix => Allows users to supply observations

of the right hand side variables

outside the sample period so that

forecasts can be calculated. The

same number of observations must be

supplied for all right hand series.

Due to the way that splines are

calculated, it is imperative that

any values of the x variables NOT

lie outside the ranges of the

original data.



The forecast sentence produces the

%fore variable and the %foreobs

variable.



Not Implemented yet.



The model specification involves specificatioon of the type

of variable and optionally a lag or lags. The model

specification allows the lags to be set in the command. Only

vectors can be supplied in this release. If no[ ] is supplied,

[order] is assumed. A variable is of the type "order" if it

si possible to fit a spline. A 0-1 right hand side variable

is not an order variable and fitting a spline to this

variable make no sense. The specification



call abfspline(y y[order]{1} x[order]{0 to 3}

z[predictor]{1} )$



is the same as



call abfspline(y y[order]{1}

x[order]

x[order]{1}

x[order]{2}

x[order]{3}

z[predictor]{1})$





Variables Created



%YVAR - Name of left hand variables.



%NAMES - Names of exogenous variables.



%TYPEVAR - = 0 for continuous, NE 0 for categorical var.



%LAG - Lags of independent variables.



%COEF - Final Model Coefficients. Constant in

location one. Size nk+1



%MINVAR - Minimum of input variables.



%MAXVAR - Maximum of input variables.



%TYPEK - =0 if coef * max(var -knot,0)

=1 if coef * max(knot-var,0)



%VARINK - Variable # of that knot



%CKNOT - Character*1 array nk,28 holding

positional indicator of catagorical

variable right hand sides. Set to

0000000 if not used.



%KNOT - Knot



%PARENT - Index number of parent in interaction

otherwise 0



%K - # on right



%NOB - # of observations in model



%RSS - Residual sum of sq.



%SUMRE - Sum absolute residuals



%REMAX - Maximum absolute residual



%RESVAR - Residual Var.



%YHAT - Estimated Y



%Y - Y variable. Same # obs as YHAT



%RES - Residual



%VARRIMP - Relative variable importance.



%fore - Forecast



%foreobs - Observations of the forecast. If there are

lags, must have to increase %foreobs by

maxlag. This assumption may change is later

releases. For now it is the obs number.





Simple Example:



b34sexec options ginclude('b34sdata.mac') member(trees);

b34srun;

b34sexec matrix;

call loaddata;

call load(dispmars :staging);

call echooff;



call olsq(volume girth height :print);



call mars(volume girth height :nk 20 :df 2. :mi 3 :print);

call dispmars;

call tabulate(%res,%y,%yhat);



call abfspline(volume girth height :nk 21 :df 2.

:print :trace);

call print(%coef);

call tabulate(%res,%Y,%yhat);



b34srun;



ACEFIT Alternating Conditional Expectation Model Estimation



call acefit(y x[orderable] z[orderable]{2} :options);





Implements the ace algorithm under matrix to provide

estimation of ACE (alternating condition expectation) models

following work by Brieman, L and Friedman J. (1985). Chapter 7

of Hastie and Tibshtiani (1990) provides a good reference. For

another approach see the GAMFIT command. The ACEFIT command

optionally can use the AVAS (Additivity and Variance

Stabilization) approach. As noted in Hastie-Tibshirani (1990

page 193) "The AVAS procedure seeks transformations that

achieve additivity and a homogenious varianxce and is more

directed towards regresison problems than ACE." While AVAS

may be more desirable for regresison models, its theoretical

support is not as strong as for the ACE approach.



Brieman, L. and Friedman J. "Estimating Optimal Transformations

for Multiple Regression and Correlation (with discussion),"

Journal of American Statistical Association, 80, (1985)

580-619.



Hastie, T. J. and Tibshirani, R. J. (1990) "Generalized

Additive Models," New York: Chapman and Hall



Recent papers in the area include:



Fan, Jianqing and Jiancheng Jiang. "Nonparametric Inference for

Additive Models," Journal of the American Statistical

Association, 100, # 471 (2005) 890-907.



where the generalized likelighood ratio test (GLR) is

discussed. This test has not been implemented but can be

implemented by interested users.



Assume



y = f(x1,...,x2)



gamfit transforms the independent variables while acefit

transforms both independent and dependent variables. Hastie and

Tibshirani make the point that a model of the form



y=exp(x1+x2**2)e



cannot be estimated in additive form by gamfit but a simple

additive model can be found that describes log(y). For example

log(y)=x1+x2**2 + ln(e)



Acefit procedure:



Assume G(y) is the transformed dependent variable. The

ACE procedure forces var{G(y)} = 1. The ACE procedure

minimizes E{G(y)-f(X)}**2 subject to var{G(y)}=1.



Assume one input variable x.



yhat = ((G(y))**-1){a+sum(f(x))}



where f(x]=) is the transformation for the input variable

x and the transformation for the dependent variable is

assumed to be invertable..



Logic of ACE:



1. For fixed G, the minimizing f is f(x)=E{G(y)|x}

2. For the minimizing f in step 1, the minimizing G is

G(y)=E(f(x)|Y}. In this step

new_(y)=estimated_g(y)/var{estimated_g(y)}**.5



Steps 1 and 2 alternate after assuming G(y) so that it has unit

variance at each step to avoid a trivial zero solution.



In words, the ace algorithm alternates between smoothing g(y)

on x to get a new f(x), and f(x) on y to get a new g(y),

until the mean-squared error does not change.



Since the B34S implementation of ace saves all yhat vectors and

residual vectors, it is up to the user to select the best

model to use. The below listed examples show one criteria using

the sum of squares of the residuals. However the user may

want to weight the later performance more than the earlier

performance of the model. The code to select best ace model

(shown below) is placed after the call acefit command:



/; Get best model



ibest=1;

rss_base=sumsq(%res(,ibest));



if(%ns.gt.1)then;



do i=2,%ns;

rss_try=sumsq(%res(,i));



if(rss_try.lt.rss_base)then;

ibest=i;

rss_base=rss_try;

endif;



enddo;

endif;



ace_res=%res(,ibest);





Logic of AVAS



In theory AVAS is more suitable for regession models in that it

involves an asymptotic variance stabilizing transformation.

For more detail see Stokes (200x).



Variables created



%res - Residuals saved for last %nob %ns

matrix



%y - Y variable



%yhat - Predicted y saved as a %nob,%ns array

matrix



%yvar - Y variable name



%names - Names in Model



%lag - Lag



%vartype - Variable type



%dist - Error Distribution



%nob - Effective number of observations.



%k - Number of right hand side variables.



%ns - Number of passes.



%rsq - Vector of R**2 for ns runs.



%ty(n,ns) - Transformed y.



%tx(n,p,ns) - Transformed x.



[ ] Specifications. Allowed values are:



order e => usual case. This is

default for y and x.



circular => periodic in range 0.0 to

1.0 with period 1.



monotone => Transform must be monotone

linear => transform is linear



cat => not orderable.



If the transformatiion is supplied,

then the corresponding codes are



fix_order



fix_circular



fix_monotone



fix_linear



fix_cat



Examples: Call acefit(y x1 x2[order] x3[order]{1}

x4[order]{1 to 6} :print);



Note: while x1 is allowed x1{1} is not since [ ] is missing.



Options supported



:print Show output



:itprint Show Iterations



:avas Use AVAS approach to get

transformations.



:span r1 Sets span. Default = 0.0. Set as a

fraction of observations in window.

0.0 => automatic (variable) span

selection. For small samples (n 0) should be

used. Reasonable span values are 0.3 to

0.5.



:alpha r2 Sets alpha. Default = 0.0. Controls

high frequency (small span) penality

used with automatic span selection

(bass tone control). alpha.le.0.0 or

alpha.gt.10.0 => no effect.)



:ns ns Number of solutions. Default = 3.



:ty ty Supplied y transformation. ty(n,ns)



:tx tx(n,p,ns) Supplied x transform

:maxit i1 Maximum number of iterations.

Default=20



:nterm i2 Maximum number of terminal iterations.

Default = 3



:tol delrsq Sets termination threshold.

Default=.1e-3. Iteration stops when

R**2 changes less than delrsq in i2

iterations.



:weight w Set weight for each obs. Series w must

have same # of observations as left

hand variable.



:spans r3 Sets a three element array.

Spans values are for the three running

linear smoothers.



spans(1) : tweeter span.

spans(2) : midrange span.

spans(3) : woofer span.



Default => array(:.05,.2,.5)

This parameter should not be adjusted

under normal circumstances.





call acefit(y x[orderable]{1 to 6} z[cat,4] :print);



The model specification involves specificatioon of the type

of variable and optionally a lag or lags. The model

specification allows the lags to be set in the command. Only

vectors can be supplied in this release. If no[ ] is supplied,

[orderable] is assumed. The specification



call acefit(y y[orderable]{1} x[orderable]{0 to 3}

z[predictor]{1} )$



is the same as



call acefit(y y[orderable]{1}

x[orderable]

x[orderable]{1}

x[orderable]{2}

x[orderable]{3}

z[predictor]{1})$







Discussion of variable types and how to use command.





Examples:

b34sexec options ginclude('b34sdata.mac') member(gam);

b34srun;

b34sexec options noheader; b34srun;

b34sexec matrix;

call loaddata;

call echooff;

call acefit(y[cat] age[order]

start_v[order ]

numvert[order]

:print);

call gamfit(y age[predictor,3]

start_v[predictor,3]

numvert[predictor,3]

:link logit :dist gauss :maxit index(2000,1500)

:tol array(:.1d-13,.1d-13));

b34srun;



/;

/; ACEFIT Problem showing plots for various NS values

/;

b34sexec options ginclude('b34sdata.mac') member(gam_3);

b34srun;

b34sexec options noheader; b34srun;

b34sexec matrix;

call loaddata;

call olsq(cpeptide age bdeficit : print);

call echooff;

call acefit( cpeptide[order ] age[order] bdeficit[order]

:maxit 20 :nterm 10 :ns 2 :tol .1e-8 :print);

call names(all);

call tabulate(%rsq,%ssres);

call print(%y);

call print(%yhat,%res);

do i=1,%ns;

call graph(%res(,i));

enddo;

b34srun;



/;

/; Experimental AVAS Option

/;

b34sexec options ginclude('b34sdata.mac') member(gam_3);

b34srun;

b34sexec options noheader; b34srun;

b34sexec matrix;

call loaddata;

call olsq(cpeptide age bdeficit : print);

call echooff;

call acefit( cpeptide[order ] age[order] bdeficit[order]

:avas

:maxit 20 :nterm 10 :tol .1e-8 :print);

call names(all);

call tabulate(%rsq,%ssres);

call print(%y);

call print(%yhat,%res);

do i=1,%ns;

call graph(%res(,i));

enddo;

b34srun;



/;

/; ACEFIT Vs GAMFIT on Gas Data

/;

b34sexec options ginclude('b34sdata.mac') member(gas);

b34srun;

b34sexec options noheader; b34srun;

b34sexec matrix;

call loaddata;



call gamfit(gasout gasout[predictor,3]{1 to 4}

gasin[predictor,4]{1 to 4} :print);



call acefit(gasout gasout[order]{1 to 4}

gasin[order]{1 to 4} :print);

b34srun;



/;

/; Best ACE Model against OLS, GAM and MARS

/;

b34sexec options ginclude('b34sdata.mac') member(gam_3);

b34srun;

b34sexec options noheader; b34srun;

b34sexec matrix;

call loaddata;

call olsq(cpeptide age bdeficit : print);

ols_res=%res;

call echooff;

call acefit(cpeptide[order ] age[order] bdeficit[order]

:maxit 20 :nterm 10 :ns 2 :tol .1e-8 :print);

call names(all);

call tabulate(%rsq,%ssres);

call print(%y);

call print(%yhat,%res);

do i=1,%ns;

call graph(%res(,i));

enddo;



/; Get best model



ibest=1;

rss_base=sumsq(%res(,ibest));

if(%ns.gt.1)then;



do i=2,%ns;

rss_try=sumsq(%res(,i));



if(rss_try.lt.rss_base)then;

ibest=i;

rss_base=rss_try;

endif;



enddo;



endif;



ace_res=%res(,ibest);



/; Gam Models



call gamfit(cpeptide age[predictor,3]

bdeficit[predictor,3]

:dist gauss :maxit index(2000,1500)

:tol array(:.1d-13,.1d-13) :print);

call print(%tss,%rss,%sigma2);

call tabulate(%coef,%z,%nl_p,%ss_rest);

gam_res=%res;



call mars(cpeptide age bdeficit :nk 40 :mi 2 :print

);

mars_res=%res;



Models=c8array(:'OLS','ACE','GAM','MARS');

fit =array(:sumsq(ols_res),sumsq(ace_res),

sumsq(gam_res),sumsq(mars_res));

call tabulate(models,fit,

:heading 'Residual Sum of Squares for Various Models');



call graph(ols_res,ace_res,gam_res mars_res :nolabel

:heading 'Test of various nonlinear Models');

call tabulate(ols_res,ace_res,gam_res mars_res);

b34srun;



ACF_PLOT Simple ACF Plot



subroutine acf_plot(series,nacf,title);

/$ Simple ACF Plot routine

/$ Series = Input series

/$ nacf = # NACF and PACF

/$ Title = Title

/$

/$ DATA_ACF is a more complex command

/$

/$ ***************************************



Example:



b34sexec options ginclude('gas.b34')$ b34srun$

b34sexec matrix;

call loaddata;

call load(acf_plot);

call acf_plot(gasout,24,'gasout');

b34srun;



ADDCOL Add a column to a 2d array or matrix.



call addcol(x,jbegin);



Adds col at jbegin.



The command for adding more than one col is:



call addcol(x,jbegin,number);



To add a col at right, give:



call addcol(x);



Note that jbegin and number are integer*4.



ADDROW Add a row to a 2d array or matrix.



call addrow(x,ibegin);



Adds row at ibegin.



The command for adding more than one row is:



call addrow(x,ibegin,number);



To add at bottom, give command:



call addrow(x);



Note that ibegin and number are integer*4.



AGGDATA Aggregate Data under control of an ID Vector.



call aggdata(id,x,newx,newid);



Aggregates data in accordance with ID variable



id Id variable to determine subgroup.

ID must have been sorted and be lined up with x.



x Series to be aggregated



newx Mean of elements in group



newid Group id of new series



Series created



%nelm # of observations in the group



%nnzero # of non zero observations in the group

%varx variance of elements in group





Notes: The series %nelm allows one to subset the x easily.





Example:



b34sexec matrix;

id=10.;

x=20.1;

call aggdata(id,x,newx,newid);

call print(id,x,newx,newid,%nelm,%nnzero,%varx);

id=array(6:10. 10. 11. 11. 11. 12.);

x= array(6:1 2 3 4 5 6);

call tabulate(id,x);

call aggdata(id,x,newx,newid);

call tabulate(newx,newid,%nelm,%nnzero,%varx);

b34srun;



ALIGN Align Series with Missing Data



The align command trims series that are the same length

initially but contain missing data. This command works for

series like the goodrow( ) function works for a matrix.

Align works for real*8, real*4 integer*4 and character*8



call align(x1, x2);



After this command runs x1 and x2 are still the same length

but now contain only non missing data. x1 and x2 must be 1D or

2d objects. To line up time series data starting in different

periods use the command:



call tslineup(ts1,ts2,ts3);



which will place missing data where there are no observations.



Example:



b34sexec matrix;

n=10;

x=rn(array(n:));

y=rn(x);

call tabulate(x,y);

i=integers(1,n,2);

x(i)=missing();

call tabulate(x,y);

call align(x,y);

call tabulate(x,y);

b34srun;



Advanced Time Series Example

/;

/; Shows line up and purging time series data.

/; Due to possible missing data inside the series the

/; timestart and timebase have not been set. However a

/; date variable can be added to preserve the date of each

/; observation

/;

b34sexec matrix;

call tsd(:get c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);

call tsd(:get c96c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);

call tsd(:get cd :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);



call names(:);

/; do i=1,norows(%names%);

/; call print(argument(%names%(i)));

/; enddo;

call names;

call tabulate(c c96c cd);

call tslineup(c c96c cd);

call tabulate(c c96c cd);

call align(c c96c cd);

call tabulate(c c96c cd);

call names;



/; Using a date variable



call clearall;



call tsd(:get c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a1);

call tsd(:get c96c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a2);

call tsd(:get cd :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a3);

call names(:);

/; do i=1,norows(%names%);

/; call print(argument(%names%(i)));

/; enddo;

call names;

call tabulate(c a1 c96c a2 cd a3);

call tslineup(c a1 c96c a2 cd a3);

call tabulate(c a1 c96c a2 cd a3);

call align( c a1 c96c a2 cd a3);

call tabulate(c a1 c96c a2 cd a3);

call names;



b34srun;



ARMA ARMA estimation using ML and MOM.

The ARMA command estimates univariate BJ models using ML

and method of moments. Only one AR and MA factor is allowed.

This command can be used to select relatively simple models

from inside a user selected framework. If many series are

to be filtered quickly, this command should be considered.



The more complex command AUTOBJ will identify models with

AR, MA, SAR and SMA factors. This command is based on the

BJIDEN and BJEST routines available as B34S commands. The

underlying code for this comamnd is the Peck Box Jenkins

program that was developed under the supervision of George

Box at UW in the late 60's and early 70's. Many accuracy

improvements have been made by Houston H. Stokes.



call arma(x :options):



Estimates an ARIMA model on series x using the method of

moments & nonlinear least squares. Forecasts and residuals

can be calculated. Both unrestricted and restricted

models can be fit.



Box-Jenkins-Reinsel (1994) page 220 - 223 discusses the

method of moments approach using the Newton-Raphson algorithm.

The ARMA command uses the IMSL Library routines DN2LSE

and DN2PE.



Options supported to estimate unrestricted models:



:nar n - Sets n as the max AR order

provided all terms up to n

are to be estimated. In this

case the keyword :arorder is

not needed.



:arorder ivec - Sets AR terms to be estimated

for restricted model. :nar

is not set in this case.



:arparms rvec - Sets initial AR parameter values.

Usually not required.



:nma m - Set for max MA order provided

all terms up to m are to

be estimated. In this case

:maorder is not needed.



:maorder ivec - Sets MA terms to be estimated

for restricted models. :nma is

not set in this case.



:maparms rvec - Sets initial MA parameter values.

Usually not required.



:relerr r - Stopping criterion for method of

moments (MM) estimation. If

r =0.0, default = 100*amach(4).



:maxit n - Maximum number of iterations for MM

of estimation. Default = 300.



:refine r - Removes parameters whose |t| is LT r



:nomm - Do not use MM starting values

for unrestricted models.



:nonlls - Do not use NLLS for unrestricted

model.



:maxbc n - Sets maximum backforecasting.

Default = 20.



:tolbc r - Sets convergence tolerance for

backforecasting. Backcasting

terminates when abs value of

backcast tolbc=.01*series sd.



:tolss r - Sets convergence tolerance.

Default = 0.0.



:warn - Turns on nlls warning messages.

If this option is used, a common

message regarding convergence can

usually be ignored.



:forecast n nf - Sets base and # of forecasts



:foreprob r - Sets Probability limit for forecasts.

Default = .95



:itprint - Prints from IMSL routines MM estimates

and forecasts. This is usually not

needed.



:print - Print results of estimation.





Variables created if options selected:



%numar - Number of AR parameters



%arparms - AR parameters



%arorders - AR orders



%numma - Number MA parameters

%maparms - MA parameters



%maorders - MA orders



%fcast - Vector of forecasts



%foreobs - Vector of Forecast obs



%fconf - Forecast conf. Int



%fpsi - Forecast psi weights



%seriesm - Series mean



%coef - constant, ar parameters, ma

parameters



%se - Coefficient Standard Errors



%t - Coefficient t scores



%cname - Coefficient name



%corder - Coefficient order



%const - = %seriesm*(1-par(1)-..-par(nrap)



%nres - nob - (max(arorder,maorder)+2)



%res - Residual vector of length %nres



%resobs - Observation # of residual



%y - Y vector lined up same as %res



%yhat - Estimated y



%avar - Random shock variance



%yvar - Y variable name



%rss - Residual sum of squares



%sumabs - Sum of |e(t)|



%maxabs - Maximum |e(t)|



%yvar - Y variable







Unless it fails to solve, the method of moments starting values

will substantially speed up calculations. The switch :nomm can

be used to turn off MM starting values if there are problems.

A better choice would be to make the model simplier.



To estimate an unrestricted ar(4) model



call arma(gasout :nar 4 :print);



To estimate an unrestricted arma(2,1) model



call arma(gasout :nar 2 :nma 1 :print);



To estimate a restricted model with AR terms at lag 2 and 3.



call arma(gasout :arorder idint(array(:2 3))

:print)





Example 1. AR model on gasin series:



b34sexec options include('c:\b34slm\gas.b34'); b34srun;

b34sexec matrix;

* Model Discussed in Box-Jenkins and in Stokes (1997);

call loaddata;

call arma(gasin :nar 3

:forecast 296 24

:itprint

:print);

call graph(%res);

call graph(%y,%yhat);

call graph(acf(%res));

b34srun;



Example 2. ARMA model on real m1



b34sexec options include('c:\b34slm\b34sdata.mac.b34')

memb34(res79); b34srun;

b34sexec matrix;

call loaddata;

diff2rm=dif(fmscom,2,1);

call arma(diff2rm :nar 2

:nma 1

:itprint

:print);

call graph(%res);

call graph(%y,%yhat);

call graph(acf(%res));

call arma(diff2rm :nar 2

:maorder idint(array(:3,4,7))

:itprint

:print);

call graph(%res);

call graph(%y,%yhat);

call graph(acf(%res));

b34srun;

AUTOBJ - Automatic Estimation of Box-Jenkins Model



The ARMA command estimates univariate BJ models using ML and

method of moments. Since only one AR and MA factor is allowed,

this command can be used to select relatively simple models

from inside a user selected framework. If many series are to be

filtered quickly, this command should be considered. Models

with very many terms can be estimated.



The more complex command AUTOBJ will automatically identify

models with AR, MA, SAR and SMA factors without the user having

to specify the model. This use of time series AI allows

filtering of a large number of quite different series

possible. A limit of 10 terms can be in the model but up to 6

factors can be estimated. These limits are due to the Box-

Jenkins philosophy that suggests parsimonious models be used.



The AUTOBJ command is based on the BJIDEN and BJEST routines

available as B34S commands. The underlying code is based on

the Peck Box Jenkins program that was developed under the

supervision of George Box at UW starting in the late 60's.



In addition to automatic model selection using the :autobuild

option, the AR amd MA parameters can be specified in "manual"

mode of operation..



call autobj(x :options);



x series to filter.



If the user wants to impose differencing, this should be done

outside the command or inside the command with the command

:rdif or :sdif. Other wise using automatic model building,

differencing will be selected if the AR parameter is above

the :roottol value which defaults to .8.



:autobuild - Automatically selects the arima model

starting from a "generic" arima(1,1)

model on appropriately differenced

data.



:rawacfpacf - Give Raw ACF and PACF prior to model

being fit..



:difrawacf - Gives difference as well as raw acf

and pacf if :rawacfpacf set.



:assumptions - Lists assumptions. Not usually used.



:seasonal n - Sets the seasonal period. If this is

not present seasonal differencing will

not be attempted.

:seasonal2 n - Sets the second seasonal period. If

seasonal2 is set, seasonal must be set.

Used with hourly and weekly data.



:longar n - Sets initial default AR order.

Default=1. Range 0-2. This is not

allowed if seasonal2 is set.



:longma n - Sets initial default MA order.

Default=1. Range 0-2. This option is

not allowed if seasonal2 is set.



:nodif - Suppress automatic differencing

selection.



:rdif - Forces Regular Differencing.



:sdif - Forces Seasonal Differencing.



:trend - Estimate a trend if there is

differencing.



:noest - No estimation will be performed. This

option requires that the model has been

saved.



:cleanmod - On the last step, the model will be

cleaned of parameters that have |t|

values LT droptol. This option makes a

very parsimonious model.



:forcedstart - Forces a default starting value of .1

to be set. This is usually not needed.



:nosearch - Turns off spike hunting.



:spikelimit i - Sets limit to look for spikes.

Default = max(12,2*seasonal)



:spiketol r - Sets t for spike inclusion.

Default = droptol. If this is set too

low the program will cycle since a term

will be added which will not be

significant due to the |t| not meeting

the droptol.



:arlimit r - Sets a value to check for |t| of

adjacent ACF terms. If r is set

smaller, it is more likely AR terms

will be added. Change this value

with caution. Default = 1.3.



:startvalue r - Sets default parameter start value

for automatic model building.

Default = .1



:print - Print results.



:printres - Print residuals.



:printit - Print iterations



:printsteps - Prints Model selection steps for

automatic model building.



:backforecast - Use backforecasting. This option allows

residuals to be calculated for all data

points. It can result in instable

estimation. This option should be used

with care.



:maxtry n - Maximum tries at auto model selection.

Default = 4.



:roottol r - Set auto model differencing tolerance.

Default = .8



:droptol r - Sets drop tolerance. Default = 1.7



:eps1 r - Sets max change in relative sum of

squares before iteration stops.

Default = 0.0 => this criterian

not used.



:eps2 r - Sets relative max change in each

parameter. Default = .004



:maxit i - Sets maximum number of iterations

allowed. Default = 20



:nac i - Sets # autocorrelations printed.

Max = 999.



:npac i - Sets number of partial autocorrelations

printed.



:holdout n - Sets number of observations to hold out



Options to override auto selection of the model.



Note: Specify AR and MA in this order if present.



:ar ivec - set AR orders. Can specify up to

three factors. For example:



:ar index(1 2 3) index(12)

:ma ivec - set ma orders. Can specify up to

three factors. For example:



:ma index(1 2 3) index(12)



:arparm rarray - Initial ar values. Usually not

needed.



:maparm - Initial ma values. Usually not

needed.



:dif ivec - set differencing orders. Can specify

up to three factors. For example



:dif index(1 1)

:dif index(1 1) index(1 12)

:dif index(1 1) index(1 12)

index(1 48)



Note: :dif index(1 1 1 12)

not supported!



:forecast index(i1 i2)



- Sets forecast number and origin.

Limit for number = 100



:smodeln - Sets model save name. If :noest

is in effect,this sets the model

name to used to make forecasts.





Variables created if options selected:



%numar - Number of AR factors



%numma - Number MA factors



%numdif - Number difference factors



**********************************************



Defined if %numar > 0



%arparms - AR parameters



%arse - SE of AR parameters



%arord - AR orders



%narfact - Number of parameters in each factor



**********************************************

Defined if %numma > 0



%maparms - MA parameters



%mase - SE of MA parameters



%maord - MA orders



%nmafact - Number of MA parameters in

each factor



**********************************************



Defined if %numdif > 0



%diford - Dif Orders (6 element array)



**********************************************





%coef - constant, ar parameters, ma

parameters



%se - Coefficient Standard Errors



%t - Coefficient t scores



%cname - Coefficient names



123456

AR - 1

AR - 2

MA - 1

MA - 2



give info on the factor



%corder - Coefficient order



Defined if Forecasting



*********************************************



%fcast - Vector of forecasts



%foreobs - Vector of Forecast obs



%fse - Forecast standard error



%fpsi - Forecast psi weights



%nres - nob -(max(arorder,maorder)+2)



%res - Residual vector of length %nres.

%resobs - Observation # of residual



%y - Y vector lined up same as %res.



%yhat - Estimated y



%yvar - Y variable name



%rss - Residual sum of squares



%sumabs - Sum of |e(t)|



%maxabs - Maximum |e(t)|





Notes: If :ar or :ma is found, auto identification will not be

performed.



If auto identification is used, the beginning values

will often be close to the final values because of the

"hidden" identification estimation runs. The switch

:printsteps will show these estimations although usually

this is not needed.



The following statement will detect if the program ran:





if(kind(%res).eq.-99)then;

call print('AUTOBJ failed');

endif;



Example # 1 Identify the Gas model:



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;

call load(rtest);

/$

/$ This roottol setting forces no differencing

/$

/$ call autobj(gasout :print :nac 24 :npac 24

/$ :roottol .99 :autobuild );



/$ This turns off differencing



call autobj(gasout :print :nac 24 :npac 24 :nodif

:autobuild );



call rtest(%res,gasout,48);



/$ Default let program decide

call autobj(gasout :print :nac 24 :npac 24

/$ :printsteps

:spiketol 2.0 :autobuild );



call rtest(%res,gasout,48);



b34srun;



Example # 2 Identify Retail Data



b34sexec options ginclude('b34sdata.mac')

member(retail); b34srun;



b34sexec matrix;

call loaddata;

call load(rtest);



call autobj(applance :autobuild :seasonal 12 :nac 36

:print :assumptions

/$

/$ maxtry limits model

/$ :printsteps :maxtry 2

/$

:forecast index(20,norows(applance))

);



call names(all);

call tabulate(%cname,%corder,%coef,%se,%t);

call print(%yvar,%numar,%numma,%numdif);

if(%numdif.ne.0)call print(%diford);

if(%numar.ne.0)

call print(%narfact,%arord,%arparms,%arse);

if(%numma.ne.0)

call print(%nmafact,%maord,%maparms,%mase);



b34srun;



AUTOCOV - Autocovariance of a series



call autocov(series,auto,nn);



series = data

auto = autocovariance

nn = # of elements in auto



Note: AUTOCOV is a Matrix Command subroutine contained in

matrix2.mac. Before it is run it must be loaded with



call load(autocov);







Example:

b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call echooff;

call loaddata;

call load(autocov);

call autocov(gasout,aa,norows(gasout)/2);

aatest=acf(gasout,norows(gasout)/2);

call tabulate(aa,aatest);

call graph(aatest :heading 'ACF');

call graph(aa :heading 'Autocovariance');

b34srun;



BACKSPACE - Backspace a unit



call backspace(n);



backspaces unit n



Example:



b34sexec matrix;

/$

/$ Notes: After the call copyf unit 6 has hit an

/$ end of file.

/$ The call backspace(6); makes this file

/$ able to be written. The call to echooff;

/$ is needed since the call to rewind

/$ will be echoed in the output

/$ file before the backspace is given and

/$ cause problems!!

/$

x=rn(matrix(4,4:));

xi=inv(x);

call print(x,xi);

call open(77,'b34sout.out');

call rewind(77);

call echooff;

call copyf(6,77);

call backspace(6);

call echoon;

b34srun;



BDS BDS Nonlinearity test.





call bds(x,eps1,m,dim,bdsu,bdsv,probu,probv)



Calculates BDS test for series x.





Eps1 should be in range .5 to 2.0. Eps used is sd*eps1.

If sd = 200 and eps1 = .5 , then eps = 100.



M = dimension of test. Upper limit = 17.

X must be filtered such that there is no

autocorrelation remaining. If this is not done, the

BDS test will give a false positive reading.



DIM = a vector for the dimension of the test.

DIM goes from 2 .. M.



BDSU = U form of test.



BDSV = V form of test.



PROBU = probability associated with BDSU



PROBV = probability associated with BDSV.



The BDS test is based on subroutines from Patterson &

Ashley which in turn based their routines on LeBaron (1997).



If : is added to the argument list the results will be printed.

A short form of the command is



call bds(x,eps1,m:);



Example:



b34sexec options ginclude('b34sdata.mac') member(blake);

b34srun;

b34sexec matrix;

call loaddata;

call print('Results should be:'

' 2 3 4 5 '

' -.086613 -1.6219 -1.8737 -1.2281');

call bds(blake,.5,5,mm,bdsu,bdsv,pbdsu,pbdsv);

call tabulate(mm,bdsu,bdsv,pbdsu,pbdsv);

b34srun;



B_G_TEST Breusch-Godfrey (1978) Residual Test





call b_g_test(iorder,x,res,gbtest,gbprob,iprint,iprint2)





subroutine b_g_test(iorder,x,res,gbtest,gbprob,iprint,iprint2);

/;

/; Implements Breusch- Godfrey (1978) Test

/; See Greene (2000) page 541

/;

/; iorder => Max order of the test

/; x => original x matrix

/; res => residual from original equation

/; gbtest => Breusch-Godfrey (1978) test Stat

/; gbprob => Probability of stat

/; iprint => ne 0 prints results

/; iprint2 => ne 0 prints stage 2 results

/; +++++++++++++++++++++++++++++++++++++++++++++++++++

/;

/; Use: call olsq(y x1 x2 x3 :savex);

/; do iorder=1,4;

/; call b_g_test(iorder,%x,%res,gbtest.gbprob,1,0);

/; enddo;

/;



Example:

/;

/; Test Case From Greene (2000) page 541

/;

b34sexec options ginclude('greene4.mac') member(a13_1);

b34srun;

b34sexec matrix;

call loaddata;

call load(b_g_test);

call echooff;



call olsq(realnvst realgnp realint :print :savex);

call print(' ':);



do iorder=1,4;

call B_G_test(iorder,%x,%res,gbtest,gbprob,1,0);

enddo;



b34srun;



BGARCH Calculate function for a BGARCH model.



call bgarch(res1,res2,arch1,arch2,y1,y2,func,

maxlag,nbad :options);



The BGARCH subroutine supports a general way to setup a BGARCH

(bivariate GARCH) model and avoid the overhead of recursive

calls. Fixed correlation and time varrying correlation models

are possible. The BGARCH command works with two series. If more

than two series are desired, use the Fortran implementation.



The purpose of the BGARCH command is to provide aflexible way

to input a general BGARCH model. If more complex models are

desired, the best way to proceed for a recursive system is to

hard code the model in Fortran. An example below shows these

alternative ways to proceed.



The BGARCH subroutine calculates the function which is then

maximized with CMAXF2 or the in more complex cases with the

nonlinear programing with nonlinear constraints command

NLPMIN1. The latter approach allows nonlinear restrictions on

the parameters but does not give SE's. By use of a bootstrap

SE's can be obtained at substantial computer cost.



BGARCH modeling in RATS often has a problem which result in the

message "useable observations" that arises because during the

iteration phase in the second moment equation the value goes LE

0 causing problems with the LOG and the division. If BGARCH is

used with the CMAXF2 command it is possible to restrict the

parameters of the second moment equation such that this does

not occur.



The b34s BGARCH subroutine is slower than Rats, but provides

complete instrumentation of the solution process and will not

give the "useable observations" message that indicates that

only a reduced number of datapoints are using in estimating the

model.



Required BGARCH Subroutine arguments



res1 - first moment residual for series 1

res2 - first moment residual for series 2

arch1 - second moment residual for series 1

arch2 - second moment residual for series 2

y1 - Series 1

y2 - Series 2

func - function

maxlag - maxlag of model for purposes of ML sum.

nbad - number of bad datapoints



:rho - rho parameter or 3 parameters in :tvrho



:tvrho - Name for rho series for tvrho. This series must

be allocated and must be the same length as y1.



If res1, res2, arch1 or arch2 are allocated prior to the call

to BGARCH, the initial values placed in these series are used.

If BGARCH allocates these series, all values are set to 0.0.



Options supported



:ar11 arparm arorder - AR parameters & orders

series 1 for equation 1.



:ar12 arparm arorder - AR parameters & orders

series 2 for equation 1.



:ar22 arparm arorder - AR parameters & orders

series 2 for equation 2.



:ar21 arparm arorder - AR parameters & orders

series 1 for equation 2.



:ma11 maparm maorder - MA parameters & orders

series 1 for equation 1.



:ma12 maparm maorder - MA parameters & orders

series 2 for equation 1.

:ma22 maparm maorder - MA parameters & orders

series 2 for equation 2.



:ma21 maparm maorder - MA parameters & orders

series 1 for equation 2.



:gar11 garparm garorder - GAR parameters & orders

for second moment eq for

series 1 to series 1.



:gar21 garparm garorder - GAR parameters & orders

for second moment eq for

series 1 to series 2.



:gar12 garparm garorder - GAR parameters & orders

for second moment eq for

series 2 to series 1.



:gar22 garparm garorder - GAR parameters & orders

for second moment eq for

series 2 to series 2.





:gma11 gmaparm gmaorder - GMA parameters & orders

for second moment eq for

series 1 to series 1.



:gma21 gmaparm gmaorder - GMA parameters & orders

for second moment eq for

series 1 to series 2.



:gma22 gmaparm gmaorder - GMA parameters & orders

for second moment eq for

series 2 to series 2.



:gma12 gmaparm gmaorder - GMA parameters & orders

for second moment eq for

series 2 to series 1.



:mu11 muparm muorder - Mu parameters and order

for second moment eq

for series 1 mapping to

series 1.



:mu21 muparm muorder - Mu parameters and order

for second moment eq

for series 1 mapping to

series 2.



:mu22 muparm muorder - Mu parameters and order

for second moment eq

for series 2 mapping to

series 2.

:mu12 muparm muorder - Mu parameters and order

for second moment eq

for series 2 mapping to

series 1.



:rho rhoname - Pass D1 array with one

element for constant

correlation model, three

elements for tvrho model.



:tvrho series - Pass a series name for

time varrying rho. This

is the rho vector. It must

be allocated prior to the

call. Its size is the

same as data1.



:negrho - The default is to assume a

positive rho for the time

varrying rho. The negative

rho constraints the rho to

be negative. While usually

rho is positive, if there

are convergence problems

impose the negative

constraint.



:constant cparm - Constant. If no constant is

desired, do not pass this

parameter to the maximize

command. cparm must be a 4

element array. It it is not

present zero is assumed.



:dorange irange - Sets do range. Usually this

is not needed. Default is

1 to noob.



Form of BGARCH Model



Constant correlation case:



max sum(gdet -0.5*((res1(t)**2/ arch1(t))

+ (res2(t)**2/ arch2(t))

-2*rho*res1(t)*res2(t)/sqrt(arch1(t)*arch2(t)))

/(1.0-rho**2))



where



gdet = -0.5*(log(arch1(t))+log(arch2(t))

+ log(1.0-rho**2))



Time varrying case:

max sum(gdet -0.5*((res1(t)**2/ arch1(t))

+ (res2(t)**2/ arch2(t))

-2*rho*res1(t)*res2(t)/

dsqrt(arch1(t)*arch2(t)))/(1.0-rho(t)**2))



rho = q0 +q1*rho(t-1)

+q2*res1(t-1)*res2(t-1)/

dsqrt(arch1(t-1)*arch2(t-1))



rho = dexp(rho(t))/(1.0+dexp(rho(t))



gdet = -0.5*(log(arch1(t))+log(arch2(t))

+ log(1.0-rho(t)**2))





where:



res1(t)=y(t)-cparm(1)

-arparm11(1)*y1(t-arorder11(1))-...

-arparm12(1)*y2(t-arorder12(1))-...

-maparm11(1)*res1(t-maorder11(1))-...

-maparm12(1)*res2(t-maorder12(1))-...

-muparm11(1)*dsqrt(arch1(t-muorder11(1)))-...

-muparm12(1)*dsqrt(arch2(t-muorder12(1)))-...



res2(t)=y(t)-cparm(2)

-arparm22(1)*y2(t-arorder22(1))-...

-arparm21(1)*y1(t-arorder21(1))-...

-maparm11(1)*res1(t-maorder11(1))-...

-maparm21(1)*res2(t-maorder21(1))-...

-muparm21(1)*dsqrt(arch1(t-muorder21(1)))-...

-muparm22(1)*dsqrt(arch2(t-muorder22(1)))-...





arch1(t)=cparm(3)

+gmaparm11(1)*(res1(t-gmaorder11(1))**2) +

+gmaparm12(1)*(res2(t-gmaorder12(1))**2) +

+garparm11(1)* arch1(garaorder11(1)) + ...

+garparm12(1)* arch2(garaorder12(1)) + ...



arch2(t)=cparm(4)

+gmaparm22(1)*(res2(t-gmaorder22(1))**2) +

+gmaparm21(1)*(res1(t-gmaorder21(1))**2) +

+garparm22(1)* arch2(garaorder22(1)) + ...

+garparm21(1)* arch2(garaorder12(1)) + ...





Note: If overflows occur the parameters of the model may have

to be restricted in such a way that they do not get near

0.0 during the solution iterations.



Since the order in which the equations are solved is

res1 and res2, if muorder(1)=0, then the system will

have to be coded with DO loops. Examples of

alternative coding are contained in BGARCH_B and

BGARCH_C jobs in matrix.mac.



Sample Jobs



Job # 1 is a Diagonal Constant Correlation Model



b34sexec scaio readsca

/$ file('/usr/local/lib/b34slm/findat01.mad')

file('c:\b34slm\findat01.mad')

dataset(d_HKJA); b34srun;



b34sexec matrix;

call loaddata;



count=0.0;

call echooff;



program test;



/$ Here we have only diagonal elements



zero=0.0d+00;

call bgarch(res1,res2,arch1,arch2,data1,data2,

func,7,nbad

:ar11 array(:p6) index(6)

:constant array(:zero,zero,a0,b0)

:gma11 array(:a1) index(1)

:gar11 array(:a2) index(1)

:gma22 array(:b1) index(1)

:gar22 array(:b2) index(1)

:dorange index(8,469)

:rho array(:rho));

count=count+1.0;



/$ Optional Visual Solution info



call outdouble(10,1 , func);

call outdouble(10,2 , count);

call outdouble(10,3, p6);

call outdouble(10,4, a0);

call outdouble(10,5, b0);

call outdouble(10,6, a1);

call outdouble(10,7, a2);

call outdouble(10,8, b1);

call outdouble(10,9, b2);

call outdouble(10,10, rho);



return;

end;



call print(test);



j=integers(1,469);

data1 = ln_hk(j);

data2 = ln_ja(j);

arch1 = data1*0.0 ;

arch2 = data1*0.0 ;

res1 = data1 ;

res2 = data2 ;



/$ a0 = .1, a1 = .1, a2 = .4

/$ b0 = .1, b1 = .2, b2 = .6

/$ p6 = .1, rho = 0.1



call cmaxf2(func :name test

:parms p6 a0 b0 a1 a2 b1 b2 rho

:ivalue array(:.1 .1 .1 .1 .4 .1 .6 .1)

:maxit 300

:gradtol .1e-4

:lower array(:-.5 ,.1d-12,.1d-12,.1d-12,.1d-12,

.1d-12,.1d-12,.1d-12)

:upper array(:.1d+30,.1d+30,.1d+30,.1d+30,.1d+30,

.1d+30,.1d+30,.1d+30)

:print);



b34srun;



Job # 2 Is Constant Correlation but NOT diagonal





/$ BGARCH Constant Correlation Example 9.2, 9.22

/$ page 369

/$

b34sexec scaio readsca

/$ file('/usr/local/lib/b34slm/findat01.mad')

file('c:\b34slm\findat01.mad')

dataset(M_IBMLN2); b34srun;

/$

/$ See Tsay(2001) page 368 Example 9.2 Equation 9.22

/$ See BGARCH_B test case



/$ Uses BGARCH



b34sexec matrix;

call loaddata;



program test;

/$

/$ Rats setup info

/$

/$ c1 p11 p22 p12 c2 a0 a11 b11 b12 b0 a21 a22

/$ b21 b22 rho

/$ a1t=r1(t)-c1-p11*r1{1}-p22*r1{2}-p12*r2{2}

/$ a2t=r2(t)-c2

/$ gvar1=a0+a11*a1t(t-1)**2+b11*h1(t-1)+

/$ b12*h2(t-1)

/$ gvar2=b0+a21*a1t(t-1)**2+a22*a2t(t-1)**2+

/$ b21*h1(t-1) + b22*h2(t-1)

/$ gdet=-0.5*(log(h1(t)=gvar1(t))+log(h2(t)=

/$ gvar2(t))+log(1.0-rho**2))

/$ garchln = gdet-0.5/(1.0-rho**2)*

/$ ((a1t(t)**2/h1(t))+(a2t(t)**2/h2(t))

/$ -2*rho*a1t(t)*a2t(t)/sqrt(h1(t)*h2(t)))



call bgarch(res1,res2,arch1,arch2,data1,data2,

func,3,nbad

:ar11 array(:p11 p22) index(1 2)

:ar12 array(:p12) index(2)

:gma11 array(:a11) index(1)

:gar11 array(:b11) index(1)

:gar12 array(:b12) index(1)

:gma22 array(:a22) index(1)

:gma21 array(:a21) index(1)

:gar21 array(:b21) index(1)

:gar22 array(:b22) index(1)

:rho array(:rho)

:dorange index(3,888)

:constant array(:c1 c2 a0 b0));



count=count+1.0;



/$ Optional instrumentation



call outdouble(10,1 , func);

call outdouble(10,2 , count);

call outdouble(10,3, c1);

call outdouble(10,4, p11);

call outdouble(10,5, p22);

call outdouble(10,6, p12);

call outdouble(10,7, c2);

call outdouble(10,8, a0);

call outdouble(10,9, a11);

call outdouble(40,1, b11);

call outdouble(40,2, b12);

call outdouble(40,3, b0);

call outdouble(40,4, a21);

call outdouble(40,5, a22);

call outdouble(40,6, b21);

call outdouble(40,7, b22);

call outdouble(40,8, rho);



return;

end;



call print(test);



/$ c1 = 1.4, c2 = 0.7, p11 = 0.1, p22 = 0.1, p12 = -0.1

/$ a0 = 3.0, a11=0.1, a21=0.02, a22=0.05

/$ b0=2.0, b11=.8, b12=.01, b21=.01, b22=.8, rho = 0.1



count=0.0;

j=integers(1,888);

data1=ibmln(j);

data2=spln(j);

call echooff;



call cmaxf2(func :name test

:parms c1 p11 p22 p12 c2

a0 a11 b11 b12 b0

a21 a22 b21 b22 rho



:ivalue array(:1.4, .1, .1, -.1, .7

3.0, .1, .8, .01, 2.0,

.02, .05,.01, .8, .1)

:maxit 30000

:maxfun 30000

/$

/$ Rats Names

/$ c1 p11 p22 p12 c2

/$ a0 a11 b11 b12 b0

/$ a21 a22 b21 b22 rho

/$

:lower array(:.1d-12,.1d-12,.1d-12,-.2, .1d-12,

.1d-12,.1d-12,.1d-12,-.06, .1d-12,

.1d-12,.1d-12,-.1, .1d-12,.1d-12)



:upper array(:.1d+3, .1d+3, .1d+3, .1d+3, .1d+3,

.1d+3, .1d+3, .1d+3, .1d+3, .1d+3,

.1d+3, .1d+3, .1d+3, .1d+3, .1d+3)

:print);



b34srun;



Job # 3 is a Time-varying Correlation Model



/$

b34sexec scaio readsca

/$ file('/usr/local/lib/b34slm/findat01.mad')

file('c:\b34slm\findat01.mad')

dataset(m_ibmln2); b34srun;



/$

/$ stablemod = 1

/$ Forces GARCH parameters GE 0.0

/$ Tsay RATS code allows "unstable" models due to

/$ unconstrained estimator

/$ stablemod = 1 can cause problems in convergence since

/$ parameters are at theirt zero point

/$

/$ => stablemod=0 => -3678.3455

/$ => stablemod=1 => -3685.0870



%b34slet stablemod=0;



b34sexec matrix;

call loaddata;



program test;



call bgarch(res1,res2,arch1,arch2,ibmln,spln,func,3,nbad

:ar11 array(:p1) index(1)

:ar12 array(:p3) index(2)

:gar11 array(:b1) index(1)

:gma11 array(:a1) index(1)

:gar12 array(:f1) index(1)

:gma22 array(:a11) index(1)

:gar22 array(:b11) index(1)

:gma21 array(:d11) index(1)

:gar21 array(:f11) index(1)

:rho array(:q0,q1,q2)

:tvrho rho

:dorange index(3,888)

:constant array(:c1 c2 a0 a00));



count=count+1.0;



/$ Optional visual output to monitor solution progress



call outdouble(10,1 , func);

call outdouble(10,2 , count);

call outdouble(10,3, c1);

call outdouble(10,4, p1);

call outdouble(10,5, p3);

call outdouble(10,6, c2);

call outdouble(10,7, a0);

call outdouble(10,8, a1);

call outdouble(10,9, b1);

call outdouble(40,1, f1);

call outdouble(40,2, a00);

call outdouble(40,3, a11);

call outdouble(40,4, b11);

call outdouble(40,5, f11);

call outdouble(40,6, d11);

call outdouble(40,7, q0);

call outdouble(40,8, q1);

call outdouble(40,9, q2);



/$

/$ Trap > 0 value and reset

/$



if(func.gt.0.0)func=-10.d+9;

return;

end;



call print(test);

count=0.0;



/$ c1 = 1.4, p1 = 0.1, p3 =-.1 , c2 = .07, a0 = 2.95

/$ a1 = .08 b1 = .87 f1 =-.03 a00= 2.05 a11=.05

/$ b11= .92 f11=-.06 d11=.04 q0 = -2.0 q1 = 3.0

/$ q2 = .1



j=integers(888) ;

data1=ibmln(j) ;

data2=spln(j) ;

res1 =array(norows(data1):);

res2 =array(norows(data1):);

arch1=array(norows(data1):) + 45.;

arch2=array(norows(data2):) + 31.;

rho =array(norows(data2):) + .8 ;



call echooff;



call cmaxf2(func :name test

:parms c1 p1 p3 c2 a0

a1 b1 f1 a00 a11

b11 f11 d11 q0 q1

q2

/$

/$ c1, p1, p3, c2, a0

/$ a1, b1, f1, a00, a11

/$ b11 ,f11, d11, q0, q1

/$ q2

/$ Rats Answers reported in Tsay (2001)

/$ Note that Tsay allows GARCH parameters to be First Moment Residual

y => Input Series

nccf => Number ccf terms

lags => lags

title => title



High resolution graphs are made. List of CCF values also given.

ccftest is a subroutine and must be loaded with the statement



call load(ccftest);



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call load(ccftest);

nn=norows(gasout)/4;

call character(title,'Gasin vs Gasout');

call ccftest(gasin,gasout,nn,lags,title);

b34srun;



CFREQ Determine Cumulative Frequency Distribution



call cfreq(series,cseries,cc);



series = Input series



cseries = Sorted input series



cc = Cumulative frequency







Note: CFREQ is a Matrix Command subroutine contained in

matrix2.mac. It must be loaded with



call load(cfreq);



before it is used.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call load(cfreq);

call cfreq(gasout,sgasout,cc);

call tabulate(gasout,sgasout,cc);

b34srun;



See test cases cfreq and quantile in matrix.mac



CHAR1 Place a string in a character*1 array.



call char1(cc,'text');



Places text in ' ' in a character literal object cc.

There is currently no limit on the number of cols of text

inside ' '. This text can be placed in an array. For example:



call char1(c,'ABCDEFGHI');

cc=array(3,3:c);

call print(cc);



results in



ABC

DEF

GHI





call character( ) can be used in place of call char1.



If cc is a character*8 variable of any length, the statement



call char1(newc,cc);



places cc in newc, a chartacter*1 object. The variable cc can

be > 72 characters.



If more than two arguments are supplied, a 2D array is

created where the length is automatically padded.



Advanced options:



Note that the B34S matrix command converts any string of

length LE 8 to a character*8 object. The command



call char1(cc,'a');



places the character a in a 1 element character*1 array

since 'a' became a temp with elements 'a ' and

the command automatically looked for the actual length.



If the alternative setup



call char1(cc,'a':1);



was used, cc would be a character*1 object with one element.

However



call char1(cc,'a':2);



would create a 2 element character*1 object.



If the actual length of the input string is > 8, its actual

length is used.



Examples of Structured use of character arrays:



b34sexec matrix;

call character(cc,'1234567890qwertyuiop');

i=integers(7);

ccc=cc(i);

i=i+3;

cccp3=cc(i);

call print(cc,ccc,cccp3);

* get a large character array;

call character(clarge,rtoch(array(1000:)));

call names(all);

b34srun;



b34sexec matrix;

call char1(c1,'This is a long string what do you think');

call char1(c2,'This is ');

call print(c1,c2);

call char1(x ,'This is a long string what do you think'

'so it this '

'But this is not');

call names(all);

call print(c1,c2,x);

b34srun;



b34sexec matrix;

/$

/$ Job shows creating char*8 and char*1 variables

/$ and moving data between the variable types

/$

call character(cc_3, '012');

call character(cc, '012':3);

call character(cc0, '0' :1);

call character(cc1, '1' :1);

call names(all);



call print(cc(2),cc0);

if(cc(2).eq.cc0)call print('yes-error');



call print(cc(1),cc0);

if(cc(1).eq.cc0)call print('yes-right1');



call print(cc(2),cc0);

if(cc(2).ne.cc0)call print('yes-right2');



call print(cc(1),cc1);

if(cc(1).ne.cc1)call print('yes-right3');



cc=array(:0.,1.,2.);

call print(cc);

if(cc(2).eq.0.)call print('yes-error');

if(cc(1).eq.0.)call print('yes-right1');

if(cc(2).ne.0.)call print('yes-right2');

if(cc(1).ne.1.)call print('yes-right3');



b34srun;

CHARACTER Place a string in a character*1 array.



call character(cc,'text');



Places text in ' ' in a character literal object cc.

For detail on this command see the help file for

call char1.





CHTOHEX Convert a character to a hex value



call chtohex(ch,hex);



ch = Character*1 character vector of size n



hex= character*1 character matrix of size 2*n



Extended example



b34sexec matrix;

/$ Looking at Printable Characters ;

i=integers(33,127);

call igetchari(i,cc);

call names(all);

call tabulate(i,cc);

call igetichar(cc,iitest);

call chtohex(cc,hexcc);

/$ Repack character*2 array save as character*1;

/$ Next two statments work the same

/$ hexcc2= array(norows(hexcc)/2,2:hexcc);

hexcc2=c1array(norows(hexcc)/2,2:hexcc);

hex1=hexcc2(,1);

hex2=hexcc2(,2);

call hextoch(hexcc,cctest);

xx=transpose(hexcc2);

call print(xx,hexcc2);

call hextoch(xx,cctest2);

call names(all);

/$ get hexcc2 in a printable variable;

blank=c1array(norows(hex1):);

call names(all);

c8var=catcol(hex1, hex2,blank,blank,

blank, blank,blank,blank);

call names(all);

/$ call print(c8var);

c8var=c8array(norows(c8var):transpose(c8var));

call tabulate(i,cc,iitest,hex1,hex2,

cctest,cctest2,c8var);

b34srun;



CHECKPOINT Save workspace in portable file.



call checkpoint;

Will save the workspace with a default name. Alternative

options can be passed with :keywords. The checkpoint command

works the same as the save command except that it automatically

uses the :speakeasy option.



Keywords supported include:



:file - to pass a file name.

Default name is 'matrix.psv'.



:var - to restrict saving to a list of variables.

Do not place , between names. If variable is

known at the local and global level, the

local copy is saved. This means that formula

results, not formulas are saved. If :var is

not present, all objects will be saved.



:speakeasy - Only pass data, no programs. If this option

is used, the save file can be read by the

Speakeasy(r) program. The



call checkpoint;



command automatically assumes this option. As

a result real*16 and complex*32 variables are

saved as real*8 and complex*16 respectively.

If



call save;



is used, then this conversion is not made.

While real*16 and complex*32 variables are

preserved, this save file will not work with

Speakeasy!



:ndigits4 - Sets save format e12.4



:ndigits8 - Sets save format e16.8.



:ndigits16 - Sets save format e24.16. This is the default.



:ndigits32 - Sets save format e40.32. If real*16 data is

to be saved, it is highly recommended that

this option be used to preserve accuracy.





Examples:



call checkpoint(:var x y z);

call checkpoint(:var x y z :file 'myrun.psv');

call checkpoint(:file 'myrun.psv');

call checkpoint(:var x y :file 'mygood.psv' );



If you are running with Speakeasy, it is suggested that you use

the ending *.psv.



The SAVE and RESTORE commands use a subset of the Speakeasy

EXPORTALL & IMPORTALL format and are designed to facilitate

moving objects from one system to another. Since B34S MATRIX

programs, subroutines and functions will not work on Speakeasy,

the keyword :speakeasy MUST be used to save into a file that

will be read by Speakeasy(r). Since Speakeasy does not at

present support real*16 and complex*32, these data types are

automatically saved as real*8 and complex*16 respectively.



VPA data can not be directly saved in a savefile. However VPA

data can be hidden in a real*8 variable so VPA numbers can be

saved with checkpoints etc using the command



call vpaset(vpa r8 :saveasr8);



The variable r8 can be reloaded into a VPA variable with



call vpaset(r8 vpa :saveasvpa);



The first four elements give kind, nr8, norows, nocols.





For related commands see restore and save.



CLEARALL Clears all objects from workspace.



call clearall;



Clears data, programs,subroutines and functions. Use with

caution! See related, and safer command, cleardata.



CLEARDAT Clears data from workspace.



call cleardat;



Clears all data. Use with caution. See related, and more

dangerous command clearall.



CLOSE Close a logical unit.



call close(n);



Closes unit n.



Example:



call close(72);



CLS Clear screen.





call cls;

Clears the screen.



Alternatives:



call cls(arg);



arg > 0 => clear row.

arg LE 0 => clear window.



Examples:



call cls(2); clears row 2 in current window.



call cls(-1); clears current window.



CMAXF1 Constrained maximization of function using zxmwd.





The CMAXF1 function provides a quick way to maximize a

constrained function using the Quasi-Newton Method. If the

functional value is multiplied by -1.0, a minimum can be

obtained. A simple setup for a maximum / minimum is:



call cmaxf1(func :name test :parms x1 x2 :ivalue rvec

:lower lvalues :upper uvalues :print);



where func is a scalar computed with the user MATRIX program

test and x1 and x2 are parameters. Initial guess values for x1

and x2 are in the real vector rvec.



For example the minimum of



func = -3.*x2**2. + 4*x1**2 - x2 + 2.*x1;



with answers -.2500, .1667 and func = -.3333



where -1. LE x1 LE 0. and 0. LE x2 LE 1.



can be found with the commands:



b34sexec matrix;



program test;

func=(-1.0)*((-3.)*x2**2. + 4*x1**2 - x2 + 2.*x1);

call outstring(3,3,'Function to be minimized');

call outdouble(36,3,func);

return;

end;



rvec=array(2:-1.2 1.0);

ll=array(2:-1.,0.0);

uu=array(2:.0 ,1.0 );

call cmaxf1(func :name test :parms x1 x2

:lower ll :upper UU

:ivalue rvec :print);

b34srun;



The function name (func) the program name (test) and the parms

are required to be passed. If there is a concern that the

function has more than one minimum, the NLSTART command can be

used to investigate a larger number of starting values. This

feature of CMAXF1 makes it quite valuable.



For example:



b34sexec matrix;



program test;

func=-3.*x2**2. + 4*x1**2 - x2 + 2.*x1;

return;

end;



n=2;

k=10;

a=array(n:-2. 2.);

b=array(n:.5 2.);

ll=array(2:-1.,0.0);

uu=array(2:.0,1.0 );

call nlstart(a,b,k,s);



do i=1,k

rvec=s(,i);

call cmaxf1(func :name test :parms x1 x2

:lower ll :upper UU

:ivalue rvec :print);

enddo;

b34srun;



**********************************************************



Required:



func - Function name



:name pgmname - User program to determine func



:parms v1 v2 - Parameters in the model. These parameters

must be in the function in the user

program pgmname that determines func. The

keyword :parms MUST be supplied prior to

all keywords except :name.



:lower ll - Vector of lower values for parameters.



:upper uu - Vector of upper values for parameters



Optional keywords for CMAXF1 are:

:print - Print results



:ivalue rvec - Determines initial values. rvec must be a

vector containing the number of elements

equal to the number of parameters

supplied. Default = .1.



:nsig i - Sets number of digits of accuracy for

convergence. Default = 4.



:nstart n - Number of starting points.

Default = min(2**n+5,100)

where n = number of parameters.



CMAXF1 automatically creates the following variables.



%coef - a vector containing the parameters.



%nparm - a vector with coefficient names.



%nsig - estimate of # of significant values.



%func - final value of function.





CMAXF2 Constrained maximization of function using dbconf/g.





The CMAXF2 function provides a way to maximize a constrained

function using the Quasi-Newton Method. If the functional value

is multiplied by -1.0, a minimum can be obtained. CMAX2 uses

IMSL routines dbconf & dbcong.



A simple setup for a maximum / minimum is:



call cmaxf2(func :name test :parms x1 x2 :ivalue rvec

:lower ll :upper uu :print);



If the gradiant is known the call is



call cmaxf2(func grad :name test test2 :parms x1 x2

:ivalue rvec

:lower ll :upper uu :print);



where func is a scalar computed with the user MATRIX program

test and x1 and x2 are parameters. Initial guess values for x1

and x2 are in the real vector rvec.



For example the minimum of



FUNC = 100.*(x2-x1*x1)**2. + (1.-x1)**2.



can be found with the commands:

b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. +(1.-x1)**2.);

return;

end;



rvec=array(2:-1.2 1.0);

ll=array(2:-2.,-1.0);

uu=array(2:.5,2.0 );

call cmaxf2(func :name test :parms x1 x2

:ivalue rvec

:lower ll :upper uu :print);

b34srun;



The function name (func) the program name (test) and the parms

are required to be passed. If there is a concern that the

function has more than one minimum, the NLSTART command can be

used to investigate a number of starting values.



For example:



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

return;

end;



n=2;

k=10;

a=array(n:-2. 2.);

b=array(n:.5 2.);

call nlstart(a,b,k,s);

do i=1,k

rvec=s(,i);

call cmaxf2(func :name test :parms x1 x2 :ivalue rvec

:lower ll :upper uu :print);

enddo;



b34srun;



Note that in the default mode, the commands for cmaxf1 and

cmaxf2 are the same. The cmaxf2 command can optionally pass

the name of the gradiant array after the func name and the

name of the gradiant subroutine after the function subroutine.



The set up for this optional mode is:



b34sexec matrix;



program test;

func=(-1.0)*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

call outstring(3,3,'Function');

call outdouble(36,3,func);

call outdouble(4, 4, x1);

call outdouble(36,4, x2);

return;

end;



program der;

g(1)= (400.0*(x2-x1*x1)*x1) + (2.0*(1.0-x1));

g(2)= -200.0*(x2-x1*x1);

return;

end;



call print(test,der);



rvec=array(2:-1.2, 1.0);

ll= array(2:-2. ,-1.0);

uu= array(2:.5 , 2.0);

call echooff;

call cmaxf2(func g :name test der

:parms x1 x2

:ivalue rvec

:lower ll

:upper uu :print);

b34srun;





********************************************************



Required:



func - Function name. Optionally the gradiant

variable name can be supplied.



:name pgmname - User program to determine func and

optionally the program to determine

the gradiant.



:parms v1 v2 - Parameters in the model. These

parameters must be in the function in

the user program pgmname that determines

func. The keyword :parms MUST be

supplied prior to all keywords except

:name.



:lower rvec - Vector of lower values for parameters.



:upper rvec - Vector of upper values for parameters



Optional keywords for CMAXF2 are:



:print - Print results.



:ivalue rvec - Determines initial values. rvec must be

a vector containing the number of

elements equal to the number of

parameters supplied. Default = .1.



:xscale vec - Vector of n elements to scale x.

Default = 1.0



:fscale real - Functional scaling. Default = 1.0.



:ngood int - Sets number of good digits in the

function.



:maxit int - Maximum number of iterations.

Default = 100.



:maxfun int - Maximum number of function evaluations.

Default = 400



:maxg int - Maximum number of gradiant evaluations.

Default = 400



:gradtol real - Scaled gradiant tolerance.

Default = eps**(1/3).



:steptol real - Scaled step tolerance.

Default = eps**(2/3).



:rftol real - Relative functional tolerance.

Default = max(1.0d-20,eps**(2/3)).



:aftol real - Absolute functional tolerance.

Default = max(1.0d-20,eps**(2/3)).



:fctol real - False convergence tolerance.

Default = 100.*eps.



:maxsteps real - Maximum allowable step size.

Default = (1000*max(tol1,tol2))

where

tol1=sqrt(sum (xscale(i)*ivalue(i))**2)

for i=1,n

tol2 = 2-norm of XSCALE



:ihessian key - where key is 0 to initialize hessian to

identity matrix. This is default. If key

NE 0, hessian initialized to

max(|f(XGUESS|,FSCALE)*XSCALE(i)





Warning: If you are not sure how to change a parameter,

use the default.



CMAXF2 automatically creates the following variables

%coef - a vector containing the parameters.



%nparm - a vector with coefficient names



%se - a vector containing parameter

standard errors



%t - a vector containing parameter t scores



%hessian - hessian matrix



%grad - estimate of gradiant at final parameter

values



%func - final value of function





Comments: CMAXF2 uses the IMSL routines dbconf & dbcong which

are based the Scittkowski routine NLPQL. Both

routines use the quasi-Newton method. The solution is

updated according to the BFGS approach. For further

references see the IMSL documentation.

CMAXF3 Constrained maximization of function using db2pol.



The CMAXF3 function provides a way to maximize a function using

function comparison. No smoothness is assumed. While this

approach is not efficient for smooth problems, it can be

useful when the function is not smooth or to get starting

values.



The CMAXF3 function provides a way to maximize a constrained

function using the complex method. Although no SE's are given,

this command is useful to obtain starting values. If the

functional value is multiplied by -1.0, a minimum can be

obtained.



A simple setup for a maximum / minimum is:



call cmaxf3(func :name test :parms x1 x2 :ivalue rvec

:lower ll :upper uu :print);



where func is a scalar computed with the user MATRIX program

test and x1 and x2 are parameters. Initial guess values for x1

and x2 are in the real vector rvec.



For example the minimum of



FUNC = 100.*(x2-x1*x1)**2. + (1.-x1)**2.



can be found with the commands:



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

return;

end;



rvec=array(2:-1.2 1.0);

ll=array(2:-2.,-1.0);

uu=array(2:.5,2.0 );

call cmaxf3(func :name test :parms x1 x2 :ivalue rvec

:lower ll :upper uu :print);

b34srun;



The function name (func), the program name (test), and the

parms are required to be passed. If there is a concern that the

function has more than one minimum, the NLSTART command can be

used to investigate a number of starting values. For example:



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

return;

end;



n=2;

k=10;

a=array(n:-2. 2.);

b=array(n:.5 2.);

call nlstart(a,b,k,s);

do i=1,k

rvec=s(,i);

call cmaxf3(func :name test :parms x1 x2 :ivalue rvec

:lower ll :upper uu :print);

enddo;

b34srun;



Note that in the default mode, the commands for cmaxf1, cmaxf2

and cmaxf3 are the same.



*****************************************************



Required:



func - Function name. Optionally the

gradiant variable name can be

supplied.



:name pgmname - User program to determine func

and optionally the program to

determine the gradiant.



:parms v1 v2 - Parameters in the model. These

parameters must be in the function in

the user program pgmname that

determines func. The keyword :parms

MUST be supplied prior to all keywords

except :name.



:lower rvec - Vector of lower values for parameters.



:upper rvec - Vector of upper values for parameters.



Optional keywords for CMAXF3 are:



:print - Print results.



:ivalue rvec - Determines initial values. rvec must

be a vector containing the number of

elements equal to the number of

parameters supplied. Default = .1.



:ftol real - Relative functional tolerance.

Default =max(1.0d-20,eps**(2/3)).



:maxit int - Maximum number of iterations.

Default = 100.





CMAXF3 automatically creates the following variables



%coef - a vector containing the parameters.



%nparm - a vector with coefficient names



%func - final value of function



The iterations proceed until:



1. # of iteratiions is reached.



2. func(best)-func(worst) LE ftol*(1+dabs(f(best))



3. sum(1,...,(n+1))(f(i)-(sum(f(j))/(n+1))**2 LE ftol





Warning: If you are not sure how to change a parameter, use

the default.





COPY Copy an object to another object



call copy((2./4.),half);



Works the same as an assingment but allows the target to be

calculated real time.



call copy(xx,xy);



xx a character*1, character*8, real*4, real*8, real*16,

VPA, complex*16, complex*32 or integer*4 or integer*8

variable.



xy target



Note: The statement



call copy(x,y(i));



will not work as intended!!! Here y(i) is a temp variable.



Example:



b34sexec matrix;

x=2.;

call copy(x,y);

call print(y);

vpax=vpa(rn(array(5:)));

call copy(vpax,vpay);

call print(vpax,vpay);

i=integers(6);

i8=i4toi8(i);

call copy(i8,i8copy);

call print(i,i8,i8copy);

b34srun;



Example showing a copy on the fly



b34sexec matrix;



/; shows passing a name to a routine at execution;

/; User wants the name my_x_dat & my_Y_dat for the

/; random walk series!!

/; These sure look like economic series



n=10000;

data1= cusum(rn(array(n:)));

data2= cusum(rn(array(n:)));



subroutine test(data1,data2,name1,name2);

call copy(data1,argument(name1));

call copy(data2,argument(name2));

call graph(argument(name1),argument(name2)

:Heading 'This Model is Spurious!!' :nokey);

call describe(argument(name1),argument(name2));

call olsq(argument(name1),argument(name2) :print);

return;

end;



name1='my_y_dat';

name2='my_x_dat';

call test(data1,data2,name1,name2);

b34srun;

COMPRESS Compress workspace.



call compress;



To compress workspace. If



call names(all);



is given before and after this command, space compression can

be observed. This command is usually never needed unless

there are substaintal calculations being made.



The variant



n=100;

call compress(n);





will compress every 100 calls.



call compress(:off);



turns off compression even if



call compress;



or



call compress(n);



are found.



call compress(:on);



will turn on compression.



call compress(:info);



will provide information of settings. This command is useful

for software developers.



Note: The command call compress; will be ignored if it is

used in a program, function or subroutine that is called as

part of a nonlinear estimation command such as NLLLSQ, CMAX2

etc. The reason for this restriction is to avoid the

possibility of data movement that is not known to the calling

command. If memory management is needed in this case, use the

solvefree command. The compress command will also be ignored

if it is called from a function or from a subroutine that

has been called by a user function.



Example:



/$ Illustrates call compress inside a LOOP

/$

/$ Job # 1 runs saving space

/$

/$ Note difference in space use

/$

b34sexec matrix;

call echooff;

subroutine doit(n);

x=rn(matrix(n,n:));

c=inv(x);

return;

end;



count=1.;

top continue;

call compress;

call doit(100);

count=count+1.0;

if(count.le.100.)go to top;



b34srun;

/$

/$ Job # 2 has call compress turned off

/$

b34sexec matrix;

call echooff;

subroutine doit(n);

x=rn(matrix(n,n:));

c=inv(x);

return;

end;



count=1.;

top continue;

/$ call compress;

call doit(100);

count=count+1.0;

if(count.le.100.)go to top;



b34srun;



CONSTRAIN Subset data based on range of values.



call constrain(x,y,z:var z :lower .1 upper 10.);



Returns x, y and z values where z is in the range .1 to 10.



If upper is not supplied it defaults to 1.0d+32.

If lower is not supplied it defaults to -1.0d+32.



Meld and constrain can be used to look at planes of more than

2d objects. H. H. Stokes is in debt to Stan Cohen the developer

of Speakeasy for the idea for meld and constrain.

Meld in b34s works like the simular command in Speakeasy.

Constrain in Speakeasy allows multiple input testing.



The variable tested in constrain must be real*8. If :lower and

:upper are missing :var checks z against missing. A variable

not tested against can be real*8, char*8 or integer.



Constrain does not work for real*16 data at this time.



Test Problem:



b34sexec matrix;

i=array(:1. 2. 3.);

j=array(:4.,5.,6.);

k=array(:7.,8.,9.);

call tabulate(i,j,k);

call meld(i,j,k);

f=i**2.+j**2.+k**2.;

call tabulate(i,j,k,f);

call constrain(i,j,k,f:var i :lower 2.);

call tabulate(i,j,k,f);

call constrain(i,j,k,f:var k :upper 8.);

call tabulate(i,j,k,f);

b34srun;



CONTRACT Contract an array



call contract(old,ibegin,iend)



Will contact a character*1 array.



old = Character*1 string.



ibegin = Integer pointer to a substring



iend = Integer pointer to end of a substring



old will be changed to have elements ibegin-iend removed.



Example:



b34sexec matrix;

call character(cc,'This is a test');

call print(cc);

call ilocatestr(cc,'is',istart,iend);

call contract(cc,newcc,istart,iend);

call print(newcc);

b34srun;



b34sexec matrix;

call character(cc,'This is a test');

call print(cc);

call ilocatestr(cc,istart,iend);

i=integers(istart,iend);

subs=cc(i);

call print(subs);

call contract(cc,istart,iend);

oldnewcc=cc;

call print(cc);

call character(new,'aaaissaa');

call expand(cc,new,1,8);

call print(oldnewcc,cc);

b34srun;





COPYLOG Copy file to log file.



call copylog('file')



Copies a file to log unit. By use of call system, call copyout

and call copylog, external programs such as RATS can be called

inside a MATRIX command do loop to further process data.



COPYOUT Copy file to output file.



call copyout('file')



Copies a file to output unit. By use of call system, call

copyout and call copylog external programs such as RATS can be

called inside a MATRIX command do loop to further process data.



COPYF Copy a file from one unit to another



call copyf(in,iout);



Copies a file from, unit in to unit iout.

Units in and iout must have been allocated. Units are not

closed.



Example:



call copyf(4,77);





Application calling Matlab





/$ Running Matlab script under B34S Matrix

/$ Datacards allows saving of a Matlab script.



b34sexex options;

b34srun;



b34sexec matrix;

datacards;

x=rand(6)

xi=inv(x);

x*xi

yy=[1 2 3 2 1]

plot(yy)

pause

quit

b34sreturn;



call open(77,'test.m');

call rewind(77);

call copyf(4,77);

call system(

'start /w matlab /r test /logfile test.out':);

call copyout('test.out');

b34srun;



Discussion: The cards after "datacards;" and before

"b34sreturn;" are matlab commands that are copied from unit 4,

the default parmcards unit, to unit 77.



CSPECTRAL Do cross spectral analysis.



call cspectral( );



Does spectral analysis on two series.



The command:



call cspectral(x,y,sinx,siny,cosx,cosy,

px,py,sx,sy,rp,ip,cs,qs,a,k,ph,freq :weights);



calculates:



sinx - sine transform for x

siny - sine transform for y

cosx - cosine transform for x

cosy - cosine transform for y

px - Periodogram for x

py - Periodogram for y

sx - Spectrum for x

sy - Spectrum for y

rp - real part of cross periodogram.

ip - imag. part of cross periodogram.

cs - cross spectrum

qs - quadra spectrum

a - amplitude

k - coherience

ph - phase

freq - frequency



The CSPECTRAL command has 18 arguments or 19 arguments

depending on whether weights are supplied.



For one series, see spectral command.



CSUB Call Subroutine

call csub('NAME', arguments :options)



Options



:lengthargs intarray( )



:list lists all supported routines





Comment: The routine is for the expert user with access to

subroutine argument lists. A branch will be made to

b34smatcsubc in sourc16.f.



This routine can someday be used for a DLL branch.

This feature is not implemented at this time. The

design of tyhis routine may change substantially in

the future.







COINT2 Cointegration Tests of Two Series



call coint2( );



Does cointegration tests on two series.





call coint2(x,y,xname,yname,dfx,dfy,adfx,adfy,

lagx,lagy,speedx,speedy,tspeedx,tspeedy,

dfx2,dfy2,adfx2,adfy2,dflag,

resid0,resid1,resid2,iprint);



Tests for Cointegration using Engle Procedure and two series.



COINT2 is a subroutine and must be loaded with



call load(coint2);



Arguments



x = first series

y = second series

xname = name of first series set

with call character(xname,' ')

yname = name of second series set

with call character(yname,' ')

dfx = Unit root test for x

dfy = Unit root test for y

adfx = Augmented DF test for x for lag=dflag

adfy = Augmented DF test for y for lag=dflag

lagx = Number of lags of x

lagy = Number of lags of y

speedx = Speed of adjustment of x

speedy = Speed of adjustment of y

tspeedx= t stat of speedx

tspeedy= t stat of speedy

dfx2 = Unit root test for x RES

dfy2 = Unit root test for y RES

adfx2 = Augmented DF test for x RES for lag=dflag

adfy2 = Augmented DF test for y RES for lag=dflag

dflag = Lag of DF test

resid0 = Residual for Cointegrating Eq

resid1 = Residual for Equation 1

resid2 = Residual for Equation 2

iprint = 0 no print, = 1 print



For a discussion of the analysis see Enders (1995,365-373).



Test Case: COINT2



Example:





b34sexec options ginclude('b34sdata.mac')

macro(coint6); b34srun;

b34sexec matrix;

call loaddata;

call load(coint2);

/$ call print(coint2);



call character(xname,'Enders y Series');

call character(yname,'Enders z Series');

call echooff;

lagx=1; lagy=1; dflag=4;

call coint2(y,z,xname,yname,dfx,dfy,

adfx,adfy,lagx,lagy,speedx,speedy,tspeedx,tspeedy,

dfx2,dfy2,adfx2,adfy2,dflag,resid0,resid1,resid2,1);

call print(speedx,speedy,tspeedx,tspeedy);

b34srun;



COINT2LM Cointegration Tests of Two Series, OLS, L1, MM



call coint2LM(x,y,xname,yname,dfx,dfy,adfx,adfy,

lagx,lagy,speedx,speedy,tspeedx,tspeedy,

l1speedx,l1speedy,mmspeedx,mmspeedy

dfx2,dfy2,adfx2,adfy2,dflag,

resid0,resid1,resid2,iprint);



Tests for Cointegration using Engle Procedure and two series.

Gives OLS, L1 and Minimax



COINT2LM is a subroutine and must be loaded with



call load(coint2lm);





x = first series

y = second series

xname = name of first series set

with call character(xname,' ')

yname = name of second series set

with call character(yname,' ')

dfx = Unit root test for x

dfy = Unit root test for y

adfx = Augmented DF test for x for lag=dflag

adfy = Augmented DF test for y for lag=dflag

lagx = Number of lags of x

lagy = Number of lags of y

speedx = Speed of adjustment of x

speedy = Speed of adjustment of y

tspeedx= t stat of speedx

tspeedy= t stat of speedy

L1speedx= Speed of Adjustment of x L1 estimator

L1speedy= Speed of Adjustment of y L1 estimator

mmspeedx= Speed of Adjustment of x Minimax estimator

mmspeedx= Speed of Adjustment of y Minimax estimator

dfx2 = Unit root test for x RES

dfy2 = Unit root test for y RES

adfx2 = Augmented DF test for x RES

for lag=dflag

adfy2 = Augmented DF test for y RES

for lag=dflag

dflag = Lag of DF test

resid0 = Residual for Cointegrating Eq

resid1 = Residual for Equation 1

resid2 = Residual for Equation 2

iprint = 0 no print, = 1 print



Test case COINT2LM



Example:



b34sexec options ginclude('b34sdata.mac')

macro(coint6); b34srun;

b34sexec matrix cbuffer=100000;

call loaddata;

call load(coint2LM);

call print(coint2LM);



call character(xname,'Enders y Series');

call character(yname,'Enders z Series');

call echooff;

lagx=1; lagy=1; dflag=4;

call coint2LM(y,z,xname,yname,dfx,dfy,

adfx,adfy,lagx,lagy,speedx,speedy,tspeedx,tspeedy,

l1speedx,l1speedy,mmspeedx,mmspeedy,

dfx2,dfy2,adfx2,adfy2,dflag,resid0,resid1,resid2,1);

call print(speedx,speedy, tspeedx, tspeedy,

l1speedx,l1speedy,mmspeedx,mmspeedy);

b34srun;

COINT2M Moving Cointegration of Two Series

call coint2m(x,y,xname,yname,number,lagx,lagy,

speedx,speedy,tspeedx,tspeedy);



Routine to drive coint2 using windows of data



COINT2M is a subroutine and must be loaded with



call load(coint2m);





x = Input series # 1

y = Input series # 2

xname = Name of x series

yname = Name of y series

number = Number of observations in moving model

lagx = Number of lags of X

lagy = Number of lags of y

speedx = Moving Error correction coefficient for x

speedy = Moving Error correction coefficient for y

tspeedx = t Stat of speedx

tspeedy = t stat of speedy



Test Case: COINT2M



Example:



b34sexec options ginclude('b34sdata.mac')

macro(coint6); b34srun;

b34sexec matrix;

call loaddata;

call load(coint2);

call load(coint2m);

call print(coint2,coint2m);



call character(xname,'Enders y Series');

call character(yname,'Enders z Series');

call echooff;

number=60; lagx=1; lagy=1;

call coint2m(y,z,xname,yname,number,lagx,lagy,

speedx,speedy,tspeedx,tspeedy);

call graph(speedx,tspeedx

:heading 'Enders Y Series Moving Error Correction');

call graph(speedy,tspeedy

:heading 'Enders Z Series Moving Error Correction');

call tabulate(speedx,speedy,tspeedx,tspeedy);

b34srun;



COINT2ME Moving Cointegration of Two Series - Extended Version



call coint2me(x,y,xname,yname,number,lagx,lagy,

speedx,speedy,dfx,dfy,adfx,adfy,dfres1,dfres2,

adfres1,adfres2,dflag);

Routine to drive coint2 using windows of data.



COINT2ME is a subroutine and must be loaded with



call load(coint2me);



Uses expanded Arg list



x = Input series # 1

y = Input series # 2

xname = Name of x series

yname = Name of y series

number = Number of observations in moving model

lagx = Number of lags of X

lagy = Number of lags of y

speedx = Moving Error correction coefficient for x

speedy = Moving Error correction coefficient for y

tspeedx = t-Stat for speedx

tspeedy = t-stat for speedy

dfx = Dickey Fuller Test on Raw Data Series x

dfy = Dickey Fuller Test on Raw Data Series y

adfx = Augmented Dickey Fuller Test Raw Data

Series x lag=dflag

adfy = Augmented Dickey Fuller Test Raw Data

Series y lag=dflag

dfres1 = Dickey Fuller Test on RES1 Data Series

dfres2 = Dickey Fuller Test on RES1 Data Series

adfres1 = Augmented Dickey Fuller Test RES1 Data

Series lag=dflag

adfres2 = Augmented Dickey Fuller Test RES2 Data

Series lag=dflag

dflag = Lags for augmented DF test





Test Case COINT2ME



Example:



b34sexec options ginclude('b34sdata.mac')

macro(coint6); b34srun;

b34sexec matrix;

call loaddata;

call load(coint2);

call load(coint2me);

call print(coint2,coint2me);



call character(xname,'Enders y Series');

call character(yname,'Enders z Series');

call echooff;

number=60; lagx=1; lagy=1; dflag=4;



/$ Shows simple call

/$ call coint2m(y,z,xname,yname,number,lagx,lagy,speedx,

/$ speedy,tspeedx,tspeedy);

/$

call coint2me(y,z,xname,yname,number,lagx,lagy,speedx,

speedy,tspeedx,tspeedy,dfx,dfy,adfx,adfy,dfres1,

dfres2,adfres1,adfres2,dflag);



call graph(speedx,tspeedx

:heading 'Enders Y Series Moving Error Correction');

call graph(speedy,tspeedy

:heading 'Enders Z Series Moving Error Correction');

call graph(dfx,dfy,speedx,speedy);

call graph( speedx,speedy,tspeedx,tspeedy);

call tabulate(speedx,speedy,tspeedx,tspeedy,dfx,dfy,

dfres1,dfres2);

call tabulate(speedx,speedy,tspeedx,tspeedy,adfx,adfy,

adfres1,adfres2);

b34srun;





COINT2M2 Moving Cointegration Two Series OLS, L1 Minimax



call coint2m2(x,y,xname,yname,number,lagx,lagy,

speedx,speedy,tspeedx,tspeedy,l1speedx,l1speedy,

mmspeedx,mmspeedy,dfx,dfy,adfx,adfy,dfres1,dfres2,

adfres1,adfres2,dflag);



Routine to drive coint2 using windows of data.

Uses expanded Arg list. OLS, L1 and Minimax Estimates



COINT2M2 is a subroutine and must be loaded with



call load(coint2m2);



x = Input series # 1

y = Input series # 2

xname = Name of x series

yname = Name of y series

number = Number of observations in moving model

lagx = Number of lags of X

lagy = Number of lags of y

speedx = Moving Error correction coefficient for x

speedy = Moving Error correction coefficient for y

tspeedx = t-Stat for speedx

tspeedy = t-stat for speedy

l1speedx= Moving Error correction L1 coefficient for x

l1speedy= Moving Error correction L1 coefficient for y

mmspeedx= Moving Error correction Minimax coefficient

for x

mmspeedy= Moving Error correction Minimax coefficient

for y

dfx = Dickey Fuller Test on Raw Data Series x

dfy = Dickey Fuller Test on Raw Data Series y

adfx = Augmented Dickey Fuller Test Raw Data Series x

lag=dflag

adfy = Augmented Dickey Fuller Test Raw Data Series y

lag=dflag

dfres1 = Dickey Fuller Test on RES1 Data Series

dfres2 = Dickey Fuller Test on RES1 Data Series

adfres1 = Augmented Dickey Fuller Test RES1 Data Series

lag=dflag

adfres2 = Augmented Dickey Fuller Test RES2 Data Series

lag=dflag

dflag = Lags for augmented DF test



test Case COINT2M2



Example:



b34sexec options ginclude('b34sdata.mac')

macro(coint6); b34srun;

b34sexec matrix cbuffer=100000;

call loaddata;

call load(coint2lm);

call load(coint2m2);

call print(coint2lm,coint2m2);



call character(xname,'Enders y Series');

call character(yname,'Enders z Series');

call echooff;

number=60; lagx=1; lagy=1; dflag=4;



/$ Shows simple call

/$ call coint2m(y,z,xname,yname,number,lagx,lagy,speedx,

/$ speedy,tspeedx,tspeedy);

/$

call coint2m2(y,z,xname,yname,number,lagx,lagy,speedx,

speedy,tspeedx,tspeedy,l1speedx,l1speedy,

mmspeedx,mmspeedy,dfx,dfy,adfx,adfy,dfres1,

dfres2,adfres1,adfres2,dflag);



call graph(speedx,tspeedx :nokey

:heading 'Enders Y Series Moving Error Correction');

call graph(speedy,tspeedy :nokey

:heading 'Enders Z Series Moving Error Correction');

call graph(speedx,l1speedx,mmspeedx :nokey

:heading 'Enders Z Series Moving Error Correction');

call graph(speedy,l1speedy,mmspeedy :nokey

:heading 'Enders Z Series Moving Error Correction');



call graph(dfx,dfy,speedx,speedy :nokey);

call graph( speedx,speedy,tspeedx,tspeedy :nokey);

call tabulate(speedx,speedy,tspeedx,tspeedy,dfx,dfy,

dfres1,dfres2);

call tabulate(speedx,speedy,tspeedx,tspeedy,adfx,adfy,

adfres1,adfres2);

call tabulate(speedx,l1speedx,mmspeedx,speedy,

l1speedy,mmspeedy);

b34srun;

COINT3 Moving Cointegration of Three Series



call coint3(x,y,z,xname,yname,zname,dfx,dfy,dfz,

adfx,adfy,adfz,lagx,lagy,lagz,speedx,speedy,

speedz,tspeedx,tspeedy,tspeedz,dfx2,dfy2,dfz2,

adfx2,adfy2,adfz2,dflag,resid0,resid1,resid2,

resid3,iprint);



Tests for Cointegration using Engle Procedure and three series



COINT3 is a subroutine and must be loaded with



call load(coint3);



x = first series

y = second series

z = third series

xname = name of first series set

with call character(xname,' ')

yname = name of second series set

with call character(yname,' ')

zname = name of third series set

with call character(zname,' ')

dfx = Unit root test for x

dfy = Unit root test for y

dfz = Unit root test for z

adfx = Augmented DF test for x lag=dflag

adfy = Augmented DF test for y lag=dflag

adfz = Augmented DF test for z lag=dflag

lagx = Number of lags of x

lagy = Number of lags of y

lagz = Number of lags of z

speedx = Speed of adjustment of x

speedy = Speed of adjustment of y

speedz = Speed of adjustment of z

tspeedx = t of Speed of adjustment of x

tspeedy = t of Speed of adjustment of y

tspeedz = t of Speed of adjustment of z

dfx2 = Unit root test for x RES

dfy2 = Unit root test for y RES

dfy2 = Unit root test for y RES

adfx2 = Augmented DF test for x RES lag=dflag

adfy2 = Augmented DF test for y RES lag=dflag

adfz2 = Augmented DF test for z RES lag=dflag

dflag = Sets lag on DF test

resid0 = Residual for Cointegrating Eq

resid1 = Residual for Equation 1

resid2 = Residual for Equation 2

resid3 = Residual for Equation 3

iprint = 0 no print, = 1 print



Test Case: COINT3



Example:

b34sexec options ginclude('b34sdata.mac')

macro(coint6); b34srun;

b34sexec matrix;

call loaddata;

call load(coint3);

call print(coint3);

call character(xname,'Enders w Series');

call character(yname,'Enders y Series');

call character(zname,'Enders z Series');

call echooff;

lagx=1; lagy=1; lagz=1; dflag=4;

call coint3(w,y,z,xname,yname,zname,dfx,dfy,dfz,

adfx,adfy,adfz,lagx,lagy,lagz,speedx,speedy,speedz,

tspeedx,tspeedy,tspeedz,dfx2,dfy2,dfz2,adfx2,adfy2,

adfz2,dflag,resid0,resid1,resid2,resid3,1);

call print(speedx,speedy,speedz);

call print(tspeedx,tspeedy,tspeedz);

b34srun;

COINT3ME Moving Cointegration of Three Series



call coint3me(x,y,z,xname,yname,zname,number,

lagx,lagy,lagz,speedx,speedy,speedz,

tspeedx,tspeedy,tspeedz,dfx,dfy,dfz,adfx,

adfy,adfz,dfres1,dfres2,dfres3,adfres1,

adfres2,adfres3,dflag);



Routine to drive coint2 using windows of data.

Uses expanded Arg list.



COINT3ME is a subroutine and must be loaded with



call load(coint3me);





x = Input series # 1

y = Input series # 2

z = Input series # 3

xname = Name of x series

yname = Name of y series

zname = Name of z series

number = Number of observations in moving model

lagx = Number of lags of X

lagy = Number of lags of y

speedx = Moving Error correction coefficient for x

speedy = Moving Error correction coefficient for y

speedz = Moving Error correction coefficient for z

tspeedx = t-Stat for speedx

tspeedy = t-stat for speedy

tspeedz = t-stat for speedz

dfx = Dickey Fuller Test on Raw Data Series x

dfy = Dickey Fuller Test on Raw Data Series y

dfz = Dickey Fuller Test on Raw Data Series z

adfx = Augmented Dickey Fuller Test Raw Data

Series x lag=dflag

adfy = Augmented Dickey Fuller Test Raw Data

Series y lag=dflag

dfres1 = Dickey Fuller Test on RES1 Data Series

dfres2 = Dickey Fuller Test on RES2 Data Series

dfres3 = Dickey Fuller Test on RES3 Data Series

adfres1 = Augmented Dickey Fuller Test RES1 Data

Series lag=dflag

adfres2 = Augmented Dickey Fuller Test RES2 Data

Series lag=dflag

adfres3 = Augmented Dickey Fuller Test RES3 Data

Series lag=dflag

dflag = Lags for augmented DF test





Test case: COINT3ME



Example:



b34sexec options ginclude('b34sdata.mac')

macro(coint6); b34srun;

b34sexec matrix;

call loaddata;

call load(coint3);

call load(coint3me);

call print(coint3,coint3me);



call character(xname,'Enders y Series');

call character(yname,'Enders z Series');

call character(zname,'Enders w Series');

call echooff;

number=60; lagx=1; lagy=1; lagz=1; dflag=4;



call coint3me(y,z,w,xname,yname,zname,number,

lagx,lagy,lagz,speedx,speedy,speedz,

tspeedx,tspeedy,tspeedz,

dfx,dfy,dfz,adfx,adfy,adfz,

dfres1,dfres2,dfres3,

adfres1,adfres2,adfres3,dflag);



call graph(speedx,tspeedx

:heading 'Enders Y Series Moving Error Correction');

call graph(speedy,tspeedy

:heading 'Enders Z Series Moving Error Correction');

call graph(speedz,tspeedz

:heading 'Enders w series Moving Error Correction');



call tabulate(speedx,speedy,speedz,

tspeedx,tspeedy,tspeedz);

b34srun;





CSV Read and Write a CVS file

call csv(:readfile 'mycsv.csv' );

call csv(:readfile 'mycsv.csv' :nonames);

call csv(:readfile 'mycsv.csv' :var x);

call csv(:readfile 'mycsv.csv' :var x);

call csv(:writefile 'mycsv.csv' :var x1 x2 x3);



Reads and writes csv files. Real*8 or character*8 data may be

supplied. A row of names must proceed the data. Comments

can be supplied before the names row.



Options, some of which may be required.



:readfile 'filename Supplies a file name of a csvfile

and opens for indicated action.



:writefile 'filename' Supplies a file name of a csvfile

and opens for indicated action.





:nodatestamp Will not put a datestamp comment

in file if there is a :writefile.



:comment Supply a comment file of 1-80

charactacters.



:var If a :writefile then :var is

required to supply variable names.

Up to 255 can be supplied. If a

matrix is supplied, then only one

variable name is allowed.



:nsmissing Sets missing to N/S for real data

for a write.



:missing Sets missing to blank for a write

for real data.



:add Will add data at the end of the CSV

file. The file cannot be read

back into B34S at this time but can

be read into Excel but not with

100% reliability since all data

is seen as just cells. The :add

option allows the matrix command to

"dump" results into one file that

can be read into Excel for

further copying into Word etc.

Note that if :add is supplied the

file must exist and be of the csv

type. Use :add with caution.





Variables created:

%series created if :readfile is supplied



Example of loading data into the matrix command and graphing.



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;

people=c8array(:'houston','diana','will','bobby');

ii=dfloat(integers(10));

call csv(:writefile 'mycsv.csv' :comment 'This is a test'

:var gasout gasin people ii);

x=rn(matrix(10,5:));

call echooff;

do i=1,nocols(x);

call print(i,mean(x(,i)));

enddo;

/; call print(x);

call csv(:writefile 'mycsv2.csv'

:comment 'This is a test matrix'

:var x );

call cleardat;

call names;



call csv(:readfile 'mycsv.csv');

call names;

call print(%series);

n= norows(%series);

call tabulate(gasout,gasin,people,ii);

call print(mean(gasout),mean(gasin));



do i=1,n;



if(kind(eval(%series(i))).eq.8)then;

g=goodrow(eval(%series(i)));

call copy(g,argument(%series(i)));

call print(' ':);

call describe( eval(%series(i):));

call graph( eval(%series(i):));

endif;

enddo;



/; reading matrix



call cleardat;

call names;



call csv(:readfile 'mycsv2.csv');

call names;



/; Tests with alternative file saving of missing data



x=rn(array(5:));

y=rn(array(10:));

call csv(:writefile 'mycsv3.csv' :var x y :nsmissing );

call csv(:writefile 'mycsv4.csv' :var x y :missing );

call cleardat;

call csv(:readfile 'mycsv3.csv' );

call tabulate(X,Y);

call cleardat;

call csv(:readfile 'mycsv4.csv' );

call tabulate(X,Y);



b34srun;





Examples of reading into a b34s data set. Max of 98 serries.



b34sexec matrix;

call csv(:readfile 'mycsv2.csv');

n=norows(%series);



/; space between names



c=c8array(n*2:);

i=integers(1,n);

j=integers(1,2*n,2);

c(j)=%series(i);

call makedata(argument(c) :file 'new.b34');

b34srun;

b34sexec options include('new.b34'); b34srun;



Alternate makedata.



call makedata(%series :file 'new.b34' :add :member(tt));



Example of a *.csv file



File built 20/ 4/05 at 19:50:26 by b34s,,,,

Real*8 and character*8 data loaded,,,,,

Missing data in last line,,,,,

a,b,c,d,e,names

1,4,6,1,2,Houston

2,5,7,1,2,Bobby

3,6,8,1,2,Diana

4,7,9,,2,Will



DATA_ACF - Calculate ACF and PACF Plots



subroutine data_acf(x,heading1,nacf);

/$

/$ Display series and ACF

/$

/$ x = Series to display

/$ heading = Heading for series

/$ nacf = Number of ACF and PACF

/$

/$ Note: Can be called alone or under dataview

/$

/$ ***********************************************

/$



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call load(data_acf);

call character(cc,'ACF & PACF of GASOUT');

call data_acf(gasout,cc,60);

b34srun;



DATAFREQ - Data Frequency



Calculate Data Frequencies for various options



call datafreq(x,table :options);





Required:



x - series (must be real*8).

table - Frequency count



:key - must be set either equal, equaluser,

usercutoff, userclass



:equal k midpts => k equal intervals whose midpoints

are in midpts where data sets

xlow and xhigh.



:equaluser k midpts xlow xhigh



=> k equal intervals whose midpoints

are in midpts but xlow and xhigh

are used.



:usercutoff cutpts => k counts in table where there are

k-1 cut points supplied



:userclass classmk clhw => Class marks are input in

classmk and class half width

in clhw.



Example:



b34sexec matrix;



* IMSL test cases for one-way Frequency analysis;



x=array(:0.77, 1.74, 0.81, 1.20, 1.95, 1.20, 0.47, 1.43,

3.37, 2.20, 3.00, 3.09, 1.51, 2.10, 0.52, 1.62,

1.31, 0.32, 0.59, 0.81, 2.81, 1.87, 1.18, 1.35,

4.75, 2.48, 0.96, 1.89, 0.90, 2.05);



call datafreq(x,table1 :equal 10 midpts1);

call tabulate(table1,midpts1);



xlow=.5;

xhigh=4.5;

call datafreq(x,table2 :equaluser 10 midpts2 xlow xhigh);

call names(all);

call tabulate(table2,midpts2);



cutpts=array(:.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5);

call datafreq(x,table3 :usercutoff cutpts);

call tabulate(table3,cutpts);



classmk=array(:.25 .75 1.25 1.75 2.25 2.75 3.25 3.75 4.25

4.75);

clhw=.25;

call datafreq(x,table4 :userclass classmk clhw);

call tabulate(table4,classmk);



b34srun;



DATAVIEW View a Series Under Menu Control



subroutine dataview(x,'xname');

/$

/$ Views data series x under User Control

/$ x => series

/$ xname => x series name

/$



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call load(dataview);

call dataview(gasout,namelist(gasout));

b34srun;



DES - Code / decode.



This command should be regarded as experimental.



call des(ch1,ch2,key,task);



ch1 - in text. Must be character*8 or Character*1

of up to 16 characters.

ch2 - out text

key - up to 16 characters

task - = 0 => code

= 1 => decode

Text must be in hex form. See chtohex and hextoch.



b34sexec matrix;

/$ 12345678901234567890123456789012

call character(line1,

'This is a test of the system ');

call character(line2,

'This is line # 2 of code test');

call chtohex(line1,hexline1);

call chtohex(line2,hexline2);

call print(hexline1,hexline2);

hexline1=c1array(4,16:hexline1);

hexline2=c1array(4,16:hexline2);

call print(hexline1,hexline2);



in=catrow(hexline1,hexline2);

call print(in);



call character(key,'0101010101010101');

out=c1array(norows(in)*2,nocols(in):);

in=transpose(in);



do i=1,nocols(in);

call des(in(,i),work ,key,0);

out(,i)=work;

enddo;

call print(out);



test=c1array(nocols(in),norows(in):);

do i=1,nocols(in);

call des(out(,i),work,key,1);

call hextoch(work,work2);

call print(work2);

test(i,)=work2;

enddo;

call names(all);

call print(test);

i=integers(1,nocols(test)/2);

newtest=test(,i);

call print(c1array(norows(newtest)*

nocols(newtest):transpose(newtest)));

b34srun;



Test cases in DES.



DESCRIBE Calculate Moment 1-4 and 6 of a series



call describe(x);

call describe(x :print);



Variables created are:



%mean = mean

%sd = small sample SD

%sk = skewness

%c4 = kurtosis

%c6 = 6-th order cumulant

%max = maximum

%min = minimum

%median = median

%q1 = First Quartile

%q3 = Third Quartile

%jb_test = Jarque-Bera (1987) Normality test

%jb_prob = Probability of Jarque-Bera Test

%sk_adj = Adjusted Skewness

%c4_adj = Adjusted Kurtosis

%sk_z = z value for Skewness

%sk_prob = Probability of accepting Skewness

%c4_z = z value for Kurtosis

%sk_prob = Probability of accepting Kurtosis





Note: If missing data is found, the command returns.



%sd = sqrt(sum(x(i)**2)/(n-1) - sum(x)**2)

%sk = sum((x(i)-mean(x))**3.)/(N*sd**3.)

%c4 = sum((x(i)-mean(x))**4.)/(N*sd**4.)-3.0

%c6 = sum((x(i)-mean(x))**6.)=15.0*%c4 -10*%sk*%sk-15.

%sk_adj = ((n**2)/((n-1)*(n-2))*(m3/s**3)

((n+1)*m4 -3.(N-1)*m2*m2)/s**4

%c4_adj = ((n**2)/((n-1)*(n-2)*(n-3))*

((n+1)*m4 -3.(N-1)*m2*m2)/s**4

%jb_test = N*( ((%sk_adj*%sk_adj)/6.)

+ ((%c4_adj*%c4_adj)/24.))

%jb_prob = Chisq probability with DF = 2 of %jb_test

%sk_z = %sk_adj*sqrt(((n-1)*(n-2))/(6*n))

%c4_z = %c4_adj*sqrt(((n-1)*(n-2)*(n-3))/

(24*n*(n+1))





Note: %sk_adj and %c4_adj and %jb_test are the same as Rats and

are based on formulas from Kendall & Stuart (1958)



This command works for real*8 data.



Example:



b34sexec options ginclude('gas.b34');

b34srun;

b34sexec matrix;

call loaddata;

x=rn(array(1000:));

call describe(x :print);

call describe(gasin :print);

call describe(gasout :print);

b34srun;

DUD Derivative Free Nonlinear Estimation



call dud(xvar,yvar,beta,r,f,sse,seb,covb,corrb,

iprint,iout);



Routine based on SAS nonlinear routine dud in technical report

a-102 page 8-9. Routine was implemented in Speakeasy April 1987

and in the B34S Matrix language June 1998.



DUD provides derivative free nonlinear estimation. Its use is

to study nonlinear estimation. For production use see NLLSQ and

NL2SOL which are faster.



DUD needs user subroutine resid.





xvar = matrix of x variables - input

yvar = left hand side variable vector - input

beta = vector of initial guess on coefficients

- input/output

r = residual vector - output

f = predicted variable vector - output

sse = sum of squared residuals (sumsq(r)) - output

seb = se's of the beta coefficients - output

covb = covariance matrix of beta coefficients

- output

corrb = correlation matrix of beta coefficients

- output

iprint= 0 for no iteration print, =1 for iteration print

- input

iout = 0 for no output printing, =1 output will be given



Test Cases: NLLS1, NLLS2, NLLS3



Example from NLLS1



b34sexec matrix cbuffer=10000;

call echooff;

call load(dud);

call load(marq);



program prob1;

/$

/$ test marquardt method of nonlinear estimation

/$ calls marquardt subroutine marq

/$ user supplied resid and deriv

/$

/$ imar=0 marquardt , =1 = dud

/$

call message(

'enter=> deriv. method, Cancel=> deriv. free method',

'Estimation Options', itest);

imar=0;

if(itest.eq.23)imar=1;

/$ get data

call uspopdat;

/$ initial values

call free(deriv,resid,beta,r);

resid=resid1 ;

deriv=deriv1 ;

/$

/$ rename routines on the fly

/$

call subrename(resid);

call subrename(deriv);

call makeglobal(resid,deriv) ;

beta(1)=3.9 ;

beta(2)=.022 ;

beta=vfam(beta) ;

year=mfam(year) ;

pop=mfam(pop) ;

lamda=.1e-8 ;

iprint=0 ;

iout=1 ;

/$call print('IMAR',imar);

if(imar .eq. 0)

call marq(year,pop,beta,r,f,sse,seb,covb,corrb,

lamda,iprint,iout);

if(imar .eq. 1)

call dud(year,pop,beta,r,f,sse,seb,covb,corrb,

iprint,iout);

return;

end;



subroutine resid1(beta,f,r,sse,xvar,yvar);

/$

/$ user supplied routine with model

/$ sas tech report a-102 page 8-7

/$

f=vfam(beta(1)* exp(beta(2)*afam(xvar-1790.)));

r=yvar-f;

sse=sumsq(r);

return ;

end ;



subroutine deriv1(der,f,beta,xvar);

/$

/$ user routine to calculate derivatives

/$

der=matrix(norows(f),norows(beta):);

der(,1)=vfam(afam(f)/beta(1));

der(,2)=vfam(afam(xvar-1790.)*afam(f));

return;

end;



program uspopdat;

/$ data from sas technical report page 9-2

year=dfloat(integers(179,197));

year=year*10. ;

pop=array(:3.929 5.308 7.239 9.638 12.866 17.069

23.191 31.443 39.818 50.155 62.947 75.994

91.972 105.710 122.775 131.669 151.325 179.323

203.211 );

call tabulate(year pop);

return;

end;



call print(prob1,resid1,deriv1);

call prob1;

b34srun;



DELETECOL Delete a column from a matrix or array.



call deletecol(x,jbegin);



Deletes column of x at jbegin.



The code for deleting more than one col is



call deletecol(x,jbegin,number);



The command



call deletecol(x);



deletes the last column.



Note that jbegin and number are integer*4.



DELETEROW Delete a row from a matrix or array.



call deleterow(X,ibegin);



Deletes row at ibegin.



The code for deleting more than one row is:



call deleterow(x,ibegin,number);



The command



call deleterow(x);



deletes the last row.



Note that ibegin and number are integer*4.



DF Calculate Dickey-Fuller Unit Root Test.



call df(x,d);



Returns Dickey-Fuller Unit Root Test.

x => Series to test

d => DF test



Added options:



:adf n => augmented DF test

:adft n => augmented DF with trend

:zform => uses z-form of test

:print => Print value and significance



Table options. x can contain more than one element.



:table n => Generates prob value d for DF value x

using "no constant assumption."

:table2 n => Generates prob value d for DF value x

using "constant assumption.".

:table4 n => Generates table value d for DF value x

using "constant plus trend."

assumption.



Automatic Variable Created



%DFPROB - Probability of DF test.

.05 => Cannot reject unit root at 95%

.10 => Cannot reject unit root at 90%



Discussion: The .05 critical value for N=100 is -1.95. This

suggests that if the value found was -2.0 (-1.95) we could

reject (could not reject) a unit root at the 95% level. The

.10 critical value is -1.61. Using this standard we can

reject a unit root.



The related command PP tests for a unit root using the

Phillips Perron test.



Notes: The DF and PP commands have a "table look up" routine

that will return the Dickey Fuller values. The matrix.mac file

DF1 uses Monti Carlo Methods to approximate this table if the

x value passed is not .01, .025 .05 .10 .90 .95 .975 .99



Example:



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata; call echooff;

call print('Dickey Fuller Tests on Gasout');

call df(gasout,d :print);

n=30;

adf=array(n+1:); adft=array(n+1:); lag=array(n+1:);

do i=0,n;

call df(gasout,a1:adf i);

call df(gasout,a2:adft i);

j=i+1;

adf(j)=a1;

adft(j)=a2;

lag(j)=dfloat(i);

enddo;

call print('Dickey-Fuller test',d);

call tabulate(lag,adf,adft);

b34srun;



DF_GLS Elliot, Rothenberg-Stock DF_GLS Test





call DF_GLS(x,lag1,notrend, trend,

notrendx,trendx,iprint);



Implements the Elliott-Rothenberg-Stock (1996) unit root test

documented in "Efficient Tests for an Autoregressive Root"

Econometrica 64(4): 813-836.



See also "Introduction to Econometrics," By James Stock and

Mark Watson, Addison Wesley New York 2003 page 549-550



x = series to test

lag1 = Lag for DF part of test. Must be GE 1

notrend = > no trend test statistic

trend = > trend test statistic

notrendx = x smoothed without a trend

trendx = x smoothed with a trend

iprint = 2 to print steps and test,

= 1 print test only



Critical values:



10% 5% 1%

No trend -1.62 -1.95 -2.58

Trend -2.57 -2.89 -3.48



Note: Command is a subroutine and needs to be loaded with:



call load(df_gls);



Example:





b34sexec matrix;

call load(df_gls);

call print(df_gls);



iprint=1;



n=1000;

x=rn(array(n:));

root=cusum(x);

call graph(x);

call graph(root);

call echooff;



do i=1,4;

call print(' ':);

call print('For lag ',i:);

call print('Non unit root case':);

call DF_GLS(x,i,notrend, trend,

notrendx,trendx,iprint);

call print(' ':);

call print('----------------':);

call print(' ':);

call print('Unit root case':);

call DF_GLS(root,i,notrend, trend,

notrendx,trendx,iprint);

enddo;

b34srun;



DISPLAYB Displays a Buffer contents



call displayb(x);



Will display the contents of X. X can be real*8, character*8,

character*1, integer, real*4 or complex*16.



This command is useful in looking at contents of database

files etc.



Alternative arguments are:



call displayb(x,istart,iend)



to display only bytes istart to iend



Example:



b34sexec matrix;

call character(cc,'This is a test');

call displayb(cc);

call character(cc2,

'This is a test with numbers 1 2 3 # $ % 7 && 8 &');

call displayb(cc2);

* Put in reals we know what they are;

x(1)=0.0; x(2)=1.0;

* Hide an integer in a real;

i1=1;

i2=2;

call ilcopy(4,i1,1,1,x,1,1);

call ilcopy(4,i2,1,1,x,1,3);

call displayb(x);

b34srun;



Example # 2:

/$

/$ Shows moving a real*16 value in a real*8 work array

/$ Uses a real*8 array to look at bits!!

/$

b34sexec matrix;

x=array(2:);

y=10.0;

y=r8tor16(y);

yy=y;

y=r8tor16(12.8);

call print('is yy 10.? ',yy);

call pcopy(2,pointer(y),1,pointer(x), 1,8);

call pcopy(2,pointer(x),1,pointer(yy),1,8);

call print('is yy 12.8.? ',yy);

call displayb(x);

call names(all);

call displayb(yy);

b34srun;





DIST_TAB Distribution Table





call dist_tab(x,10,q,qvalue,number,iprint);



Gives distribution



subroutine dist_tab(x,n,q,qvalue,number,iprint);

/$

/$ x => input series

/$ n => input # of quantile values

/$ q => q

/$ qvalue => qvalue

/$ number => # in the group

/$ iprint => NE 0 = print

/$

/$ Built July 2003

/$



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call load(dist_tab);

call echooff;

call describe(gasin :print);

call dist_tab(gasin,20,q,gvalue,number,1);

b34srun;



DODOS Execute a command string if under dos/windows.



call dodos(' ');

Works the same as



call system(' ' );



but only works on Windows & DOS.



Note: The form



call dodos(' command');



should be used if "silent" operation is desired. If the

command writes any output, the form



call dodos('command',:);



should be used.



If what is desired is for B34S to terminate and the program

called to be active, the command



call dodos('command',::);



should be used.



Example



/$ Matlab command file

b34sexec options open('test.m')

unit=77 disp=unknown;

b34srun;

b34sexec options clean(77); b34srun;

b34sexec options copyf(4,77);

pgmcards;

x=rand(6)

xi=inv(x);

x*xi

yy=[1 2 3 2 1]

plot(yy)

pause

quit

b34sreturn;

b34srun;

b34sexec options close(77); b34srun;

b34sexec matrix;

call system('start /w matlab /r test /logfile jj':);

call copyout('jj');

b34srun;



DO_SPEC Display Periodogram and Spectrum



call do_spec(gasout,cc,weights);



Will display the periodogram and Spectrum.

subroutine do_spec(x,heading1,weights);

/;

/; Display Periodogram and Spectrum

/;

/; x = Input Series

/; heading1 = Heading for series

/; weights = Smoothing weights

/;

/; Note: Can be called alone or under dataview

/;

/; Graphs saved in Clip Board

/; ***********************************************

/;



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call load(do_spec);

weights=array(:1 2 3 2 1);

call character(cc,'Analysis of Gasout');

call do_spec(gasout,cc,weights);

rr=rn(array(400:));

call character(cc,'Analysis of a Random Series');

call do_spec(rr,cc,weights);

b34srun;



DOUNIX Execute a command string if under unix.



call dounix(' ');



Works the same as



call system(' ');



but only works on unix.



Note: The form



call dounix(' command');



should be used if "silent" operation is desired. If the command

writes any output, the form



call dounix('command',:);



should be used.



If what is desired is for B34S to terminate and the program

called to be active, the command



call dounix('command',::);

should be used.





DQDAG - Integrate a function using Gauss-Kronrod rules



call dqadg(f x :name test :lower 0.0

:upper 2.0

:errabs 0.0

:errrel .001

:irule 1

:maxsub 500

:print);



Integrates a function using Gauss-Kronrod Rules.



Required:



f = function value

x = Integration variable

test = program name

:lower a => sets lower bound of integration

:upper b => sets upper bound of integration



Optional



:errabs r1 => Sets absolute accuracy desired.

Default = 0.0

:errrel r2 => Sets relative accuracy desired.

Default = .001

:rule i => Sets Gauss-Kronrod rule. Default=2

If function has a peak singularity

use :rule 1, if function is

oscillatory, use :rule 6

1 => 7-15 points

2 => 10-21 points

3 => 15-31 points

4 => 20-41 points

5 => 25-51 points

6 => 30-61 points

:maxsub i => sets # of subiterations allowed.

Default=500.



Variables Created:



%result = value of integral



%error = error estimate

%alist = list on left endpoints

%blist = list of right endpoints

%rlist = area in the endpoints.

%elist = error estimates by regions



Note: This command uses IMSL routine DQDAG

Example:



b34sexec matrix;



program test;

f=x*dexp(x);

return;

end;



call print(test);

call echooff;



do i=1,6;

call dqdag(f x :name test :lower 0.0

:upper 2.0

:errabs 0.0

:errrel .001

:rule i

:maxsub 500

:print);

enddo;

b34srun;



DQDNG - Integrate a smooth function using a nonadaptive rule.



call dqdng(f x :name test

:lower 0.0

:upper 2.0

:errabs 0.0

:errrel .001

:print);

Integrates a smooth function using a nonadaptive rule



Required:



f = function value

x = Integration variable

test = program name

:lower a => sets lower bound of integration

:upper b => sets upper bound of integration



Optional



:errabs r1 => Sets absolute accuracy desired.

Default = 0.0



:errrel r2 => Sets relative accuracy desired.

Default = .001





Note: This command uses IMSL routine DQDNG. It may not work

well, if so try dqdags.



Variables Created:

%result = value of integral

%error = error estimate



Example:



b34sexec matrix;



program test;

f=x*dexp(x);

return;

end;



call echooff;

call dqdng(f x :name test :lower 0.0

:upper 2.0

:errabs 0.0

:errrel .001

:print);



b34srun;



DQDAGI - Integrates over a infinite/semi-infinite interval.



call dqdagi(f x :name test :lower 0.0

:upper 0.0

:errabs 0.0

:errrel .001

:maxsub 500

:print);

Integrates a function over infinite/semi-infinite interval.



Required:



f = function value

x = Integration variable

test = program name



:lower a => sets lower bound of integration

:upper b => sets upper bound of integration



Cannot have both upper lower.



If lower => range = lower - Inf

If upper => range = inf - upper

If neither => range = -int - inf



Optional



:errabs r1 => Sets absolute accuracy desired.

Default = 0.0



:errrel r2 => Sets relative accuracy desired.

Default = .001

:maxsub i => sets # of subitervals used.

Default=500.





Variables Created:



%result = value of integral

%alist = list on left endpoints

%blist = list of right endpoints

%rlist = area in the endpoints.

%elist = error estimates by regions

%error = error estimate





Note: maxsub determines an upper limit on # of intervals.

This command uses IMSL routine DQDAGI



Example:



b34sexec matrix;



program test;

f=dlog(x)/(1.+(10.*x)**2.);

return;

end;



call dqdagi(f x :name test :lower 0.0

:errabs 0.0

:errrel .001

:maxsub 500

:print);



exact = -1.*pi()*dlog(10.)/20. ;

error=%result-exact;



call print('Exact ',exact:);

call print('Error ',error:);

call tabulate(%alist %blist %rlist %elist);

b34srun;



DQDAGP - Integrete a function with singularity points given



call dqdagp(f x :name test :lower

:upper 0.0

:errabs 0.0

:errrel .001

:breakp p

:maxsub 500

:print);

Integretes a function with singularity points given.



Required:

f = function value

x = Integration variable

test = program name

:lower a => sets lower bound of integration

:upper b => sets upper bound of integration

:breakp p => sets vector of break points



Optional



:errabs r1 => Sets absolute accuracy desired.

Default = 0.0



:errrel r2 => Sets relative accuracy desired.

Default = .001



:maxsub i => sets # of subitervals used.

Default=500.





Variables Created:



%result = value of integral

%alist = list on left endpoints

%blist = list of right endpoints

%rlist = area in the endpoints.

%elist = error estimates

%error = error estimate



Note: maxsub determines an upper limit on # of intervals.

This command uses IMSL routine DQDAGP



Example:



program test;

f=x**3.*dlog(dabs((x*x-1.0)*(x*x-2.0)));

return;

end;



call dqdagp(f x :name test

:breakp array(:1. dsqrt(2.))

:lower 0.0

:upper 3.0

:errabs 0.0

:errrel .001

:maxsub 500

:print);



exact = 61.0*dlog(2.0)+77./4.*dlog(7.0) - 27.;

error=dabs(%result-exact);



call print('Exact ',exact:);

call print('Error ',error:);



call tabulate(%alist %blist %rlist %elist);

b34srun;



DQDAGS - Integrate a function with end point singularities



call dqdags(f x :name test :lower

:upper 0.0

:errabs 0.0

:errrel .001

:maxsub 500

:print);

Integrates a function with end point singularities



Required:



f = function value

x = Integration variable

test = program name

:lower a => sets lower bound of integration

:upper b => sets upper bound of integration

:breakp p => Sets vector of break points



Optional



:errabs r1 => Sets absolute accuracy desired.

Default = 0.0



:errrel r2 => Sets relative accuracy desired.

Default = .001



:maxsub i => sets # of subitervals used.

Default=500.





Variables Created:



%result = value of integral



%alist = list of left endpoints



%blist = list of right endpoints



%rlist = area in the endpoints.



%elist = error estimates



%error = error estimate



Note: maxsub determines an upper limit on # of intervals



Note: This command uses IMSL routine DQDAGS



Example:

b34sexec matrix;

program test;

f=dlog(x)/dsqrt(x);

return;

end;



call dqdags(f x :name test :lower 0.0

:upper 1.0

:errabs 0.0

:errrel .001

:maxsub 500

:print);



exact = -4.0;

error=dabs(%result-exact);



call print('Exact ',exact:);

call print('Error ',error:);



call tabulate(%alist %blist %rlist %elist);



b34srun;

DQAND - Multiple integration of a function



call dqand(f x :name test :lower lower

:upper upper

:errabs 0.0

:errrel .001

:maxsub 500

:print);



Estimates a multiple integral. A max of 20 integrals can be

calculated.



Required:



f = function value



x = Integration variable name. X must exist and

be an array or vector of up to 20 elements.

The size of x is n and sets the size

expected for lower and upper.



test = program name



:lower a => sets lower bound of integration. A is

a vector or array of size n.



:upper b => sets upper bound of integration. B is

a vector or array of size n.



Optional



:errabs r1 => Sets absolute accuracy desired.

Default = 0.0

:errrel r2 => Sets relative accuracy desired.

Default = .001



:maxsub i => sets # of evaluations allowed. I cannot

be set > 256*n where n is # of elements in

lower. Default = 256*n.





Variables Created:



%result = value of integral



%error = error estimate



Note: This command uses IMSL routine DQAND





Example:





b34sexec matrix;

* This is a big problem. Note maxsub 100000 ;

program test;

f=dexp(-1.*(x(1)*x(1)+x(2)*x(2)+x(3)*x(3)));

return;

end;



/$ We solve 6 problems.

/$ As constant => inf and => pi()**1.5



lowerv=array(3:);

upperv=array(3:);

x =array(3:);



call print(test);



call echooff;



j=integers(3);



do i=1,6;

cc=dfloat(i)/2.0;

lowerv(j)=(-1.)*cc;

upperv(j)= cc;

call dqand(f x :name test :lower lowerv

:upper upperv

:errabs .0001

:errrel .001

:maxsub 100000

:print);



call print('lower set as ',cc:);

call print('results ',%result:);

call print('error ',%error:);

enddo;



call print('Limit answer ',pi()**1.5 :);

b34srun;



DTWODQ - Two Dimensional Iterated Integral



call dtwodq(f x y g h :name test1 test2 test3

:lower lower

:upper upper

:errabs 0.0

:errrel .001

:rule 1

:print);



Estimates a 2 dimensional integral f= int(f(x,y))dy dx



Required:



f = function value



x = outer integral



y = inner integral



g = inner integral lower bound g=g(x)



h = inner integral upper bound h=h(x)



test1 = program name for function.

test1 creates f(x,y)



test2 = program name for lower bound

of inner integral



test3 = program name for upper bound

of outer integral





:lower a => sets lower bound of outer integral



:upper b => sets upper bound of outer integral



Optional



:errabs r1 => Sets absolute accuracy desired.

Default = 0.0



:errrel r2 => Sets relative accuracy desired.

Default = .001



:rule i => sets Gauss-Kronrod Rule

1 7-15 points

2 10-21 points

3 15-31 points

4 20-41 points

5 25-51 points

6 30-61 points



For singular peak use 1

For oscillatory function use 6



Default = 6





:maxsub i => sets # of evaluations allowed. Should

be set greater than or equal to 250.



Variables Created:



%result = value of integral



%error = error estimate



%alist = list of left endpoints



%blist = list of right endpoints



%rlist = area in the endpoints.



%elist = error estimates



Note: This command uses IMSL routine DTWODQ



Warning. Be sure that the three programs supplied

actually do what they are required to do.



Example:



/$ Fixed inner bounds test case first



%b34slet prob1=1;

%b34slet prob2=1;



%b34sif(&prob1.eq.1)%then;

b34sexec matrix;



program test1;

f=y*dcos(x+y*y);

return;

end;



program test2;

g=1.0;

* g=(-2.)*x;

return;

end;

program test3;

h=3.0;

* h=5.*x;

return;

end;



call print(test1,test2,test3);



call echooff;



call dtwodq(f x y g h

:name test1 test2 test3

:lower 0.0

:upper 1.0

:errabs .000

:errrel .001

:rule 6

:print);



call print(' ':);

call print('***************************':);

call print('IMSL thinks result is -.514':);

call print('results ',%result:);

call print('error ',%error:);



call tabulate(%alist,%blist,%rlist,%elist);



b34srun;

%b34sendif;





/$ Problem # 2



%b34sif(&prob2.eq.1)%then;

b34sexec matrix;



program test1;

f=y*dcos(x+y*y);

return;

end;



program test2;

* g=1.0;

g=(-2.)*x;

return;

end;



program test3;

* h=3.0;

h=5.*x;

return;

end;

call print(test1,test2,test3);



call echooff;



call dtwodq(f x y g h

:name test1 test2 test3

:lower 0.0

:upper 1.0

:errabs .001

:errrel .00

:rule 6

:print);



call print(' ':);

call print('***************************':);

call print('IMSL thinks result is -.083':);

call print('results ',%result:);

call print('error ',%error:);



call tabulate(%alist,%blist,%rlist,%elist);



b34srun;

%b34sendif;



ECHOOFF Turn off listing of execution.



call echooff;



Turns off output to b34s file. By default all commands will

echo. It is usually a good idea to turn off command echo inside

a do loop unless there are problems to trap. Once a user

subroutine, function or program is working correctly, it is a

good idea to call echooff before calling the routine. If

problems develop, then they can be easily trapped by

commenting this call.



Note: Matlab will echo any command without the ; and will not

echo any command with a ;. This approach requires the developer

to be taking out and putting in ; all over the place when

problems are being tracked down.



See related command call echoon;





ECHOON Turn on listing of execution.



call echoon;



Echos output in b34s output file. By default all commands will

echo. It is usually a good idea to turn off command echo inside

a do loop unless there are problems to trap.



See related command call echooff;

EPPRINT Print to log and output file.



call epprint(x);



Prints to both output and error units.



See also eprint and print.



EPRINT Print to log file.



call eprint(x);



Works the same as call print( ) but prints to the error unit.



See also epprint and print.



ERASE Erase a file



call erase('c:\junk\*.out');



Will erase files. If a file cannot be deleted an error message

is given. If ' ' is blank, there is no effect.



Warning. Uses system calls. An open file can be deleted without

an error message. Use this power commnd with caution.



EXPAND Expand an array



call expand(oldcc,newcc,ibegin,iend);



Expand an array of Character *1 data.



oldcc - Character*1 string



newcc - Character*1 string to be placed in

ibegin - iend in oldcc moving

old characters over. Elements in

newcc from will be placed in oldcc

from ibegin to iend. If length

of newcc less than iend-ibegin+1,

then blanks placed in file.



Note: If just a replacement is needed then code such as



/$ aabb at 5-8

b34sexec matrix;

call character(cc,'This is a test');

call character(new,'aabb');

call print(cc);

i=integers(1,4);

j=i+4;

cc(j)=new(i);

call print(cc);

b34srun;

Will work.



Example:



b34sexec matrix;

call character(cc,'This is a test');

call print(cc);

call ilocatestr(cc,istart,iend);

i=integers(istart,iend);

subs=cc(i);

call print(subs);

call contract(cc,istart,iend);

oldnewcc=cc;

call print(cc);

call character(new,'aaaissaa');

call expand(cc,new,1,8);

call print(oldnewcc,cc);

b34srun;





For related commands see CONTRACT and the function EXTRACT.



FILTER High Pass - Low Pass Filter using Real FFT



call filter(xold,xnew,nlow,nhigh);



Depending on nlow and nhigh subroutine filter can be a low pass

or a high pass filter. A real FFT is done for a series. FFT

values are zeroed out if outside range nlow - nhigh. Xnew is

recovered by inverse FFT. FILTERC uses the complex FFT.

FILTERC should be used in place of FILTER to avoid phase and

gain loss.



xold - input series



xnew - filtered series



nlow - lower filter bound



nhigh - upper filter bound



Routine built 2 April 1999. Use of filter requires the command



call load(filter);





Example:



b34sexec matrix;

/$ Uses FFT to High and Low Pass Random Series

/$

/$ Illustrate with random numbers

/$

call load(filter);

n=500;

test=rn(array(n:));

spec=spectrum(test,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random series');





call filter(test,newtest,1,200);

spec=spectrum(newtest,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random after Low Pass');



call filter(test,high,201,500);

spec=spectrum(high,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random after High Pass');



b34srun;

FILTERC High Pass - Low Pass Filter using Complex FFT



call filterc(xold,xnew,nlow,nhigh);



Depending on nlow and nhigh filter can be a low pass or a high

pass filter. Complex FFT is done for a series. FFT values are

zeroed out if outside range nlow - nhigh. Xnew recovered by

inverse FFT. FILTERC should be used in place of FILTER to avoid

phase and gain loss.



xold - input series



xnew - filtered series



nlow - lower filter bound



nhigh - upper filter bound



Routine built 2 April 1999. Use of filter requires the command



call load(filterc);





Example:



b34sexec matrix;

/$ Uses FFT to High and Low Pass Random Series

/$

/$ Illustrate with random numbers

/$

call load(filterc);

n=500;

test=rn(array(n:));

spec=spectrum(test,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random series');





call filterc(test,newtest,1,200);

spec=spectrum(newtest,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random after Low Pass');



call filterc(test,high,201,500);

spec=spectrum(high,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random after High Pass');



b34srun;



FPLOT Plot a Function



call fplot(inline('dcos(dsqrt(x**2.+y**2.))'),

:args x y

:rangex array(:-10.,10.)

:rangey array(:-10.,10.)

);



This command has not been implemented in this release.



FPRINT - Formatted print facility.



call fprint(:clear :display rr '(g48.32)' :print);



Advanced printing capability with format control.

The casual matrix programmer usually does not need this command

and can use the more general call print( );



:clear => clear buffer



:col n => go to col 10



:string ' ' => pass a string to buffer

(As of June 2005 :string

and :display work the same for

character*8 and character*1.

See use notes below.



:display object fmt => display object using

optional format.

Limited to a 132 line.

Types supported are:

real*8

complex*16

real*4

integer*4

integer*8

real*16

character*8

character*1

complex*32

fm

fp

im

ip

zm

zp







:print => prints the buffer.

Does not clear buffer!!

Sections of buffer can be

cleared by passing a blank

string.



:save bname => saves buffer



:cr n => blank lines



:unit ii => Sets unit for output.

If unit not present then usual

output unit is assumed.



Notes: The line



a='le 8 ';



creates a character*8 variable while



a='more than 8 characters here';



creates a character*1 variable. The command



a=c1array(:'aa');



places aa in a character*1 array. Hence for best

results it is a good idea to code



:col i :string c1array(:':')



rather than



:col i :string ':'



for more control.



Example:



b34sexec matrix;

r =dsqrt(110.);

ii=202;

name='Diana';

call fprint(:clear

:col 10

:string 'At 10'

:col 20

:display r '(g16.8)'

:col 40

:string 'At col 40'

:print

:col 60

:string 'Added string at 60'

:print

:clear

:string 'String at 1'

:print

:col 40

:string 'Added at 40'

:col 70

:string name

:print

:cr 2);

b34srun;



Notes: The internal print buffer of 132 lines is saved

between calls. This allows fprint to be a way to format a

line!! In first call :clear should be used.



b34sexec matrix;

call echooff;

call fprint(:clear

:col 1

:string 'Mars Results after Stepwise Elimination');

call fprint(:print);

call fprint(:save jj);

call print(jj);

call ialen(jj,ii);

call print('len was ',ii);

jjj=integers(1,ii-11);

less=jj(jjj);

call print(less);

b34srun;





/; Shows building a vector of names

/; The vector of 246 names can be passed to a routine with

/; the argument(cc) function



b34sexec matrix;

cc=c8array(246*2:);



/; shows moving from character*1 to character*8 using

/; fprint buffer

/; tt is longer than needed but we pick off just first

/; element

j=1;

do i=1,246;

call fprint(:clear :col 1 :string 'X000');

if(i.le.9) call fprint(:col 4 :display i '(i1)');

if(i.le.999.and.i.ge.10)

call fprint(:col 3 :display i '(i2)');

if(i.gt.99) call fprint(:col 2 :display i '(i3)');

call fprint(:save cc1);

tt=c8array(:cc1);

cc(j)=tt(1);

j=j+2;

enddo;

call print(cc);

b34srun;



FREE Free a variable.



call free(x);



Frees X. The free command will free at the local level and

above. If the variable is defined at both the global level and

the local level, it is freed at the local level. To free at the

global level use the form:



call free(x:);



Multiple series can be listed.



Example:



b34sexec matrix;

n=4;

x=rn(matrix(n,n:));

pdx=transpose(x)*x;

call names;

call free(n:);

call names(info);

call makeglobal(pdx);

call names(info);

r=pdfac(pdx);

call print(pdx,r);

call makelocal(pdx);

call names(info);

r=pdfac(pdx);

call print(pdx,r);

pdx(1,1)=.9999;

call names;

call print(pdx,'We now free at the local level');

call free(pdx);

call names(info);

call print('We now free at the global level');

call free(pdx:);

call names(info:);

b34srun;

FORMS - Build Control Forms



The FORMS options under the MATRIX command allows access

to the Interacter low-level menu generation forms routines.

This command is NOT intended for the general user.

To make use of this command the user has to license the

Interacter Software system and obtain the supporting manuals.

The forms facility allows the B34S developer to have access to

a general menu writting facility. The general B34S user uses

the forms facility to interactively run MATRIX commands.



call forms(:start );

call forms(:cont );

call forms(:final );



--------------------------------------------------------

:start sentence

--------------------------------------------------------



Required on :start as the first argument



:formdefine key index(ifield) index(ix) index(iy)

index(iwidth) index(itype)



key type of form



W single form

S Full screen

T tabbed



ifield => field numbers



ix => array of field col positions



iy => array of field row positions



iwidth => array of field widths



itype => array for field types



1 unprotected string

2 unprotected integer

3 unprotected real

4 cycling

5 push button

6 unprotected double

7 vertical menu

8 unprotected long string

9 check box

10 check box discription



add 1000 for protected fields

or



:formload filename key



W => Form in a window



S => Form Full Screen



T => Form Tabbed



-----------------------------

Options on :start

-----------------------------



:formdefinetabs key array(:labels) index(limitf)

index(limitb)



key



T => show tabs on top



R => show tabs on right



B => show tabs on bottom



labels char*8 array of size ntabs



limitf integer array of last field identifiers



limitb array of last box identifiers



:formdefinebox index(iboxnum) index(ix) index(iy)

index(iw)



iboxnum => array of box numbers



ix => array of form box left hand col



iy => array of form box top-row



iw => array of form box widths



ih => array of form box heights





:formhelp index(ix iy iwidth)



place where iformputhelp is displayed





:commandn ' '



Up to 70 characters of menu window header

---------------------------------------------------

:cont sentence

---------------------------------------------------



required on some :cont sentence unless :formload supplied



:formshowedit iexit



iexit defines exit code





--------------------------------------------------

optional input commands used before :formshowedit

--------------------------------------------------



:formattribute ifield key forcolor backcolor



ifield = 0 used for help field



key



B => bold



F => flashing



I => italics



R => reverse video



U => underline



N => all disabled



:formattribute 7 'N' 'BRED' ' '



:defaultattribute



:formbox nbox iftype forcolor backcolor clearcolor



i4 i4 ch1 ch1 ch1



:formframe ifield iftype forcolor backcolor



i4 i4 ch1 ch1



:formpopupmenu ifield noptn



:formrangedouble ifield array(:dmin dmax)



:formrangeinteger ifield index(ifmin ifmax)



:formrangereal ifield array(:rmin rmax)

:formputstring ifield 'string' isize



isize is an optional argument that sets

the length of a long string.



:formputinteger ifield integer



for negative # use form



ifield index(-99)



:formputreal ifield real 'fmt'



:formputdouble ifield dvar 'fmt'



:formputhelp ifield 'message'



:formputformat ifield 'fmt'



:formputmenu ifield choices istart



:formverticalmenu ifield nseen iframe



Note: placed after formputmenu.



:formputbutton ifield cvalue iexitk



:formputbutton 12 run 21



:formputcheckbox ifield ivalue idfield

0 or 1





-------------------------------------------------

optional input commands used after :formshowedit

-------------------------------------------------



:forminfolist makes variables for the currently

loaded form.



nfield_1

nbox_1

ntab_1

ifx_1

ify_1

ifwid_1

iftype_1

ifiden_1



Note: If called at subroutine level data

made at level > 100.





:formsave 'header' 'filename'

:formsave can be used to convert forms built

with :formdefine to use :formload



:formclearfield ifield



:formgetcheckbox ifield ivalue



:formgetdouble ifield real8



:formgetinteger ifield ivalue



:formgetmenu ifield ioptn



:formgetradiobutton ifield ivalue



:formgetreal ifield real4



:formgetstring ifield string





-------------------------------------------------

:final sentence

-------------------------------------------------



Note: The :final sentence has no options.



The :final sentence triggers the menu.



Notes: The forms command has the same function as the makemenu

command except for the fact that it makes matrix

variables rather than macro variables and that access is

provided to lower level Interacter routines.



Examples:



1. Illustrate the FORMS Command Capability



b34sexec matrix;

/$

/$ Use this job as a template

/$

call echooff;



subroutine testform(ii,int4,r4,check,menu,string,

menu2,r8,string2);

nfields=18;

ioff=3;

/$

/$ type codes string 1 integer 2 real 3 cycling 4

/$ push 5 double 6 vert 7 long string 8

/$ check 9 check discript 10

/$

idfield=integers(nfields);

icol =

index( 2 40 2 40 2 40 2 40 2 40 2 40 2 40 2 40 10 50);

irow =

index( 1 1 2 2 3 3 6 6 10 10 13 13 14 14

15 15 18 18)+ioff;

iwidth=

index(20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 10);

itype =

index( 1001 2 1001 3 10 9 1001 7 1001 1 1001 4

1001 6 1001 8 5 5);



/$

/$ Defines Exit box

/$

idbox =index(1);

icolbox=index( 3);

irowbox=index(17+ioff);

iwbox =index(68);

ihbox =index(3);



/$

/$ Allocte a 3 by 40 character*1 array to hold character info

/$



cc =c1array(3,40:);

call character(hold,'Do ARIMA Model');

cc(1,)=hold;

call character(hold,'Do Regression Model');

cc(2,)=hold;

call character(hold,'Do Nonlinear Model');

cc(3,)=hold;



call character(fmt,'(g16.8)');



call forms(:start :formdefine S idfield icol irow iwidth itype

:formhelp index(2 21+ioff 68)

:formdefinebox idbox icolbox irowbox iwbox ihbox

:commandn 'Test Form # 1 - Shows all Options'

);

call forms(:cont

:formputstring 1 'This is int*4'

:formputstring 3 'This is a real*4'

:formputstring 5 'Check Box'

:formputstring 7 'Vertical Menu Box'

:formputstring 9 'String'

:formputstring 10 ' '

:formputstring 11 'Cycling Menu'

:formputstring 13 'Real*8 number'



:formputstring 15 'Long String'

:formputstring 16 ' ' 60



:formputinteger 2 index(-9)

:formputcheckbox index(6 0 5)

:formputhelp 2 'Enter an integer*4 here'

:formrangeinteger 2 index(-99999 99999)



:formputhelp 4 'Enter an real*4 here'

:formputreal 4 .1 fmt

:formrangereal 4 array(:-999.,999.)



:formputhelp 8 'This is a vertical menu - we show 2'

:formputmenu 8 cc 1

:formverticalmenu 8 2 999



:formputmenu 12 cc 1

:formputhelp 10 'Enter a short string here'

:formputhelp 12 'Click to cycle'



:formputdouble 14 99.9 fmt

:formrangedouble 14 array(:-999.,999.)

:formputhelp 14 'This is a real*8 input menu'



:formputhelp 16 'This is a long string menu'

/$

/$ Exit group type 5 push

/$

:formputbutton 17 'Run' 21

:formputhelp 17 'Run the Menu'

:formattribute 17 'N' 'byellow' ' '



:formputhelp 18 'Escape without running'

:formputbutton 18 'Escape' 23

:formattribute 18 'N' 'bred' ' '



/$

:formshowedit ii



/$ :forminfolist



/$

/$ pull out data into b34s matrix command names

/$

:formgetinteger 2 int4

:formgetreal 4 r4

:formgetcheckbox 6 check

:formgetmenu 8 menu

:formgetstring 10 string

:formgetmenu 12 menu2

:formgetdouble 14 r8

:formgetstring 16 string2

);



call forms(:final);

return;

end;



call testform(ii,int4,r4,check,menu,string,menu2,r8,string2);

/$ forminfolist data

/$ call print('nfield_1 ',nfield_1:);

/$ call print('nbox_1 ',nbox1 :);

/$ call tabulate(ntab_1 ifx_1 ify_1 ifwid_1 iftype_1 ifiden_1);



if(ii.eq.21)then;

call print('ii =',ii:);

call print('int =',int4:);

call print('r4 =',r4:);

call print('check =',check:);



call print('menu =',menu:);

call print('string =',string );

call print('menu2 =',menu2:);

call print('r8 =',r8:);

call print('string2=',string2);

endif;



if(ii.eq.23)call print('Menu terminated at user request');



b34srun;



++++++++++++++++++++++++++++++++++++++++++++++++++++++++



2. Shows Tabbed Menu



b34sexec matrix;

call echooff;



subroutine testform(ii,int4,r4,check,menu,string,

menu2,r8,string2);

nfields=18;



/$ type codes string 1 integer 2 real 3 cycling 4

/$ push 5 double 6 vert 7 long string 8

/$ check 9 check discript 10



idfield=integers(nfields);

icol =index( 2 40 2 40 2 40 2 40 2 40 2 40 2 40

2 40 10 50);

irow =index( 1 1 2 2 3 3 6 6 1 1 3 3 5 5

6 6 16 16);

iwidth=index(20 20 20 20 20 20 20 20 20 20 20 20

20 20 20 20 10 10);

itype =index( 1001 2 1001 3 10 9

1001 7 1001 1 1001 4

1001 6 1001 8 5 5);



idbox =index(1 2);

icolbox=index(3 3);

irowbox=index(15 15);

iwbox =index(68 68);

ihbox =index( 3 3);

cc =c1array(3,40:);

call character(hold,'Do ARIMA Model');

cc(1,)=hold;

call character(hold,'Do Regression Model');

cc(2,)=hold;

call character(hold,'Do Nonlinear Model');

cc(3,)=hold;

call character(fmt,'(g16.8)');



call forms(:start :formdefine t idfield icol irow

iwidth itype

:formhelp index(2 20 68)

:formdefinebox idbox icolbox irowbox iwbox ihbox

:formdefinetabs t array(2:'first','second')

index(8,16) index(1,2)

:commandn 'Test Form # 1 - Shows Tabbed form with global');



call forms(:cont

:formputstring 1 'This is int*4'

:formputstring 3 'This is a real*4'

:formputstring 5 'Check Box'

:formputstring 7 'Vertical Menu Box'

:formputstring 9 'String'

:formputstring 10 ' '

:formputstring 11 'Cycling Menu'

:formputstring 13 'Real*8 number'

:formputreal 4 .1 fmt

:formputdouble 14 99.9 fmt

:formrangedouble 14 array(:-999.,999.)

:formrangereal 4 array(:-999.,999.)

:formrangeinteger 2 index(-99999 99999)

:formputstring 15 'Long String'

:formputstring 16 ' ' 60

:formputbutton 17 'Run' 21

:formputbutton 18 'Escape' 23

:formattribute 17 'N' 'byellow' ' '

:formattribute 18 'N' 'bred' ' '

:formputinteger 2 index(-9)

:formputcheckbox index(6 0 5)

:formputhelp 2 'Enter an integer*4 here'

:formputhelp 4 'Enter an real*4 here'

:formputhelp 8 'This is a vertical menu - we show

2'

:formputmenu 8 cc 1

:formverticalmenu 8 2 999

:formputmenu 12 cc 1

:formputhelp 10 'Enter a short string here'

:formputhelp 12 'Click to cycle'

:formputhelp 14 'This is a real*8 input menu'

:formputhelp 16 'This is a long string menu'

:formputhelp 17 'Run the Menu'

:formputhelp 18 'Escape without running'



:formshowedit ii

/$ :forminfolist



:formgetinteger 2 int4

:formgetreal 4 r4

:formgetcheckbox 6 check

:formgetmenu 8 menu

:formgetstring 10 string

:formgetmenu 12 menu2

:formgetdouble 14 r8

:formgetstring 16 string2

);

call forms(:final);

return;

end;



call testform(ii,int4,r4,check,menu,string,

menu2,r8,string2);



/$ forminfolist data

/$ call print('nfield_1 ',nfield_1:);

/$ call print('nbox_1 ',nbox1 :);

/$ call tabulate(ntab_1 ifx_1 ify_1 ifwid_1

iftype_1 ifiden_1);



if(ii.eq.21)then;

call print('ii =',ii:);

call print('int =',int4:);

call print('r4 =',r4:);

call print('check =',check:);



call print('menu =',menu:);

call print('string =',string );

call print('menu2 =',menu2:);

call print('r8 =',r8:);

call print('string2=',string2);

endif;



if(ii.eq.23)

call print('Menu terminated at user request');



b34srun;





3. Tests Loading a Production File



b34sexec matrix;

call forms(:start :formload 'iighco6.ifd' S);

call forms(:cont :forminfolist);

call names(all);

call print('# of Fields ',nfield_1:);

call print('# of Boxes ',nbox_1 :);

call print('# of Tabs ',ntab_1 :);

call tabulate(ifx_1,ify_1,ifwid_1,iftype_1,ifiden_1);

b34srun;



FORPLOT Forecast Plot using GRAPHP



call forplot(y,yhat,se,se2,title);



This command is subject to changes in the arguments. Command

has to be loaded with



call load(forplot);



subroutine forplot(y,yhat,se,se2,title,file);

/$

/$ y => Actual Data

/$ yhat => Forecast

/$ se => Positive SE

/$ se2 => Negative SE

/$ title => Title

/$

/$ **********************************************

/$ Version 18 July 2001

/$ **********************************************



Example:



b34sexec matrix;

y=rn(array(20:));

yhat=rn(array(4:));

error=dfloat(integers(4))/2.;

se =error+yhat;

se2 =yhat - error;

call character(title,'Test Forecast Plot');



call load(forplot);



/$ Graph using graph



call graph(y :pgborder

:heading 'graph command'

:htitle 2. 2.

:pgxscaletop 'I'

:pgyscaleleft 'NT'

:pgyscaleright 'I'

:colors black bred );



/$ Forplot using graphp



call forplot(y,yhat,se,se2,title,' ');



b34srun;



GARCH2P GARCH Model Estimation using 2 pass method



call garch2p(data,nar,nma,coef1,se1,t1,gnar,gnma,

coef2,se2,t2,res1,res2,refine);



Estimate ARMA / GARCH model following Enders (1995, page 150)

two pass method. Use of this subroutine requires the command



call load(garch2p);



See GARCH2PA for automatic two pass method. There is also an

interactive version with graphics under the matrix command.



GARCH2PA is in the staging2.mac file.



Arguments:



Data => Data

nar => # of ar terms for first moment

nma => # of ma terms for first moment

coef1 => first moment coefficients

se1 => first moment se

t1 => first moment t

gnar => second moment # of ar terms

gnma => second moment # of ma terms

coef2 => second moment coef

se2 => second moment se

t2 => second moment t

res1 => first moment residual

res2 => second moment residual

refine => if NE 0 refine models





Test cases: ARMA_6, GARCH2P



For a reference See Enders (1995, page 150).



Example:



b34sexec options ginclude('gas.b34'); b34srun;



/$ User is controlling model



b34sexec matrix;



call loaddata;

call load(garch2p);



nar=6;

nma=0;

gnar=1;

gnma=0;



call garch2p(gasout,nar,nma,coef1,se1,t1,gnar,gnma,coef2,se2,

t2,res1,res2,2.0);

call graph(res1); call graph(res2);

acf1=acf(res1); call graph(acf1);

acf2=acf(res2); call graph(acf2);

call tabulate(acf1,acf2);

b34srun;



GARCH2PF GARCH Model Estimation - 2 pass method with forecasts



call garch2pf(data,nar,nma,coef1,se1,t1,gnar,gnma,

coef2,se2,t2,res1,res2,refine,fbase1,nf1,fbase2,

nf2,obs1,f1,conf1,obs2,f2,conf2);



Estimate ARMA / GARCH model following Enders (1995, page 150)

two pass method. Use of this subroutine

requires the command



call load(garch2pf);



See GARCH2PA for automatic two pass method. There is also an

interactive version with graphics under the matrix command.



GARCH2PA is in the staging2.mac file.



Arguments:



Data => Data

nar => # of ar terms for first moment

nma => # of ma terms for first moment

coef1 => first moment coefficients

se1 => first moment se

t1 => first moment t

gnar => second moment # of ar terms

gnma => second moment # of ma terms

coef2 => second moment coef

se2 => second moment se

t2 => second moment t

res1 => first moment residual

res2 => second moment residual

refine => if NE 0 refine models

fbase1 => Forecast base for first moment

nf1 => # of first moment forecasts

fbase2 => Forecast base for second moment

nf2 => # of second moment forecasts

obs1 => Observation for forecast of first moment

f1 => forecast for first moment

conf1 => confidence intervals for first moment

obs2 => Observation for forecast of second moment

f2 => forecast for second moment

conf2 => confidence intervals for second moment



Test case: GARCH2PF



For a reference See Enders (1995, page 150)



Example:

/$

/$ User attempts AR model with 10 terms

/$

b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;



call loaddata;

call load(garch2pf);



* This setting is too big but tests software ;

* For a more excessive example see ARMA_6 ;



nar=10;

nma=0;

gnar=1;

gnma=0;

fbase1=norows(gasout);

nf1=10;

fbase2=fbase1;

nf2=nf1;



call garch2pf(gasout,nar,nma,coef1,se1,t1,gnar,gnma,coef2,

se2,t2,res1,res2,2.0,fbase1,nf1,

fbase2,nf2,obs1,f1,

conf1,obs2,f2,conf2);

call graph(res1); call graph(res2);

acf1=acf(res1); call graph(acf1);

acf2=acf(res2); call graph(acf2);

call tabulate(acf1,acf2);

call tabulate(obs1,f1,conf1,obs2,f2,conf2);

b34srun;



GAMFIT Generalized Additive Model Estimation



call gamfit(y x[predictor,3] z[predictor,2]{2} :options);





Implements the gamfit command under matrix to provide

estimation of GAM (generalized additive Models) following work

at Stanford by Hastie and Tibshtiani. For another approach

see the GAMFIT command which ahs been implemented in "stand

alone" form. GAMFIT implements code developed by Hastie-

Tibshirani

(1986, 1990) that is in the public domain. A basic references

are:



Hastie, T. J. and Tibshirani (1986) "Generatized Additive

Models (with discussion)," Statistical Science, 1, 297-310



Hastie, T. J. and Tibshirani, R. J. (1990) "Generalized

Additive Models," New York: Chapman and Hall



The basic idea is to estimate a non parametric regression that

drops the assumption of linearity. The user sets the degrees of

freedom of each independent variable. A df=1 implies a linear

assumption. Hastie and Tibshirani were PhD students at Stanford

in the 1980's.



Variables created



%res - Residuals



%y - Y variable



%yhat - Predicted y



%yvar - Y variable name



%names - Names in Model



%lag - Lag



%vartype - Variable type



%df - DF of variable



%link - Linktype of Model



%dist - Error Distribution



%nob - Effective number of observations.



%coef - Coefficient



%z - z score. se = %coef/%t.



%nl_p - Test for nonlinearity



%dof - Degrees of freedom



%rss - Residual sum of squares



%tss - Total sum of squares



%ss_rest - Restricted Sum of Squares



%sigma2 - Scale Factor



Note: testnl= (%ss_rest - %rss)/%sigma2;

%nl_p =chisqprob(testnl,%dof);



Reported R**2 =(%tss-%rss)/%tss;





Options supported

:print Show output.



:info Shows iteration summary table.



:noint No intercept is estimated.





:punch_sur Makes a fsave file for each variable on

the right having name coef_____n.

Variables saved are:



obsnum => Obs number

smooth_x => Smoothed x

lower => Lower Bound

upper => Upper Bound

part_res => Partial Residual





:punch_res Makes a fsave file for each predictor

variable with name scoef____n. Variables

saved are:



x s(x) s(x)-1.96*se s(x)+1.96*se



Names in file are:



obsnum = > obs number

effect => x

variable => s(x) smoothed x

lower => s(x)-1.96*se

upper => s(x)+1.96*se



In addition a file containing y, yhat and

the residual is made. This file has name

gam_res.



:filename=' ' Sets file name if output is requested. Unit

used is 44. Default gamfit.fsv





:dist type Sets error distribution. Allowed values

are:



gauss => gaussian (This is the default)

binom => binomial

poiss => Possion

gamma => gamma

cox => cox



:tol array(:r1 r2) Sets inner and outer loop convergence.

Defaults are array(:.1d-8, .1d-8)



:maxit index(i1,i2) Sets Maximum number of iterations for

backfitting and local scoring

respectively.



:link linktype Sets link function



ident (default)

inver

logit

logar

cox



call gamfit(y x[predictor,1]{1 to 6} z[cat,4] :link ident);



The model specification involves specificatioon of the type

of variable and optionally a lag or lags. Unless :noint is

supplied, a constant will be automatically added to the model.

The model specification allows the lags to be set in the

command. Only vectors can be supplied in this release. If no

[ ] is supplied, [predictor,3] is assumed. The specification



call gamfit(y y[predictor,1]{1} x[predictor,2]{0 to 3}

z[predictor,3]{1} )$



is the same as



call gamfit(y y[predictor,1]{1}

x[predictor,1]

x[predictor,2]{1}

x[predictor,2]{2}

x[predictor,2]{3}

z[predictor,3]{1})$





Examples: Call gamfit(y x1 x2[predictor,3] x3[predictor,4]{1}

x4[predictor,3]{1 to 6} :print);



Note: while x1 is allowed x1{1} is not since [ ] is missing.



Discussion of variable types and how to use command.





In the model specification inside [vtype, df] is a variable

type key word and a degrees of freedom. Variable types

response, weight and censoring variables must have df=0.

Response is automatically added to the left hand variable which

automatically has its DF set to 0.0 For a predictor df=1 means

a linear fit, and df > 1 means a nonparametric fit with the

desired degrees of freedom df. (A df=0 excludes the variable

and should not be used.) A factor is a categorical variable,

its df must be 1 less than the number of distinct values.



The :dist parameter indicates the error model which can be set

as gauss, binom, poiss, gamma or cox.



The :link parameter sets the link function. Valid settings are:

ident, inver, logit, logar or cox.



The :tol parametsr specifies the convergence thresholds for the

outer and inner loops of the local scoring procedure.





Output contains the analysis of deviance table that includes

the slope and standard error of the linear part of the fit,

plus "nl-pval" a nonlinear pvalue that tests whether a function

estimate is nonlinear (large p-value (GE .95) is evidence for

nonlinearity). While it is hard to use qamfit to test a

hypothesis due to the difficulty of interpretaion of the

coefficnts on the spline smoothed data, plots of the spline

function against conditional residual values, may give an

indication of the presence of latent nonlinearity in the model

that would suggest a specific functional form to be

investigated.



Example:



b34sexec options ginclude('b34sdata.mac') member(gam);

b34srun;

b34sexec options noheader; b34srun;

b34sexec matrix;

call loaddata;

call echooff;

call gamfit(y age[predictor,3]

start_v[predictor,3]

numvert[predictor,3]

:link logit :dist gauss :maxit index(2000,1500)

:tol array(:.1d-13,.1d-13));

b34srun;





Examples with plots and plots and file creation:



/;

/; Linear = OLS

/;

/; Shows possible gains of going nonlinear

/;

b34sexec options ginclude('b34sdata.mac') member(gam_3);

b34srun;

b34sexec options noheader; b34srun;



b34sexec matrix;

call loaddata;

call load(gamplot :staging);

call echooff;



/; calling OLS and testing against GAMFIT



call olsq( cpeptide age bdeficit :print);

%olsyhat=%yhat;

%olsres =%res;



file='gam_3.fsv';



call gamfit(cpeptide age[predictor,3]

bdeficit[predictor,3]

:punch_sur

:punch_res

:filename file

:print);



call gamplot(%names,%lag,file,%olsyhat,%olsres,0);

b34srun;



/; Example Using Gas Data with Lags

/; Illustrates call gamfit options

b34sexec options ginclude('b34sdata.mac') member(gas);

b34srun;

b34sexec options noheader; b34srun;



b34sexec matrix;

call loaddata;

call load(gamplot :staging);

call echooff;



maxlag=3;



call olsq(gasout gasout{1 to maxlag} gasin{1 to maxlag}

:print);

%olsyhat=%yhat;

%olsres =%res;



file='gam_2.fsv';



call gamfit(gasout gasout[predictor,7]{1 to maxlag}

gasin[predictor,8]{1 to maxlag} :print

:punch_sur :punch_res :filename file );



call gamplot(%names,%lag, file,%olsyhat,%olsres,1);

b34srun;



GARCH Calculate function for a ARCH/GARCH model.



call garch(res,arch,y,func,maxlag,nbad :options);



The GARCH subroutine supports a general way to setup a

GARCH/ARCH/GARCH-M model and avoid the overhead of recursive

calls. The GARCH command works with one series although more

than one series can be on the right.



The GARCH subroutine calculates the function which is then

maximized with CMAXF2 or the in more complex cases with the

nonlinear programing with nonlinear constraints command

NLPMIN1. The advantage of GARCH over GARCHEST is that

constraints can be placed on parameters and constrained

maximizer routines other than CMAXF2 can be used. In addition

the parameters can optionally be observed as they change. For

most GARCH applications, GARCHEST should be used.



GARCHEST has been enhanced for alternative models. Since

the solution depends on only func, if an alternative model not

built into GARCH is needed, the func can be recalculated in the

user's routine.



GARCH modeling in RATS often has a problem with "useable"

observations that arises because during the iteration phase in

the second moment equation the value goes LE 0 causing problems

with the LOG and the division. If GARCH is used with the CMAXF2

command it is possible to restrict the parameters of the second

moment equation such that this does not occur.



Sample jobs GARCH3,.., GARCH7 illustrate the use of the GARCH

subroutine. The key sections of these jobs are listed below.

In the complete jobs, RATS commands are supplied so as to

benchmark the results.



The job GARCHEST_3 shows GARCHEST on the McCullough-Renfro

benchmark. GARCH_6 shows the same test case using the GARCH

subroutine and calling CMAX2 directly. This tests case

illustrates how the initial values in res1 and res2 make a

difference.



The b34s GARCH subroutine is slower than Rats, but provides

complete instrumentation of the solution process and will not

give the "useable" observations message.



The GARCHEST command is 4-5 times faster than the GARCH/CMAXF2

combination and should be used for most cases. If speed is NOT

an issue and a custom model is estimated, then the model should

be hand coded in a matrix command subroutine. This will not be

fast.



Required GARCH Subroutine arguments



res - first moment residual

arch - second moment residual

y - first moment variable

func - function

maxlag - maxlag of model for purposes of ML sum.

nbad - number of bad datapoints



If res1 and res2 are allocated prior to the call to GARCH, the

initial values placed in these series are used. If GARCH

allocates res1 and res2, all values are set to 0.0.



Options supported



:AR arparm arorder - AR parameters & orders

:MA maparm maorder - MA parameters & orders



:GAR garparm garorder - GAR parameters & orders



:GMA gmaparm gmaorder - GMA parameters & orders



:MU muparm muorder - Mu parameters and order



:NOSQRT if present does not take squrt for garch-M

models



:CONSTANT cparm - Constant



:XVAR xmatrix xparm

xorder maxlagvec - X matrix parms. orders lags



xmatrix - data matrix for inputs



xparm - parameter names



xorder - vector of orders for inputs



maxlagvec - number of parameters for

each input



:FORECAST Produces %F_M1_M2 a two element array

containing first and second moment forecast for

last observation.



Model estimated



max -.5 * (dlog(res2) + ((res1**2)/res2) )



where



res1(t)=y(t)-cparm(1)-arparm(1)*y(t-arorder(1))-...

-maparm*res(t-maorder(1))-...

-muparm(1)*dsqrt(arch(t-muorder(1)))-...

-xparm(1)*x1(t-xorder(1))-...



arch(t)=cparm(2)+gmaparm(1)*(res(t-gmaorder(1))**2) +

garparm(1)* arch(garaorder(1) + ...





Note: If overflows occur the parameters of the model may

have to be restricted in such a way that they do not get

near 0.0 during the solution iterations.



Since the order in which the equations are solved is res1 and

res2, if muorder(1)=0, then the system will have to be coded

with DO loops. Examples of alternative coding are contained in

ENDERS2 and ENDERS2B jobs in b34stest.mac.

Sample Jobs



GARCH3 Joint GARCH(0,1) Estimation



/$

/$ Joint GARCH(0,1) Estimation using GARCH subroutine

/$

b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix ;

call loaddata;

count=0.0;

j=norows(gasout);



arch = array(j:)+1.;

res = array(j:);

archlog= array(j:);

call echooff;



program test;



/$ Using built in garch subroutine



func=0.0;

count=count+1.0;



call garch(res,arch,gasout,func,2,n

:ar array(:b1,b2) idint(array(:1 2))

:gma array(:a1) idint(array(:1) )

:constant array(:b0 a0) );



call outstring(4,3,'F count a0 a1 b0 b1 b2');

call outdouble(34,3,func);

call outdouble(54,3,count);

call outdouble(4, 4, a0);

call outdouble(24,4, a1);

call outdouble(44,4, b0);

call outdouble( 4,5, b1);

call outdouble(24,5, b2);

return;

end;



call print(test);



/$ tests

a1=.05;

/$

/$ Get starting values

/$

call olsq(gasout gasout{1 to 2} :print);

call print(%coef);



call cmaxf2(func :name test

:parms b0 b1 b2 a0 a1

:ivalue array(:%coef(3),%coef(1),%coef(2),%resvar,a1)

:maxit 300

:gradtol .1e-4

:lower array(:-.1d+30,-.1d+30,-.1d+30,0.0,0.0)

:upper array(: .1d+30, .1d+30, .1d+30,.1d+30,.1d+30)

:print);



call print('Number out of function ',n);

call print(sumsq(res));

call tabulate(res,arch);

b34srun;



********************************************************



GARCH4 Joint GARCH(1,1) Estimation



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix ;



call loaddata;

j=norows(gasout);

count=0.0;



arch = array(j:);

res = array(j:);

archlog= array(j:);

call echooff;



program test;



/$ Using built in garch subroutine



func=0.0;

count=count+1.0;



call garch(res,arch,gasout,func,2,n

:ar array(:b1,b2) idint(array(:1 2))

:gma array(:a1) idint(array(:1) )

:gar array(:a2) idint(array(:1) )

:constant array(:b0 a0) );



call outstring(4,3,'Function');

call outdouble(24,3,func);

call outdouble(64,3,count);

call outdouble(4, 4, a0);

call outdouble(24,4, a1);

call outdouble(44,4, a2);

call outdouble(64,4, b0);

call outdouble( 4,5, b1);

call outdouble(24,5, b2);

return;

end;

call print(test);



/$ tests

a1=.05;

a2=0.0;

/$

/$ Get starting values

/$

call olsq(gasout gasout{1 to 2} :print);

call print(%coef);



/$



call cmaxf2(func :name test

:parms b0 b1 b2 a0 a1 a2

:maxit 200

:maxsteps 10.

:ivalue array(:%coef(3),%coef(1),%coef(2),%resvar,a1,a2)

:maxit 300

:gradtol .1e-4

:lower array(:-.1d+30,-.1d+30,-.1d+30,.1d-16,.1d-16,

-.1d-16)

:upper array(: .1d+30, .1d+30, .1d+30,.1d+30,.1d+30,

.1d+30)

:print);



b34srun;



************************************************************



GARCH5 Transfer Function Model with GARCH. Rats used to test



b34sexec options ginclude('gas.b34'); b34srun;

/$

/$ Estimate a GARCH Transfer function.

/$ RATS used to validate results.

/$

b34sexec matrix ;



call loaddata;

j=norows(gasout);

count=0.0;



arch = array(j:);

res = array(j:);

archlog= array(j:);

call echooff;



program test;



/$ Using built in garch subroutine to estimate a GARCH

/$ Transfer function



func=0.0;

count=count+1.0;



call garch(res,arch,gasout,func,3,n

:ar array(:b1,b2) idint(array(:1 2))

:gma array(:a1) idint(array(:1) )

:gar array(:a2) idint(array(:1) )

:xvar gasin array(:gin1 gin2) idint(array(:1 3))

idint(array(:2))

:constant array(:b0 a0) );



call outstring(4,3,'Function');

call outdouble(24,3,func);

call outdouble(64,3,count);

call outdouble(4, 4, a0);

call outdouble(24,4, a1);

call outdouble(44,4, a2);

call outdouble(64,4, b0);

call outdouble( 4,5, b1);

call outdouble(24,5, b2);

call outdouble( 4,6, gin1);

call outdouble(24,6, gin2);



return;

end;



call print(test);



/$ tests

a1=.01;

a2=.01;

/$

/$ Get starting values

/$

call olsq(gasout gasout{1 to 2} gasin{1} gasin{3} :print);

call print(%coef);



/$



call cmaxf2(func :name test

:parms b0 b1 b2 gin1 gin2 a0 a1 a2

:maxit 200

:maxsteps 4.

:ivalue array(:%coef(5),%coef(1),%coef(2),%coef(3),

%coef(4),%resvar,a1,a2)

:gradtol .1e-4

:lower array(:-.1d+30,-.1d+30,-.1d+30,-.1d+30,-.1d+30,

.1d-16,.1d-16,-.1d-16)

:upper array(: .1d+30, .1d+30, .1d+30, .1d+30, .1d+30,

.1d+30,.1d+30, .1d+30)

:print);

call print(sumsq(res));

call tabulate(res,arch);



b34srun;

/$

/$ BHHH method used..residuals set to 0 for beginning obs

/$

/$ User must replace GASOUT with user series name

/$



b34sexec options open('rats.dat') unit(28) disp=unknown$

b34srun$

b34sexec options open('rats.in') unit(29) disp=unknown$

b34srun$

b34sexec options clean(28)$ b34srun$

b34sexec options clean(29)$ b34srun$



b34sexec pgmcall$

rats passasts

pcomments('* ',

'* Data passed from B34S(r) system to RATS',

'* ') $

pgmcards$

*

set seriesn = gasout

compute iter = 100,isiter=100

*

* garch(1,1)

*

smpl(series=seriesn)

set u11 = 0.0

set v11 = 0.0

nonlin b0 b1 b2 gin1 gin2 a0 a1 beta1

frml regresid = seriesn-b0-b1*seriesn{1}-b2*seriesn{2} $

-gin1*gasin{1}-gin2*gasin{3}

frml garchvar = a0+a1*u11{1}**2 + $

beta1 * %if(v11{1}>1.e+100,%na,v11{1})

frml garchlogl = v11(t)=garchvar(t),u11(t)=regresid(t),$

-.5*(log(v11)+u11**2/v11)

linreg seriesn

# constant seriesn{1} seriesn{2} gasin{1} gasin{3}

compute b0=%beta(1),b1=%beta(2),b2=%beta(3),a0=%seesq, $

a1=.05

compute beta1=0.0

compute gin1=%beta(4)

compute gin2=%beta(5)

nlpar(subiterations=isiter)

* maximize(method=simplex,recursive,iterations=iter) $

garchlogl 4 *

maximize(method=bhhh,recursive,iterations=iter) $

garchlogl 4 *

print * * u11 v11

smpl(series=u11)

statistics u11

set rssg11 = u11(t)*u11(t)

statistics rssg11

smpl(series=rssg11)

compute sumsqu11 = %sum(rssg11)

display 'sum of squares of u11 for garch' sumsqu11

b34sreturn$

b34srun$



b34sexec options close(28)$ b34srun$

b34sexec options close(29)$ b34srun$

b34sexec options dodos('rats386 rats.in rats.out')

dounix('rats rats.in rats.out')$

b34srun$

b34sexec options npageout

writeout('output from rats',' ',' ')

copyfout('rats.out')

dodos('erase rats.in','erase rats.out',

'erase rats.dat')

dounix('rm rats.in','rm rats.out',

'rm rats.dat')$

b34srun$



*************************************************************

GARCH6 Illustrates various test problems



b34sexec options ginclude('b34sdata.mac')

macro(bg_test1); b34srun;

/$

/$ Set dorats=1 to run RATS on the test problem

/$

/$ Problem discussed in

/$ "Benchmarks and Software Standards: A Case study of

/$ GARCH procedures" McCullouch & Renfro

/$ Journal of Economic and Social Measurement 25 (1998)

/$ 59-71

/$

/$ Has Do loop and GARCH implementation

/$ Do loop runs very very slowly

/$

b34sexec matrix ;

call loaddata;

count=0.0;

j=norows(returns);



arch = array(j:);

res = array(j:);

archlog= array(j:);

* one and pfive make code run faster;

one=1;

pfive=.5;

smu=mean(returns);



svar=variance(returns-smu);



/$ Set starting value for h(1) if ne 0.0

/$ arch= arch+1.;

/$ arch= arch+ (sumsq(returns-smu)/dfloat(j));

call echooff;



program test;



func=0.0;

count=count+1.0;



/$ Uncomment do loop and comment call garch to switch

/$ mode of running



/$ res=returns-mu;



/$ do i=2,j;

/$ arch(i)=a0+a1*(res(i-one)*res(i-one))+b1*arch(i-one);

/$ func=func-(pfive*mlsum(arch(i)))-

/$ (pfive*((res(i)*res(i))/arch(i)));

/$ enddo;

/$

/$ adjusting h(1)

/$

/$ if(count.gt.1.)then;

/$ arch(1)=(sumsq(res)-(res(1)*res(1)))/dfloat(j-1);

/$ endif;

/$

/$ Using built in garch subroutine results in faster code

/$

res=returns-mu;



call garch(res,arch,returns,func,1,n

:gar array(:b1) idint(array(:1))

:gma array(:a1) idint(array(:1))

:constant array(:mu a0) );



call outstring(4,3,'F count mu a0 a1 b1');

call outdouble(34,3,func);

call outdouble(54,3,count);

call outdouble(4, 4, mu);

call outdouble(24,4, a0);

call outdouble(44,4, a1);

call outdouble( 4,5, b1);

* call print(func mu a0 a1 b1);

return;

end;



call print(test);



/$

/$ tests starting values

/$



call cmaxf2(func :name test

:parms mu a0 a1 b1

/$ These are benchmark starting values.

/$ :ivalue array(:-.016427, .221130, .35,.50)

:ivalue array(:smu, svar .01 .5)

:maxit 9000

/$ :gradtol .1d-07

/$ :steptol .1d-12

:lower array(:-10., .1d-2, .1d-2, .1d-2)

:upper array(: 10. 10. 10. 10. )

:print);



call print(sumsq(res));

* call tabulate(res,arch);

* Two pass method ;

* fixedet=(returns-mean(returns))*(returns-mean(returns));

* call arma(fixedet :maxit 2000 :relerr 0.0

:nar 1

:nma 1

:print);

b34srun;





Example using DO loop. See GARCH_DO1 in matrix.mac



b34sexec options ginclude('gas.b34'); b34srun;



/$ This problem runs slow but is most general case.

/$ Using DO loops can express any model.

/$ Can use CMAXF2 if limit problems.



b34sexec matrix ;



call loaddata;



/$ subset if j reduced



j=norows(gasout);

call print('# cases used was ',j);

count=0.0;



arch = array(j:);

res = array(j:);

archlog= array(j:);

call echooff;



program test;



/$ Using do loop



func=0.0;



do ii=i,j;

res(ii) =gasout(ii) - (b0 +(b1*gasout(ii-1))+

(b2*gasout(ii-2)));

arch(ii) =a0 + (a1*(res(ii-1)*res(ii-1))) +

a2*dmin1(dabs(arch(ii-1)),.1e+70);

func=func+((-.5)*(dlog(dmax1(dabs(arch(ii)),

.1e-10))+

( (res(ii)*res(ii)) /arch(ii)))) ;

* call outdouble(3,1,dfloat(ii));

* call outdouble(43,1,func);

enddo;



count=count+1.0;



call outstring(4,3,'Function');

call outdouble(24,3,func);

call outdouble(64,3,count);

call outdouble(4, 4, a0);

call outdouble(24,4, a1);

call outdouble(44,4, a2);

call outdouble(64,4, b0);

call outdouble( 4,5, b1);

call outdouble(24,5, b2);

return;

end;



call print(test);



i=3;



/$ initial values that were set

b0=2.;

b1=1.7;

b2=-.7;

a0=.04;

a1=.2;

a2=.5;

/$



/$ call test;

/$ call stop;



call maxf2(func :name test

:parms b0 b1 b2 a0 a1 a2

:maxit 200

:ivalue array(:b0, b1, b2, a0, a1, a2)

:print);



/$ Alternative setup



* call cmaxf2(func :name test

:parms b0 b1 b2 a0 a1 a2

:maxit 2000

:maxfun 2000

:maxg 2000

:ivalue array(:b0, b1, b2, a0, a1, a2)

:lower array(:-.1d+30,-.1d+30,-.1d+30,

.1d-16, .1d-16, .1d-16)

:upper array(: .1d+30, .1d+30, .1d+30,

.1d+30, .1d+30, .1d+30)

:print);



b34srun;



***********************************************************



GARCH_7 IGARCH(1,1) using NLPMIN1 - see test case GARCH_7



/$ IGARCH(1,1) using NLPMIN1 - showsgeneral case

b34sexec options ginclude('b34sdata.mac')

member(garchdat);

b34srun;



b34sexec matrix ;

call loaddata;





y=sp500;



vstart=variance(y-mean(y));



arch=array(norows(y):)+ vstart;

res= y-mean(y);

call print('mean y ',mean(y):);

call print('vstart ',vstart :);



program test;

call garch(res,arch,y,func,1,nbad

:gar array(:gar) idint(array(:1))

:gma array(:gma) idint(array(:1))

:constant array(:a0 b0)

);

if(%active(1)) g(1)=gar+gma-1.;

func=(-1.)*func;

return;

end;



call print(test);



call echooff;



call NLPMIN1(func g :name test :parms gar gma a0 b0

:ivalue array(:.5,.5,mean(y),vstart)

:nconst 1 0

:lower array(: 1.d-6, 1.d-6, 1.d-6, 1.d-6)

:upper array(: 1.d+2, 1.d+2, 1.d+2, 1.d+2)

:print :maxit 100

:iprint final);

b34srun;



GARCHEST Estimate a ARCH/GARCH model.

call garchest(res1,res2,y,func,maxlag,nbad :options);



The GARCHEST subroutine provides a simple way to setup and

estimate GARCH/ARCH/GARCH-M class models and avoid the overhead

of both recursive calls and calling a user program. The

GARCHEST command supports univariate and multiple input

transfer function models and provides the fastest and simplest

way to setup and run these complex models.



The GARCH command and the call to CMAXF2 should be used for

more complicated models or models where the calculation

progress has to be monitored. The GARCHEST command will be

faster than the GARCH/CMAX2 commands. The GARCHEST command

provides added capability for alternative models that are not

in the GARCH command which is really just a function that

speeds the recursive calculation. If there is demand, the GARCH

command can be extended.



For complete model flexibility, use a DO loop implementation.

Due to the recursive nature of the GARCH/ARCH class of models,

vectorizing the calculation is not possible. The speed will be

substantially less!!



For complex nonlinear constraints use the NLPMIN1 command,

which solves nonlinear programming models with nonlinear

constraints.



The GARCHEST command automatically calls the CMAXF2 routine

to maximize the function. The GARCHEST arguments are very

simular to GARCH and the options simular to ARMA to facilitate

movement back and forth.



The sample jobs GARCHEST and GARCHEST_2 illustrate the use of

the GARCHEST command. The key sections of these jobs are listed

below. In the complete jobs, RATS commands are supplied so as

to benchmark the results and to show clearly what is being

calculated.



The job garchest_3 shows GARCHEST on the McCullough-Renfro

benchmark. GARCH_6 shows the same test case using the GARCH

subroutine and calling CMAX2 directly. This tests case

illustrates how the initial values in res1 and res2 make a

difference.



GARCHEST Subroutine arguments



res1 - first moment residual



res2 - second moment residual



y - first moment variable



func - function

maxlag - maxlag of model for purposes of ML sum



nbad - number of bad datapoints



If res1 and res2 are allocated prior to the call to GARCHEST,

the initial values placed in these series are used. If GARCHEST

allocates res1 and res2, all values are set to 0.0.



Options supported



:nar n - Sets n as the max AR order provided

all terms up to n are to be estimated.

In this case the keyword :arorder is

not needed.



:arorder ivec - Sets AR terms to be estimated for

restricted model. :nar is not set in

this case.



:arparms rvec - Sets initial AR parameter values.

Initial values usually set by using

OLS coefficients.



:nma m - Set for max MA order provided all

terms up to m are to be estimated. In

this case :maorder is not needed.



:maorder ivec - Sets MA terms to be estimated for

restricted models. :nma is not set in

this case.



:maparms rvec - Sets initial MA parameter values.



:ngar n - Sets n as the max GAR order provided

all terms up to n are to be estimated.

In this case the keyword :garorder is

not needed.



:garorder ivec - Sets GAR terms to be estimated for

restricted model. :ngar is not set in

this case.



:garparms rvec - Sets initial GAR parameter values.

Usually not required.



:ngma m - Set max GMA order provided all terms

up to m are to be estimated. In this

case :gmaorder is not needed.



:gmaorder ivec - Sets GMA terms to be estimated for

restricted models. :ngma is not set in

this case.



:gmaparms rvec - Sets initial GMA parameter values.

Usually not required.



:nmu m - Set for max MU order provided all

terms up to m are to be estimated. In

this case :muorder is not needed.

:nmu needs to be set for GARCH-M

models or :muorder needs to be set.



:muorder ivec - Sets order of MU terms to be estimated

for restricted models. :nmu is not set

in this case.



:muparms rvec - Sets initial MU parameter values.

Usually not required.



:noconst1 - No first moment constant.



:noconst2 - No second moment constant.



:noconst3 - No constant for etgarch.



:cparms rvec - Pass 2 element initial constant

values. Two elements passed even if

:noconst1 or :noconst2 are set.

If :etgarch is set, pass three element

vector.



:print - Print results of estimation.



:lower rvec - Vector of lower values for parameters.

Usually not needed. First moment parms

have range -1.d+32 - 1.d+32. Second

moment parameters are restricted to be

> 0.0.



:upper rvec - Vector of upper values for parameters

Usually not needed. First moment parms

have range -1.d+32 - 1.d+32. Second

moment parameters are restricted to be

> 0.0.



:xvar xmatrix xparm xorder maxlagvec



- xmatrix - data matrix for inputs



- xparm - initial values.



- xorder - vector of input orders



- maxlagvec - number of parameters for

each input



Note that initial values must be

supplied.

:xscale vec - Vector of n elements to scale coef

vector. Default = 1.0



:fscale real - Functional scaling. Default = 1.0.



:ngood int - Sets number of good digits in the

function. Default = 15.



:maxit int - Maximum number of iterations.

Default = 400.



:maxfun int - Maximum number of function

evaluations. Default = 400



:maxg int - Maximum number of gradiant

evaluations. Default = 400



:gradtol real - Scaled gradiant tolerance.

Default = eps**(1/3).



:steptol real - Scaled step tolerance.

Default = eps**(2/3).



:rftol real - Relative functional tolerance.

Default = max(1.0d-20,eps**(2/3)).



:aftol real - Absolute functional tolerance.

Default = max(1.0d-20,eps**(2/3)).



:fctol real - False convergence tolerance.

Default = 100.*eps.



:maxsteps real - Maximum allowable step size.

Default = (1000*max(tol1,tol2))

where for i=1,n



tol1=

sqrt(sum of (xscale(i)*ivalue(i))**2



tol2 = 2-norm of XSCALE



:simplex - Use simplex (db2pol) to obtain better

starting values.



:print2 - Prints simplex results. Unless print2

is set, max iteration limit message

will not be given.



:print3 - Produces limited output for use under

SCA Work Bench



:ftol real - Relative functional tolerance for

simplex.

Default = max(1.0d-20,eps**(2/3)).



:maxit2 int - Maximum number of iterations for

simplex. Default = 100.



:stop - Makes exceeding maxit iterations a

fatal error that will terminate

further processing of the matrix job

and stop b34s. This option is usually

not used and instead the user inspects

the log. The purpose of this option is

to kill a long batch job if there was

an iteration limit exceeded early in a

long job.



Advanced Modeling options. There is a wide variaty of

advances GARCH type models and various forms. Only a few are

"hard wired" here. For exact detail on the format used, see the

examples listed below. To estimate models not "hard coded," use

the garch subroutine or directly code the models. This will

be substantially slower although any model can be estimated

as long as it can be coded.



:fattail vd - Modifies the GARCH likelihood function

for fattails. The parameter vd is

calculated. If vd is NOT supplied, it

is set to dfloat(n) as an initial

guess.



:shape vd - Sets shape. Here are fat tail

distribution is set, not estimated.

:shape is used for :fattail :dist=0,

:dist=1 and :dist=2 only.



:dist i - i=0 => Rats Formula.

i=1 => Tsay formula Tsay (2002) 3.8

page 89

i=2 => GED Generalized Error See

Hamilton (1994, 668)

i=3 => Cauchy Distribution



:nosqrt - Does not take the sqrt of the second

moment when estimating ARCH-M and

GARCH-M models.



:igarch - Estimates a GARCH(1,1) model with the

constraint that gar(1)+gma(1)=1.0.



If this option is used, only :ngar is

supplied. If more than a IGARCH(1,1)

is estimated, the DO loop or GARCH

setup must be used and NLPMIN1 should

be used to set the appropriate

constraint. Since as a default there

is no positive upper bound, using the

:igarch option might cause problems if

gar(1) > 1.0 since this implies

gma(1) 0 and

one for res1(i) 0 and

one for res1(i) 0.0 and



res2(t)=cparm(2)+gma(1) *(res1(t-gmaorder(1))**2)

+gma2(1)*(res1(t-gmaorder(1))**2)

+gar(1) * res2(t-garorder(1) + ...



otherwise.



The GJR model is also called the tarch model by Enders (2004)

page 141,



Note: The GJR (tarch) model adjusts the gma side of the

second moment equation.



The :tgarch command adjusts the gar part of second

moment equation.

*********************************************************



If :tgarch is set, the second moment equation becomes



Define (mask-) =1 if res1(t-1) 0

+ gma2(1)*res1(t-1) if res1(t-1) 126

Delete (127) KeyDelete

cursor up/down/right/left (128) KeyCursorUp ->

(131) KeyCursorLeft

shift/cursor u/d/r/l (132) KeyPageUp ->

(135) KeyPageLeft

ctrl /cursor u/d/r/l (136) KeyUpExtreme ->

(139) KeyLeftExtreme

Home / Find (140) KeyHome

End/Copy / Select (141) KeyEnd

Insert / Insert Here (142) KeyInsert

Delete-under-cursor (e.g. Remove) (143) KeyDeleteUnder

Backtab (e.g. shift/Tab) (144) KeyShiftTab

keypad keys 0 to 9 (145) Keypad0 ->

(159) Keypad9

keypad - (minus) (160) KeypadMinus

keypad . (period) (161) KeypadPoint

keypad + or , (plus/comma) (162) KeypadPlus

keypad / (slash) (163) KeypadDivide

keypad * (asterisk) (164) KeypadMultiply

keypad # (hash) (165) KeypadHash

keypad Enter (166) KeypadEnter

Print (170) KeyPrint

function keys 1 to 20 (171) KeyF1 ->

(190) KeyF20

SHIFT/fn keys 1 to 20 (191) KeyShiftF1 ->

(210) KeyShiftF20

CTRL /fn keys 1 to 20 (211) KeyCtrlF1 ->

(230) KeyCtrlF20

ALT /fn keys 1 to 20 (231) KeyAltF1 ->

(250) KeyAltF20

Left mouse button down (251) LeftButtonDown

Middle mouse button down (252) MiddleButtonDown

Right mouse button down (253) RightButtonDown

Left mouse button up (254) LeftButtonUp

Middle mouse button up (255) MiddleButtonUp

Right mouse button up (256) RightButtonUp

Mouse movement event (257) MouseMove

reserved (258)

Graphics window expose/resize event (259) ResizeEvent

Close-window request (260) CloseRequest

8-bit ASCII chars 128-255 384 ->

511 (i.e.256+8-bit

code)

Alt/backspace (520) KeyAltBackspace

Alt/tab (521) KeyAltTab

Alt/Return (525) KeyAltReturn

Alt/Escape (539) KeyAltEscape

Alt/0 - Alt/9 560 -> 569

(i.e. 512+ASCII code)

Alt/A - Alt/Z 577 -> 602





Example:



b34sexec matrix;

call echooff;

i=0;

start continue;

call getkey(i);

if(i.ne.0)then;

call outstring(1,3,'Hit escape to terminate');

call outstring(1,4,'key');

call outinteger(22,4,i);

if(i.eq.27)go to stop;

endif;



go to start;

stop continue;

b34srun;





GETMATLAB Gets data from matlab.



call getmatlab(x :file 'junk');



Reads a special file that the b34s supplied matlab m file

makeb34s makes. Files created with makeb34s can be read back

into MATLAB with the matlab command getb34s.

If :file is not present, the default name is _b34smat.dat



The commands getmatlab & makematlab pass series as a matrix.



If more accuracy is desired the matrix language commands

gmatlab and mmatlab (which are shown in the WRITE2 and READ2

examples) can be modified. If accuracy is increased, the matlab

m files getb34s.m and makeb34s.m will have to be changed.



The MATLAB sentence under the PGMCALL command allows passing of

b34s data to MATLAB via vectors. In addition MATLAB commands

can be appended. To get data from MATLAB to b34s use the

GETMATLAB command under the MATRIX command and use the MATRIX

command MAKEDATA to make the appropriate b34s data loading step

so that procedures can be run..



Options:



:file ' ' - Supply file name.



For a related command see makematlab.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

/$ When using the MATLAB GETB34S file use full path

/$ xx=getb34s('c:\junk\junk.ttt');

call loaddata;

call names;

xx=rn(matrix(5,5:));

call makematlab(gasout,gasin:file 'junk.ttt');

call makematlab(xx :file 'junk2.ttt');

call getmatlab(x, :file 'junk.ttt');

call getmatlab(xx2 :file 'junk2.ttt');

call print(x,xx,xx2);

call names;

cx=complex(xx,xx*2.);

call makematlab(cx :file 'junk3.ttt');

call getmatlab(cx2, :file 'junk3.ttt');

call print(cx,cx2);

b34srun;



GET_FILE Gets a File Name



Get a file name using a menu.



call get_file(cc);



Gets a File name in CC.



Example:



b34sexec matrix;

call get_file(cc);

call print('File found was ',cc);

call erase(cc);

b34srun;



GET_NAME Gets a Variable name



subroutine get_name(nn,ii);

/;

/; nn = name

/; ii = 0 is a problem

/; = 1 otherwise

/;

/; *****************************************

/;



Note: This command has to be loaded with the command



call load(get_name);



Example:





b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

back continue;

call loaddata;

call load(get_name);

call load(dataview);

call load(data_acf);

call get_name(cc,ii);

if(ii.eq.0)go to done;

call character(nn,cc);

call dataview(eval(cc),nn);

go to back;

endif;

done continue;

b34srun;





GETRATS Reads RATS Portable file.







call getrats(' ');



Loads data from rats portable file. If no arguments are

passed, the default name of myrun.por is used. Unless

keepmiss is in effect, missing data will be removed as the

default.



Options:



:keepmiss - Optionally keep missing data.



For a related command see makerats.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

newgasi=gasin;

newgaso=gasout;

call makerats(gasin,newgasi,gasout,newgaso

:file 'full.por');

call print(mean(gasin)

mean(newgasi)

mean(newgaso)

mean(gasout) );



call cleardat;

call getrats('full.por');

call print(mean(gasin)

mean(newgasi)

mean(newgaso)

mean(gasout) );

call names;

call tabulate(obsnum,gasin,newgasi,gasout,newgaso);

b34srun;





GETSCA Reads SCA FSAVE and MAD portable files.



call getsca('fname');



Loads SCA fsave 'fname' into the MATRIX command. This assumes

that the first member is loaded. The variant



call getsca('fname' :member jones);

will load member jones. If the series are of different lengths,

then series of different lengths are created.



Optional commands



:mad



allows reading of a SCA MAD file with possibly unequal data

lengths.



The folowing options are only needed for last datasets read

with more than oner series on the row.



:maxseries n1



Set to read more than 300 series. The default # of series read

in a mad file with more than one series on a row is 300.



:maxcwork n2



Set greater than the default of 4000 if parse space is needed.



:maxptokens n3



Set to the max parse tokens in file. Can be set above default

of 3000.



:info



Displays internal settings.



For related commands see makesca and makemad.



Example:



b34sexec options ginclude('b34sdata.mac') member(gas);

b34srun;

b34sexec matrix;

call loaddata;

call makemad(gasin,gasout

:file 'full.mad'

:member test);

b34srun;

b34sexec matrix;

call getsca('full.mad' :mad);



call names;



call print('mean(gasin)' , mean(gasin) :line);

call print('mean(gasout)', mean(gasout) :line);



call tabulate(gasout,gasin);

b34srun;

GMFAC - LU factorization of n by n matrix



call gmfac(x,l,u);

call gmfac(x,l,u,info);



Factors n by n matrix x such that



x = L*U



U = upper triangular matrix L is a "psychologically lower

triangular matrix" (i.e. a product of lower triangular and

permutation matrices) in L. This command works the same way

as the MATLAB lu(x) command.



In contrast to



x=inv(xx);



which uses LINPAC DGECO/DGEFA/DGEDI ZGECO/ZGEFA/ZGEDI unless

options are set, GMFAC uses the LAPACK routines DGETRF and

ZGETRF.



GMFAC optionally will return info > 0 if U(i,i)=0.



x - n by n matrix



l - Lower triangular matrix



u - Upper triangular matrix



info - 0 all ok

ne 0 x not full rank



Example:



b34sexec matrix;

* Problem from MATLAB;

x=matrix(3,3:8. 1. 6.

3. 5. 7.

4. 9. 2.);

call gmfac(x,l,u,info);

call print(x,l,u,info,l*u);



cx=complex(x,dsqrt(dabs(x)));

call gmfac(cx,cl,cu,info);

call print(cx,cl,cu,info,cl*cu);

b34srun;



GMINV - Inverse of General Matrix using LAPACK



call gminv(x,xinv);

call gminv(x,xinv,info);

call gminv(x,xinv,info,rcond);



Inverts a general matrrix using LAPACK



Given x - is n by n matrix

xinv - inverse of x



Optional Arguments. If these arguments are present program will

not stop if there is a problem. This allows "code trapping"

of a problem.



info - 0 all ok

ne 0 x not full rank



rcond - if present returns the condition of the

matrix if info = 0



GMINV uses LAPACK DGETRF/ZGETRF and DGETRI/ZGETRI DGECON/DGECON



Note that rcond takes time to compute.



The test job GMINV_2 suggests that LINPACK runs faster than

LAPACK. The advantage of GMINV is that rank problems can be

easily captured and code can be written to handle the

exception. Rank can also be found using PINV(x,rank) for a

real*8 matrix.



Example 1:



b34sexec matrix;

n=5;

x=rn(matrix(n,n:));

call gminv(x,xinv1,info);

xinv2=inv(x);

test1=x*xinv1;

test2=x*xinv2;

call print(x ,xinv1 ,xinv2 ,test1,test2);



cx=complex(x,dsqrt(dabs(x)));

call gminv(cx,cxinv1,info);

cxinv2=inv(cx);

test1=cx*cxinv1;

test2=cx*cxinv2;

call print(cx,cxinv1,cxinv1,test1,test2);

b34srun;





Example 2: Speed tests of LAPACK vs LINPACK



b34sexec matrix;

* Tests speed of Linpack vs LAPACK;

call echooff;

icount=0;

n=0;

upper=600;

mesh=50;



top continue;



icount=icount+1;

n=n+mesh;

if(n .eq. upper)go to done;

x=rn(matrix(n,n:));

ii=matrix(n,n:)+1.;



call timer(base1);

call gminv(x,xinv1,info);

call timer(base2);



error1(icount)=sum(dabs(ii-(xinv1*x)));



call timer(base3);

xinv1=inv(x);

call timer(base4);



error2(icount)=sum(dabs(ii-(xinv1*x)));

size(icount) =dfloat(n);

lapack(icount) =(base2-base1);

linpack(icount)=(base4-base3);

call free(x,xinv1,ii);

call compress;

go to top;



done continue;



call tabulate(size,lapack,linpack,error1,error2);

call graph(size lapack,linpack :plottype xyplot);

b34srun;



GMSOLV - Solve Linear Equations system using LAPACK



call gmsolv(x,b,ans,info);



Solves a linear system using LAPACK



Given x - n by n matrix



b - n by k matrix



ans - answer of inv(x)*b



Optional Argument: If this argument is present the program will

not stop if there is a rank problem.



info - 0 all ok

ne 0 not full rank



:refine If present the LAPACK routines DGESVX and ZGESVX

will be used to refine the solution. This will

take substantially more time. Automatic

variables created include:



%rcond = LAPACK estimate of the condition

%ferror = forward error

%berr = backward error



:refinee If present the LAPACK routines DGESVX and ZGESVX

will be used to refine the solution. This will

take substantially more time. Automatic

variables created include:



%rcond = LAPACK estimate of the condition

%ferror = forward error

%berr = backward error



With this option matrix equilibrating will be

performed.



If :refine or :refinee are used, info must be present and

tested. Routine will not stop if there are problems.



GMSOLVE uses LAPACK DGETRF/ZGETRF and DGETRS/ZGETRS. Since the

inverse is NOT formed, and BLAS 3 is used for large systems

there is a speed gain over an implementation that explicitly

forms the inverse.



Since the command solves



x * ans = b



Assuming x is (n by n)



if b is an identity matrix, then here ans will be the inverse.

This tricks the program to give the inverse but is wasteful of

space. If :refine is used, then the inverse may be accurate,

but at higher cost!!



Example:



b34sexec matrix;

n=5;

x=rn(matrix(n,n:));

b=rn(x);



call gmsolv(x,b,test1,info);

test2=inv(x)*b;

call print(x ,b ,test1,test2);



cx=complex(x,dsqrt(dabs(x)));

cb=complex(b,dsqrt(dabs(b)));

call gmsolv(cx,cb,test1,info);

test2=inv(cx)*cb;

call print(cx,test1,test2);

b34srun;





GRAPH High Resolution graph.



call graph(x);



Allows graphing of one to nine series using high resolution

plotting. If graphics not available, use plot command.



Advanced Graph features using keywords:





:heading 'Heading here'

Can set up to 72.



:pspaceon can improve looks.



:htitle xsize ysize



xsize = 1. => 75 characters per line.

ysize = 1. => 25 characters per col.



:plottype keyword



obsplot - Series plotted against

observation number.

This is the default.



xyplot - Plots first series on x axis.



xyzplot - Plots three series in 3D Plot.



hist2d - 2 dimensional histogram.



hist2dv - 2 dimensional histogram with labels.



hist2dhl - 2 dimensional histogram with

high/low labels.

series 1 = low value,

series 2 = high value)



hist3d - 3 dimensional histogram



hist2dc - 2 dimensional cumulative histogram



hist3dc - 3 dimensional cumulative histogram



bar2d - 2 dimensional bar graph



bar2dv - 2 dimensional bar graph with labels



bar3d - 3 dimensional bar graph

bar2dc - 2 dimensional cumulative bar graph



bar3dc - 3 dimensional cumulative bar graph



pie - Pie chart



scatter - Scatter diagram



xyscatter- Scatter diagram with first series on

x axis





Note: For a time plot use xyplot and pass a year variable in.



The command



call loaddata;



will generate a julian variable bjulian_ that can be

used. See the commands getyear( ) and fyear( ) commands.

If a variable has time series info, then makejul( ) can

be used to get the julian date vector.





The next four options require a 2-D matrix be passed



mesh - Plots a 2 by 2 matrix



meshc - Plots a 2 by 2 matrix using a matrix

of colors.



meshstep - Plots a 2 by 2 matrix using a step

3-D plot



meshstepc - Plots a 2 by 2 matrix using a step

3-D plot with colors



****************************************************



The next two options require a 3-D matrix and do volume plots.

Vold3 uses a range of 9 colors. Vold3c plots individual cells.



vol3d - Plots a three dimensional real*8

matrix passed as a 1-D array. If

dimensions are not the same, use



:dimension index(n1,n2,n3)



to set the dimensions of the matrix.



Plots using one color



vol3dc - Plots a three dimensional real*8

matrix passed as a 1-D array. If

dimensions are not the same, use



:dimension index(n1,n2,n3)



to set the dimensions of the matrix.



Elements of matrix in range

0.0 - 256. plot as a color.

For elements = missing

plot without color.

If :scale is supplied data will be

scaled to be in range 0.0 - 256.





Example of complex graphs:



b34sexec options ginclude('b34sdata.mac')

member(windvel);

b34srun;



b34sexec matrix;

call loaddata;

call graph(vel

:Heading 'Data looked at as a 1-D array');

call graph(vel :plottype vol3d

:d3axis :d3border :grid

:angle 10.

:dimension index(35,41,15)

:heading 'Vol3d plot of Wind Vel.');



call graph(vel :plottype vol3d

:d3axis :d3border :grid

:angle 30. :scale

:dimension index(35,41,15)

:heading 'Vol3d plot of Wind Vel.' );

call graph(vel :plottype vol3dc

:d3axis :d3border :grid :scale

:dimension index(35,41,15) :angle 10.

:heading 'Vol3dc plot of Wind Vel.');

b34srun;



****************************************************



The next ten options require 3 series



contours - 3D Scatter plot.



contoursx- 3D Scatter plot line to X axis.



contoursy- 3D Scatter plot line to Y axis.



contoursz- 3D Scatter plot line to Z axis.

contour3 - Three demensional surface plot.

User supplies three vectors.



steped3d - Stepped plot version of countour3.



contourc - Same as contour3, except that

Height vector cheight is generated.



steped3dc- Same as contourc except uses step

plot



contour2 - Two dimensional line based contour

plot.



contourf - Two dimensional fill based contour

plot.



obsplotb - Line plot with two error bars. Bars

set as 2nd and 3rd series.



timeplotb- Time plot with two error bars. Bars

set as 2nd and 3rd series.



Example:



b34sexec matrix;

n=100;

k=20;

x=rn(matrix(n,k:));

call graph(x :plottype mesh

:angle 10. :d3axis :d3border

:heading 'This is the data');

call graph(x :plottype meshc

:heading 'The data as a surface');

x=transpose(x)*x;

call graph(x :plottype mesh

:heading 'This is what transpose(x)*x is');

call graph(x :plottype meshc

:heading 'Transpose(x)*x in color!!');

call graph(x :plottype meshc :grid

:heading 'Transpose(x)*x in color with Grid');

call graph(x :plottype mesh :angle 10.

:heading 'Transpose(x)*x - angle 10.');

call graph(x :plottype meshc :angle 10.

:heading 'Transpose(x)*x - angle 10.');

call graph(x :plottype mesh :rotation 90.

:heading 'Transpose(x)*x rotation 90.');

call graph(x :plottype meshc :rotation 90.

:grid :d3axis :d3border

:heading 'Transpose(x)*x rotation 90.');

call graph(x :plottype meshstep :rotation 70.

:angle 10. :grid

:heading 'Transpose(x)*x rotation 70.

meshstep');

call graph(x :plottype meshstepc :rotation 70.

:angle 30. :grid :d3axis

:heading 'Trans(x)*x rotation 70. meshstepc');

call graph(x :plottype meshstepc

:rotation 70. :angle 0. :grid

:heading 'Trans(x)*x rotation 70.

meshstepc');



b34srun;





*******************************************************



Note: For obsplotb and timeplotb the series are

entered as y ylower yupper.



The pie graph type requires two series.

The second of which must be character for

labels.



Color keywords



black

red

yellow

green

cyan

blue

magenta

white

gray

bred

byellow

bgreen

bcyan

bblue

bmagenta

bwhite



-------------------------------------------------------



:overlay keyword



keywords recognized are:



acfplot - assumes acfplot2d

acfplot2d

acfplot3d



for ACF we use



call graph(acfval se :nokey :nolabel

:heading 'ACF Plot'

:overlay acfplot);

Example:



b34sexec options ginclude('gas.b34')$ b34srun$



b34sexec matrix;

call loaddata;

acf2=acf(gasin,24,se2,pacf2);

call graph(acf2 se2 :overlay acfplot);

b34srun;



----------------------------------------------------------



:file 'file name'



Saves plot.



:noshow Turns off display of graph if hardcopy to a

file is selected



:fitspline Fits a spline to line and x-y plots.



:linetype key



key can be solid (Default)

dotted

dashed

dotdash

dotdotdash (device dependent)

longshort (device dependent)

short (device dependent)



:linetype solid dotted



makes plot 1 solid and plot 2 dotted



:markpoint istart ievery icode1 icode2



istart Sets position to mark point.



ievery Sets number between points.



icode1 Sets 0 => No not mark the plot (default)

1 => digits

2 => letters

3 => Markers

4 => Symbols



icode2 Sets what to plot with



For digits set 1-9

For letters 1-26 (A-Z)

27-25 (a-z)

For Markers 1-20

For Symbols 33-126 or 161-255

icode2 can be set as an array





Examples:



1 1 3 14 => mark with big dot

1 1 4 111 => mark with small dot

1 1 4 116 => mark with dot

1 1 4 120 => mark with a bar

1 1 4 166 => Mark with small dot



1 1 1 index(1,2,3,4,5,6,7,8,9)





Recommended settings are



1 1 4 162

1 1 4 165

1 1 4 206

1 1 4 218

1 1 4 219



For a complete visual table of what is available go to



"Settings"

"Graph Settings"

"View Character / Symbol Table"







:wait # of centiseconds to wait while a graph displays.



:colors keywords for 1-9



:grcharset filename



loads a character set file. Once this file is

loaded it is the default charset. See



call igrcharset('filename')



command to set the default character set.



File names supported



'H' Hardware font.

'standard.chr' General Purpose character set.

'roman.chr' Times Roman

'romanbld.chr' Roman Bold

'swiss.chr' Swiss / Helvetica style font

'swissbld.chr' Swiss / Helvetica bold font

'simplexrchr' Similar to standard with more detail.

'duplexr.chr' More detailed that simplex.

'triplexr.chr' Heavier variant than duplex.

'complexr.chr' More tapered segments than triplexr.

'complexi.chr' Italic version of Complex Roman.

'triplexi.chr' Italic version of triplex Roman.

'simplexs.chr' Handwritten style.

'complexs.chr' More detailed variant of simplexs.

'simplexg.chr' Greek characters added to simplex.

'complexg.chr' More detailed simplexg.

'gothicen.chr' Very detailed old English style.

'gothicit.chr' Variant of gothicen.

'standden.chr' Danish variant of standard.

'standfra.chr' French variant of standard.

'standger.chr' German variant of standard.

'standita.chr' Italian variant of standard.

'standnor.chr' Norwegian variant of standard.

'standswe.chr' Swedish variant of standard.

'standuk.chr' UK variant of standard.



:grcharfont ikey



ikey codes



Fixed Proportional

1 Helvetica Courier

2 Helvetica ital Courier ital

3 Helvetica bold Courier bold

4 Helvetica bold/Ital Courier bold/ital

5 Times Roman Courier

6 Times Roman ital Courier ital

7 Times Roman bold Courier bold

8 Times Roman bold/ital Courier bold/ital



The grcharfont option requires :grcharset 'h' be in effect.



Examples of grcharset and grcharfont are in graph7.



b34sexec options ginclude('gas.b34')$ b34srun$



b34sexec matrix;

call loaddata;



call graph(gasout :heading 'This is the current default');



call graph(gasout :heading 'This is a standard.chr'

:grcharset 'standard.chr');

call grcharset('H');

call graph(gasout :heading 'This is a test 1' :pspaceon

:grcharfont 1 :file 't1.wmf');

call graph(gasout :heading 'This is a test 2'

:grcharfont 2 :file 't2.wmf');

call graph(gasout :heading 'This is a test 3'

:grcharfont 3 :file 't3.wmf');

call graph(gasout :heading 'This is a test 4'

:grcharfont 4 :file 't4.wmf');

call graph(gasout :heading 'This is a test 5'

:grcharfont 5 :file 't5.wmf');

call graph(gasout :heading 'This is a test 6'

:grcharfont 6 :file 't6.wmf');

call graph(gasout :heading 'This is a test 7'

:grcharfont 7 :file 't7.wmf');

call graph(gasout :heading 'This is a test 8'

:grcharfont 8 :file 't8.wmf');



call graph(gasout :heading 'This is a test roman.chr'

:grcharset 'roman.chr');

call graph(gasout :heading 'This is a test romanbld.chr'

:grcharset 'romanbld.chr');

call graph(gasout :heading 'This is a test swiss.chr'

:grcharset 'swiss.chr');

call graph(gasout :heading 'This is a test swissbld.chr'

:grcharset 'swissbld.chr');

call graph(gasout :heading 'This is a test fixed.chr'

:grcharset 'fixed.chr');

call graph(gasout :heading 'This is a test fixedbld.chr'

:grcharset 'fixedbld.chr');

call graph(gasout :heading 'This is a test simplexr.chr'

:grcharset 'simplexr.chr');

call graph(gasout :heading 'This is a test duplexr.chr'

:grcharset 'duplexr.chr');

call graph(gasout :heading 'This is a test triplexr.chr'

:grcharset 'triplexr.chr');

call graph(gasout :heading 'This is a test complexr.chr'

:grcharset 'complexr.chr');

call graph(gasout :heading 'This is a test H'

:grcharset 'H');

call graph(gasout :heading 'This is a test complexi.chr'

:grcharset 'complexi.chr');

call graph(gasout :heading 'This is a test triplexi.chr'

:grcharset 'triplexi.chr');

call graph(gasout :heading 'This is a test simplexs.chr'

:grcharset 'simplexs.chr');

call graph(gasout :heading 'This is a test complexs.chr'

:grcharset 'complexs.chr');

call graph(gasout :heading 'This is a test simplexg.chr'

:grcharset 'simplexg.chr');

call graph(gasout :heading 'This is a test complexg.chr'

:grcharset 'complexg.chr');

call graph(gasout :heading 'This is a test complexc.chr'

:grcharset 'complexc.chr');

call graph(gasout :heading 'This is a test gothicen.chr'

:grcharset 'gothicen.chr');

call graph(gasout :heading 'This is a test gothicit.chr'

:grcharset 'gothicit.chr');



b34srun;

:scale Scale all data to have the same mean as the

first variable



:nolabel Turns off labels



:pspaceon Turns on proportional spacing. This setting

stays on unless turned off in a later graph

call.





:pspaceoff Turns off proportional spacing. This setting

stays off unless turned on in a later graph

call.



:rotation real number



:nocontact real number



Automatically adjusts xaxis and yaxis such that

plot does not touch the sides



An optional argument percent determines how

much adjustment.



A manual mode way to get the same result is to

do an xyplot and manually supply



:setxrange and :setyrange



nocontact works with obsplot and xyplot.





:angle real number in range 0.0 - 45



:d3axis Sets 3D axis.



:d3border Sets 3D border.



:dimension Sets dimension of 3 dimensional arrays.



form :dimension index(5,6,7)



:box ngrid



Notes on 3D routines.



The commands CONTOUR3, CONTOURC, CONTOUR2 and CONTOURF

transform three vectors into a two dimensional matrix of

heights with dimensions NGRID by NGRID by the

Interacter subroutine iPGXYZToGrid.





:grid Turn on grid lines for mesh, meshc, meshstep,

meshstepc, vol3d, vol3dc. Turns on Graticules

for plots using dotted lines.



:nokey Turns off key for plots



:noxlabel Turn off X label



:noylabel Turn off Y label



**************************************************



Advanced Graph Settings to over ride defaults



:xdecimal int



Sets number of decimal places.

autoselect.



:ydecimal int



Sets number of decimal places.

autoselect.



:zdecimal int



Sets number of decimal places.

autoselect.





:rxtick real



Sets relative tick size. Default = 1.0



:rytick real



Sets relative tick size. Default = 1.0



:rztick real



Sets relative tick size. Default = 1.0



:xlabeltop ' ' key



Sets text up to 90 and key where key must be

'L', 'C' or 'R' for left, centered, or right.



:xlabeltop will override the :heading.



Use :heading to change the size of the title.



Use :xlabeltop to write near the top of the

graph.



:xlabel ' ' key

Sets text up to 90 and key where key must be

'L', 'C' or 'R' for left, centered, or right



:ylabelleft ' ' key



Sets text up to 90 and key where key is a 2

level code set inside ' '.



Position 1 is:



T -> Starting at top edge

C -> Centered (default)

B -> Ending at bottom edge



Position 2 is:



V -> Verticle (default)

R -> Rotated 270 degrees

9 -> Rotated 90 degrees



:ylabelright ' ' key



Sets text up to 90 and key where key is a two

level code set inside ' '.



Position 1 is:



T -> Starting at top edge

C -> Centered (default)

B -> Ending at bottom edge



Position 2 is:



V -> Verticle (default)

R -> Rotated 270 degrees

9 -> Rotated 90 degrees



:zlabelleft ' ' key



Sets text up to 90 and key where key is a 2

level code set inside ' '.



Position 1 is:



T -> Starting at top edge

C -> Centered (default)

B -> Ending at bottom edge



Position 2 is:



V -> Verticle (default)

R -> Rotated 270 degrees

9 -> Rotated 90 degrees

:zlabelright ' ' key



Sets text up to 90 and key where key is a two

level code set inside ' '.



Position 1 is:



T -> Starting at top edge

C -> Centered (default)

B -> Ending at bottom edge



Position 2 is:



V -> Verticle (default)

R -> Rotated 270 degrees

9 -> Rotated 90 degrees



:xlabelpos r8



Sets relative position of xlabel. r8 must be

in range 0 to 1.0 Default = .7. Smaller

numbers mean nearer to figure.



:ylabelpos r8



Sets relative position of ylabel. r8 must be

in range 0 to 1.0 Default = .8. Smaller

numbers mean nearer to figure.



:zlabelpos r8



Sets relative position of zlabel. r8 must be

in range 0 to 1.0 Default = .8. Smaller

numbers mean nearer to figure.



:linewidth int array of 2 elements



Sets line width in pixels for screen and hard

copy. Default is



:linewidth index(1 1)



:xscale real array



Sets user x label values. Length of array must

be le 100



:xscale array(:4 8 12)



:yscale real array



Sets user y label values. Length of array must

be le 100

:yscale array(:4 8 12)



:zscale real array



Sets user z label values. Length of array must

be le 100



:zscale array(:4 8 12)



:histscale int array



Sets user histogram label values. Length of

array must be le 100



:histscale integers(1,6)



:barscale int array



Sets user bar label values. Length of array

must be le 100



:barscale integers(1,8)



:hardcopyfmt key



Sets hardcopy output format for this graph

only.



HP_GL => 1 HP-GL

EPS => 2 PostScript

RAST => 3 Raster Graphic

PCX_BMP => 6 PCX/BMP

LOTUS => 7 Lotus PIC

DXF => 8 DXF

CGM => 9 Computer Graphics Metafile

WPM => 10 Windows Print Manager

WMF => 11 Windows Meta File

HP_GL2 => 12 HP_GL/2



Example:



:hardcopyfmt hp_gl



:pgaxesxy real array of 2 elements



Sets position of axes. Default is 0.0 0.0



Alternatives to above commands for expert users.



:setxscale real array of 2 elements



Sets left hand value and incrument for

X scale. If this parameter is not set

correctly all or parts of the graph may

be off the screen. The value r1 is the

lower left X value and r2 is the incrument

between tick marks for X scale.



:setyscale real array of 2 elements



Sets left hand value and incrument for

Y scale. If this parameter is not set

correctly all or parts of the graph may

be off the screen. The value r1 is the

lower left Y value and r2 is the incrument

between tick marks for Y scale.



:nxticks i4



Sets number of user X ticks if :setxscale

is in effect. 2 LE i4 LE 100. Default = 5.



:nyticks i4



Sets number of user Y ticks if :setyscale is

in effect. 2 LE i4 LE 100. Default = 5.



:setxrange real array of 2 elements



Sets Min (r1) and Max (r2) for xscale.



:setyrange real array of 2 elements



Sets Min (r1) and Max (r2) for yscale.





:grborder



Draws a border around graph area. Not used

in full screen mode.



:pgborder



Draws a border around presentation graph

area.



:pgxscaletop key



Places x scale on top.



Key is a 2 level code



t -> places ticks outside

I -> places ticks inside

N -> Numbers axis



Example: The following code places ticks top, middle, bottom

and left and right. It is based on fact that

:pgxscaletop redefines tick positions.



:grunits array(:mmin_1 mmin_2 mmax_1 mmax_2)

:pgarea array(:.1 .1 .9 .9)

:pgunits array(:mmin_1 mmin_2 mmax_1 mmax_2)

:color black

:heading title

:pgxscale 'NT'

:pgaxes

:pgxscale 'NT'

:pgborder

:pgyscaleleft 'NT'

:pgyscaleright 'I'

:pgxscaletop 'I'

:pgxscale 'NT'





:pgyscaleleft key



Places y scale on left.



Key is a 2 level code



t -> places ticks outside

I -> places ticks inside

N -> Numbers axis



:pgyscaleright key



Places y scale on right.



Key is a 2 level code



t -> places ticks outside

I -> places ticks inside

N -> Numbers axis









Examples of GRAPH command for simple plots



call graph(x,y,z :plottype hist2d

:heading 'Test of Histogram');



call graph(x :heading 'Test of plot'

:file 'c:\junk\test.wmf');



call graph(x);





GRAPHP - Multi-Pass Graphics Programing Capability



This command is not for the general user. However by its use

custom graphic objects can be displayed.



call graphp(:start);

call graphp(:cont ...);

call graphp(:final);



The above commands allow users to program complex graphs that

are not possible with the "built-in" graphics capability in the

GRAPH command. The GRAPHP command is not intended for the

general user. A detailed knowledge of Interacter Software is

assumed.



GRAPHP commands provide access to the Interacter Graphics

primative commands so that custom graphics applications can be

developed by the B34S programming team. These applications are

distributed in the form of B34S Matrix Command subroutines and

programs to give the user to the ability to create "custom"

graphs without hardwiring the graph types into the B34S

execuitable.



A general user wishing to make use of this facility for

building user custom graphics should license Interacter /

Winteracter and use the GRAPHP command to prototype potential

graphics applications before they are hard coded in the user's

Fortran.



Help documentation for the GRAPHP command is terse. Note that

while the menu system in Interacter and Winteracter are

different, the graphics routines are the same.



All GRAPHP command blocks begin with the :start option,

contain a number of :cont commands and finish with the

:final option.



Other matrix commands can be mixed inside the GRAPHP commands

as long as GRAPH and GRREPLAY are not called. The reason for

this limitation is that such calls would kill the graphics

screen. The only exception to this would be to save and

restore the screen. This work-around may not function

correctly and is not supported.



Use of the :toolbox command allows user input into the graph.

The Toolbox feature allows the user to interactively build

complex graphs that can be saved into *.bmp or *.pcx format

which can be imported into Word.



On the :cont option, commands are processed in sequence so that

for example colors can be changed as we move down a list of

options.



Colors set by integer value n the range 0-255 rather than

names. Base colors can be obtained with the integer function



i=icolor(red);

and shades can be adjusted by adding or substracting from i.



***************************************************************



Missing Data: The MATRIX command dmax and dmin have an optional

argument : which supports missing data. The graphp commands

:grpoint, :grjoin and :grmarker will ignore missing data.



Warning: Many arguments in graphp are not checked due to many

possible ways the commands are used. Users have to take care to

check the results of their setups. The design goal of GRAPHP is

to allow users to develope custom subroutines for types of

graphs that are not possible with the GRAPH command.



As we get more experience with graphp, the command language for

various commands may be changed.



The present implementation should be considered to be in

"mature" beta form. Bugs may remain.



***************************************************************



:start option section



:start is the first option in a sequence of GRAPHP

commands. The only options allowed on the

:start command are :file and :hardcopyfmt



:file ' '



Saves the graph in a file. If file is present, the

graph will not show on the screen. If a blank

string of the form ' ' is passed and B34S is

running on windows, the file will be placed on the

clip board as long as the file save type is wmf.

Due to the fact that the current Interacter

implementation for wmf files uses the Windows API

if a number of files are placed in one file and the

combined file saved, the component files must be in

a format other than wmf.



:hardcopyfmt key



Sets hardcopy output format for this graph only



HP_GL => 1 HP-GL

EPS => 2 PostScript

RAST => 3 Raster Graphic

PCX_BMP => 6 PCX/BMP

LOTUS => 7 Lotus PIC

DXF => 8 DXF

CGM => 9 Computer Graphics Metafile

WPM => 10 Windows Print Manager

WMF => 11 Windows Meta File

HP_GL2 => 12 HP_GL/2





***************************************************************



:cont option section



Key words and arguments for :cont



:toolbox



Opens a windows to allow user input into graphics

screen. The toolbox allows B34S users to

interactively draw complex economics diagrams that

can be moved into Word. The quickest way to get into

this command interactively is through the 'Menu'

Command in the Display Manager and select the DRAW

command.



:graphpvocab



lists vocab of graphp



:grarea array(4: x1 y1 x2 y2)



:grunits array(4:xleft,ylower,xright,yupper)



:grviewport array(4:x1 y1 x2 y2)



Defines graphics viewport. Same as :grarea except

current user units are recalculated to ensure the

image size remains unchanged instead of being

rescaled. Character size remains unchanged.



:pgunitstogrunits x y gr_x gr_y



x and y can be elements or an array. The variables

gr_x and gr_y are automatically created. These names

must be used to refer to these values due to the fact

we are creating variables inside a parsed command.



:pgunitsfromgrunits x y pg_x pg_y



x and y can be elements or an array. The variables

pg_x and pg_y are automatically created. These names

must be used to refer to these values due to the fact

we are creating variables inside a parsed command.



:replayarea array(4: xx y1 x2 y2)



Sets area for :replay to work



:replay filename

Loads a file into the graphics area where further

processing can be done. Files loaded are HP-GL,

HP-GL/2, GCM, Lotus PIC and WMF format.



:grloadimage filename



Loads BMP and PCX into graphics area.



:grprintimage filename



Dumps contents of graphics area to a file or a

printer.



:grplotmode key



N => normal mode overwritting.

O => OR plotting mode.

A => AND plottong mode.

E => EOR/XOR (Exclusive or) plotting mode.



Example :grplotmode n



:grarc array(5:xpos,ypos,radius,sangle,aangle)



Draws a circular arc.



xpos = x co-ordinate of circle centre

ypos = y co-ordinate of circle centre

radius = radius of circle in plotting units

sangle = Arc start angle in degrees counter

clockwise from 3 o'clock

aangle = arc angle in degrees counter-clockwise



Note: Arc can be filled with :grfillpattern



:grarcrel array(3:radius,sangle,aangle)



Draws a circular arc centered at current position.



radius = radius of circle in plotting units.



sangle = Arc start angle in degrees counter

clockwise from 3 o'clock



aangle = arc angle in degrees counter-clockwise.



Note: Arc can be filled with :grfillpattern



:grarrow array(4:xfrom,yfrom,xto,yto) itype



Optional argument



itype = 1 simple

= 2 outline filled see grfillpattern



:grarrowjoin array(:xtail ytail xhead yhead) itype



Optional argument



itype = 1 simple

= 2 outline filled see grfillpattern



:grblockcopy array(:xsour ysour xdest ydest width height)



:grblockmove xsour ysour xdest ydest width height



:grcircle array(:xpos ypos radius)



Arguments can be arrays. If so pass three arrays.

For futher information see grfillpattern.



:grcirclerel radius



:grellipse array(:xpos ypos radius ratio)



Arguments can be 4 individual arrays for

multiple ellipses.



:grellipserel array(:radius ratio)



:grlineto array(:xpos ypos)



For arrays see grjoin



:grlinetorel array(:dxpos dypos)



:grmarkerrel marker



Marker is an integer is range 1-20



:grparallel array(:xpos1,ypos1,xpos2,ypos2,apslen)

itype



apslen = length of axis parallel side



itype = 1 y axis parallel

= 2 x axis parallel



:grparallelrel array(:dxpos,dypos,apslen) itype



:grtrapezium array(:xpos1,ypos1,xpos2,ypos2,

alen1 alen2) itype



alen1=length of axis parallel side ending at

xpos1 ypos1



alen2=length of axis parallel side ending at

xpos2 ypos2



itype = 1 y axis parallel

= 2 x axis parallel



:grtranpeziumrel array(:dxpos,dypos,alen1,alen2)

itype



alen1 = length of axis-parallel side starting at

current position



alen2 = length of axis-parallel side ending at

current position



itype = 1 y axis parallel

= 2 x axis parallel





:grtrianglerel array(:dxpos2 dypos2 dxpos3,dypos3)



:grcharlength string rlength



calculates relative length of a string in rlength.



With fixed spacing



rlength=len(string).



With porportional spacing these are not the same.



rlength is a real*8 variable.





:grcharspace ichr space



Allows the proportional spacing table to be reset at

runtime. Space for 'I' is .56 of its fixed space

value. Since 'I' is code 73 the command



:grcharspace 73 .45



resets 'I' smaller to .45



ichr = character code mist be 32-126 or 161-255



space = relative character space



Note: ichr and space can be arrays



ichr=0 => reset to defaults



:grcharunderline key



on => underline on

off => underline off



:grsaveimage fname



use name.pcx or name.bmp



Example



:grsaveimage 'my.pcx'



:grfileinfo fname info



info(1) file type

info(2) image width

info(3) image height

info(4)

info(5)

info(6)



Info(1) codes:

-1 File does not exist.

0 Unable to determine file type.

1 Windows .bmp

2 pcx format

3 Windows metafile

4 HP-GL plotter file

5 HP-GL/2 plotter file

6 Computer graphics Metafile cgm

7 Lotus PIC file

8 Acorn Draw

9 DEC LN03+Tektronix 4014

10 Postscript or EPS

11 HP PCL

12 Epson ESC/P2

13 Epson ESC/P

14 AutoCAD DXF



See Interacter Documentation for further help.



Example:



:grfileinfo 'test.wmf' ii



:grinputdevice key



K => keyboard

M => mouse

D => digitising tablet



:grinputlimits array(:xleft ylower xright yupper)



:grdistanceline array(:x1 y1 x2 x2 xcheck ycheck)

method rdist

Defines a line and a check point and gets distance in

rdist



method nearest

perpend



:grinsidecircle array(:xpos ypos radius

xcheck ycheck) isin



Finds if point xcheck ycheck is in circle.

If so isin=1.



:grinsideellipse array(:xpos ypos radius ratio

xcheck ycheck) isin



Finds if point xcheck ycheck is in ellipse.

If so isin=1.





:grisidepolygon xpos ypos xcheck ycheck isin



Finds if point xcheck ycheck is in polygone.

Note that xpos and ypos are arrays. If so isin=1





:grintersectionline array(:x1 xy x2 y2 x3 y3 x4 y4)

xinter yinter istatus



xinter intersection points

yinter intersection points

istatus



=> 0 lines parallel and collinear

=> 1 lines parallel not collinear

=> 2 intersec outside

=> 3 intersect on line 1

=> 4 intersect on line 2

=> 5 intersect on both lines





:grborder



Draws a border around graph area. Not used in full

screen mode.



:pgarea array(4:x1 x2 y1 y2)



Defines a relative position. x1, x2, y1, y2 are 0.0



:pgunits array(4:xmin ymin xmax ymax)



Defines the units of x and y.

:pause



Stops processing until (cr).



:pause clear



Pause and wait for a key. If the optional key clear

is present, the screen will be cleared after the

next key it hit



:grarerclear



Clear graphics area.



:pgborder



Draws a border around presentation graph area.



:grjoin array(:x) array(:y)



Variants



:grjoin array(:x1 y1 x2 y2)



:grjoin x1 y1 x2 y2



:grjoin array(:x1) array(:y1) array(:x2) array(:y2)



Note that array must have been built prior to call to

command or with pgunitstogrunits. array(:x1 y1 x2 y2)

can be used in place of x1 y1 x2 y2 if variables

built prior to command. If multiple x1 values are

passed, multiple lines are drawn.



If either x or y are missing, point will be dropped.



:grjoinrel array(4:x1 y1 dx1 dy1)



Draws from a specified position to a new relative

position.



:grcurve array(:x) array(:y) nstep



Draws a spline through a series of points.



nstep is optional argument. default = 32



If either x or y are missing point will be dropped.



:grmarker array(:x) array(:y) marker (1-20)



Marker is optional

If either x or y are missing, point will be dropped.



:grpoint array(:x y)



Set to point x, y.



:grpointrel array(:dx dy)



Set to point relative to curent position.



:grmoveto array(2:x1 y1)



Move to point x1, y1.



:grmovetorel array(2:dx1 dy1)



Move relative to current point.



:pspaceon



Turns on proportional space.



:pginfo



Lists out graphics settings



:pspaceoff



Turns off proportional space.



:charsize array(2:width height)



Set character size.



:charjustify key



Sets how charout outputs.



C => center

L => left justified

R => rightjustified



:charout array(2:xpos ypos) string



Draws in GR area. See also charoutrel to add text.



:charoutrel string



:charrotate r8



Measured counter clockwise from horizontal.



:chardirection key

h => horizontal

v => vertical



:charslant r8



r8 => Range -60. to + 60.



:color key



Color keywords



black

red

yellow

green

cyan

blue

magenta

white

gray

bred

byellow

bgreen

bcyan

bblue

bmagenta

bwhite



:colorn i4



i4 in range (0-255). The command icolor(red) can

be used to set the base color which can be

adjusted. The :colorn command allows exact control

over colors.



black => 0 - 15

light red => 16 - 31

dark red => 32 - 47

light yellow => 48 - 63

dark yellow => 64 - 79

light green => 80 - 95

dark green => 96 - 111

light cyan => 112 - 127

dark cyan => 128 - 143

light blue => 144 - 159

dark blue => 160 - 175

light magenta => 176 - 191

dark magenta => 192 - 207

white => 208 - 223

light grey => 224 - 239

dark grey => 240 - 255



:grrectangle array(4:x1 xy x2 y2)

Draws a rectangle.



:grpolygonsimple array(:x) array(:y)



Draws a simple polygon. Borders must not cross.

If borders cross, use :grpolygoncomplex.



:grpolygoncomplex array(:x) array(:y)



Draws a complex polygon. Borders must not cross.

If borgers do not cross, use :grpolygonsimple.



:grpolygongrad array(:x) array(:y) ikey



Draw irregular polygon using graduated color fill.



ikey codes



1 => bottom-to-top

2 => left-to-right

3 => top-to-bottom

4 => right-to-left



:grfillpattern index(istyle idense iangle)



Sets fill pattern. Used with



:grrectangle

:grpolysimple

:grpolycomplex

:grpolydongrad



istyle codes



0 outline

1 hatch

-1 hatched no outline

2 cross hatch

-2 cross hatch no outline

3 mixedcolor

4 solid



idense codes



1 sparse

2 medium

3 dense1

4 dense2

5 dense3



iangle codes



1 diagonal sloping up

2 diagonal sloping down

3 fill horizontal lines

4 fill verticle lines





:linetype key



key codes



solid (Default)

dotted

dashed

dotdash

dotdotdash (device dependent)

longshort (device dependent)

short (device dependent)



:linewidth int array of 2 elements



Sets line width in pixels for screen and hard copy.

Default is :linewidth index(1 1)



:grpolyline array(:x) array(:y)



Draws a poly-line through a series of absolute

coordinates.



:grtriangle array(:x1 y1 x2 y2 x3 x4)



Draws a triangle.



:grrectanglerel arrray(:width height)



Draws a rectangle ad correct point.



:heading 'Heading here' key



Heading can set up to 72 characters.



Optional key set as



L => left

C => center

R => right



:grcharset filename



Loads a character set file



File names



standard.chr General Purpose character set.

standden.chr Danish variant of standard.

standfra.chr French variant of standard.

standger.chr German variant of standard.

standita.chr Italian variant of standard.

standnor.chr Norwegian variant of standard.

standswe.chr Swedish variant of standard.

standuk.chr UK variant of standard.

simplexr.chr Similar to standard but with

more detail.

duplexr.chr More detailed that simplexr.

triplexr.chr Heavier variant than duplexr.

complexr.chr More tapered segments than

triplexr.

complexi.chr Italic version of Complex Roman.

triplexi.chr Italic version of triplex Roman.

simplexs.chr Handwritten style.

complexs.chr More detailed variant of

simplexs.

simplexg.chr Greek characters added to

simplexr.

complexg.chr More detailed simplexg.

gothicen.chr Very detailed old English style.

gothicit.chrt Variant of gothicen.

roman.chr Times Roman

romanbld.chr Roman Bold

swiss.chr Swiss / Helvetica style font

swissbld.chr Swiss / Helvetica bold font



Example:



:grcharset 'roman.chr'



:grcharfont ikey



Sets Hardware fonts.



ikey codes



Fixed Proportional

1 Helvetica Courier

2 Helvetica ital Courier ital

3 Helvetica bold Courier bold

4 Helvetica bold/Ital Courier bold/ital

5 Times Roman Courier

6 Times Roman ital Courier ital

7 Times Roman bold Courier bold

8 Times Roman bold/ital Courier bold/ital





:rxtick r8



Sets relative tick size. Default = 1.0



:rytick r8



Sets relative tick size. Default = 1.0

:rztick r8



Sets relative tick size. Default = 1.0



Note: For next commands key can be a character string or a

string of letters. A character string, like that used

in graph, is recommended.





:xlabeltop ' ' key



Sets text up to 90 and key where key must be L, C or

R for left, centered, or right.



:xlabeltop will override the :heading.



Use :heading to change the size of the title. Use

:xlabeltop to write near the top of the graph.



:xlabel ' ' key



Sets text up to 90 and key where key must be L,

C or R for left, centered, or right.

Key can be set as 'R' or R.



:ylabelleft ' ' key



Sets text up to 90 and key where key is a 2 level

code. Key can be set as 'TV' or TV.



Position 1 is:



T -> Starting at top edge

C -> Centered (default)

B -> Ending at bottom edge



Position 2 is:



V -> Verticle (default)

R -> Rotated 270 degrees

9 -> Rotated 90 degrees



:ylabelright ' ' key



Sets text up to 90 and key where key is a two level

code. Key can be set as 'TV' or TV.



Position 1 is:



T -> Starting at top edge

C -> Centered (default)

B -> Ending at bottom edge



Position 2 is:

V -> Verticle (default)

R -> Rotated 270 degrees

9 -> Rotated 90 degrees



:zlabelleft ' ' key



Sets text up to 90 and key where key is a 2 level

code. Key can be set as 'TV' or TV.



Position 1 is:



T -> Starting at top edge

C -> Centered (default)

B -> Ending at bottom edge



Position 2 is:



V -> Verticle (default)

R -> Rotated 270 degrees

9 -> Rotated 90 degrees



:zlabelright ' ' key



Sets text up to 90 and key where key is a two level

code. Key ca be set as 'TV' or TV.



Position 1 is:



T -> Starting at top edge

C -> Centered (default)

B -> Ending at bottom edge



Position 2 is:



V -> Verticle (default)

R -> Rotated 270 degrees

9 -> Rotated 90 degrees



:xlabelpos r8



Sets relative position of xlabel. r8 must be in

range 0 to 1.0. Default = .7. Smaller numbers

mean nearer to figure.



:ylabelpos r8



Sets relative position of ylabel. r8 must be in

range 0 to 1.0. Default = .8. Smaller numbers mean

nearer to figure.



:zlabelpos r8



Sets relative position of zlabel. r8 must be in

range 0 to 1.0 Default = .8. Smaller numbers

mean nearer to figure.





:xscale real array



Sets user x label values. Length of array must be

le 100.



:xscale array(:4 8 12)



Note: pgxscale controls display.



:yscale real array



Sets user y label values. Length of array must be le

100



:yscale array(:4 8 12)



Note: pgyscale controls display.



:zscale real array



Sets user z label values. Length of array must be le

100.



:zscale array(:4 8 12)





:grpalettehls index(ncolor ihue ilight isat)



Sets colors using hue light and saturation.



ncolor in range 0-255



ihue in range 0-360



0 => blue

60 => magenta

120 => red

180 => yellow

240 => green

300 => cyan



ilight in range 0 = 100



0 => black

100 => white



isatur in range 0 to 100



0 => gray

100 => pure color

:grpaletteinit



Restores default settings.



:grpalettergb index(ncolor ired igreen iblue)





Controls colors by % of red green blue



ncolor in range 0-255

ired in range 0-255

igreen in range 0-255

iblue in range 0-255



***********************************************************



Higher level commands requiring detailled access to Interacter

manuals.



:pgnewplot index(itype nsets layout ireset)

index(nvalue1 nvalue2 nvalue3)



nvalue = 1 element integer array usually

= 2 element array for contour surface

= 3 element array for volume plots





:pgnewgraph index(nsets nvalue1 nvalue2)

array(:cuml layout grtype)



nsets => Number of datasets



nvalue = 1 element integer array usually

= 2 element array for contour surface

Note: elenets 1 # of points



cum1 = 'c' array containing c for cumulative,

' ' otherwise



layout 3 => 3 dimensional

A => adjacent bars in histograms/bar or

anti clockwise wedges

B => View 3-d from back

S => Fit spline.. display spider tags

V => Variable grid size 3D surface plots

Variable length spider tags

Value labels on 2D non-cumulative

bar-charts histograms

H => Height dependent contour colors on 3D

surfaces or high/low histogram plot.

F => Fill-based 2D contour plot or plot

bars in front of each other on 2D

cumulative histograms

C => Point-dependent colors on 3D

scatter plots

T => Tile-dependent colors on 3D contour

plots.



grtype B => bar

C => contour

F => function plot

H => histogray

L => line plot

P => pie chart

S => scatter

T => table

X -> x/y co-ordinate plot



:pgxscale string



'T' => ticks outside

'I' => ticks inside

'N' => numbering



:pgyscale string



'T' => ticks outside

'I' => ticks inside

'N' => numbering



:pgxscalepos r8



:pgyscalepos r8



:pgyscaleangle array(2:tangle,sangle)



tangle => Y axis tick mark angle

sangle => Y axis scale value string angle



in degrees counter-clockwise from horizontal



:pgyticklength r8



r8 => relative length of Y axis tick mark default=1.0



:pgytickpos array(2:xleft,xright)



xleft => x position of left Y axis tick mark

xright => x position of right Y axis tick mark



xright restore default





:pgaxes



Draws pg axis

:pgaxesxy array(2:x1 y1)



Sets position of axes. Default is 0.0 0.0



:pgxgraticules key



Key can be solid (Default)

dotted

dashed

dotdash

dotdotdash

longshort

short



:pgygraticules key



Key can be solid (Default)

dotted

dashed

dotdash

dotdotdash

longshort

short



:pgzgraticules key



Key can be solid (Default)

dotted

dashed

dotdash

dotdotdash

longshort

short



:pgxscaletop key



Places x scale on top.



Key is a 2 level code





t -> places ticks outside

I -> places ticks inside

N -> Numbers axis



:pgyscaleleft key



Places y scale on left.



Key is a 2 level code



t -> places ticks outside

I -> places ticks inside

N -> Numbers axis



:pgyscaleright key



Places y scale on right.



Key is a 2 level code





t -> places ticks outside

I -> places ticks inside

N -> Numbers axis





:pgstyle index(iset istyle istyle2 istyle3 icol1 icol2)



:pglineplot array(:x)



:pgcliprectangle key



G => main graphics area

P => PG area



:pgconfill2granul igan



igan ge 1 sets fill granularity



:pgcontourlabel iset label



iset contour number



label label (max 10 characters)



:pgdecimalplaces ndec



ndec => number of decimal places

auto select



:pgelevation angle



0. le angle le 45.



:pggriddirection igrid



3D surface plots



3 => both x and y

2 => perpendicular to y

1 => perpendicular to x

0 => no grid





:pggridlines igrid

3D contour



1 => height dependent grid lines

2 => no grid lines

3 => grid lines drawn in background color



:pgmarker iset marker



iset => data set

marker => marker code 0-9, 1-52



Note: This option must be used with style2 or

pgstyle. For further detail see Interacter

documentation.



:pgmarketfrequency istart ievery



Sets marker frequency and start



:pgrotation angle



Angle rotation for 3D plot views



:pgscalling xscalkey yscalkey



key LIN

LOG



:pgstyle3daxes index(istyle icol11 icol12 icol13

icol21 icol22 icol23)



istype 0 => outline

3 => mixed

4 => solid



icol1 & icol2 set primary and secondary fill colors.



Color codes can be set using



icolor(' ') command



:pgstyleoutline icol



Sets outline color



:pgunitspolar rmax



Maximim radius for polar plots



:pgunitsz array(:zmin zmax)





:pgxkeypos relpos

Sets relative key position.



0. le relpos le 1.



:pgxscaleangle array(:tangle sangle)



tangle= axis tick mark angle



sangle= axis scale value string angle





:pgxtickpos array(:ybottom,ytop)



:pgxuserscale spoint



:pgxuserscalehist ibars



ibars is an integer array



:pgylabelpoc r8



r8 is a relative position



:pgyuserscale spoint



spoint is an array of user scales. max # = 100



No argument disables.





:pgyuserscalebar ibars



ibars = array of histogram scales



No argument disables.



:pgzscaleangle array(:tangle sangle)



tangle= axis tick mark angle



sangle= axis scale value string angle



:pgkeyall descr layout



descr = array of discriptions



layout V

9

X

B

R

E => end of lines

P

Set both arguments as character*8



:pgkeyall namelist(income price) '9B'



For further detail see Interacter Documentation



:pgkeysingle iset xpos ypos descr



Sets a key. Can be supplied for a

number of points.



:pgxtext descr



x axis dscriptions. Pass as character*8



:pgxtexttop descr



x axis dscriptions. Pass as character*8



:pgytextleft descr



Labels left Y axis. Pass as character*8



:pgytextright descr



Labels right y axis. Pass as character*8.



:pgzscale key

I => inside

T => outside

N => no ticks



:pgztext descr



Labels z axis



:pgbarchart xvalues



:pgerrorbars ylow yhigh



For line plot



Note: Must supply right #



:pghighlow ylow yhigh



For histogram



Note: Must supply right amount



:pghistogram yvalue



:pgpiechart pival sangle explode

pival => array of values to be plotted



sangle => start angle



explode => character*1 array with blanks or

E to explode. If argument left

off assumes blanks



:pgscatterplot xvalue yvalue



:pgscatterplot3d xvalue yvalue zvalue



:pgscatterplot3dcol xvalue yvalue zvalue colors



Same as pgscatterplot3d except supply colors.



:pgtableinteger ivalues



ivalues => array of integer values



:pgtablereal rvalues fmt



rvalues => array of real values to

be plotted in table.



fmt is optional. Default g16.8.





:pgxypairs xvalue yvalue



:pgxyztriplets xvalue yvalue zvalue



:pgconfill2irreg zvalue zcontr xgrid ygrid



zvalue => is nxdim nydim



zcontr => sets nc set on pgnewplot



xgrid => is nxdim



ygrid => is nydim



:pgconfill2reg zvalue zcontr



zvalue => is nxdim nydim



zcontr => sets nc on pgnewplot



:pgcontour2irreg zvalue zcontr xgrid ygrid



zvalue => is nxdim nydim



zcontr => sets nc set on pgnewplot

xgrid => is nxdim



ygrid => is nydim



:pgcontour2reg zvalue zcontr



zvalue => sets nxdim nydim



zcontr => sets nc on pgnewplot



:pgsurf3data zvalue



zvalue => is nxdim nydim



:pgsurf3datacol zvalue icol



zvalue => is nxdim nydim



icol => is nxdim nydim





:pgsurf3datacont zvalue zcontr



zvalue => is nxdim nydim



zcontr => is nc on pgnewplot





:pgsurf3step zvalue



zvalue => is nxdim nydim



:pgsurf3stepcol zvalue icol



zvalue => is nxdim nydim



icol => is nxdim nydim



:pgsurf3stepcont zvalue zcontr



zvalue => is nxdim nydim



zcontr => is nc on pgnewplot



:pgvolume3col icolr index(nxdim nydim nzdim)



icolr => is nxdim nydim nzdim



:pgvolume3cont value index(nxdim nydim nzdim) contr



contr => nc array of contour values



:pgxyzsearchbox array(:boxwidth boxhgt)

:pgxyztogrid x y z zrec index(n1 n2)



x => array of x data

y => array of y data

z => array of heights



zrec is n1 by n2 and contains a matrix

that can be plotted in 3D.



Note: zrec is real*8



:pgjoin2 array(:xpg1 ypg1 xpg2 ypg2)



:pgjoin3 array(:xpg1 ypg1 zpg1 xpg1 ypg2 zpg2)



:pgpolygoncomplex2 xpg ypg



Arrays of x and y points to draw

# of points LE 4095



:pgpolygoncomplex3 xpg ypg zpg



Will draw a 3D figure.

# of points LE 4095



:pgpolyline2 xpg ypg



Arrays of x and y points to draw

# of points LE 4095





:pgpolyline3 xpg ypg zpg



Will draw a 3D figure

# of points LE 4095



:pgunitxfromgrunitsp gxpos gypos angle radius



Can be supplied as arrays



:pgunitstogrunits3 pgxpos pgypos pgzpos gxpos gypos



:pgunitstogrunitsp angle radius gxpos gypos



***********************************************************



:final option section



call graphp(:final);



Terminates the progessing of the graph and either displays or

produces hardcopy depending on settings on the

:start option cl.



Functions useful for graphp command:



infograph - Obtain Interacter Graphics INFO



r=infograph(n);



n in range 1-14



1 => Current x plotting position

2 => Current y plotting position

3 => Current character width

4 => Current character height

5 => Mouse x position

6 => Mouse y position

7 => Left limit on graphics area

8 => lower limit on graphics area

9 => Right limit on main graphics area

10 => Upper limit on main graphics area

11 => Lower x co-ordinate limit

12 => Lower y co-ordinate limit

13 => Upper x co-ordinate limit

14 => Upper y co-ordinate limit



r is real*4



Note: This routine must be used on distinct call graphp(:cont)

calls to be updated properly.



This routine has no use outside graphp.





Example of graphs with call graph and call graphp.



b34sexec matrix;

call loaddata;

call graph(cac :plottype hist2d

/$ :heading 'CAC Ratio ordered by Size of Firm'

:nolabel

:nokey

:colors black black

:pspaceon

:file 'CACPLOT.WMF'

:xlabel

'Participants arrayed by emissions size'

:ylabelleft 'CAC ratio' 'C9'

);



/$ graphp implementation



icolor=223;



call graphp(:start

/$ :file 'newfig2.wmf'

/$ :hardcopyfmt wmf

);

call graphp(:cont :graphpvocab);

call graphp(:cont

:grarea array(:0. 0. 1. 1.)

:grunits array(:1. 0. 168. 3.)

:pgarea array(:.1 .1 .9 .9)

:pgunits array(:1. 0. 168. 3. )

:color black

:pgborder

:pspaceon

:pgxscale 'N'

:pgyscaleleft 'tN'

:xlabel

'Participants arrayed by emissions size'

:ylabelleft 'CAC ratio' C9



/$ :pgnewplot index(1,1,0,1) index(norows(cac))

:pgnewgraph index(1 norows(cac) 0)

array(:' ',' ','H')

:pgstyle index(1,-4,3,1,icolor,icolor)

:pghistogram cac



/$ :pgnewplot index(4,1,0,1) index(norows(cac))

:pgnewgraph index(1 norows(cac) 0)

array(:' ',' ','L')

:pgstyle index(1, 0,0,0,icolor,icolor)

:pglineplot constant



/$ :toolbox

);

call graphp(:final);



b34srun;



Example of a distribution plot with a user axis



b34sexec matrix;

call echooff;



call getsca('c:\b34slm\findat01.mad' :mad :member D_AA);



YMean=Mean(D_AA);

YSigma2=Variance(D_AA-YMean);



call garchest(res1, res2, D_AA,func,1,nbad

:cparms array(:YMean, YSigma2)

:garorder idint(array(:1))

:gmaorder idint(array(:1))

:print );



_sqrmat=array(dmax1(norows(res1),norows(res2)),2:);

_sqrmat(,1)=res1;

_sqrmat(,2)=res2;

_sqrmat =goodrow(_sqrmat);

res1=_sqrmat(,1);

res2=_sqrmat(,2);



Residual=goodrow(res1);

Sigma=goodrow(dsqrt(goodrow(res2)));



et=Residual/Sigma;

x=et;



/; data in variable x



ibars=13 ;



/; Automatic calculation not used.

/; call datafreq(x _table :equal ibars midpts);



/; midpoints set as -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6



upper= 5.5;

lower=-5.5;

call datafreq(x _table

:equaluser ibars midpts lower upper);



/; call tabulate(_table midpts);



/; a test case showing defaults

call character(cc,'Default plot ');



call graph(_table :plottype hist2d

:heading cc

:pspaceon

:pgyscaleright 'i'

:pgborder

:pgxscaletop 'i'

:colors black bblue bred

);



/; +++++++++++++++++++++++++++++++++++++++++++++++++++++





/; we set range of x axis and y axis.

/; By defining xmax2 etc it allows a fudge as has been

/; done with ymax2

/; Note that datafreq gives us the exact midpoints of each

/; rectangle



xmax=dmax(x);

xmin=dmin(x);



/; xmax2=xmax;

/; xmin2=xmin;

xmax2= 6.5;

xmin2=-6.5;

ymin2=0.0;

ymax2=dmax(_table)+(dmax(_table)/20.);

uscale=midpts;



/; Make sure no rectangles are 0.0 height. Add a "fudge"



/; testing



xmin=lower;



do ii=1,norows(_table);

if(_table(ii).le.0.0)_table(ii)=.1e-3;

enddo;



call graphp(:start :file '_table.wmf');

call graphp(:cont

:grarea array(:0.0 0.0 1. 1.)

:grunits array(: 1. xmin2 xmax2 dfloat(norows(_table)))

:pgarea array(: .1 .1 .9 .9)

:pgunits array(: xmin2 ymin2 xmax2 ymax2)

:pgborder

:pspaceon

:xscale uscale

:pgxscale 'TN'

:pgyscaleleft 'n'

:xlabel 'Distribution of Standardized Residual'

:ylabelleft '# of Cases'

/; :ylabelleft '# of Cases' 'Cr'

/; :ylabelleft '# of Cases' 'C9'

:heading 'This is a test histogram'

:pgnewgraph index(1,norows(_table)) array(:' ' ' ' 'H')

:pgstyle index(1,4,0,0,160,20)

:pghistogram _table

);

call graphp(:final);



/; Quick see what we have!!



call grreplay('_table.wmf');

b34srun;



Error Messages from Interacter:



1 Error opening file.



2 Error reading or writting to a device.



3 Error closing a file.



4 Number too large iun string to numeric conversion.



5 Graphics not supported on requested printer.

6 Screen mode not supported for load/save operation.



7 Max number of windows exceeded.



8 Window buffer space exceeded.



9 Invalid window co-ordinates.



10 No substring found.



11 More than one decimal point in number.



12 Invalid character detected.



13 Operating system command error in an OS routine.



14 Invalid text co-ordinates for clear operation.



15 Centred string truncated (exceeds screen or window width).



16 X or Y graphics unit range is invalid. Default of 0-1 used.



17 Window destination partly or wholly off-screen. Destination

co-ordinates adjusted.



18 Numeric to string conversion error. String filled with *'s.



19 All options start with '-' in a menu.



20 Radius of a circle/ellipse, or height ratio of an ellipse

is = 1 HP-GL

EPS => 2 PostScript

RAST => 3 Raster Graphic

PCX_BMP => 6 PCX/BMP

LOTUS => 7 Lotus PIC

DXF => 8 DXF

CGM => 9 Computer Graphics Metafile

WPM => 10 Windows Print Manager

WMF => 11 Windows Meta File

HP_GL2 => 12 HP_GL/2



Example:



call grreplay('myplot.wmf'

:hardcopyfmt PCX_BMP

:file 'myplot.pcx');



reformats the graph.



More than one file can be displayed as long as the number of

files is 1, 2, 4 or 9. The command



call grreplay('plot1.wmf','plot2.wmf');



displays one on top of the other.



call grreplay('plot1.wmf',

'plot2.mmf'

:file 'newplot.wmf');



call grreplay('newplot.wmf');



Combines a two plots into one plot and displays the combined

plot. If 4 or 9 files are supplied, then, these are shown in a

predefined form:



twograph 1

2



fourgraph 1 2

3 4



ninegraph 1 2 3

4 5 6

7 8 9





Advanced options:



The GRREPLAY command can be given a number of times to build a

custom plot. In this mode or operation for the first call use

the key



:start



If :start is given the only allowed options are

:hardcopyfmt and :file.



For all subsequent calls except the final call use

the key



:cont filename



If :cont is supplied only the options :gformat,

:area or :zoom are allowed





For the final call use



call grreplay(:final);



Discussion:



For each call one file is passed. The positioning of the

file is controlled by either



:gformat key i4



key is set



onegraph

twograph

fourgraph

ninegraph



i4 is set to the graph number.



Example where we have 3 graphs and want to display them in a

four way graph.



call grreplay(:start);

call grreplay(:cont 'plot1.wmf' :gformat fourgraph 1);

call grreplay(:cont 'plot2.wmf' :gformat fourgraph 2);

call grreplay(:cont 'plot3.wmf' :gformat fourgraph 3);

call grreplay(:final);



to show the combined graph.



As an alternative to the :gformat the option



:area r8 array of 4 elements



can be used. The elements are:

1. => x_left

2. => y_lower

3. => x_right

4. => y_upper



Example



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:area array(:.0 .0 1. .5));

call grreplay(:cont 'plot2.wmf'

:area array(:.0 .5 1. 1.));

call grreplay(:final);



The Interacter graphics routines use Windows API calls to

display WMF files which cannot be zoomed. If a file is NOT a

WMF file the option



:zoom r8 array of 4 elements



Can be used to select just that portion of the source file to

display.



The elements are:



1. => x_left

2. => y_lower

3. => x_right

4. => y_upper



Example of a zoom of plot1.cgm:



call grreplay(:start);

call grreplay(:cont 'plot1.cgm'

:zoom array(:.5 .5 1. 1.)

:area array(:.0 .0 1. .5));

call grreplay(:cont 'plot2.cgm'

:area array(:.0 .5 1. 1.));

call grreplay(:final);



Example to save a combined plot.



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:area array(:.0 .0 1. .5));

call grreplay(:cont 'plot2.wmf'

:area array(:.0 .5 1. 1.));

call grreplay(:final);



or



call grreplay('plot1.wmf' 'plot2.wmf'

:file 'newplot.wmf');

Comprehensive example showing building plots of the form



1 2

3





b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call graph(gasout :file 'p1.hp1'

:heading 'Gasout hp_GL'

:noshow

:hardcopyfmt HP_GL);

call graph(gasin :file 'p2.hp1'

:heading 'Gasin HP_GL'

:noshow

:hardcopyfmt HP_GL);

call grreplay(:start);

call grreplay(:cont 'p1.hp1' :gformat twograph 1);

call grreplay(:cont 'p2.hp1' :gformat twograph 2);

call grreplay(:final);

b34srun;



b34sexec options ginclude('b34sdata.mac')

member(res72); b34srun;

b34sexec matrix;

call loaddata;

call graph(lnq :heading 'Ln Q'

:file 'plot1.wmf' :noshow);

call graph(lnl :heading 'Ln L'

:file 'plot2.wmf' :noshow);

call graph(lnk :heading 'Ln k'

:file 'plot3.wmf' :noshow);

call graph(lnrm1 :heading 'Ln rm1'

:file 'plot4.wmf' :noshow);

call graph(lnrm2 :heading 'Ln rm2'

:file 'plot5.wmf' :noshow);

call graph(P :heading 'P '

:file 'plot6.wmf' :noshow);

call graph(m1 :heading 'M1 '

:file 'plot7.wmf' :noshow);

call graph(m2 :heading 'M2 '

:file 'plot8.wmf' :noshow);

call graph(L :heading 'L '

:file 'plot9.wmf' :noshow);



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:gformat onegraph 1);

call grreplay(:final);



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:gformat twograph 1);

call grreplay(:cont 'plot2.wmf'

:gformat twograph 2);

call grreplay(:final);



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:gformat fourgraph 1);

call grreplay(:cont 'plot2.wmf'

:gformat fourgraph 2);

call grreplay(:cont 'plot3.wmf'

:gformat fourgraph 3);

call grreplay(:cont 'plot4.wmf'

:gformat fourgraph 4);

call grreplay(:final);



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:gformat ninegraph 1);

call grreplay(:cont 'plot2.wmf'

:gformat ninegraph 2);

call grreplay(:cont 'plot3.wmf'

:gformat ninegraph 3);

call grreplay(:cont 'plot4.wmf'

:gformat twograph 2);

call grreplay(:final);



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:gformat ninegraph 1);

call grreplay(:cont 'plot2.wmf'

:gformat ninegraph 2);

call grreplay(:cont 'plot3.wmf'

:gformat ninegraph 3);

call grreplay(:cont 'plot4.wmf'

:gformat ninegraph 4);

call grreplay(:cont 'plot5.wmf'

:gformat ninegraph 5);

call grreplay(:cont 'plot6.wmf'

:gformat ninegraph 6);

call grreplay(:cont 'plot7.wmf'

:gformat ninegraph 7);

call grreplay(:cont 'plot8.wmf'

:gformat ninegraph 8);

call grreplay(:cont 'plot9.wmf'

:gformat ninegraph 9);

call grreplay(:final);



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:gformat onegraph 1

:zoom array(:.33333 .33333 .66666 .66666));

call grreplay(:final);



call grreplay(:start);

call grreplay(:cont 'plot1.wmf'

:area array(:.33333 .33333 .66666 .66666)

:zoom array(:.33333 .33333 .66666 .66666));

call grreplay(:final);



b34srun;





GTEST Tests Output from a ARCH/GARCH Model



call gtest(res1,res2,y,nacf);



Tests the first and second moments of a ARCH / GARCH model





subroutine gtest(res1,res2,y,nacf);

/;

/; res1 => First Moment Residual

/; res2 => Second Moment Residual

/; y => Input Series

/; nacf => Number acf terms

/;

/; Plots made:

/;

/; acfa.wmf => acf of residual Moment 1

/; acfb.wmf => acf of residual Moment 2

/; acfy.wmf => acf of y series

/; mqa.wmf => Q stats residual Moment 1

/; mqb.wmf => Q stats residual Moment 2

/; pacfa.wmf => pacf of residual Moment 1

/; pacfb.wmf => pacf of residual Moment 2

/; pacfy.wmf => pacf of y series

/; resa.wmf => Plot of residual Moment 1

/; resb.wmf => Plot of residual Moment 1

/;





Example:



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix ;

call loaddata;

call load(gtest);

arch=array(norows(gasout):);

call olsq(gasout gasout{1} gasout{2} :print);

call print('RESVAR',%resvar :);

call garchest(res,arch,gasout,func,2,n

:cparms array(2:%coef(3), %resvar)

:nar 2 :arparms array(2: %coef(1) %coef(2))

:ngar 1 :ngma 1

:gmaparms array(:.05) :print );



call gtest(res,arch,gasout,48);

b34srun;



GWRITE Save Objects in GAUSS Format using one file



call gwrite(x,xxname,unit);



Saves object x on unit using name in xxname. The number of

elements in x must be LE 1000 due to internal GAUSS limits on

the size of a sentence. If the object to be passed is larger

than 1000, use gwrite2.



x - Object name

xxname - Name in file

unit - Fortran I/O unit



Real*8 and Integer*4 objects supported.



Note: Since GWRITE is a subroutine and must be loaded prior to

use.



Example:



b34sexec matrix;

call load(gwrite);



call open(70,'testdata');



y=array(2,2:1 2 3 4);

nn=namelist(y);

call gwrite(y,nn,70);



xx=rn(matrix(5,5:));

nn=namelist(xx);

call gwrite(xx,nn,70);



i=integers(1,23);

ii=namelist(i);

call gwrite(i,ii,70);



call close(70);

b34srun;



Example 2 - Runs OLS in GAUSS



b34sexec matrix;

call load(gwrite);



call open(70,'testdata');



x1=rn(array(100:));

nn=namelist(x1);

call gwrite(x1,nn,70);

yy=10. + x1 + rn(x1);

nn=namelist(yy);

call gwrite(yy,nn,70);



call olsq(yy x1 :print);



call character(cc,'ols("",yy,x1);');

call write(cc,70);

call close(70);

/$ run the file

call unix('gaussb testdata > jj.out');

b34srun;

/$

b34sexec options npageout

writeout('Output from GAUSS',' ',' ')

copyfout('jj.out');

b34srun;



GWRITE2 Pass Data to Gauss in two files



call gwrite2(x,xxname,unit);



Saves object x on unit using name in xxname in GAUSS format.

This command is used if object is larger than 1000.



x => Object name

xxname => Name in file

unit => Fortran I/O unit



Real*8 and Integer*4 objects supported.



Note: Since GWRITE2 is a subroutine it must be loaded prior to

use.



gwrite2 makes a file xxname.fmt for each series. Hence if the

object to be moved is jj.out');

b34srun;



b34sexec options npageout

writeout('Output from GAUSS',' ',' ')

copyfout('jj.out');

b34srun;



HEADER Turn on header



call header;



Turns on page numbering inside matrix command. Since a new page

number is forced every time this command is found, it can be

given multiple times inside the same job.



HEXTOCH Convert a hex value to its character representation





call hexttch(hex,ch);



Converts a hex value to character.



hex => character*1 character matrix of size 2*n



ch => character*1 character vector of size n



Extended Example



b34sexec matrix;

/$ Looking at Printable Characters ;

i=integers(33,127);

call igetchari(i,cc);

call names(all);

call tabulate(i,cc);

call igetichar(cc,iitest);

call chtohex(cc,hexcc);

/$ Repack character*2 array save as character*1;

/$ Next two statments work the same

/$ hexcc2= array(norows(hexcc)/2,2:hexcc);

hexcc2=c1array(norows(hexcc)/2,2:hexcc);

hex1=hexcc2(,1);

hex2=hexcc2(,2);

call hextoch(hexcc,cctest);

xx=transpose(hexcc2);

call print(xx,hexcc2);

call hextoch(xx,cctest2);

call names(all);

/$ get hexcc2 in a printable variable;

blank=c1array(norows(hex1):);

call names(all);

c8var=catcol(hex1, hex2,blank,blank,

blank, blank,blank,blank);

call names(all);

/$ call print(c8var);

c8var=c8array(norows(c8var):transpose(c8var));

call tabulate(i,cc,iitest,hex1,hex2,

cctest,cctest2,c8var);

b34srun;



HINICH82 Hinich 1982 Nonlinearity Test.



call hinich82(x,m,g,l)



Calculate Hinich(82) test for series x.



x = input series. Must be set.



m = Number of terms to average. Only set if :setm is

in effect.



g = Gaussianity test. Output by routine.



l = linearity test. Output by routine.



The test is performed over admissable range. See BTIDEN

command for more detail. Using default settings, last two G and

L values are mean and variance of prior G and L values. M is

given the values -99. and -999 for these observations.



Options:



:meanonly - averages G & L only here m set as -99

variance where m -999



:setm - # of terms set in M.



:smoothspec - smooth spectrum needed if x not white

noise.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;



call hinich82(gasout,m,g,l:meanonly);

call print('Mean Data for Hinich(82) Test on Gasout',g,l);

m=17;

call hinich82(gasout,m,g,l:setm);

call print(

'Mean Data for Hinich(82) Test on Gasout M Set',m,g,l);

call hinich82(gasout,m,g,l);

call print('Hinich(82) Test on Gasout not Smoothed');

call tabulate(m,g,l);



call hinich82(gasout,m,g,l:meanonly :smoothspec);

call print('Mean Data for Hinich(82) Test on Gasout',g,l);

m=16;

call hinich82(gasout,m,g,l:setm :smoothspec);

call print(

'Mean Data for Hinich(82) Test on Gasout Mean Set',g,l);

call hinich82(gasout,m,g,l :smoothspec);

call print('Hinich(82) Test on Gasout Smoothed');

call tabulate(m,g,l);

b34srun;



HINICH96 Hinich 1996 Nonlinearity Test.



call hinich96(x,c,v,h)



Calculates Hinich(96) v and h test for x.



x = series



c = sets number of lags. If c le 0, c defaults to .4.

# of lags = nob**c.



For detail on this test see Stokes (1997).



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call echooff;

call hinich96(gasout,0.0,V,H);

call print(

'Mean Data for Hinich(96) Test on Gasout',V,H);

c=grid(.2 .45,.02);

v=array(norows(c):);

h=array(norows(c):);

do i=1,norows(c);

call hinich96(gasout,c(i),vv,hh);

v(i)=vv; h(i)=hh;

enddo;

call print(

'Hinich(96) Test on Gasout for various c values');

call tabulate(c,v,h);

b34srun;



HPFILTER Hodrick-Prescott Filter.



call hpfilter(data,datat,datadev,lamda);



Uses Hodrick-Prescott filter to decompose data into trend

(datat) and deviations from trend (datadev). Data must be

real*8. If data is a matrix or 2d array, each column is

transformed.



data = real*8 series (can be a matrix) or 2d array).

datat = trend part of series

datadev = deviation part of series

Lamda = sets the cost of incorporating fluctuations

into the trend. Default = 1600.

Prescott suggests 1600. for quarterly data.

For yearly data set 1600 / 4**2 = 100.

For monthly data set 1600 * 3**2 = 14,400.



This command uses Prescott's subroutine that selects u(t)

such that



(1/T)sum((y(t)-u(t)**2)-(lamda/T)*

sum((u(t+1)-u(t)-(u(t)-u(t-1)))**2



is minimized.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

s=1600.;

call hpfilter(gasout,gast,gasdev,s);

call graph(gasout,gast,gasdev);

call hpfilter(gasout,gast2,gasdev2,0.0);

call tabulate(gasout,gast,gasdev,gast2,gasdev2);

b34srun;



HP_BP_1 Hodrich-Prescott and Baxter-King Analysis



call hp_bp_1(julian,series,name,highfreq,

lowfreq,nterms,lamda,

print,graphit,rjulian,rseries,hptrend,

hpdev,bptrend,bpdev);



Performs Hodrick - Prescott and Baxter King Analysis



julian = Julian date. If not available pass series

of zero same length as series



series = Input series



name = Character object of name



highfreq = Barter-King High Freq (6.)



lowfreq = Baxter-King Low Freq (32.)



nterms = # of terms for Baxter - King

lamda = Hodrick-Prescott Lamda 1600.



print = 0 => nothing, ne 0 => print



graphit = 0 => nothing, ne 0 => graph



rjulian = Revised julian



rseries = Revised series



hptrend = Hodrick-Prescott trend



hpdev = Hodrick-Prescott dev



bptrend = Baxter-King trend



bpdev = Baxter-King dev



HP_BP_1 is a subroutine from matrix2.mac. It must be loaded

with



call load(hp_bp_1);



Test Case: HP_BP_1



HP_BP_2 Baxter-King & Hodrick-Prescott Moving Filtering



call hp_bp_2(julian,series1,series2,nwindow,ncc,

highfreq,lowfreq,nterms,lamda,njulian,

cortrhp,cordevhp,cortrbp,cordevbp,

var1trh,var2trh,var1devh,var2devh,

var1trb,var2trb,var1devb,var2devb,

corrmat1,corrmat2,corrmat3,corrmat4);



Hodrick-Prescott and Baxter King Analysis on two series for a

moving period. The estimated Hodrick - Prescott Series are

truncated BEFORE variances and correlations are calculated.



julian => Julian date. If not available pass

series of zero same length as series



series1 = Input series



series2 = Input series



nwindow = number in window



ncc = # of lags for cross correlations



highfreq = Barter-King High Freq (6)



lowfreq = Baxter-King Low Freq (32)

nterms = # of terms for Baxter - King



lamda = Hodrick-Prescott Lamda



njulian = Revised julian vector



cortrhp = Correlation of trend HP data



cordevhp = Correlation of dev HP data



cortrbp = Correlation of trend BP data



cordevbp = Correlation of dev BP data



var1trh = Variance of series 1 trend HP data



var2trh = Variance of series 2 trend HP data



var1devh = Variance of series 1 dev HP data



var2devh = Variance of series 2 dev HP data



var1trb = Variance of series 1 trend BP data



var2trb = Variance of series 2 trend BP data



var1devb = Variance of series 1 dev BP data



var2devb = Variance of series 2 dev BP data



corrmat1 = Correlation matrix for trend HP data



corrmat2 = Correlation matrix for dev HP data



corrmat3 = Correlation matrix for trend BP data



corrmat4 = Correlation matrix for dev BP data





HP_BP_2 is a subroutine from matrix2.mac. It must be loaded

with



call load(hp_bp_2);



Test case: HP_BP_2



HP_2 Hodrick - Prescott Moving Filtering



call hp_2(series1,series2,nwindow,ncc,lamda,cortrhp,

cordevhp,var1trh,var2trh,var1devh,var2devh,

corrmat1,corrmat2,corrmat3,corrmat4);



Performs Hodrick - Prescott Anlysis on two series for a

moving period

series1 = Input series



series2 = Input series



nwindow = number in window



ncc = # cc



lamda = Hodrick-Prescott Lamda



cortrhp = Correlation of trend HP data



cordevhp = Correlation of dev HP data



var1trh = Variance of series 1 trend HP data



var2trh = Variance of series 2 trend HP data



var1devh = Variance of series 1 dev HP data



var2devh = Variance of series 2 dev HP data



corrmat1 = Correlation matrix for trend HP data



corrmat2 = Correlation matrix for dev HP data





HP_2 is a subroutine from matrix2.mac. It must be loaded with



call load(hp_2);



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;



call load(hp_2);

call print(hp_2);



julian=array(norows(gasin):);



nwindow=50;

ncc=10;

lamda=100.;



series1=gasin;

series2=gasout;

call echooff;



call hp_2(series1,series2,nwindow,ncc,

lamda,cortrhp,cordevhp,var1trh,var2trh,

var1devh,var2devh,corrmat1,corrmat2,

corrmat3,corrmat4);



call names;

call graph(var1trh,var1devh);

b34srun;





Test case: hp_2

IALEN Gen actual length of a buffer of character data



call ialen(charvar,ilen)



Gets actual length of a character*1 series





charvar = Character*1 string



ilen = position of last character



Example:



b34sexec matrix;

call character(cc,'This ends at 15 ');

call ialen(cc,ipos);

call print('Should be 15',ipos);

b34srun;



IBFOPEN Open a file for Binary I/O



call ibfopen('filename',accesscode,ihandle)



Open a file for Binary I/O



Examples:



call ibfopen('test.ff',READONLY,ihande);



call ibfopen('test.ff',WRITEONLY,ihandle);



call ibfopen('test.ff',READWRITE,ihandle);





Open file test.ff for readonly, writeonly and readwrite

respectively. The access commands READWRITE and READ require

existing files. The access command WRITEONLY will remove any

data in the file prior to writting.



Note: The file open must be accessed with the binary file I/O

subroutines:



call IBFOPEN('name',access,ihandle)

call IBFCLOSE(ihandle);

call IBFREADR(ihandle,rbuffer,ntoread,nread);

call IBFREADC(ihandle,cbuffer,ntoread,nread);

call IBFSEEK(ihandle,ipos,method);

call IBFWRITER(ihandle,rbuffer,ntowrite,nwrite);

call IBFWRITEC(ihandle,cbuffer,ntowrite,nwrite);



Properly used, these commands allow reading and processing of a

large number of file types.



Extensive example



b34sexec matrix;

/$

/$ Tests both Character and real reading and writting

/$

call ibfopen('test.ff',writeonly,ihandle);

x=rn(array(10:));

j=norows(x)*8;

call ibfwriter(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);



call ifilesize(' ','test.ff',isize);

call print('The file size for test.ff is ',isize);

xnew=array((isize/8)+1:);

call ibfopen('test.ff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call ibfreadr(ihandle,xnew,isize,ii);

call tabulate(x,xnew);

call ibfclose(ihandle);

/$

/$ Character Tests

/$

call ibfopen('test.cff',writeonly,ihandle);

call character(x,'abcdefghi');

j=norows(x);

call ibfwritec(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);



call ifilesize(' ','test.cff',isize);

call print('The file size for test.cff is ',isize);

xnew=rtoch(array((isize/8)+1:));

call character(cnew,xnew);

call ibfopen('test.cff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call names(all);

call print(cnew);

call ibfreadc(ihandle,cnew,isize,ii);

call print(x,cnew);

call ibfclose(ihandle);

call dodos('erase test.ff');

call dounix('rm test.ff');

b34srun;



IBFCLOSE Close a binary file that was opened by IBFOPEN



call ibfclose(ihandle);



Closes a file that was currently open.



Extensive example



b34sexec matrix;

/$

/$ Tests both Character and real reading and writting

/$

call ibfopen('test.ff',writeonly,ihandle);

x=rn(array(10:));

j=norows(x)*8;

call ibfwriter(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);



call ifilesize(' ','test.ff',isize);

call print('The file size for test.ff is ',isize);

xnew=array((isize/8)+1:);

call ibfopen('test.ff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call ibfreadr(ihandle,xnew,isize,ii);

call tabulate(x,xnew);

call ibfclose(ihandle);

/$

/$ Character Tests

/$

call ibfopen('test.cff',writeonly,ihandle);

call character(x,'abcdefghi');

j=norows(x);

call ibfwritec(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);



call ifilesize(' ','test.cff',isize);

call print('The file size for test.cff is ',isize);

xnew=rtoch(array((isize/8)+1:));

call character(cnew,xnew);

call ibfopen('test.cff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call names(all);

call print(cnew);

call ibfreadc(ihandle,cnew,isize,ii);

call print(x,cnew);

call ibfclose(ihandle);

call dodos('erase test.ff');

call dounix('rm test.ff');

b34srun;



IBFREADR Read a Real*1 value from a binary file



call ibfreadr(ihandle,rbuffer,ntoread,nread)



Read a real*1 value from a binary file



ihandle => File handle from ibfopen



rbuffer => Real buffer



ntoread => Number of bytes to read



nread => Actual number read



ibfseek can be used to position the read/write pointer



Extensive example



b34sexec matrix;

/$

/$ Tests both Character and real reading and writting

/$

call ibfopen('test.ff',writeonly,ihandle);

x=rn(array(10:));

j=norows(x)*8;

call ibfwriter(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);



call ifilesize(' ','test.ff',isize);

call print('The file size for test.ff is ',isize);

xnew=array((isize/8)+1:);

call ibfopen('test.ff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call ibfreadr(ihandle,xnew,isize,ii);

call tabulate(x,xnew);

call ibfclose(ihandle);

/$

/$ Character Tests

/$

call ibfopen('test.cff',writeonly,ihandle);

call character(x,'abcdefghi');

j=norows(x);

call ibfwritec(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);

call ifilesize(' ','test.cff',isize);

call print('The file size for test.cff is ',isize);

xnew=rtoch(array((isize/8)+1:));

call character(cnew,xnew);

call ibfopen('test.cff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call names(all);

call print(cnew);

call ibfreadc(ihandle,cnew,isize,ii);

call print(x,cnew);

call ibfclose(ihandle);

call dodos('erase test.ff');

call dounix('rm test.ff');

b34srun;





IBFREADC Read a Character*1 value from a binary file



call ibfreadc(ihandle,cbuffer,ntoread,nread)



Reads a character*1 value from a binary file



ihandle => File handle from ibfopen



rbuffer => Real buffer



ntoread => Number of bytes to read



nread => Actual number read



ibfseek can be used to position the read/write pointer



Extensive example



b34sexec matrix;

/$

/$ Tests both Character and real reading and writting

/$

call ibfopen('test.ff',writeonly,ihandle);

x=rn(array(10:));

j=norows(x)*8;

call ibfwriter(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);

call ifilesize(' ','test.ff',isize);

call print('The file size for test.ff is ',isize);

xnew=array((isize/8)+1:);

call ibfopen('test.ff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call ibfreadr(ihandle,xnew,isize,ii);

call tabulate(x,xnew);

call ibfclose(ihandle);

/$

/$ Character Tests

/$

call ibfopen('test.cff',writeonly,ihandle);

call character(x,'abcdefghi');

j=norows(x);

call ibfwritec(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);



call ifilesize(' ','test.cff',isize);

call print('The file size for test.cff is ',isize);

xnew=rtoch(array((isize/8)+1:));

call character(cnew,xnew);

call ibfopen('test.cff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call names(all);

call print(cnew);

call ibfreadc(ihandle,cnew,isize,ii);

call print(x,cnew);

call ibfclose(ihandle);

call dodos('erase test.ff');

call dounix('rm test.ff');

b34srun;



IBFSEEK Position Binary read/write pointer



call ibfseek(ihandle,ipos,method)



Positions the read/write pointer



ihandle => File handle from ibfopen



ipos => required position to read/write.

on exit ipos set to updated position

method => set as: FROMSTART

FROMCURRENT

FROMEND



Use of IBFSEEK allows random access of a binary file.



Extensive example



b34sexec matrix;

/$

/$ Tests both Character and real reading and writting

/$

call ibfopen('test.ff',writeonly,ihandle);

x=rn(array(10:));

j=norows(x)*8;

call ibfwriter(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);

call ifilesize(' ','test.ff',isize);

call print('The file size for test.ff is ',isize);

xnew=array((isize/8)+1:);

call ibfopen('test.ff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call ibfreadr(ihandle,xnew,isize,ii);

call tabulate(x,xnew);

call ibfclose(ihandle);

/$

/$ Character Tests

/$

call ibfopen('test.cff',writeonly,ihandle);

call character(x,'abcdefghi');

j=norows(x);

call ibfwritec(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);

call ifilesize(' ','test.cff',isize);

call print('The file size for test.cff is ',isize);

xnew=rtoch(array((isize/8)+1:));

call character(cnew,xnew);

call ibfopen('test.cff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call names(all);

call print(cnew);

call ibfreadc(ihandle,cnew,isize,ii);

call print(x,cnew);

call ibfclose(ihandle);

call dodos('erase test.ff');

call dounix('rm test.ff');

b34srun;



IBFWRITER Write noncharacter buffer on a binary file



call ibfwriter(ihandle,rbuffer,ntowrite,nwrite)



Write a noncharacter buffer of a binary file



ihandle => File handle from ibfopen



rbuffer => Real buffer



ntoread => Number of bytes to write



nread => Actual number of bytes written



ibfseek can be used to position the read/write pointer

Example



b34sexec matrix;

/$

/$ Tests both Character and real reading and writting

/$

call ibfopen('test.ff',writeonly,ihandle);

x=rn(array(10:));

j=norows(x)*8;

call ibfwriter(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);



call ifilesize(' ','test.ff',isize);

call print('The file size for test.ff is ',isize);

xnew=array((isize/8)+1:);

call ibfopen('test.ff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call ibfreadr(ihandle,xnew,isize,ii);

call tabulate(x,xnew);

call ibfclose(ihandle);

/$

/$ Character Tests

/$

call ibfopen('test.cff',writeonly,ihandle);

call character(x,'abcdefghi');

j=norows(x);

call ibfwritec(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);

call ifilesize(' ','test.cff',isize);

call print('The file size for test.cff is ',isize);

xnew=rtoch(array((isize/8)+1:));

call character(cnew,xnew);

call ibfopen('test.cff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call names(all);

call print(cnew);

call ibfreadc(ihandle,cnew,isize,ii);

call print(x,cnew);

call ibfclose(ihandle);

call dodos('erase test.ff');

call dounix('rm test.ff');

b34srun;





IBFWRITEC Write character buffer on a binary file



call ibfwritec(ihandle,cbuffer,ntowrite,nwrite)

Write character buffer on a binary file



ihandle => File handle from ibfopen



cbuffer => character buffer



ntoread => Number of bytes to write



nread => Actual number of bytes written



ibfseek can be used to position the read/write pointer



Example



b34sexec matrix;

/$

/$ Tests both Character and real reading and writting

/$

call ibfopen('test.ff',writeonly,ihandle);

x=rn(array(10:));

j=norows(x)*8;

call ibfwriter(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);



call ifilesize(' ','test.ff',isize);

call print('The file size for test.ff is ',isize);

xnew=array((isize/8)+1:);

call ibfopen('test.ff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call ibfreadr(ihandle,xnew,isize,ii);

call tabulate(x,xnew);

call ibfclose(ihandle);

/$

/$ Character Tests

/$

call ibfopen('test.cff',writeonly,ihandle);

call character(x,'abcdefghi');

j=norows(x);

call ibfwritec(ihandle,x,j,iwrite);

call print('Number of bites written ',iwrite);

call names(all);

call ibfclose(ihandle);

call ifilesize(' ','test.cff',isize);

call print('The file size for test.cff is ',isize);

xnew=rtoch(array((isize/8)+1:));

call character(cnew,xnew);

call ibfopen('test.cff',readonly,ihandle);

ipos=0;

call ibfseek(ihandle,ipos,fromstart);

call names(all);

call print(cnew);

call ibfreadc(ihandle,cnew,isize,ii);

call print(x,cnew);

call ibfclose(ihandle);

call dodos('erase test.ff');

call dounix('rm test.ff');

b34srun;



IB34S11 Parse a token using B34S11 parser



call ib34s11(string,ibase,ifbase,isize,itokty,inewp,imax)



Parses a character*1 array string



string => Character*1 string to parse from

ibase to imax. If IMAX = 0

uses end of string.



ibase => Where to start looking in string



ifbase => Location of token. = 0 if not found



isize => Size of token. If isize=0 => no token found.



itokty => Token type:



0 = unknown

1 = $

2 = (

3 = )

4 = =

5 = integer value

6 = real value

7 = var name (coded 77 if between " " and ' ')

7 is also a var string

8 = opt (such as x=log(z)$ )

9 = parm (parm=key or parm=(key1,key2) )

10 = *

11 = -

12 = +

13 = b34send

14 = /

15 = :

16 = ;

17 = .

18 = '

19 = "

20 = logical operator

21 = |

22 = {

23 = }

24 = [

25 = ]

26 = @

27 = ,





inewp => New pointer if the string has space left.

=-99 if done.



imax => Upper limit to look at. If set = 0

then the max of string used.



Note: The b34s11 routine is the main b34s parser/tokenizer.

Use of this routine allows the expert programmer to

parse a line and detect what is there, and decide

on the next step quickly. This command is of use

for a developer. Look at the getr16 and getr8 routines in

staging2.mac for how this routine might be used.



Example:



b34sexec matrix;

call character(cc,'10. 11 test y(10) jj=44 print');

ibase=1;

call echooff;

do j=1,100;

imax=0;

call ib34s11(cc,ibase,ifbase,isize,itokty,inewp,imax);

if(isize.eq.0)go to finish;

call print('ifbase found ',ifbase :line);

call print('Size of token found ',isize :line);

call print('Type of token found ',itokty :line);

call print('inewp of token found ',inewp :line);

i=integers(ifbase,ifbase+isize-1);

find=cc(i);

call character(tt,'Token found was: ');

call expand(tt,find,20,(20+isize));

call print(tt :line);

call print(' ' :line);

ibase=inewp;

if(inewp.eq.-99)go to finish;

enddo;

finish continue;

call print('All done tokenizing');

b34srun;



Application loading data using getr16 routine.



/$

/$ Reads a character array into real*16 and real*8.

/$ Tests input

/$

b34sexec matrix;



call character(cc,'

1 0 6 1

63 2 364 3

1365 4 3906 5

9331 6 19608 7

37449 8 66430 9

111111 10 177156 11

271453 12 402234 13

579195 14 813616 15

1118481 16 1508598 17

2000719 18 2613660 19

3368421 20');



call load(ntokin :staging);

call load(getr16 :staging);

call echooff;



call ntokin(cc,nfind,0,ibad);

call getr16(cc,nfind,x16,ibad);



/$ repack



xm=matrix(nfind/2,2:x16);

call print(xm);

b34srun;



IFILESIZE Determine number of bites in a file



call ifilesize('dir','fname',isize)



Determine number of bites in a file



'dir' => Directory of file



'fname' => File name



isize => size if bytes of file.

isize=0 if file not found



Example



b34sexec matrix;

call ifilesize('c:\b34slm','gas.b34',isize);

call print(isize);

b34srun;

IFILLSTR Fill a string with a character



call ifillstr(string,chr)



Fill a string with a character



string => String to fill



char => Character to place in string



Example:

b34sexec matrix;

call character(cc,'This is a string');

newcc=cc;

call ifillstr(newcc,'a');

call print(cc,newcc);

b34srun;





IGETICHAR Obtain ichar info on a character buffer



call igetichar(charvar,ival)



Obtain ichar info on a character buffer



charvar => Character*1 variable



ival => Integer*4 array of size iend-istart+1



Example



b34sexec matrix;

call character(astring,'ABCDEFG');

call igetichar(astring,ichar);

ichar2=ichar+1

call igetchari(ichar2,newstr);

call print(astring,ichar,ichar2,newstr);

b34srun;





IGETCHARI Get character from ichar value



call igetchari(ival,charvar)



Get character from ichar value



ival => Integer vector of ichar values



charvar => Characters from ival



Example



b34sexec matrix;

call character(astring,'ABCDEFG');

call igetichar(astring,ichar);

ichar2=ichar+1

call igetchari(ichar2,newstr);

call print(astring,ichar,ichar2,newstr);

b34srun;



IJUSTSTR Left/Right/center a string



call ijuststr(string,task)



Left/Right/center a string

string => String to operate on



task => task is LEFT, CENTER, RIGHT



Example:



b34sexec matrix;

call character(c,'This is a statement ');

leftc=c;

centerc=c;

rightc=c;

call ijuststr(leftc, left);

call ijuststr(centerc,center);

call ijuststr(rightc, right);

call print(c,leftc,centerc,rightc);

b34srun;



ILCOPY Move bites from one location to another



call ilcopy(nbytes,in,inc1,instart,out,inc2,ioutstart)



Move bites from one location to another



nbytes => # of bytes to move



in => input variable



inc1 => incrument for in



instart => byte to start with for in



out => out variable



inc2 => incrument for out variable



ioutstart => byte to start with for out



Variables IN and OUT must be real*8, integer*4 or real*4.



Warning: Do not use subscripted variable for out variable

since it will replaced by a temp and NOT copied.



This command allows exact placement of bits within an array

and is able to by pass the usual Fortran copy. The ILCOPY

command is intended for the expert programmer.



Example:



b34sexec matrix;

* Put in reals we know what they are;

x=array(20:integers(20));

call print(x);

call displayb(x);

x(1)=0.0; x(2)=1.0;

* Hide an integer in a real;

call displayb(x);

i1=1;

i2=2;

call ilcopy(4,i1,1,1,x,1,1);

call ilcopy(4,i2,1,1,x,1,5);

call displayb(x);

b34srun;



Note: If Character*1 data is need to be moved, use EXPAND and

CONTRACT. In place replacement can be done with:



b34sexec matrix;

* we want aabb at 5-8 in cc;

* We do not want to expand;

call character(cc,'This is a test');

call character(new,'aabb');

call contract(cc,5,8);

call expand(cc,new,5,8);

call print(cc);

b34srun;



ILOCATESTR Locate a first non blank character



call ilocatestr(string,ipos)



Cocate first non blank character



string => Character*1 string to search



ipos => position of string



Example:



b34sexec matrix;

call character(cc,' in5to11 ');

call ilocatestr(cc,in,iout);

call print(cc,in,iout);

b34srun;



ILOWER Lower case a string - 500 length max



call ilower(string)



Lower case a string - 500 length max



string => Character*1 array to lower case.

Max length 500.



Example:



b34sexec matrix;

call character(cc,'THIS IS UPPER');

lower=cc;

call ilower(lower);

upper=lower;

call iupper(upper);

call print(cc,lower,upper);

b34sreturn;





INEXTR8 Convert next value in string to real*8 variable



call inextr8(string,real8val)



Convert next value in string to real*8 variable



string => Character*1 array of max length 500.



real8val => Next real*8 value. If blank set to

missing.



Note: String is cleared.



Example:



b34sexec matrix;

call character(cc,'2.3 5. 99 Bob');

call print(cc);

call inextr8(cc,r8); call print(cc);

call inextr4(cc,r4); call print(cc);

call inexti4(cc,i4); call print(cc);

call inextstr(cc,ss,ihave); call print(cc);

call inextstr(cc,ss2,ihave2);

call print(r8,r4,i4,ss,ihave,ihave2);

b34srun;





INEXTR4 Convert next value in string to real*4 variable



call inextr4(string,real4val)



Convert next value in string to real*4 variable



string => Character*1 array of max length 500.



real4val => Next real*4 value. If blank set

-999999999.



Note: String is cleared.



Example:



b34sexec matrix;

call character(cc,'2.3 5. 99 Bob');

call print(cc);

call inextr8(cc,r8); call print(cc);

call inextr4(cc,r4); call print(cc);

call inexti4(cc,i4); call print(cc);

call inextstr(cc,ss,ihave); call print(cc);

call inextstr(cc,ss2,ihave2);

call print(r8,r4,i4,ss,ihave,ihave2);

b34srun;





INEXTSTR - Extract next blank deliminated sub-string from string



call inextstr(string,substr,ihave)



Extract next blank deliminated sub-string from a string



string - Character*1 array of max length 500.



substr - Character*1 array of substring.



ihave - =0 if have a substring, =1 if do not.



Example:



b34sexec matrix;

call character(cc,'2.3 5. 99 Bob');

call print(cc);

call inextr8(cc,r8); call print(cc);

call inextr4(cc,r4); call print(cc);

call inexti4(cc,i4); call print(cc);

call inextstr(cc,ss,ihave); call print(cc);

call inextstr(cc,ss2,ihave2);

call print(r8,r4,i4,ss,ihave,ihave2);

b34srun;





INEXTI4 - Convert next value in a string to integer



call inexti4(string,intval)



Convert next value in a string to integer



string - Character*1 array of max length 500.



intval - Next integer*4 value. If blank set

-999999999



Note: String is cleared.



Example:



b34sexec matrix;

call character(cc,'2.3 5. 99 Bob');

call print(cc);

call inextr8(cc,r8); call print(cc);

call inextr4(cc,r4); call print(cc);

call inexti4(cc,i4); call print(cc);

call inextstr(cc,ss,ihave); call print(cc);

call inextstr(cc,ss2,ihave2);

call print(r8,r4,i4,ss,ihave,ihave2);

b34srun;



INTTOSTR - Convert integer to string using format



call inttostr(int,str,fmt)



Convert integer to string using format



int - integer



str - string



fmt - up to 8 characters of format





Example:



b34sexec matrix;

call inttostr(88,is88,'(i4)');

call character(cc,'99.88D32');

call istrtor8(cc,bigr8);

call character(cc,'77');

call istrtoint(cc,is77);

xx=99.99;

call ir8tostr(xx,is99p99,'(g12.4)');

call print(is88,bigr8,is77,is99p99);

b34srun;



IR8TOSTR - Convert real*8 value to string using format



call ir8tostr(real8,str,fmt)



Convert real*8 value to string using format



real8 - Real*8 value



str - string



fmt - up to 8 characters of format



Example:



b34sexec matrix;

call inttostr(88,is88,'(i4)');

call character(cc,'99.88D32');

call istrtor8(cc,bigr8);

call character(cc,'77');

call istrtoint(cc,is77);

xx=99.99;

call ir8tostr(xx,is99p99,'(g12.4)');

call print(is88,bigr8,is77,is99p99);

b34srun;





ISTRTOR8 - Convert string to real*8



call istrtor8(string,real8)



Convert string to real*8



string - string



real8 - Real*8 value



Example:



b34sexec matrix;

call inttostr(88,is88,'(i4)');

call character(cc,'99.88D32');

call istrtor8(cc,bigr8);

call character(cc,'77');

call istrtoint(cc,is77);

xx=99.99;

call ir8tostr(xx,is99p99,'(g12.4)');

call print(is88,bigr8,is77,is99p99);

b34srun;



ISTRTOINT - Convert string to integer



call istrtoint(string,int)



Convert string to integer.



string - string



int - integer that was in string



Example:



b34sexec matrix;

call inttostr(88,is88,'(i4)');

call character(cc,'99.88D32');

call istrtor8(cc,bigr8);

call character(cc,'77');

call istrtoint(cc,is77);

xx=99.99;

call ir8tostr(xx,is99p99,'(g12.4)');

call print(is88,bigr8,is77,is99p99);

b34srun;



IUPPER - Upper case a string - 500 length max



call iupper(string)

Upper case a string - 500 length max



string - Character*1 array to upper case Max length 500.



Example:



b34sexec matrix;

call character(cc,'THIS IS UPPER');

lower=cc;

call ilower(lower);

upper=lower;

call iupper(upper);

call print(cc,lower,upper);

b34sreturn;



ISEXTRACT - Place data in a structure.



call isextract(n(2),data);



Places DATA into a structured object n in location 2.





An optional form:



call isextract(n(2),data,i);



places data into the ith location. The name isextract is

the inverse of command sextract. The function call



g=sextract(n(2));



and



g=sextract(n(2),i);



can be used to take all the data or element i out of

the structure.



Example:



b34sexec matrix;

people=namelist(pname,ssn,age,race,income);

pname =namelist(sue,joan,bob);

ssn =array(:99,9821,22);

age =idint(array(:35,45,58));

race =namelist(hisp,white,black);

income=array(:40000,35000,50000);

call tabulate(pname,ssn,age,race,income);

call print(sextract(people(3)));

call print('Second person',sextract(people(1),2),

sextract(people(3),2));

nage=age+1;

call isextract(people(3),nage);

call print(age);

call isextract(people(3),77,1);

call print(age);

b34srun;



I_RNOPG - Gets the type of generator currently in use.



call i_rnopg;



Prints the type of IMSL random generator and current recver

and rnver settings.



The alternative form



call i_rnopg(i);



produces an integer in range 1-7.



1 => multiplier 16807 with no shuffling



2 => multiplier 16807 with shuffling



3 => multiplier 397204094 with no shuffling



4 => multiplier 397204094 with shuffling



5 => multiplier 950706376 with shuffling



6 => multiplier 950706376 with no shuffling



7 => GFSR with recursion



To get info on the current settings of RECVER and RNVER, add

one to two more arguments



call i_rnopg(i,recver);



or



call i_rnopg(i,recver,rnver);



Example:



b34sexec matrix;

call i_rnopg;

call echooff;

do i=1,7;

call i_rnopt(i);

call i_rnopg;

call i_rnopg(j);

if(i.ne.j)then;

call epprint('ERROR: i_rnopt and i_rnopg not correct');

call epprint('sett was ',i,' return was ',j);

endif;

enddo;

call i_rnopg(ii,recver,rnver);

call print('imsl code ',ii,recver,rnver);

b34srun;





I_RNOPT - Selects the type of uniform (0,1) generator.



call i_rnopt(i);



Selects the type of random number generator in use for I_xxxx

series calls. i must be in range 1-7



1 => multiplier 16807 with no shuffling



2 => multiplier 16807 with shuffling



3 => multiplier 397204094 with no shuffling



4 => multiplier 397204094 with shuffling



5 => multiplier 950706376 with shuffling



6 => multiplier 950706376 with no shuffling



7 => GFSR with recursion



Example:



b34sexec matrix;

call i_rnopg;

call echooff;

do i=1,7;

call i_rnopt(i);

call i_rnopg;

call i_rnopg(j);

if(i.ne.j)then;

call epprint('ERROR: i_rnopt and i_rnopg not correct');

call epprint('sett was ',i,' return was ',j);

endif;

enddo;

b34srun;



I_RNSET - Sets seed used in IMSL Random Number generators.



call i_rnset(ii);



Sets the seed for the IMSL random number generators;



Example:



b34sexec matrix;

call i_rnget;

call i_rnget(ii);

call print('Seed was ',ii);

call i_rnset(3452);

call i_rnget;

b34srun;



I_DRNSES - Initializes the table for shuffled generators.



call I_drmses(table);



Sets the internal sfuffle table. Table must be exactly 128

elements in the range 0.0 to 1.0. If table(1) is set le 0.0,

then table is NOT used to set the suffled generarator and the

first 128 calls to the generator are used to set the table.



Example:



b34sexec matrix;

table=rec(array(128:));

call i_drnses(table);

call i_drnges(table2);

call tabulate(table,table2);

b34srun;



I_DRNGES - Get the table used in the shuffled generators.



call i_drnges(table);



Obtains the table for the shuffled generator. The objective is

to save the current table and reload it to start the generator

again. The command:



call i_dgnses(table);



will reload the table.



Example:



b34sexec matrix;

table=rec(array(128:));

call i_drnses(table);

call i_drnges(table2);

call tabulate(table,table2);

b34srun;



I_DRNUN - Uniform (0,1) Generator



call i_drnun(x);



Fills x with uniform numbers using the currently selected IMSL

generator. The commands



x=array(10:);

x=rn(x:imsl10);



are the same as

call i_rnset(1);

call i_drnun(x);



Example:



b34sexec matrix;

* IMSL test case;

call i_rnset(123457);

x=array(5:);

call i_drnun(x);

call print('answers should be'

' .9662 .2607 .7663 .5693 .8448');

call print(x);

n=300;

x=array(n:);

call i_drnun(x);

call graph(x :heading 'random numbers');

b34srun;





I_DRNNOA - Random Normal Distribution - Acceptance / Rejection



call i_drnnoa(x);



Generates random numbers from standard nornal distribution

using acceptance / rejection method.



x = Real*8 object



Example:



b34sexec matrix;

* problem from IMSL ;

x=array(5:);

call i_rnset(123457);

call i_drnnoa(x);

call print('answers should be ',

' 2.0516 1.0833 .0826 1.2777 -1.2260',x);

x=array(500:);

call i_drnnoa(x);

call graph(x :Heading 'Random Normal Values');

b34srun;



I_DRNNOR - Random Normal Distribution - CDF Method



call i_drnnor(x);



Generates random numbers from standard nornal distribution

using an inverse cdf method.



Example:



b34sexec matrix;

* problem from IMSL ;

x=array(5:);

call i_rnset(123457);

call i_drnnor(x);

call print('answers should be ',

' 1.8279 -.6412 .7266 .1747 1.0145',x);

x=array(500:);

call i_drnnor(x);

call graph(x :Heading 'Random Normal Values');

b34srun;





I_DRNBET - Random numbers from beta distribution



call i_drnbet(bet,p,q);



Calculates the beta (p,q) distribution in bet.



bet = real*8 array / vector



p = real*8 variable gt 0.0



q = real*8 variable gt 0.0



Example:



b34sexec matrix;

* Test problem from IMSL;

p=3.;

q=2.;

n=5;

beta=array(n:);

call i_rnset(123457);

call i_drnbet(beta,p,q);

call print('Beta(3. 2.) Distribution',

'Answers should be .2814 .9483 .3984 .3103 .8296',beta);

b34srun;



I_DRNCHI - Random numbers from Chi-squared distribution



call i_drnchi(chisq,df);



Calculates a random chi-squared distributiion



chisq = real*8 vector or array that contains

chi-squared distribution



df = real*8 variable GT 0.0 containing

degress of freedom.



Example:



b34sexec matrix;

* Test problem from IMSL;

df=5.;

n=5;

chisq=array(n:);

call i_rnset(123457);

call i_drnchi(chisq,df);

call print('Chisq Distribution',

'Answers should be 12.0900 .4808 1.7976 14.8712 1.7477',

chisq);

b34srun;



I_DRNCHY - Random numbers from Cauchy distribution



call i_drnchy(cauchy);



Places random variables from the cauchy distribution in cauchy.



cauchy - Size of cauchy must be set.



Example:



b34sexec matrix;

* Test problem from IMSL;

n=5;

cauchy=array(n:);

call i_rnset(123457);

call i_drnchy(cauchy);

call print('Cauchy Distribution',

'Answers should be 3.5765 .9353 15.5797 2.0815 -.1333',

cauchy);

b34srun;



I_DRNEXP - Random numbers from standard exponential



call i_drnchy(expdis);



Places random variables from the standard exponential

distribution in expdis.



expdis - Size of expdis must be set.



Example:



b34sexec matrix;

* Test problem from IMSL;

n=5;

expdis=array(n:);

call i_rnset(123457);

call i_drnexp(expdis);

call print('Exponential Distribution',

'Answers should be .0344 1.3443 .2662 .5633 .1686',

expdis);

b34srun;



I_DRNEXT - Random numbers from mix of exponential distributions

call i_drnext(mexp,theta1,theta2,p);



Places in mexp the mixture of two exponential distributions

having mean theta1 and theta2.



mexp = real*8 vector / array containing distribution



theta1 = real*8 mean of dsitribution 1



theta2 = real*8 mean of distribution 2

theta2 gt 0.0 and le theta1



p = real*8 mixing parameter.

p le (theta1/(theta1-theta2))



f(x) = (p/theta1)*exp(-1/theta1) +

((1.0-p)/theta2)*exp(-x/theta2)



Example:



b34sexec matrix;

* Test problem from IMSL;

n=5;

theta1=2.0;

theta2=1.0;

p=.5;

mexp=array(n:);

call i_rnset(123457);

call i_drnext(mexp,theta1,theta2,p);

call print('Mixture of two Exponentials',

'Answers should be .0700 1.3024 .6301 1.9756 .3716',mexp);

b34srun;



I_DRNGAM - Random numbers from standard gamma distribution



call i_drngam(gamma,a);



Generates a gamma distribution



gamma = real*8 vector / array containing the distribution



a = Shape parameter for distribution. a gt 0.0



Example:



b34sexec matrix;

* Test problem from IMSL;

n=5;

a=3.0;

gamma=array(n:);

call i_rnset(123457);

call i_drngam(gamma,a);

call print('Gamma Distribution',

'Answers should be 6.8428 3.4452 1.8535 3.9992 .7794',

gamma);

b34srun;



I_DRNGCT - Random numbers from general continuous distribution



call I_drngct(rx,x,cdf);



Generates random numbers from a general continuous

distribution where the user supplies the CDF and the x range.



rx = real*8 array containing the random numbers.



x = real*8 array containing range over which CDF

is evaluated.



cdf = real*8 array containing cumulative density

function evaluated at x values. cdf must

contain the same number of elements as

x. First and last elements must be 0.0 and

1.0. At least 4 elements must be supplied.



This command allows generation of randon numbers from any

continuous distrubution provided that the cdf is known.



Example:



b34sexec matrix;

* Problem from IMSL. Tests Berta(3.,2.) distribution;

x = grid(0.0,1.,.01);

pp = array(norows(x):)+3.;

qq = array(norows(x):)+2.;

cdf=betaprob(x,pp,qq);

call tabulate(x,cdf);

call i_rnset(123457);

n=5;

xr=array(n:);

call i_drngct(xr,x,cdf);

call print('Test values should be',

'.9208 .4641 .7668 .6536 .8171',xr);

* Graph a bigger case ;

n=500;

xr=array(n:);

call i_drngct(xr,x,cdf);

call graph(xr :heading

'Random Numbers from Beta(3.,2.) using i_drngct');

b34srun;



I_DRNGDA - Random integers from discrete dist. alias approach



call i_drngda(ir,imin,pf);



Generates random numbers from a discrete distribution using

the alias approach.

ir = integer*4 vector containing random discreate

deviates.



imim = integer*4 value showing value of deviate for

pf(1).



pf = real*8 vector that sums to 1.0 containing the

probabilities



Example:



b34sexec matrix;

* Sample problem from IMSL;

imin=1;

n=5;

ir=idint(array(n:));

pf=array(:.05 .45 .31 .04 .15);

call i_rnset(123457);

call i_drngda(ir,imin,pf);

ir2=ir;

call i_drngda(ir2,imin,pf);

call print('Random integers Disc. Dist. - Alias Approach',

'Test values should be 3 2 2 3 5',ir,

'and 1 3 4 5 3',ir2);

b34srun;





I_DRNGDT - Random integers from discrete using table lookup



call i_drngdt(ir,imin,pf);



Generates random numbers from a discrete distribution using

the table lookup approach.



ir = integer*4 vector containing random discreate

deviates



imim = integer*4 value showing value of deviate for

pf(1).



pf = real*8 vector that sums to 1.0 containing the

probabilities



Example:



b34sexec matrix;

* Sample problem from IMSL;

imin=1;

n=5;

ir=idint(array(n:));

pf=array(:.05 .45 .31 .04 .15);

call i_rnset(123457);

call i_drngdt(ir,imin,pf);

call print(

'Random integers Discrete Dist. - Table Approach',

'Test values should be 5 2 3 3 4',ir);

b34srun;





I_DRNLNL - Random numbers from lognormal distribution



call i_drnlnl(lognorm,xmean,xsd);



Generates lognormal random variables in lognorm.



lognorm = real*8 array.



xmean = real*8 mean of distribution.



xsd = real*8 standard deviation of distribution.

xsd must be GT 0.0.



Example:



b34sexec matrix;

* Test problem from IMSL;

n=5;

xmean=0.0;

xsd=1.0;

lognorm=array(n:);

call i_rnset(123457);

call i_drnlnl(lognorm,xmean,xsd);

call print('Log Normal Distribution',

'Answers should be 7.7801 2.9543 1.0861 3.5885 .2935',

lognorm);

b34srun;



I_DRNMVN - Random numbers from multivariate normal



call i_drnmvn(r,rsig);



Generates random numbers from a multivariate normal

distribution.



r = real*8 2 dimensional object with nr rows and k

columns. R will contain the random multivariate

normal vectors in its rows.



rsig = real*8 upper triangular Cholesky factorization

of the covariance matrix.





This command can be used to draw random samples having the

same covariace structure.



Example:

b34sexec matrix;

* Problem from IMSL;

nr=5;

k=2;

r=array(nr,k:);

cov=array(k,k:.5 .375 .375 .5);

rsig=pdfac(cov);

call print(rsig);

call i_nrset(123457);

call i_drnmvn(r,rsig);

call print('Multivariate Normal Deviates'

'Col 1 1.4507 .7660 .0584 .9035 -.8669'

'Col 2 1.2463 -.0429 -.6692 .4628 -.9334',r);

b34srun;





I_DRNSTA - Random numbers from stable distribution



call i_drnsta(sta,alpha,bprime);



Generates random numbers from a stable distribution.



sta = real*8 vector having the random numbers.



alpha = real*8 characteristic exponent of stable

distribution. 0.0 lt alpha le 2.0



bprime = real*8 skewness parameters of stable

distribution. bprime ge -1.0 and le 1.0



when alpha = 1.0 => bprime - skewness parameter



when alpha ne 1.0 then



bprime = -tan((pi()/2.0)*(1.-alpha))*tan((-1*(pi()/2.)*

b*(1.-dabs(1.-alpha)))



For futher detail see IMSL manual.



Example:



b34sexec matrix;

* Test problem from IMSL;

n=5;

sta=array(n:);

call i_rnset(123457);

alpha=1.5;

bprime=0.0;

call i_drnsta(sta,alpha,bprime);

call print('Stable Distribution',

'Answers should be 4.4091 1.0564 2.5463 5.6724 2.1656',

sta);

n=500;

sta=array(n:);

call i_drnsta(sta,alpha,bprime);

call graph(sta :heading 'Stable Distribution');

b34srun;



I_DRNTRI - Random numbers from triangular distribution



call i_drntri(tri);



Calculates triangular distribution.



For 0 le x le .5 f(x)=4*x

for .5 lt x le 1. f(x)= 4*(1.-x)



Example:





b34sexec matrix;

* Test problem from IMSL;

n=5;

tri=array(n:);

call i_rnset(123457);

call i_drntri(tri);

call print('Triangular Distribution',

'Answers should be .8700 .3610 .6581 .5360 .7215',tri);

n=500;

tri=array(n:);

call i_drntri(tri);

call graph(tri :heading 'Triangular Distribution');

b34srun;



I_DRNSPH - Random numbers on the unit circle



call i_drsph(r);



Calculates random numbers on the unit circle

where r = a n by k 2 dimensional object. Numbers are placeed

in a circle of dimension k



Example:



b34sexec matrix;

* problem from IMSL;

n=2;

k=3;

r=array(n,k:);

call i_rnset(123457);

call i_drnsph(r);

call print('Random points on unit circle'

'Row 1 .8893 .2316 .3944'

'Row 2 .1901 .0396 -.9810',r);

b34srun;



I_DRNVMS - Random numbers from Von Mises distribution

call i_drnvms(vm,c);



Calculates the Von Mises distribution



vm = real*8 array con taining randon numbers



c = Von Mises parameter c ge .0001



Example:



b34sexec matrix;

* Test problem from IMSL;

n=5;

vm=array(n:);

c=1.0;

call i_rnset(123457);

call i_drnvms(vm,c);

call print('Von Mises Distribution',

'Answers should be .2472 -2.4326 -1.0216 -2.1722 -.5029'

vm);

n=500;

vm=array(n:);

call i_drnvms(vm);

call graph(vm :heading 'Von Mises Distribution');

b34srun;



I_DRNWIB - Random numbers from Weibull distribution



call i_drnwib(wb,a);



Generates random numbers from the Weibull distribution having

shape parameter a



wb = real*8 array containing random numbers



a = real*8 Weibull shape parameter. a GT 0.0



The probability density is



f(x)=a*(X**(a-1.)) *dexp(-1*x**a)



The Rayleigh distribution is the same as the Weibull with

a = 2. and scale parameter dsqrt(2)*a



Example:



b34sexec matrix;

* Test problem from IMSL;

n=5;

wb=array(n:);

a=2.0;

scale=6.;

call i_rnset(123457);

call i_drnwib(wb,a);

wb=wb*scale;

call print('Weibull Distribution',

'Answers should be 1.1122 6.9567 3.0959 4.5031 2.4638',

wb);

n=500;

wb=array(n:);

call i_drnvms(wb,a);

wb=wb*scale;

call graph(wb :heading 'Weibull Distribution');

b34srun;





I_RNBIN - Random integers from binomial distribution



call i_rnbin(ir,n,p);



Calculates integers from the binomial distribution where



ir = integer vector



n = number of Bernoulli trials



p = parbability of success. probs . 1.0





Given F(i,j) = [i/j]



f(x) = F(n,x) * (p**x)*((1-p)**(n-x))



Example:



b34sexec matrix;

* Problem from IMSL ;

ir=idint(array(5:));

ntrials = 20;

probs = .5;

call i_rnset(123457);

call i_rnbin(ir,ntrials,probs);

call print('answers should be 14 9 12 10 12',ir,

'Number of trials ',ntrials,

'Probability of Success ',probs);

b34srun;



I_RNGET - Gets seed used in IMSL Random Number generators.



call i_rnget;



Displays the IMSL seed that has been set.



The alternative call



call i_rnget(ii);



will place the seed in ii.

Example:



b34sexec matrix;

call i_rnget;

call i_rnget(ii);

call print('Seed was ',ii);

call i_rnset(3452);

call i_rnget;

b34srun;



I_RNHYP - Random integers from Hypergeometric distribution



call i_rnhyp(ii,n,m,l);



Calculates pseudorandom integers in ii from a hypergeometric

distribution where



ii = integer vector



n = Number of items in the sample



m = Number of special items in the population



l = Number of items in the lot. l > m and l > n.



Given F(i,j) = [i/j]



f(x) = F(m,x)*f((l-m),n-x))/F(l,n)



for x=max(0,n-l+m),1,2,min(n,m)



For futher help see IMSL documentation.



Example:



b34sexec matrix;

* Sample problem from IMSL ;

ii=idint(array(5:));

call i_rnset(123457);

n=4; m=12; l=20;

call i_rnhyp(ii,n,m,l);

call print('Should be 4 2 3 3 3 ',ii,

'Items in sample ',n,

'Special items in population ',m,

'Number of items in lot ',l);

b34srun;





I_RNGEO - Random integers from Geometric distribution



call i_rngeo(ir,p) ;



Generates random integers in ir from the Geometric distribution

having probability p.



ir = integer vector



p = Probability of success. p Integer*4 matrix of size nr by j.

nr = # of random nornal vectors to generate.

k = # of possible outcomes



n => # in indepent trials



p => vector of length containing probabilities.



Example:



b34sexec matrix;

* Test problem from IMSL;

nr=5;

k=3;

ir=idint(array(nr,k:));

n=20;

p=array(k:.1 .3 .6);

call i_rnset(123457);

call i_rnmtn(ir,n,p);

call print('Multinomial distribution',

'Answers should be:',

'col 1 5 3 3 5 4'

'col 2 4 6 3 5 5'

'col 3 11 11 14 10 11'

ir);

b34srun;

I_RNNBN - Negative binomial dsitribution



call i_rnnbn(ii,r,p);



Generates random numbers from a negative binomial distribution.



ii = integers generated



r = negative binomial distribution parameter.

r must be real*8 and > 0.0



p = probability of success on each trial.

p must be real*8 and in range [0.0 to 1.0]



If r is an integer real*8 value, we have the Pascal

distribution. For further information, see IMSL documentation.



Example:



b34sexec matrix;

* Test problem from IMSL;

* Since R is an integer we have a Pascal distribution;

r=4.;

p=.3;

n=5;

i=idint(array(n:));

call i_rnset(123457);

call i_rnnbn(ii,r,p);

call print('Pascal Distribution',

'Answers should be 5 1 3 2 3',ii);

b34srun;

I_RNPER - Random perturbation of integers



call i_rnper(ii);



Will randomly pertibate the integers from 1-k where



k = norows(ii);



Example:



b34sexec matrix;

* Test problem from IMSL;

n=10;

ii=idint(array(n:));

call i_rnset(123457);

call i_rnper(ii);

call print('Random Pertibation of Integers',

'Answers should be 5 9 2 8 1 6 4 7 3 10',ii);

b34srun;



I_RNSRI - Index of random sample without replacement



call i_rnsri(ii,npop);

Generates a vector of k integer indices in ii from a population

of npop where k=norows(ii)



ii = integer vector of the subsample indices



npop = integer showing size of population.

npop GT norows(ii)



This command is an alternative to



ii=booti(ii);



which uses replacement.



b34sexec matrix;

* Test problem from IMSL;

nsamp=5;

npop =100;

ii=idint(array(nsamp:));

call i_rnsri(ii,npop);

call print('Random Sample of Indices without replacement'

'Answer should be 2 22 53 61 79',ii);

b34srun;



KEENAN - Keenan Nonlinearity test



call keenan(x,keen,ip)



Calculates Keenan (1985) test for linearity.



x = real*8 series



keen = Keenan test



ip = Order of test (integer*4)



prob = Optional argument for probability



call keenan(x,keen,ip,prob)



Example:



b34sexec matrix;

call echooff;

call loaddata;

do i=2,18;

call keenan(gasout,tt,i,pp);

j=i-1;

test(j) =tt;

prob(j) =pp;

order(j) =i;

enddo;

call print('Keenan (1985) Test of Gasout Series');

call tabulate(order,test,prob);

b34srun;



KSWTEST - K Period Stock Watson Test



subroutine kswtest(x,vbegin1,vend1,nlag,nterms,

iprint,iprint2);



Generate k by k Stock Watson Test Statistics



X = Data to be Analysed. X is 1D or 2D array/Matrix



vbegin1 = vector/array of subperiod beginning points.

vbegin1 is integer*4.



vend1 = vector/array of subperiod ending points.

vend1 is integer*4.



Note: Three terms in vbegin1 and vend1 assumes three

periods. Will run period 1-2 & period 2-3



nlag = # of AR lags



nterms = # of MA terms



iprint = Controls printing in SWARTEST. Usually = 0.



iprint2 = Controls printing in kswtest.

= 1 to print in kswtest

= 0 to save data in global variable.

=-1 to print and save data.



Optional data saved:



%var_i = Variance of Series



%varh_i = Variance of yhat



%rsq_i = R**2 of series



%fac_i = Test Statistics



%dfac_i = Difference of factural



%dstr_i = Difference in counter factural Structure



%dvar_i = Difference in counter factural variance



Note: Optional data for orders > # series not cleaned.



Developed 24 April 2003 by Jin-Man Lee

Refinements made by Houston H. Stokes



Routines needed: buildlag, varest, swartest

Example:



b34sexec options ginclude('gas.b34'); b34srun$



b34sexec matrix;

call load(buildlag);

call load(varest);

call load(swartest);

call load(kswtest);



nlag = 8;

nterms =20;

iprint = 0;

iprint2= 1;



call get(gasin,gasout :dropmiss);



vbegin1 = index( 1 100 190);

vend1 = index( 99 189 296) ;

x = mfam(catcol(gasin,gasout));

call echooff;

call kswtest(x,vbegin1,vend1,nlag,nterms,

iprint,iprint2) ;



x=gasout;

call kswtest(x,vbegin1,vend1,nlag,nterms,

iprint,iprint2) ;

b34srun ;



KSWTESTM - Moving Period Stock Watson Test



subroutine kswtestm(x,vbegin1,vend1,vbegin2,vend2,

nlag,nterms,iprint,iprint2);



Generate k Stock Watson Test Statistics.

This code is made for a moving window application.



X = Data to be Analysed. X is 1D or 2D array/Matrix



vbegin1 = vector/array of subperiod beginning

points integer*4



vend1 = vector/array of subperiod endinf

points integer*4



vbegin1 = vector/array of subperiod beginning

points integer*4



vend1 = vector/array of subperiod endinf

points integer*4



nlag = # of AR lags

nterms = # of MA terms



iprint = Controls printing in SWARTEST. Usually = 0.



iprint2 = Controls printing in kswtest.

= 1 to print in kswtest

= 0 to save data in global variable.

=-1 to print and save data.



Optional data saved:





%T11___1 Period 1 structure period 1 variance



%T12___1 Period 1 structure period 2 variance



%T22___1 Period 2 structure period 2 variance



%T21___1 Period 2 structure period 1 variance



%VAR1__1 Actual variance period 1 series 1



%VAR2__1 Actual Variance period 2 series 1



%RSQ1__1 R**2 period 1 series 1



%VARH1_1 Variance of yhat period 1 series 1



%VARH2_1 Variance of yhat period 2 series 1



%RSQ2__1 R**2 period 2 series 1



%DFAC__1 dabs(t11-t22)



%DVAR1_1 dabs(t11-t12)



%DVAR2_1 dabs(t21-t22)



%DSTR1_1 dabs(t11-t21)



%DSTR2_1 dabs(t22-t12)



Developed 24 April 2003 by Jin-Man Lee & Houston H. Stokes

This code is a moving window variant of kswtest.



Routines needed: buildlag, varest, swartest



Example:



/$

/$ This example will produce kswtestm results that

/$ can be checked with kswtest example output



b34sexec options ginclude('gas.b34'); b34srun$

b34sexec matrix;

call load(buildlag);

call load(varest);

call load(swartest);

call load(kswtestm);



nlag = 8;

nterms =20;

iprint = 0;

iprint2= 1;



call get(gasin,gasout :dropmiss);



vbegin1 = index( 1 100);

vend1 = index( 99 199) ;

vbegin2 = index(100 200);

vend2 = index(199 296) ;

x = mfam(catcol(gasin,gasout));

call echooff;

call kswtestm(x,vbegin1,vend1,

vbegin2,vend2,nlag,nterms,

iprint,iprint2) ;

/$ call names(all);

call print(%t11___1

%T12___1

%T22___1

%T21___1

%VAR1__1

%VAR2__1

%RSQ1__1

%VARH1_1

%VARH2_1

%RSQ2__1

%DFAC__1

%DVAR1_1

%DVAR2_1

%DSTR1_1

%DSTR2_1

%t11___2

%t12___2

%t22___2

%t21___2

%VAR1__2

%VAR2__2

%RSQ1__2

%VARH1_2

%VARH2_2

%RSQ2__2

%DFAC__2

%DVAR1_2

%DVAR2_2

%DSTR1_2

%DSTR2_2 );

x=gasout;

call kswtestm(x,vbegin1,vend1,nlag,nterms,

iprint,iprint2) ;

/$ call names(all);

call print(%t11___1

%T12___1

%T22___1

%T21___1

%VAR1__1

%VAR2__1

%RSQ1__1

%VARH1_1

%VARH2_1

%RSQ2__1

%DFAC__1

%DVAR1_1

%DVAR2_1

%DSTR1_1

%DSTR2_1);



b34srun;

LAGTEST Use 3-D Graph to display RSS for Lags



call lagtest(y,x,ylag,xlag,nsubsets,rss);



Purpose: Use 3-D Graph to display RSS for alternative lags of

OLS model.



y => y-variable



x => x-variable



ylag => # lags on y



xlag => # lags on x



nsubsets => # subsets





Runs model



y=f(y(t-1),...,y(t-ylag),x(t-1),...,x(t-xlag))



Displays 3-D Residual sum of squares surface



Example



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;

call load(lagtest);

call echooff;

ylag = 12;

xlag = 12;

nsubsets = 3;



call lagtest(gasout,gasin,ylag,

xlag,nsubsets,rss);



call checkpoint;

b34srun;



LAGTEST2 3-D Graph to display RSS for Various MARS Lags



call lagtest2(y,x,ylag,xlag,nsubsets,mi,nk,rss);



Purpose: Use 3-D Graph to display RSS for alternative lags of

MARS Model.



y => y-variable



x => x-variable



ylag => # lags on y



xlag => # lags on x



nsubsets => # subsets



mi => # interactions



nk => # knots



rss => rss matrix





Example



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;

call load(lagtest2);

call echooff;



ylag = 12;

xlag = 12;

nsubsets = 3;

nk=20;

mi=2;





call lagtest2(gasout,gasin,ylag,

xlag,nsubsets,mi,nk,rss);

call checkpoint;

b34srun;



LM - Engle Lagrange Multiplier ARCH test.



call lm(x,lm,iorder)



Returns Engle LM test for order iorder in lm.



Added option to return the probability



Example:



call lm(x,lm,iorder,prob);



LAGMATRIX - Lags variables and builds a matrix.





call lagmatrix(x{1 to 6} xx{8} :matrix mm)



Builds a matrix mm that aligns x and xx given specified

lags. All series must contain the same number of observations

initially. This command works for real*8 and real*16 data.



:matrix kk



Specifies the output matrix. The default name is %matrix.



:sample mask - Specifies a mask real*8 variable that

if = 0.0 drops that observation.



:holdout - Sets # of observations to drop.



Note: :sample cannot be used with :holdout.



:noint Will not build a constant in position k+1



Variables built:



%lmatvar - variable name of col of matrix.



%lmatlag - Lag of variable.



%xfobs - Observation number of future data



%xfuture - Same as %matrix but for out of

sample data if that is available



%k - Number of cols is %matrix



%noblags - Number of observations in %matrix



Example

b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call lagmatrix(gasin{1 to 6} gasout{4 to 8}

:matrix mm);

call tabulate(gasin,gasout);

call print(mm);

call tabulate(%lmatvar,%lmatlag);

call print(%xfobs,%xfuture,%k,%noblags);

b34srun;



Use LAGMATRIX to generate an input matrix for MARS forecast.

See MARS_8 job.



/$ Out of sample MARS Modeling when lags

/$ Illustrates use of lagmatrix

b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

call loaddata;



* build the matrix for forecasts;

* Variables must be what is supplied ;

* Note that mars does not have to supply a constant;



call lagmatrix(gasin{1 to 6} gasout{1 to 6} :noint );

hfuture=%xfuture;

call names(all);

call print(%xfuture);

call tabulate(%lmatvar,%lmatlag);



call mars(gasout gasin{1 to 6} gasout{1 to 6} :print

:forecast hfuture);



call print(%fore,%foreobs);

call mars(gasout gasin{1 to 6} gasout{1 to 6}

:nk 80 :mi 3 :print

:forecast hfuture);

call names(all);

call print(%fore,%foreobs);

b34srun;



LAPACK - Sets Key LAPACK parameters



call lapack;



Shows current settings



call lapack(:reset);



Resets lapack.





Where -11 le i1 le -1

call lapack(i1,i2);



obtains setting in i2.



While 1 le i1 le 11



call lapack(i1,i2);



Sets key internal LAPACK parameters.





1: the optimal blocksize if this value is 1,

an unblocked algorithm will give the best performance.



2: the minimum block size for which the block routine

should be used; if the usable block size is less than

this value, an unblocked routine should be used.



3: the crossover point (in a block routine, for N less

than this value, an unblocked routine should be used)



4: the number of shifts, used in the nonsymmetric

eigenvalue routines



5: the minimum column dimension for blocking to be used;

rectangular blocks must have dimension at least k by

m, where k is given by ILAENV(2,...) and m by

ILAENV(5,...)



6: the crossover point for the SVD (when reducing an m by

n matrix to bidiagonal form, if max(m,n)/min(m,n)

exceeds this value, a QR factorization is used first

to reduce the matrix to a triangular form.)



7: the number of processors



8: the crossover point for the multishift QR and QZ

methods for nonsymmetric eigenvalue problems.



9: maximum size of the subproblems at the bottom of the

computation tree in the divide-and-conquer algorithm.



10: ieee NaN arithmetic can be trusted not to trap (1).



11: infinity arithmetic can be trusted not to trap (1).





Note: When the matrix command is called, LAPACK is initialized

to the default settings;



LOAD - Load a Subroutine from a library.



call load(name,'test.mac');

Loads name from library test.mac.



call load(pv1);



will load member pv1 from the default matrix subroutine

library which is matrix2.lib



call load(kk :staging);



will load routine kk from staging2.mac library. An alternative

call that is not portable across platforms is



call load(kk 'c:\b34slm\staging2.mac');



The command



call load(dsp_acf :wbsuppl);



can be used in place of



call load(dsp_acf 'c:\b34slm\wbsuppl.mac');



to be portable across computer systems.



wbsuppl.mac is a library of routiners developed by William

Lattyak as part of the SCA Workbench project that provides a

front end to B34S. The calls in wbsuppl can be subject to

change. At present there are no "example" files for wbsuppl

subroutines.



Load can be used to load user programs, functions and

subroutines. Use of load saves on parse time and most important

does not run into the command size limits that occur is the

subroutines are loaded with the command file..



Files matrix2.mac and staging2.mac contains routines supplied

with b34s. The help for routines in matrix2.mac is contained in

in help files inside the routine and in the b34shelp.dat file.

Help for routines in staging2.mac is only in the routine. It is

the intention to provide help inside the wbsuppl.mac files.



Files matrix.mac and staging.mac contains complete examples on

the use of these routines.



LOADDATA - Load Data from b34s into MATRIX command.



call loaddata;



Loads all current b34s variables into the matrix command

workspace. If the data is a time series of frequency 1, 4 or 12

then a julian variable bjulian_ is created.



For an alternative approach, see related command

call get( )



to load one series.



LPMAX - Solve Linear Programming maximization problem.





call lpmax(c,a,b,q);



Allows solution of simple LP maximization problems of the form:



primal



max c'*x



s.t. A*x LE b



dual



A'W ge C'



min B'W



c = vector of m prices



a = constraint matrix m by n



b = input vector of n inputs



q = number of equality constraints at end.



All 4 arguments must be supplied.



If :print is supplied, the solution will be printed.



Variables created:



%lpmax = objective



%primal = x vector of size m



%dual = w vector of size n (shadow prices)



Lpmax uses the same routine as the LPMAX command and provides

an easy way to solve a LP maximization problem.



Example:



User wants to solve



Max x1 + 3*x2



Such that

x1 le 1

x2 le 1

x1 + x2 le 1.5

-x1 - x2 le -.5

x1 ge 0

x2 ge 0



b34sexec matrix$

n=0;

a=matrix(4,2: 1.0 0.

0. 1.

1. 1.

-1. -1.);

b=vector( : 1., 1. 1.5, -.5)$

c=vector( : 1., 3.)$

call lpmax(c,a,b,n:print);

b34srun$



Answers are:



%lpmax = 3.5;

%primal=vector(:.5 1.0);

%dual= vector(:0. 2. 1. 0.);



See lpmin, qpmin and nonlinear programming commands for more

complex problems.



LPMIN - Solve Linear Programming minimization problem.



call lpmin(w,a,bu);

call lpmin(w,a,bu :print);



Allows solution of more complex LP minimization problems of the

form:



min c'*x



such that



bl le A*x le bu



Xl le X le Xu



where



c = Vector of n coefficients of objective function.



A = m by n matrix of coefficients of m constraints



bu = Vector of m upper constraints



bl = Vector of m lower constraints (optional).

Needed only if have RANGE.

Xl = Lower bound on X. Default = .1E+31 which

implies no bound. Note: It is imperative that this be

followed very closely. If -1.e+30 is set, this will

cause unpredictable problems.



Xu = Upper bound on X. Default = -.1E+30 which

implies no bound. Note: It is imperative that this be

followed very closely. If 1.e+30 is set, this will

cause unpredictable problems.



If only the first three arguments are passed, then the

constraints are assumed to be of the form LE.



If a maximum is desired, do not multiply c by -1 use :max

switch. Command will do the rest.



Optional Arguments:



:print => print solution



:max => Converts a minimize problem to a max

problem by multiplying the dual, C and the

objective function by -1.0.



If .EQ. constraints are supplied then either:



:neq k => first k constraints are .EQ.



or



:constr => namelist(LE LE EQ) is used. In the

namelist keywords are EQ LE GE RANGE



If RANGE is passed then, the lower limit needs to passed as



:bleft vector



Constraints on the X solution can be passed as:



:lowerx vector (default = 0.0)



:upperx vector (default = 1.d+30)



:noflag => Suppresses the error message

:ERROR returned by %error / iercd() to a

note.







Automatic values produced are:



%LPMIN = objective function

%PRIMAL = Solution for w (Shadow price)



%DUAL = Solution for x



%error - returns IMSL iercd( ) code



0 => solution OK

1 => Problem unbounded

2 => Max Iterations exceeded

3 => Problem is infeasible

4 => Numerical difficulty

5 => Constraints for problem not consistent







Primal



bl LE A*X LE bu



Min Z = c'*X



Dual



A'*W ge c'



max b'*w



In economics



w = the production of a good



B = production input constraint



C = price product is sold for.



x = shadow price



Example:



b34sexec matrix;

* Test Problem from IMSL ;

* Objective = 3.5 ;

* This problem is solved as a max ;

* Primal = .5 1. ;

* Dual =1. .0;

ncon=2;

nvar=2;

a=matrix(ncon,nvar:1.0 1.0 1.0 1.0);

b=vector(ncon:1.5 .1);

c=vector(nvar:1.0 3.0);

call lpmin(c,a,b :lowerx vector(:0.0 0.0)

:upperx vector(:1.0 1.0)

:constr namelist(LE GE) :print :max);

call names;

b34srun;





Notes on setups: If the problem contains



min z = 20x+4y



the appropriate max is



max -z = -20x -4y



If the problem contains



10x + 20y



it can be replaced with



-10x - 20y le -10





LMTEST Engle (1982) LM ARCH Test for a vector of lags



call lmtest(x,nlag,lag,teststat,prob,iprint);



Calculates Engle (1982) Lagrange Multiplier Test;



X = real*8 series to test

nlag = Number of lags to run test

lag = Vector of lags

teststat = LM test statistic

prob = Parbability of teststat

iprint = 0 => do not print

1 => print



LMSTEST is a subroutine from matrix2.mac.



It must be loaded with



call load(lmtest);



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call echooff;

call load(lmtest);

call lmtest(gasout,30,lag,tt,prob,1);

b34srun;



Test case: lmtest



See also: LM

LRE - McCullough Log Relative Error



call lre(c,ndigits,x,lre,bits);

call lre(c,ndigits,x,lre,bits:print);



Implements test from McCullough (1999)

"Econometric Software Reliability: EViews, Limdep, Shazam and

TSP," Journal of Applied Econometrics #14 1999 pp 191-202



Calculates log relative error



c = correct answer (input)



ndigits = # of digits in correct (input)



x = Answer to be tested (input)



lre = Log relative error (output)



bits = # bits (output)



iprint = 1 => Display answer (output)



Note: c and x can be 1 dimensional objects. c and x must be

real*8 or real*16 objects. ndigits must be integer*4.



Example:



b34sexec options ginclude('b34sdata.mac')

member(wampler); b34srun;

b34sexec matrix;

call loaddata;

n=16;



call print(' ':);

call print('With QR':);

call olsq(y5 x1 x2 x3 x4 x5 :print );

c=array(norows(%coef):)+1.0;

call lre(c,n,%coef,lrevalue,bits);

d=afam(c)-afam(%coef);

call tabulate(c,%coef,lrevalue,bits,d);

call print('Results using Cholesky':);

call lre(c,n,%coef,lrevalue,bits :print);



call olsq(y5 x1 x2 x3 x4 x5 :print :qr);

call print('Results using QR':);

call lre(c,n,%coef,lrevalue,bits :print);



nn=5;

x=rn(matrix(nn,nn:));

invx=inv(x);

tt=x*invx;

get=diag(tt);

value=array(norows(x):)+1.0d+00;

call print('Inversion test':);

call lre(value,16,get,lrevalue,bits :print);



dd=det(x);

altdd=real(prod(eig(x)));

call print('Determinant two Ways - Easy Problem':);

call lre(dd,16,altdd,test,bits :print);



xtest=mfam(catcol(x1 x2 x3 x4 x5));

xnew=transpose(xtest)*xtest;

dd=det(xnew);

altdd=real(prod(eig(xnew)));

call print('Determinant two Ways - Harder Problem':);

call lre(dd,16,altdd,test,bits :print);



b34srun;



MCLEODLI McLeod-Li (1983) Linearity test (y,ip,maxacf)



call mcleodli(y,ip,maxacf,makeplot);



Calculates y(t) = f(y(t-1) ...... y(t-ip))

Calculates ACF of %res**2 of equation # 1 using max order

maxacf.





y = series to study



ip = max lag



maxacf = max ACF to calculate



makeplot = set =0 foir no plot, 1 for a plot



Revised Feb 15 2000 to corrrect bug and add graph option



MCLEODLI is a subroutine from matrix2.mac. It must be loaded

with



call load(mcleodi);



Example:



b34sexec options ginclude('gas.b34'); b34srun;

/;

/; See McLeod-Li 'Diagnostic Checking of ARMA

/; Time Series Models

/; Using Square Residual Autocorrelations'

/; McLeod, A. & Li, Journal of Time Series

/; 4,:3:24 1983

b34sexec matrix;

call loaddata;

call load(mcleodli);

call mcleodli(gasin, 12,12,1);

call mcleodli(gasout,12,12,1);

call print(%mltest);

call tabulate(%res,%ressq2,%acf1);

/; Random number tests

x=rn(array(10000:));

call mcleodli(x, 12,12,1);

call print(%mltest);

call mcleodli(x, 100,100,1);

call print(%mltest);



b34srun;



Test case: mcleodi





MARQ Estimation of a Nonlinear Model using Derivatives



call marq(xvar,yvar,beta,r,f,sse,seb,covb,

corrb,lamda,iprint,iout);

Estimates a Nonlinear Model using derivatives. MARQ is based

on the SAS nonlinear matrix program in technical report a-102

pp.8-6. This program was initially converted for Speakeasy

by Houston H. Stokes April 1987. In June 1998 it was ported

to the B34S Matrix command.



MARQ needs user subroutines resid, deriv



xvar = matrix of x variables - input



yvar = left hand side variable vector - input



beta = vector of initial guess on coefficients

- input/output



r = residual vector - output



f = predicted variable vector - output



see = sum of squared residuals (sumsq(r)) - output



seb = se's of the beta coefficients - output



covb = covariance matrix of beta coefficients - output



corrb = correlation matrix of beta coefficients - output



lamda = ridge parameter - usually initialized as .1e-8

- input



iprint = 0 donot print inerations, = 1 print iterations



iout = 0 for no output printing, = 1 output will be given

Arguments for user supplied subroutines



call resid(beta,f,r,xvar,yvar);



call deriv(der,f,beta,xvar);



The routine resid calculates f and r given beta, xvar and yvar



deriv calculates derivative where



der=matrix(norows(xvar),norows(beta):)



Test case: NLLS1, NLLS2, NLLS3



MAKEDATA - Place data in a b34s data loading structure.



call makedata(x,y,z);



Places x, y and z in a b34s dataset with default name

_matdata.b34. If the series are not the same length, they are

padded with the b34s missing value. Only vectors, arrays and

matrices can be passed. If X is a matrix, the b34s names are

M1col__1 to m1col_98. Only real*8 or char*8 objects can be

saved using this format.



Optional arguments include:



:file 'file name here'



:member mname



:add



If add is not present, the file is rewound. The filename must

fit into 40 characters.



Examples:



call makedata(x,y,z :file 'c:\test\my.b34');



call makedata(x,z:file 'my.b34' :member r1);



Unless MEMBER is in effect, MAKEDATA uses the internal b34s

data transport format for added speed. This format does not

require a parse step.



MAKEGLOBAL - Make a variable global (seen at all levels).



call makeglobal(name1,name2);



Makes variables name1, name2 available to all user subroutines

and functions.



Example:

b34sexec matrix;

n=4 ;x=rn(matrix(n,n:));pdx=transpose(x)*x;

call free(n:);

call names(info);

call makeglobal(pdx);

call names(info);

r=pdfac(pdx);

call print(pdx,r);

call makelocal(pdx);

call names(info);

r=pdfac(pdx);

call print(pdx,r);

pdx(1,1)=.9999;

call print(pdx,'We now free at the local level');

call free(pdx); call names(info);

b34srun;



MAKELOCAL - Make a variable seen at only local level.



call makelocal(name1,name2);



Moves name1 and name2 to the local level. If given

at command level, will make a former global variable local.

Using in this mode, a number of names can be moved at once.



Optional usage using :level argument



Example:



call makelocal(name1 name2 :level level() 100);



will move name1 and name2 currently at current level seen

to level 100 which is the command level.



call makelocal(name1 :level level() 10);



will move from current level to level 10 name1). The command



call makelocal(name1 :level 10 level());



will get name1 back.



Example:



b34sexec matrix;

n=4 ;x=rn(matrix(n,n:));pdx=transpose(x)*x;

call free(n:);

call names(info);

call makeglobal(pdx);

call names(info);

r=pdfac(pdx);

call print(pdx,r);

call makelocal(pdx);

call names(info);

r=pdfac(pdx);

call print(pdx,r);

pdx(1,1)=.9999;

call print(pdx,'We now free at the local level');

call free(pdx); call names(info);

b34srun;





Example # 2 moving to the command level from a subroutine



b34sexec matrix;



subroutine test(oldlev);

getit=rn(matrix(3,3:));

call print(getit);

call print('In Test':);

call names(info);

call makelocal(getit :level level(), oldlev);

return;

end;



call test(level());



call names(info);

call print(getit);

b34srun;



MAKEMAD - Make SCA MAD portable file.



call makemad(x,y,z);



Places x, y and z in a SCA MAD DSN with default name _SCA.mad.

If the series are not the same length, they are padded with a

missing value. Only vectors, arrays and matrices can be passed.

If X is a matrix, the sca names are M1col_01. Only real*8

objects can be saved. The default member name is b34sdat.



Optional arguments include:



:file 'file name here'



:member mname



:add



If add is not present, the file is rewound.



The filename must fit into 40 characters.



Examples:



call makemad(x,y,z :file 'c:\test\my.mad');

call makemad(x,z :file 'my.mad':member r1);



In SCA the commands needed to load the data are:



call procedure is b34sdata. file is 'my.mad'





MAKEMATLAB - Place data in a file to be loaded into Matlab.



call makematlab(x,y:file 'junk');



Creates a special file that the b34s supplied matlab m file

getb34s.m can read. Files created with makematlab can be read

back into the B34S MATRIX command with the b34s MATRIX command

getmatlab. If :file is not present, the default name is

_b34smat.dat



call getmatlab(x :file 'junk');



will read the file back into B34S.



On the MATLAB side the command is



x=getb34s('c:\junk\junk');



See also the makeb34s command on the Matlab side.





Note: getmatlab & makematlab pass series as a matrix.



If more accuracy is desired the matrix language implementations

gmatlab and mmatlab, which are shown in the WRITE2 example, can

be modified.



If accuracy is increased, the matlab m files getb34s.m and

makeb34s.m will have to be changed.



For a related command see getmatlab.



MAKERATS - Make RATS portable file.



call makerats(x,y :file ' ');



Makes Rats portable file for series x and y. Series x and y

must be same length and must be real*8. If the option :file is

not present the default name myrun.por is used.



Optional keywords:



:file ' ' - Adds a file name



:add - Adds to series on file



:eformat - Writes series in extended

format of g25.16. Default

format is g18.10.



:timeseries start freq - Saves as a time series

with start as the julian

date & freq as the

frequency.





Example:



call makerats(x,y :file 'test.por'

:timeseries juldaydmy(1,02,1945) 12.);



For a related command see getrats.



MAKESCA - Make SCA FSV portable file.



call makesca(x,y,z);



Places x, y and z in a SCA FSAVE DSN with default name

_SCA.fsv. If the series are not the same length, they are

padded with the b34s missing value. Only vectors, arrays and

matrices can be passed. If X is a matrix, the sca names are

M1col_01. Only real*8 objects can be saved. The default member

name is b34sdat.



Optional arguments include:



:file 'file name here'



:member mname



:add If add is not present, the file is rewound.



The filename must fit into 40 characters.



Examples:



call makesca(x,y,z :file 'c:\test\my.fsv');



call makesca(x,z :file 'my.fsv' :member r1);



In SCA the commands needed to load the data are:



finput file is 'my.fsv'. @

dataset is b34sdat.





MANUAL - Place MATRIX command in manual mode.



call manual;



Allows user to enter commands at the terminal. This command

works only with the Display Manager.



call run; - Gets out of Manual Mode.





Notes: The manual mode restricts the user to entering

ONLY one sentence at a time. In manual mode the log and

output file can be viewed and the system can be reset

if needed. The user can get into and out of the manual

mode. Commands such as DO and IF( ) cannot be given

while in manual mode unless file input mode is being

used.



Usually the user uses OUTSTRING, OUTINTEGER and

OUTDOUBLE to monitor calculation progress. MESSAGE can

control the job. SCREENOUTON and SCREENOUTOFF allow

progress to be displayed on the screen. SETWINDOW can

control location of where OUTSTRING, OUTINTEGER and

OUTDOUBLE write.



SCREENOUTON slows execution of the program if there is

substantial output. If the matrix job is small, the

output will flash by. The use of CALL STOP(pause); can

pause the job. Enter will restart the job.



The command



call break;



or the variant



call break('we are at point A now');



can be used to stop execution if any key has been hit.



The program can be made to stop.





call manual;



is not enabled if a subroutine, program or function is

being run under another command such as nllsq, nl2sol or

cmaxf2 etc.



MARS - Multivariate Autoregressive Spline Models



call mars(y x1 x2);



Controls estimation of Multivariate Adaptive Regression Splines

This command is the matrix command equivalent of the MARS

precedure. Model save files etc from one command can be read by

the other command. The left hand variable can be continuous

(default) or 0-1 (:logit option). The call mars command uses

the original 1991 Friedman mars program. It has been

withdrawn from commercial use.



In 2005 the Hastie-Tibshirani Code, that implemented the mars

approach to modeling that was initially implemented in S in

1998 and later ported to R and made GPL compliant, has been

implemented as the MARSPLINE command under the B34S matrix

command. These routines were developed without the Friedman

MARS routines and contain a state-of-art implementation.



Basic references are:



- Friedman, Jerome, "Multivariate Adaptive Regression Splines,"

The Annals of Statistics, Vol. 19, No. 1, 1991, pp. 1-141



- Stokes, Houston H. "Specifying and Diagnostically Testing

Econometric Models," second edition 1997 Quorum Books.

Chapter 14



- Stokes, Houston H and Hugh Neuburger, "New Methods in

Financial Modeling," 1998 Quorum Books. Chapter 4.



- Stokes, Houston H. "MARS Modeling in SAS® Software Using the

MACRO Interface to B34S®," Proceedings of the Twenty-First

Annual SAS® Users Group International Conference, 1996 pp.

1145-1149.





Lags can be entered as



x{1} or x{1 to 20}



Basic reference:



- Friedman, Jerome, "Multivariate Adaptive Regression

Splines," The Annals of Statistics, Vol. 19, No. 1,

1991, pp. 1-141





Notes:



The MARS command allows the user to optionally save or reread

an estimated model. The advantage of saving models is that

forecasts can be calculated without having to estimate the

model again if in subsequent steps the getmodel option is

used. In order to preserve variable storage, the order and

number of the variables in the forecast input matrix MUST be

the same as the initially saved model for a saved model to be

used.



Options for MARS sentence.



:logit Sets left hand side variable as catagorical.

:print Print



:graph Generate %crv and %srf



:sample mask - Specifies a mask real*8 variable that

if = 0.0 drops that observation.

Unless the mask is the number of obs

after any lags, an error message will

be generated. The sample variable

must be used with great caution when there

are lags. A much better choice is the

:holdout option.



:holdout n - Sets number of observations to hold out



Note: :sample cannot be used with :holdout.



:mi i1 Sets maximum number of variables per basis

function.



MI=1 => additive model.

MI > 1 => up to MI-variable interactions

allowed. Default = 1



:nk i2 Sets maximum number of basis functions.

Default = 5.



:ngc i3 Number of raser points for computing MARS

curve estimates. Default = 100.



:nc i4 Number of curve matrices. Default=nk.

Max value that can be specified = nk.



:ngs i5 Number of raser points for MARS surface plot.

Default=40.



:ns i6 Number of surface plots. Default = nk.

Max value that can be specified is nk.



:m k1 k1 = LINEAR => a piecewise-linear model

is estimated.

k1 = CUBIC => a piecewise-cubic model

is estimated.

k1 = SEARCH => the program will estimate

the residual sum of squares

using both LINEAR and CUBIC

options and select the one

having the smaller sum of

squares.



Default = SEARCH.



Note: the cubic approximation contains

continuous derivatives. See Friedman

(1991) section 3.7 page 23 for further

discussion.



:icx k2 k2 = ENTIRE => plots of surface estimates

are done over the entire range

of the argument.

k2 = INSIDE => plots of surface estimates

are done only inside the convex

hull of the bivariate point set.

Default setting is ENTIRE.



:ms i7 Sets minimum span between each knot.

i7 = 0 => the number of observations and the

number of right hand side variables

determine the minimum span.

Default is i7 = 0. The maximum value

for i7 is the number of observations

in the dataset.



:ic k3 k3 = NORESTRICT => there are no restrictions on

interactions except for

those set with MI above.

k3 = RESTRICT => there are no interactions

allowed between ordinal and

catagorical variables.

k3 = MAXORI2 => the maximum number of

ordinal variable

interactions is 2.

Default setting is NORESTRICT.



:df r1 Sets the number of degress of freedom charged

for unrestricted knot optimization. Default=3.



:fv r2 Sets the incrumental penalty for increasing

the number of variables in the model.

The default setting is r2=0.0 or no penalty.

If r2 = .05, there is a moderate penalty.

If r2 = .1 there is a heavy penalty.

The FV parameter is useful in limiting the

size of highly collinear models and may produce

equivalent models with fewer predictor

variables.



:is i8 Sets the seed for internal random number

generator used to group observation subsets

for validation. This is used if IX is set NE

0 below. The default is 987654321.



:ix i9 The value of i9 controls the sample reuse

technique to automatically determine DF from

the data. If i9=0, the value of DF is set by

the user. This is the default setting.



If i9 > 0, the ix - fold cross validation

procedure is used.



If i9 0, then computation time

increases roughly by a factor of i9 over

the (default) case where i9 = 0.



If ix Allows users to supply observations

of the right hand side variables

outside the sample period so that

forecasts can be calculated. The

same number of observations must be

supplied for all right hand series.

Due to the way that splines are

calculated, it is imperative that

any values of the x variables NOT

lie outside the ranges of the

original data.



The forecast sentence produces the

%fore variable and the %foreobs

variable.

Variables Created



%YVAR - Name of left hand variables.



%NAMES - Names of exogenous variables.



%TYPEVAR - = 0 for continuous, NE 0 for categorical var.



%STATES - vector of states. Only defined if isum

%typevar ne 0.



%LAG - Lags of independent variables.



%COEF - Final Model Coefficients. Constant in

location one. Size nk+1



%MINVAR - Minimum of input variables.



%MAXVAR - Maximum of input variables.



%TYPEK - =0 if coef * max(var -knot,0)

=1 if coef * max(knot-var,0)



%VARINK - Variable # of that knot



%CKNOT - Character*1 array nk,28 holding

positional indicator of catagorical

variable right hand sides. Set to

0000000 is not used.



%KNOT - Knot



%PARENT - Index number of parent in interaction

otherwise 0



%MARS_VR - Sets = 1. If the MARS command is used,

This is set =0. This allows processing of the

more general GLP MARS functional form.



%K - # on right



%NOB - # of observations in model



%RSS - Residual sum of sq.



%SUMRE - Sum absolute residuals



%REMAX - Maximum absolute residual



%RESVAR - Residual Var.



%YHAT - Estimated Y

%Y - Y variable. Same # obs as YHAT



%RES - Residual



%VARRIMP - Relative variable importance.



%CRV - a ngc by 2 by nc 1D array containing MARS

curve estimates.



The below listed code will unpack



bigm=matrix(%ngc,2*%nc: %crv);

m1=submatrix(bigm,1,%ngc, 1,2);

m2=submatrix(bigm,1,%ngc, 3,4);



Note:



sx=submatrix(x,1,3,2,5);



forms a new matrix sx containing



rows 1 to 3





cols 2 to 5



%ms - :ms Span setting



%mi - :mi setting



%nk - :nk setting



%ngc - Dimension 1 of curve matrix %crv



%nc - Dimension 3 of curve matrix



%srf - a %ngs by %ngs by %ns 1D array containing MARS

surface values.



The below listed code will unpack



bigm=matrix(%ngs,%ngs*%ns:%srf);

m1=submatrix(bigm,1,%ngs,1,%ngs);

m2=submatrix(bigm,1,%ngs,%ngs+1,%ngs*2);



%ngs - Dimension of surface matrix



%ns - Max surface plot dimension



%fore - Forecast



%foreobs - Observations of the forecast. If there are

lags, must have to increase %foreobs by

maxlag. This assumption may change is later

releases. For now it is the obs number.





Simple Example:



b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

call loaddata;

call load(dispmars :staging);



call olsq(gasout gasin{0 to 6} gasout{1 to 6} :print);

call graph(%res :heading 'Residual from OLS 1-6');

call graph(%y %yhat:heading 'Fit from OLS 1-6');



call mars(gasout gasin{0 to 6} gasout{1 to 6} :print);

call dispmars;



call names(all);

call graph(%res :heading 'Residual from Mars 1-6');

call graph(%y %yhat:heading 'Fit from Mars 1-6');

b34srun;



b34sexec options ginclude('b34sdata.mac')

member(friedman);

b34srun;

b34sexec matrix;

call load(dispmars :staging);

call loaddata;

call olsq(y x1 x2 x3 x4 x5 :print);

call graph(%res :heading 'Residual from ols ');

call graph(%y %yhat:heading 'Fit from ols ');

olsres=%res;

call mars(y x1 x2 x3 x4 x5 :print);

call dispmars;

call graph(%res :heading 'Residual from Mars ');

call graph(%y %yhat:heading 'Fit from Mars ');

marsres=%res;

call graph(olsres marsres :heading 'OLS vs MARS');

b34srun;



Forecasting



/$ Job shows an estimate and a forecast

b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

call loaddata;

* We forecast the last 10 insample data points ;

npred=10;



xin=matrix(npred,2:);

nn=norows(gasout)-npred;

do i=1,npred;

xin(i,1)=gasin(nn+i);

xin(i,2)=1.0;

enddo;

call print(xin );

call names(all);

call mars(gasout gasin :print

:forecast xin );



call tabulate(%y %yhat %res gasout gasin);

call tabulate(%fore %foreobs);

b34srun;



Job shows an estimate and a model save.



b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

call loaddata;

call load(dispmars :staging);

call open(60,'junk.mod');

call mars(gasout gasin :print :savemodel :murewind);

call dispmars;

b34srun;



See if can get model. Since getmodel we will not estimate.



b34sexec matrix;

call loaddata;

* We forecast the last 10 in sample data points ;

npred=10;



xin=matrix(npred,2:);

nn=norows(gasout)-npred;

do i=1,npred;

xin(i,1)=gasin(nn+i);

xin(i,2)=1.0;

enddo;

call print(xin );

call names(all);

call mars(gasout gasin :print :getmodel

:forecast xin );

call tabulate(%fore %foreobs);

b34srun;



Plots of Curves and Surfaces



b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

call loaddata;

call mars(gasout gasin{1 to 6} gasout{1 to 6}

:ngc 100 :ngs 200

:graph :mi 2 :nk 15 :print);

call print('%ns ',%ns);

call print('%nc ',%nc);



call tabulate(%y %yhat %res);

call names(all);



/$ This logic in MARSPLOT program in

/$ matrix2.mac



i=integers(1,%ngc*2*%nc);

bigm=matrix(%ngc,2*%nc: %crv(i));



ii_=0;

do ii=1,%nc,2;

ii_=ii_+1;

m1=submatrix(bigm,1,%ngc,ii,ii+1);

call char1(cc,'Curve Plot ');

call inttostr(ii_,cc2,'(i4)');

ii2=integers(4);

ii3=ii2+11;

cc(ii3)=cc2(ii2);

call graph(m1

:plottype meshstepc

/$ :plottype meshc

:grid :d3axis :d3border

:heading cc);

enddo;



i=integers(1,%ngs*%ngs*%ns);

bigm=matrix(%ngs,%ngs*%ns:%srf(i));



do ii=1,%ns;

icol1=1+((ii-1)*%ngs);

icol2=icol1+%ngs-1;

m1=submatrix(bigm,1,%ngs,icol1,icol2);

call char1(cc,'Surface Plot ');

call inttostr(ii,cc2,'(i4)');

ii2=integers(4);

ii3=ii2+13;

cc(ii3)=cc2(ii2);

call graph(m1

:plottype meshc

/$ :plottype meshstepc

:grid :d3axis :d3border

:plottype meshc

:heading cc);

enddo;



b34srun;





Note: These jobs are MARS, MARS_2 MARS_3 & MATS_4

MARSPLINE - Updated MARS Command using Hastie-Tibshirani code



call marspline(y x1 x2);



Controls estimation of Multivariate Adaptive Regression Splines

following methods suggested by J. Friedman (1991) but using GPL

code developed by Hastie-Tibshirani. If the MARS command is

licensed, marspline can be compared with mars output. The

MARSPLINE command uses a library of subroutines developed by

T. J. Hastie and R. J. Tibshirani for implementation in S in

1998. This code was later moved to R and the source released

under the GPL 2 license. The developer of B34S respects the

Friedman trademark MARS(tm) but is greatful to

Hastie-Tibshirani for making their code available.



MARS, MARSPLINE, GAMFIT and ACEFIT are all related models that

attempt to model nonlinear data with various spline procedures.

The functional form allowed for MARSPLINE is more general than

that allowed in the original Friedman code. Due to this added

capability more space may be needed to run this command.

R code maintainer Kurt Hornik



Lags can be entered as



x{1} or x{1 to 20}



Basic references:



- Friedman, Jerome, "Multivariate Adaptive Regression Splines,"

The Annals of Statistics, Vol. 19, No. 1, 1991, pp. 1-141



- Hastie-Tibshirani "Generalized Additive Models," Chapman &

Hall 1990.



- Stokes, Houston H. "Specifying and Diagnostically Testing

Econometric Models," second edition 1997 Quorum Books.

Chapter 14



- Stokes, Houston H and Hugh Neuburger, "New Methods in

Financial Modeling," 1998 Quorum Books. Chapter 4.





Notes:



The MARSPLINE command saves the users model in matrix

command variables. The advantage of this is that forecasts can

be calculated without having to estimate the model again. In

order to preserve variable storage, the order and number of the

variables in the forecast input matrix MUST be the same as the

initial model for a saved model to be used.



Options for MARSPLINE sentence.

:logit Sets left hand side variable (0-1) as

logit. y=1/(1+exp(-xb)).

Not ready. Should not be called.



:probit Sets left hand variable (0-1) as probit.

y= cumulative normal probability.

Not Ready. Should not be called.



:print Print header and minimal output. If :print is

set it assumes :dispmars.



:mathform If set displays model in a form that does not

show adjacent operators. This from can be

placed easily in a user subroutine or program.



:dispmars Displays prior model or current model



:trace Trace solution. This is usually not needed.



:nofwdstep Turns off forward step.



:noprune Turns off model prune step. This is not

recommended in most cases.



:thresh r8 Sets threshold for Forward selection.

Default= .0001, The smaller the number the

more complex the model.



:ranktol r8 Sets threshold for prune of a multicolinear

basis. Default .1d-13. If model seems overly

complex, lower this value.



:tolbx Variable addition threshhold. Default .1d-8.



:stopfac Default = 10. Usually this should not be

changed.



:savebx Saves matrix of basic functions with name %bx.

See documentation for %bx on how to use this

matrix;



:prevcrit Default = 10**9.



:sample mask - Specifies a mask real*8 variable that

if = 0.0 drops that observation.

Unless the mask is the number of obs

after any lags, an error message will

be generated. The sample variable

must be used with great caution when there

are lags. A much better choice is the

:holdout option.



:holdout n - Sets number of observations to hold out

:getmodel 'filename' Saves model discription variables

%besin %flag %dir %cut %yvar %names

%typevar %lag %coef %minvar %maxvar %k %nob

%rss %sumre %remax %resvar %mars_vr %se



If getmodel is found, no estimation is

performed.



:savemodel 'filename' The default name is 'marss.psv'





Note: :sample cannot be used with :holdout.



:mi i1 Sets maximum number of variables per basis

function. Max = 3.



MI=1 => additive model.

MI > 1 => up to MI-variable interactions

allowed. Default = 1



:nk i2 Sets maximum number of basis functions.

Default = 5.



:df r1 Sets the number of degress of freedom charged

for unrestricted knot optimization. Default=2.





:weight Uses the last series on the model sentence as

a weight variable vector.



:forecast xmatrix => Allows users to supply observations

of the right hand side variables

outside the sample period so that

forecasts can be calculated. The

same number of observations must be

supplied for all right hand series.

Due to the way that splines are

calculated, it is imperative that

any values of the x variables NOT

lie outside the ranges of the

original data. The user must have

save the model workspace if

:forecast is the only option.



The forecast sentence produces the

%fore variable and the %foreobs

variable.



Variables Created



%YVAR - Name of left hand variables.



%NAMES - Names of exogenous variables.

%TYPEVAR - = 0 for continuous, NE 0 for categorical var.



%LAG - Lags of independent variables.



%COEF - Final Model Coefficients. Constant in

location one.



%SE - Estimate of the SE assuming knot matrix is

given. Users wanting alternative SE's can

either recalculate from the %BX matrix or

from %VAR.



%MINVAR - Minimum of input variables.



%MAXVAR - Maximum of input variables.



%FLAG - Flag(i,j) Indicates the that for coef i a knot

was found withb the jth variable



%DIR - dir(i,j) = 1 indicates a max(var-knot,0)

dir(i,j) =-1 indicates a max(knot-var,0)

for ith coef and jth var.



%BESTIN - If bestin(i) ne 0 => ith coef is in model



%CUT - cut(i,j) shows ith coef knot for jth variable



%BX - n by nk matrix of knot products. First pick

off basis vectors in the final model using

%bestin array. Then estimated coefficients are

obtainable from:



s_bestin=sum(%bestin);

xx=matrix(norows(%bx),s_bestin:);

ihave=0;

do i=1,norows(%bestin);

if(%bestin(i).eq.1)then;

ihave=ihave+1;

xx(,ihave)=%bx(,i);

endif;

enddo;

call olsq(vfam(%y) xx :noint : print);



Option :givebx will save :bx



%VAR - Covariance of parameters after QR step.

Square root of the diagonal elements *

(norows(%y)-norows(%coef)) are SE.



%FWDINFO - (nfk,3) array. (i,1)=gcv, (i,2)=rss, (i,3)=cut

Analysis of this array give insight into

the importance of a certain knot.



%IWDINFO - (nfk,3) array. (i,1)=i cut, (i,2)=j cut,

(i,3)=parent index



Note that %fw_info and %iw_info save :trace

info and are not usually used.



nfk = number of final knots.



%GVCNULL - GCV with only constant in model.



%RSSNULL - RSS with only constant in model.



%NK - :nk setting on input.



%MI - :mi setting on input.



%DF - :df setting on input



%MARS_VR - Sets = 1. If the MARS command is used,

This is set =0. This allows processing of the

more general GLP MARS functional form.



%K - # on right



%NOB - # of observations in model



%RSS - Residual sum of sq.



%SUMRE - Sum absolute residuals



%REMAX - Maximum absolute residual



%RESVAR - Residual Var.



%YHAT - Estimated Y



%Y - Y variable. Same # obs as YHAT



%RES - Residual



%VARRIMP - Relative variable importance. Not implemented

yet.



%FORE - Forecast



%FOREOBS - Observations of the forecast. If there are

lags, must have to increase %foreobs by

maxlag. This assumption may change is later

releases. For now it is the obs number.





%MODTYPE - =0 ordinal, =1 logit, =2 probit. Only ordinal

has been implemented.

Simple Example:



b34sexec options ginclude('b34sdata.mac') member(trees);

b34srun;

b34sexec matrix;

call loaddata;

call load(dispmars :staging);

call load(marsinfo :staging);

call echooff;



call olsq(volume girth height :print);



call mars(volume girth height :nk 20 :df 2. :mi 3 :print);

call dispmars;

call tabulate(%res,%y,%yhat);



call marspline(volume girth height :nk 21 :df 2. :mi 1

:print);

call marsinfo;

call marspline(volume girth height :nk 21 :df 2. :mi 3

:print);

call marsinfo;

call print(%coef);

call tabulate(%res,%Y,%yhat);

b34srun;



Example of a display



call marspline(:getmodel :dispmars);



Example of forecasting when the model had been saved



call marspline(:getmodel 'mymod.psv' :forecast x);



Forecasting:



%b34slet noob=300$

%b34slet errorm=2;



b34sexec data noob=%b34seval(&noob)$

build y1 y2 x z e1 e2$

gen e1=rn()$

gen e2=rn()$

gen x =10*rn()$

gen z =10*rn()$

gen y1 = 10 + 5*x + 5*z

+ %b34seval(&errorm)*e1 $

gen if(x .gt. 0) y2= 10 + 5*x + 5*z

+ %b34seval(&errorm)*e2$

gen if(x .le. 0) y2= 10 -10*x + 5*z

+ %b34seval(&errorm)*e2$

b34srun$



b34sexec matrix;

call loaddata;

call echooff;

call load(dispmars :staging);



call olsq(y1 x z :print);



%x=catcol(x z);



/; Validate forecasting gets yhat



call marspline(y1 x z :print :forecast %x);

call tabulate(%foreobs %fore %yhat %res %y);



call marspline(y2 x z :print :forecast %x);

call tabulate(%foreobs %fore %yhat %res %y);

b34srun;

MAXF1 - Maximize a function using IMSL ZXMIN.



call maxf1(func :name test :parms x1 x2 :ivalue rvec);





The MAXF1 command provides a quick way to maximize a function

using the Quasi-Newton Method. If the functional value is

multiplied by -1.0, a minimum can be obtained. The IMSL routine

ZXMIN is based on the Harwell routine VA10A. (See Fletcher, R.

"Fortran subroutines for minimization by Quasi-Newton methods",

Report R7125 AERW, Harwell England, June 1972.) The sample

problem is the famous Rosenbrock 'Banana' problem. In addition

to being a test case in IMSL, it has been used as a test case

for the MATLAB FMINS command.



A simple setup for a maximum / minimum is:



call maxf1(func :name test :parms x1 x2 :ivalue rvec);



where func is a scalar computed with the user MATRIX program

test and x1 and x2 are parameters. Initial guess values for x1

and x2 are in the real vector rvec.



For example the minimum of



FUNC = 100.*(x2-x1*x1)**2. + (1.-x1)**2.



can be found with the commands:



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

return;

end;



rvec=array(2:-1.2 1.0);

call maxf1(func :name test :parms x1 x2

:ivalue rvec :print);

b34srun;





The function name (func), the program name (test), the initial

values vector (rvec) and the parms are required to be passed.

If there is a concern that the function has more than one

minimum, the NLSTART command can be used to investigate a

number of starting values. The calls to outstring, outdouble

and outinteger can be used to monitor the solution.



The below listed code can be used to see if the function

minimum changes given different starting values:



/$ MAXF1 is used to minimize a function

/$ Answers should be x1=.9999 and x2=.9999



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

call outstring(3,3,'Function to be minimized');

call outdouble(36,3,func);

call outstring(3,4,'Test case ');

call outinteger(36,4,i);

return;

end;



call print(test);

n=2;

k=10;

a=array(n: -3., -3.);

b=array(n: 3., 3.);

result=array(k:);

ak =array(k:);

bk =array(k:);

call nlstart(a,b,k,s); call print(s);

call echooff;



do i=1,k;

rvec=s(,i);

ak(i)=rvec(1);

bk(i)=rvec(2);

call maxf1(func :name test :parms x1 x2

:ivalue rvec :print);

result(i)=%func;

enddo;



call tabulate(result,ak,bk);

call graph(result);

b34srun;



Required

func - Function name



:name pgmname - User program to determine func



:parms v1 v2 - Parameters in the model. These

parameters must be in the function

in the user program pgmname that

determines func. The keyword

:parms MUST be supplied prior to

all keywords except :name.



Optional keywords for MAXF1 are:



:print - Print results



:ivalue rvec - Determines initial values. rvec

must be a vector containing the

number of elements equal to the

number of parameters supplied.

Default = .1.



:nsig i - Sets number of digits of accuracy for

convergence. Default = 4.



:maxfun int - Maximum number of function

evaluations. Default = 400



:hessian key - where key is IDENT, USER, DIAG, EST.



IDENT => Initialize hessian to

identity matrix.

USER => User supplied Hessian.

DIAG => MAXF1 computes diagonal.

EST => MAXF1 estimates the Hessian.



:hessianm H - Specifies the Hessian in H. H must be

positive def. Hessian must be supplied

if hessian keyword USER is supplied.



MAXF1 automatically creates the following variables



%coef - a vector containing the parameters.



%nparm - a vector with coefficient names.



%se - a vector containing parameter

standard errors.



%t - a vector containing parameter t

scores.



%hessian - hessian matrix.



%grad - estimate of gradiant at final

parameter values.



%func - final value of function.



MAXF2 - Maximize a function using IMSL DUMINF/DUMING.



call maxf2(func :name test :parms x1 x2 :ivalue rvec

:print);



The MAXF2 function provides a way to maximize a function using

the Quasi-Newton Method. If the functional value is multiplied

by -1.0, a minimum can be obtained. A simple setup for a

maximum / minimum is:



call maxf2(func :name test :parms x1 x2 :ivalue rvec

:print);



if the gradiant is known the call is



call maxf2(func grad :name test test2

:parms x1 x2 :ivalue rvec

:print);



where func is a scalar computed with the user MATRIX program

test and x1 and x2 are parameters. Initial guess values for x1

and x2 are in the real vector rvec. For example the minimum of



FUNC = 100.*(x2-x1*x1)**2. + (1.-x1)**2.



can be found with the commands:



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

return;

end;



rvec=array(2:-1.2 1.0);

call maxf2(func :name test :parms x1 x2

:ivalue rvec :print);

b34srun;



The function name (func), the program name (test) and the parms

are required to be passed. If there is a concern that the

function has more than one minimum, the NLSTART command can be

used to investigate a number of starting values. For example:



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

return;

end;

n=2;

k=10;

a=array(n:-2. 2.);

b=array(n:.5 2.);

call nlstart(a,b,k,s);



do i=1,k

rvec=s(,i);

call maxf2(func :name test :parms x1 x2

:ivalue rvec :print);

enddo;



b34srun;



Note that in the default mode, the commands for maxf1 and

maxf2 are the same. The maxf2 command can optionally pass

a subroutine to calculate the gradiant after the function

and a name of the gradiant after the :name key word. The

set up for this mode of operation is:



/$ MAXF2 is used to minimize a function

/$ Derivatives are supplied in program der

/$ Answers should be x1=.9999 and x2=.9999



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

call outstring(3,3,'Function to be minimized');

call outdouble(36,3,func);

return;

end;



program der;

g(1)= -400.0*(x2*x1))*x1 - 2.*(1.0-x1)**2.;

g(2)= 200.0*(x2-x1*x1);

return;

end;



call print(test);

rvec=array(2:-1.2 1.0);

call echooff;

call maxf2(func g :name test der

:parms x1 x2

:ivalue rvec :print);

b34srun;



Required



func - Function name



:name pgmname - User program to determine func and

optionally the gradiant program name.

:parms v1 v2 - Parameters in the model. These

parameters must be in the function

in the user program pgmname that

determines func. The keyword

:parms MUST be supplied prior to

all keywords except :name.



Optional keywords for MAXF2 are



gradname - The gradiant name is placed after func

if the gradiant is supplied. The

gradiant program is placed after the

function program after name



:print - Print results.



:ivalue rvec - Determines initial values. rvec must

be a vector containing the number of

elements equal to the number of

parameters supplied. Default = .1.



:xscale vec - Vector of n elements to scale x.

Default = 1.0



:fscale real - Functional scaling. Default = 1.0.



:ngood int - Sets number of good digits in the

function.



:maxit int - Maximum number of iterations.

Default = 100.



:maxfun int - Maximum number of function

evaluations. Default = 400



:maxg int - Maximum number of gradiant

evaluations. Default = 400





:gradtol real - Scaled gradiant tolerance.

Default = eps**(1/3).



:steptol real - Scaled step tolerance.

Default = eps**(2/3).



:rftol real - Relative functional tolerance.

Default = max(1.0d-20,eps**(2/3)).



:aftol real - Absolute functional tolerance.

Default = max(1.0d-20,eps**(2/3)).



:fctol real - False convergence tolerance.

Default = 100.*eps.

:maxsteps real - Maximum allowable step size.

Default = (1000*max(tol1,tol2)) where

tol1=

sqrt(sum of (xscale(i)*ivalue(i))**2

for i=1,n

tol2 = 2-norm of XSCALE



:ihessian key - where key is 0 to initialize hessian

to identity matrix. This is default.

If key NE 0, hessian initialized to

max(|f(XGUESS|,FSCALE)*XSCALE(i)



Warning: If you are not sure how to change a parameter, use

the default.



Note: MAXF2 automatically creates the following variables



%coef - a vector containing the parameters.



%nparm - a vector with coefficient names



%se - a vector containing parameter standard errors



%t - a vector containing parameter t scores



%hessian - hessian matrix



%grad - estimate of gradiant at final parameter values



%func - final value of function



Notes from IMSL: MAXF2 is based on the a safeguarded quadratic

interpolation method to find a minimum

point of a univariate function. Both the code

and the underlying algorithm are based on the

routine ZXLSF written by M.J.D. Powell at the

University of Cambridge. The hessian is

calculated using the BFGS approximation.



Example:



b34sexec matrix;

* MAXF2 is used to minimize a function ;

* Answers should be x1=.5 and x2=1.0 ;

* Problem from Matlib Optimization toolbox page 1-6 ;

* Problem used as a test case in MATLAB fmins function ;



program test;

func=-1.0*dexp(x1)*((4.*x1*x1)+(2.*x2*x2)+

(4.*x1*x2)+(2.*x2)+1.0);

call outstring(3,3,'Function');

call outdouble(36,3,func);

call outdouble(4, 4, x1);

call outdouble(36,4, x2);

return;

end;



call print(test);

rvec=array(2:-1., 1.0);

call echooff;

call maxf2(func :name test :parms x1 x2 :ivalue rvec

:print);

b34srun;



MAXF3 - Maximize a function using simplex method (DU2POL).



call maxf3(func :name test :parms x1 x2 :ivalue rvec

:print);



The MAXF3 function provides a way to maximize a function using

function comparison. No smoothness is assumed. While this

approach is not efficient for smooth problems, it is quite

useful when the function is not smooth. The procedure assumes

n+1 points x(1),...,x(n+1). At each iteration a new point is

generated to replace the worst point x(j) which has the

smallest functional value among the n+1 points. The new point

is x(k)=c+alpha*(c-x(j)) where c = (1/n) sum x(i) for i ne j.

Alpha is the reflection coefficient. For further detail see

IMSL documentation.



If the functional value is multiplied by -1.0, a minimum

can be obtained. MAXF3 does produce SE's but is useful in

obtaining starting values.



A simple setup for a maximum / minimum is:



call maxf3(func :name test :parms x1 x2 :ivalue rvec

:print);





where func is a scalar computed with the user MATRIX program

test and x1 and x2 are parameters. Initial guess values for

x1 and x2 are in the real vector rvec. For example the

minimum of



FUNC = 100.*(x2-x1*x1)**2. + (1.-x1)**2.



can be found with the commands:



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

return;

end;



c=array(2:-1.2 1.0);

call maxf3(func :name test :parms x1 x2

:ivalue rvec :print);

b34srun;



The function name (func), the program name (test) and the parms

are required to be passed. If there is a concern that the

function has more than one minimum, the NLSTART command can be

used to investigate a number of starting values. For example:



b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

return;

end;



n=2;

k=10;

a=array(n:-2. 2.);

b=array(n:.5 2.);

call nlstart(a,b,k,s);

do i=1,k

rvec=s(,i);

call maxf3(func :name test :parms x1 x2

:ivalue rvec :print);

enddo;

b34srun;



Note that in the default mode, the commands for maxf1, maxf2

and maxf3 are the same.



Required



func - Function name



:name pgmname - User program to determine func and

optionally the gradiant program name.



:parms v1 v2 - Parameters in the model. These

parameters must be in the

function in the user program

pgmname that determines func.

The keyword :parms MUST be supplied

prior to all keywords except :name.



Optional keywords for MAXF3 are:





:print - Print results.



:ivalue rvec - Determines initial values. Rvec must

be a vector containing the number of

elements equal to the number of

parameters supplied. Default = .1.

:length real - Estimate of length of each side

of initial. Default = 1.0.

Final value saved in %length



:ftol real - Convergence tolerence. Default=1.d-10.



:maxit int - Maximum number of iterations.

Default = 100.



MAXF3 automatically creates the following variables



%coef - a vector containing the parameters.



%nparm - a vector with coefficient names



%length - Average distance from the vertices to

the centroid. The larger the returned

value the flatter the function in the

neighborhood of the returned point.



%func - final value of function



The iterations proceed until:



1. # of iteratiions is reached.



2. func(best)-func(worst) LE ftol*(1+dabs(f(best))



3. sum(1,...,(n+1))(f(i)-(sum(f(j))/(n+1))**2 LE ftol



Example showing starting from various positions





b34sexec matrix;

* MAXF3 is used to minimize a function ;

* Answers should be x1=.9999 and x2=.9999 ;

* Problem tests if starting values make a difference ;

* Problem is classic Rosenbrock banana problem. ;

* Problem used in IMSL & MATLAB fmins function ;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

call outstring(3,3,'Function');

call outdouble(36,3,func);

call outstring(3,4,'Test case ');

call outinteger(36,4,i);

call outdouble(4, 5, x1);

call outdouble(36,5, x2);

return;

end;



call print(test);

n=2;

k=10;

a=array(n: -3., -3.);

b=array(n: 3., 3.);

coef=array(k,2:);

result=array(k:);

ak =array(k:);

bk =array(k:);

call nlstart(a,b,k,s); call print(s);



call echooff;



do i=1,k;

rvec=s(,i);

ak(i)=rvec(1);

bk(i)=rvec(2);

call maxf3(func :name test :parms x1 x2 :ivalue rvec

:maxit 400 :print);

result(i)=%func;

coef(i,)=%coef;

enddo;



call tabulate(result,ak,bk);

call print('Answers from various starting values ',coef);

call graph(result :heading 'Function value found');

b34srun;



MELD - Form all possible combinations of vectors.



call meld(x,y,z);



Forms all possible combinations of x, y, z. Variables x, y, and

z must be same length. Values are not checked.



Note: Up to 100 vectors can be supplied.



Example:



b34sexec matrix;

i=array(:1. 2. 3.);

j=array(:4.,5.,6.);

k=array(:7.,8.,9.);

call tabulate(i,j,k);

call meld(i,j,k);

f=i**2.+j**2.+k**2.;

call tabulate(i,j,k,f);

b34srun;



Output



Obs I J K

1 1.000 4.000 7.000

2 2.000 5.000 8.000

3 3.000 6.000 9.000

=> CALL MELD(I,J,K)$





=> F=I**2.+J**2.+K**2.$





=> CALL TABULATE(I,J,K,F)$





Obs I J K F

1 1.000 4.000 7.000 66.00

2 1.000 4.000 8.000 81.00

3 1.000 4.000 9.000 98.00

4 1.000 5.000 7.000 75.00

5 1.000 5.000 8.000 90.00

6 1.000 5.000 9.000 107.0

7 1.000 6.000 7.000 86.00

8 1.000 6.000 8.000 101.0

9 1.000 6.000 9.000 118.0

10 2.000 4.000 7.000 69.00

11 2.000 4.000 8.000 84.00

12 2.000 4.000 9.000 101.0

13 2.000 5.000 7.000 78.00

14 2.000 5.000 8.000 93.00

15 2.000 5.000 9.000 110.0

16 2.000 6.000 7.000 89.00

17 2.000 6.000 8.000 104.0

18 2.000 6.000 9.000 121.0

19 3.000 4.000 7.000 74.00

20 3.000 4.000 8.000 89.00

21 3.000 4.000 9.000 106.0

22 3.000 5.000 7.000 83.00

23 3.000 5.000 8.000 98.00

24 3.000 5.000 9.000 115.0

25 3.000 6.000 7.000 94.00

26 3.000 6.000 8.000 109.0

27 3.000 6.000 9.000 126.0



Example # 2:



b34sexec matrix;

a1=-.5;

a2= .5;

b1= .6;

b2= 1.8;



do i=1,4;

x=grid(a1,a2,.125);

y=grid(b1,b2,.125);

call meld(x,y);

z=100. * (y-x*x)**2. + (1.-x)**2.;

call graph(x,y,z :plottype contour3

:heading 'Rosenbrock Banana');

call graph(x,y,z :plottype contourc

:heading 'Rosenbrock Banana');

a1=a1-1.;

a2=a2+1.;

b1=b1-1.;

b2=b2+1.;

enddo;



b34srun;



MENU - User Menus for Input



call menu(i :menutype key :heading);



Allows user menus for input in matrix command.



i = initial selection for menu options.

On output it the selection. Escape returns 0.



For input options it is the variable to be

input.



For input text if a blank line is supplied

a character*1 variable with one blank element is

returned.



:menutype key



=> menutwo Two choice menu

=> menuhoriz Horizontal menu

=> menuvert Vertical menu

=> inputint Input integer menu

=> inputreal8 Input real*8 menu

=> inputtext Input text



:heading character



used for menuhoriz, menuvert



:text 'text here'



up to 60 characters for menuvert.

up to 10 for menuhoriz



In place of ' ' can use

character*1 n by 60 array



Max Number of terms is 500





:prompt 'text here'



used for menutwo, inputint, inputr8, inputtext

max size = 60

:position index(0 0)



sets x and y position defaults to zero



Examples:



call menu(i :menutype menutwo

:text 'stop'

:text 'go'

:prompt 'Continue with graph?'

);

call print('i found to be ',i);



call menu(i :menutype menuhoriz

:text 'file'

:text 'save'

:text 'stop'

:heading 'Process Control'

);

call print('i choice found ',i);



call menu(i :menutype menuvert

:text 'Use raw data '

:text 'Use (1-B)*X '

:text 'Use (1-B)**2. * X'

:heading 'ACF Control'

);

call print('i choice found ',i);



call menu(i :menutype inputint

:prompt 'Input # of cases'

);

call print('# of cases found ',i);



call menu(r8 :menutype inputreal8

:prompt 'Input Tolerance'

);

call print('Tolerance found ',r8);



call menu(cc :menutype inputtext

:prompt 'Input save file name'

);

call print(' file name >',cc);





MESSAGE - Put up user message and allow a decision.



call message(char1,char2,i);



Puts up a message, char1, in a window with title

char2. I will return 21 for OK or 23 for Cancel.



Example:

call message('Want to stop','Control',i);

if(i.eq.21)go to part10;

if(i.eq.23)go to part20;



MINIMAX - Minimax Estimation with MAXF2



call minimax;



Minimax estimation with MAXF2 allows calculation of SE's of

coefficients. Note, minimax is a program contained in

matrix2.mac. Before use it must be loaded with:



call load(minimax);



Arguments that must be in work space at level 100



y = Left Hand side



x = Matrix of regressors

with constant in col 1



iprint = 0 => do not print

= 1 => print



The following are created *****



Coef = estimated coefficients



Sumabs = sum absolute errors



Maxerror = maximum abs error



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call echooff;

call loaddata;

call olsq(gasout gasin :l1 :minimax :print);



/$ This code gets SE for Minimax. Uses MAXF2



call load(minimax);

call print(minimax);



* See if can get minimax ;



iprint=1;

y=gasout;

x=matrix(norows(gasin),2:);

x(,1)=1.0;

x(,2)=vfam(gasin);



call minimax;

call print('Sum absolute errors ',sumabs:);



b34srun;



MISSPLOT Plot of a series with Missing Data



subroutine missplot(y,points,dots,noline,title);

/;

/; Plot a Series with Missing Data inside the series

/;

/; y => Actual Data

/; points => if 1 mark points

/; dots => if 1 use a dotted line

/; noline => if 1 no line

/; title => Title

/;

/; ***************************************************

/; Version 8 August 2001

/; ***************************************************



Note: This program must be loaded prior to use.



Example:



b34sexec matrix;

call load(missplot);

y=rn(array(20:));

call character(title,'Test missplot Plot');



y(3)=missing();

points=0;

dots=0;

noline=0;

call missplot(y,points,dots,noline,title);

call missplot(y,1 ,dots,noline,title);

call missplot(y,points,1 ,noline,title);

call missplot(y,1 ,1 ,0 ,title);

call missplot(y,1 ,dots,1 ,title);

b34srun;



MQSTAT - Multivariate Q Statistic



call mqstat(x,maxlag);



Calculates Multivariate Q Statistic



x = 1 or 2 dimensional real*8 object



maxlag = Maximum lag for Q stat



Optional arguments



:print => print results

:squared => Test squared series



:npar n => # of parameters. Assumed to be k*k

where k is # of cols of x



Data Create



%qorg1 = Original Q statistic Ljung-Box (1978)



%qnew1 = Hosking (1980) Multivariate Q



%qstar1 = Li & McLeod (1981) Multivariate Q



Tests of squared series if :squared found



%qorg2 = Original Q statistic Ljung-Box



%qnew2 = Hosking (1980) Multivariate Q



%qstar2 = Li & McLeod Multivariate Q



%sqorg1 = Significance on %gorg1



%sqnew1 = Significance on %qnew1



%sqstar1 = Significance of %qstar1



%df = Degrees of freedom



%sgorg2 = Significance on %gorg2

%sqnew2 = Significance on %qnew2

%sqstar2 = Significance of %qstar2



Example



b34sexec scaio readsca

/$ file('/usr/local/lib/b34slm/findat01.mad')

file('c:\b34slm\findat01.mad')

dataset(m_ibmln2); b34srun;



b34sexec matrix;

call loaddata;

x=array(norows(ibmln),2:);

x(,1)=ibmln;

x(,2)=spln;

call mqstat(x,12 :print :squared :npar 4);

b34srun;



References: See Tsay (2002) pages 302-308



MOVEAVE Moving average of a vector



call moveave(x,nobs,ma);

Calculates a moving average of a vector



x = vector of input data



nobs = # of obs in moving average



ma = moving average vector



Usage



call moveave(x,10,ma);



Example:



b34sexec matrix;

call echooff;

call load(moveave);

call load(movevar);

n=20;

a=array(n:integers(n));

call print('Mean of a',mean(a));

call moveave(a,norows(a),test);

call print('Test of MA where use whole period',test);

call moveave(a,2,test2);

call moveave(a,3,test3);

call print('Two & Three period Moving average');

call tabulate(a,test2,test3);



call print(a);

call print('Variance of a',variance(a));

call movevar(a,norows(a),test);

call print('Test of MVAR where use whole period',test);

call movevar(a,4,test4);

call movevar(a,5,test5);

call print('4 & 5 period Moving Variance');

call tabulate(a,test4,test4);

b34srun;



Test program: moveave



MOVEBJ Moving Arima Forecast using AUTOBJ



call movebj(series,iseas,ibegin,actual,fore,

obs,nout,iprint,rdif,sdif);



Moving Arima Forecast using AUTOBJ



subroutine movebj(series,iseas,ibegin,actual,fore,

obs,nout,iprint);

/;

/; Does within sample moving forecasts

/;

/; series => Series to forecast

/; seasonal => seasonal period (must be ge 0)

/; ibegin => Seriod to start forecast

/; actual => Actual Data

/; fore => nout step ahead moving forecast

/; obs => Observation Number

/; nout => # of period ahead forecast

/; iprint => =0 => no printing, =1 => print models

/; rdif => if set ne 0 forces differencing

/; sdif => if set ne 0 forces seasonal differencing

/;



Example:



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;

call load(movebj);



call print(movebj);

call echooff;



nout=1;

iseas=0;

ibegin=200;

iprint=0;

rdif=0;

sdif=0;



call movebj(gasout,iseas,ibegin,actual,

fore,obs,nout,iprint,rdif,sdif);

call tabulate(obs,actual,fore);

call graph(obs fore,actual :plottype xyplot

:nolabel

:heading '1 step ahead moving forecast');



nout=3;

call movebj(gasout,iseas,ibegin,

actual,fore,obs,nout,iprint,rdif,sdif);

call tabulate(obs,actual,fore);

call graph(obs fore,actual :plottype xyplot

:nolabel

:heading '3 step ahead moving forecast');



b34srun;



MOVECORR Moving Correlation of two vectors



call movecorr(x,y,nobs,cvec,nlag);



Moving Correlation of two vectors



subroutine movecorr(x,y,nobs,cvec,nlag);

/;

/; Moving correlation of two vectors

/;

/; x = vector of input data 1

/; y = vector of input data 2

/; nobs = # of obs in moving correlation

/; cvec = moving correlation vector

/; nlag = number of lags for cross correlations

/;

/; Usage call movecorr(x,y,10,cvec,0);





Example:



b34sexec options ginclude('gas.b34');

b34srun;



b34sexec matrix;

call loaddata;

call load(movecorr);

call echooff;

n=60;

call movecorr(gasin,gasout,n,cvec,0);

call print(cvec);

call graph(cvec(,1));

call movecorr(gasin,gasout,n,cvec,10);

call print(cvec);

call echoon;

b34srun;



Note: movecorr is a subroutine from matrix2.mac.

It must be loaded with



call load(movecorr);



Test program: movecor



MOVEH82 Moving Hinich 82 test



call moveh82(x,10,g,l,1);



Calculates moving Hinich 1982 Nonlinearity test



subroutine moveh82(x,nobs,g,l,ismoo);

/; x = vector of input data

/; nobs = # of obs in test

/; g = Hinich gaussianity test

/; l = Hinich linearity test

/; ismoo = 0 => do not smooth, =1 smooth

/;

/; Usage call moveh82(x,100,g,l,1);



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call echooff;

call loaddata;

call load(moveh82);

n=200;

call moveh82(gasout,n,g1,l1,1);

call tabulate(g1,l1);

call graph(g1,l1);

call echoon;

b34srun;



Test program: MOVEH82



MOVEH96 Moving Hinich 96 test



call moveh96(x,nobs,c,v,h);



Moving Hinich 1996 test.



subroutine moveh96(x,nobs,c,v,h);

/; x = vector of input data

/; nobs = # of obs in moving average

/; c = sets # of lags. Must be GE 0

/; v = second order test

/; h = third order test

/;

/; Usage call moveh96(x,nterm,c,v,h);



Note: Unlike Hinich 1982 test, here the series must be white

noise before the test is applied.



Example:



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;

call load(moveh96);

call echooff;

call olsq(gasout gasout{1 to 12});

call graph(gasout);

call graph(%res);

n=200;

call moveh96(%res,n,0.0,v,h);

call tabulate(v,h);

call graph(v,h);

call echoon;

b34srun;



Test program: MOVEH96



MOVEOLS Moving OLS with LAGS



call moveols(x,y,nobs,RSS,RSQ,resvar,nlag,nxlag);

Moving OLS model of two vectors of form

y(t)=f(y(t-1),...,y(t-nlag),x(t-nxlag),...,x(t-nlag))



subroutine moveols(y,x,nobs,rss,rsq,resvar,nlag,nxlag);

/;

/; Moving OLS model of two vectors of form

/; y(t)=f(y(t-1),...,y(t-nlag),x(t-nxlag),...,x(t-nlag))

/;

/; x = vector of input data 1

/; y = vector of input data 2

/; nobs = # of obs in moving OLS model

/; rss = moving residual sum of squares vector

/; rsq = moving centered R**2

/; resvar = moving residual variance

/; nlag = number of lags

/; nxlag = Number of lags on x

/; Usage call moveols(y,x,90,rss,rsq,resvar,10,1);



MOVEOLS is a subroutine in matrix2.mac. It must be loaded with



call load(moveols);



Example:



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;

call load(moveols);

call echooff;

n=60;

call moveols(gasout,gasin,n,rss,rsq,resvar,6,1);

call tabulate(rss,rsq,resvar);

call graph(rss :heading 'Moving rss for gasout');

call graph(rsq :heading 'Moving R**2 for gasout');

call graph(resvar :heading 'Moving resvar for gasout');

call echoon;

b34srun;



Test program: MOVEOLS



MOVEVAR Moving Variance



call movevar(x,nobs,mvar);



Calculates a moving variance.



subroutine movevar(x,nobs,mvar);

/; x = vector of input data

/; nobs = # of obs in moving average

/; mvar = moving variance vector

/;

/; Usage call movevar(x,10,ma);

Example:



b34sexec matrix;

call echooff;

call load(moveave);

call load(movevar);

n=20;

a=array(n:integers(n));

call print('Mean of a',mean(a));

call moveave(a,norows(a),test);

call print('Test of MA where use whole period',test);

call moveave(a,2,test2);

call moveave(a,3,test3);

call print('Two & Three period Moving average');

call tabulate(a,test2,test3);



call print(a);

call print('Variance of a',variance(a));

call movevar(a,norows(a),test);

call print('Test of MVAR where use whole period',test);

call movevar(a,4,test4);

call movevar(a,5,test5);

call print('4 & 5 period Moving Variance');

call tabulate(a,test4,test4);

b34srun;



Test program: MOVEVAR



NAMES - List names in storage.



call names;



Lists all names in the allocator.



Name info is saved in the array %NAMES% and type info in

%NAMESL% if : is included in the call.



Alternative forms include:



call names(info);



To list information about names in allocator and



call names(all);



To list all names at all levels. The command



call names(LISTFREE);



Lists what was free at the time of the call. This is not for

general use.



call names(dostat);

saves



%donow - # of do loop

%down - How many subroutine calls we are down

%dowhile - # of do while



Example:



b34sexec matrix;

subroutine test(i);

call print('in test');

call names(dostat);

call print(%down,%donow,%dowhile,ifnow);

return;

end;



call names(dostat);

call print(%down,%donow,%dowhile,%ifnow);



do i=1,2;

call names(dostat);

call print(%down,%donow,%dowhile,%ifnow);



if(i.eq.1)then;

call names(dostat);

call print(%down,%donow,%dowhile,%ifnow);

endif;



call test(1);

enddo;



b34srun;



NLEQ - Jointly solve a number of nonlinear equations.



call nleq(func :name test :parms x1 x2

:ivec rvec :nsig 5 :maxit 200);



The NLEQ function provides a quick way to solve N nonlinear

equations. NLEQ is based on the MINPACK HYBRD1 routine

which in the IMSL ZSPOW routine. A simple setup to

solve a system of equations is:



call nleq(func :name test :parms x1 x2

:ivec rvec :nsig 5 :maxit 200);



where func is a vector of left hand sides. At the solution

the elements of func should be as small as possible. Func

is computed using the user PROGRAM test. x1 and x2 are

parameters. Initial guess values for x1 and x2 are in the

real vector rvec.



Required

func - Function name



:name pgmname - User program to determine func



:parms v1 v2 - Parameters in the model. These

parameters must be in the function

in the user program pgmname that

determines func. The keyword

:parms MUST be supplied prior to

all keywords except :name.



Optional keywords for NLEQ are:



:print - Print results



:ivalue rvec - Determines initial values. rvec

must be a vector containing the

number of elements equal to the

number of parameters supplied.

Default = .1.



:nsig i - Sets number of digits of accuracy

for convergence. Default = 4.



:maxit n - Number of iterations. Default = 200.

The maximum number of calls to the

user program is maxit*(n+1) where

n = number of parameters.



NLEQ automatically creates the following variables



%coef - a vector containing the parameters.



%nparm - a vector with coefficient names



%func - final value of function





Example:



The solution of



0.0 = x1 + exp(x1 - 1.0) +(x2+x3)*(x2+x3)

0.0 = exp(x2-2.0)/x1+x3*x3

0.0 = x3+sin(x2-2.0)+x2*x2



with answers:



FNORM = 0.0, x1 = 1.00001, x2 = 2.0000, x3 = 3.00000



can be found with the commands:



b34sexec matrix;

program test;

func(1)=x1 + dexp(x1 - 1.0) +(x2+x3)*(x2+x3);

func(2)=dexp(x2-2.0)/x1+x3*x3;

func(3)=x3+dsin(x2-2.0)+x2*x2;

return;

end;



rvec=array(3:4.0 4.0 4.0);

call nleq(func :name test :parms x1 x2 x3

:ivec rvec :nsig 5 :maxit 200);



b34srun;



NLLSQ - Nonlinear Least Squares Estimation.



The NLLSQ command estimates a nonlinear least squares

problem for real*8 and real*16 data and is called by:



call nllsq(y yhat :name pgmname :parms b1 b2 b3);



Required arguments & keywords:



y - an existing real*8 or real*16 variable.



yhat - The name of the yhat vector given

parameters listed after :parms. If yhat

is to be used after the nllsq command

exits, be sure to issue the command



call pgmname;



to refresh this variable.



:name pgmname - specifies a user PROGRAM to calculate

yhat using the parameters listed after

the required keyword :parms.



:parms b1 b2 - Specifies parameters of nonlienar model.

The parameters can be set as scalars or

as a vector. If a vector is supplied,

only one vector can be used.If starting

values are not supplied, the program

automatically assumes .01.



Optional keywords include:



:print key - where key values are RESULT, ITER,

RESIDUALS to print the results, the

iterations or the residuals

respectively.



:eps1 r1 - where r1 is a real number set to the

maximum relative change in the sum of

squares before iteration stops. Unless

set, this stopping rule is not used.

Default = 0.0.



:eps2 r2 - where r2 is a real number set to the

maximum relative change in each

parameter before iteration stops.

Default = .004.



:flam r3 - where r3 is the starting lamda for

Marquardt iteration. Default = .01.

If there are problems, increase flam

to 1.0.



:flu r4 - where r4 is the parameter to control

flam. Marquardt recommends 10. Flu

must be set > 1.0. Default = 10.0.



:restrict ivec - where ivec is an integer vector with

elements 1 and 0 corresponding to

whether there is or is not a sign

change restriction is imposed.



:diff dd - where var is a vector with the same

number of elements as the number of

parameters. The vector dd controls the

numerical evaluation of the partial

derivatives. The default value is .01.

If diff is supplied, all values must

be in the range 0 le dd(i) le 1.0



:ivalue rvec - where rvec is a vector of initial

values. Initial values can also be set

with analytic statements before the

NLLSQ command is called but must be

passed in the rvec vector. Unless this

is done, the default .1 will be used.



:maxit i2 - where i2 is the maximum number of

iterations. Default = 20.



:forcese - Force calculation of SE even if have

obtained a warning message. This

switch can bring down the program with

a divide check. Its use is obtaining

benchmark answers if possible.



Note: The internal names for these switches are %result,

%iter, %eps1, %eps2, %flam, %flu, %restrict, %diff,

%ivalue, %maxit. If an array is supplied for :parms,

only one variable can be passed. :restrict, :diff, and

:ivalue must be supplied AFTER :parms so that the number

of parameters has been set.

The nllsq command creates the following vectors:



%coef - a vector containing the parameters



%nparm - A vector with coefficient names



%se - a vector containing parameter standard errors



%t - a vector containing parameter t scores.



%fss - final sum of squares



%see - final standard error of estimate



%arsq - adjusted r**2



%resvar - residual variance



%corrmat - correlation matrix of estimated parameters



%nob - Number of observations



%res - Error vector



Notes: The user must supply a model to calculate YHAT using

the parameters. The precision of YHAT must be the same

as y (real*8 or real*16). If YHAT contains less

observations than the left hand side variable Y, then

observations are automatically dropped off the front of

Y. Note that the user subroutine must be called after

the nllsq command exits to access yhat.



The following jobs illustrate use of the NLLSQ command:



OLS Example



/$ Nonlinear Estimation using NLLSQ Command under matrix

/$ OLS Model estimated using nonlinear methods

/$ and using REG command

b34sexec options ginclude('b34sdata.mac')

member(res72); b34srun;

b34sexec reg; model lnq=lnk lnl lnrm1 time; b34srun;

b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;

call tabulate (q l k m1dp time);



program res72;

call echooff;

yhat=a+g1*lnk + g2*lnl +r*lnrm1 + v*time;

return;

end;



call print(res72);

call nllsq(lnq,yhat :name res72 :parms a r g1 g2 v

:print result residuals);

call graph(%res);



b34srun;



/$ Illustrate lags using both commands



b34sexec reg; model lnq=lnk lnk{1} lnl lnrm1 time;

b34srun;

b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;



program res72;

call echooff;

i=integers(norows(lnk)-1);

yhat(i)= g1*lnk(i+1)+ gnew*lnk(i)+g2*lnl(i+1)+

r*lnrm1(i+1)+v*time(i+1) +a;

return;

end;



call nllsq(lnq,yhat :name res72 :parms a r g1 gnew g2 v

:print result residuals);

call res72;

%yhat=yhat;

call graph(%res); call print(yhat);

b34srun;



CES Production Function using NLLSQ



/$ CES Model estimated using nonlinear methods

b34sexec options ginclude('b34sdata.mac')

member(res72); b34srun;

b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;



program res72;

call echooff;

yhat=a*((g1*(k**r)) + (g2*(l**r)) +

((1.0-g1-g2)*(m1dp**r)) )**(v/r);

return;

end;



call print(res72);



call nllsq(q,yhat :name res72 :parms g1 g2 a r v

:maxit 50 :flam 1. :flu 10. :eps2 .004

:ivalue array(:.2769 .7754 1.0,-.05 1.8)

:print result residuals);

call graph(%res);

call print(mean(%res));

call names;

call print(%corrmat); call tabulate(%coef,%se,%t);



Complex CES and GLS CES Models



b34sexec options ginclude('b34sdata.mac')

member(res72); b34srun;

b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;

* Problem 1 is very very hard !!!!!! ;



* problem=1;



program res72;

call echooff;

yhat=a*(g1*k**r+(1.0-g1)*l**r)**(v/r);

return;

end;



call print(res72);

call nllsq(q,yhat :name res72 :parms g1 a v r

:maxit 50 :flam 1. :flu 10. :eps2 .004

:ivalue array(:.3053 1.0 1.85 .03)

:print result residuals);

call graph(%res);

b34srun;



b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;



* problem 2 ;

program res72;

call echooff;

yhat=a*(g1*k**r+g2*l**r+(1.0-g1-g2)*(m1/p)**r)**(v/r);

return;

end;



call print(res72);



call nllsq(q,yhat :name res72 :parms g1 g2 a r v

:maxit 50 :flam 1. :flu 10. :eps2 .004

:ivalue array(:.27698 .7754 1.,-.05 1.8)

:print result residuals);

call graph(%res);

b34srun;



b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;



* problem 3;

program res72;

call echooff;

i=integers(norows(q)-2);

yhat=((a*(g1*k(i+2)**r+g2*l(i+2)**r+

(1.0-g1-g2)*(m1(i+2)/p(i+2))**r)**(v/r))

+ lam1*q(i+1) + lam2*q(i) -

(lam1*a*(g1*k(i+1)**r+g2*l(i+1)**r +

(1.0-g1-g2)*(m1(i+1)/p(i+1))**r)**(v/r)) -

(lam2*a*(g1*k(i )**r+g2*l(i )**r+

(1.0-g1-g2)*(m1(i+2)/p(i ))**r)**(v/r)));

return;

end;



call print(res72);



call nllsq(q,yhat :name res72 :parms g1 g2 a r v lam1 lam2

:maxit 500 :flam .1 :flu 10. :eps2 .004

:ivalue array(:.27698,.7754,1.00,.05,1.8,.8,-.6)

:print result iter residuals);

call graph(%res);

b34srun;



b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;

* CES GLS Models ;

* problem=4;

program res72;

call echooff;

i=integers(norows(q)-2);

yhat=((dexp(tt*dfloat(i+2))*a*(g1*k(i+2)**r+g2*l(i+2)**r+

(1.0-g1-g2)*(m1(i+2)/p(i+2))**r)**(v/r))

+ lam1*q(i+1) + lam2*q(i) -

(lam1*dexp(tt*dfloat(i+1))*a*(g1*k(i+1)**r+g2*l(i+1)**r+

(1.0-g1-g2)*(m1(i+1)/p(i+1))**r)**(v/r)) -

(lam2*dexp(tt*dfloat(i)) *a*(g1*k(i)**r+g2*l(i)**r+

(1.0-g1-g2)*(m1(i+2)/p(i ))**r)**(v/r)));

return;

end;



call print(res72);



call nllsq(q,yhat :name res72

:parms g1 g2 a r v tt lam1 lam2

:maxit 500 :flam .1 :flu 10. :eps2 .004

:ivalue array(:.27698 .7754 1.00 .05 1.8 .0004 .8,-.6)

:print result iter residuals);

call graph(%res);

b34srun;



Real*8 vs Real*16 Code (See NLLSQ_R16 job)



/; Illustrates Nonlinear Estimation using NLLSQ Command

/; under matrix using real*8 and real*16 paths.

/; This case does not make a diffference if good starting

/; values are used. Note when terrible starting values

/; are used (.1) the Real*16 approach will recover while

/; the real*8 dies.

/;

/; This suggests that real*16 may be more "robust" to

/; starting values. Note that this problem generates

/; error messages entering the complex domain.

/;

/; VPA math can be used insdie a function provided that

/; the parameters and yhat etc are copied back to real*8

/; or real*16 as appropriate.

/;

%b34slet showgraph=yes;



b34sexec options ginclude('b34sdata.mac')

member(res72); b34srun;

b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;

* Problem 1 is very very hard !!!!!! ;



* problem=1;

program res72;

call echooff;

yhat=a*(g1*k**r+(one-g1)*l**r)**(v/r);

call outstring(3,3,'Coefficients');

call outstring(3,4,'g1 v r');

call outdouble(14,4,g1);

call outdouble(34,4,v);

call outdouble(50,4,r);

return;

end;



call print(res72);

one=kindas(q,1.0);

call nllsq(q,yhat :name res72 :parms g1 a v r

:maxit 500 :flam 1. :flu 10. :eps2 .1e-14

:ivalue array(:.3053 1.0 1.85 .03)

/$ :ivalue array(: .1 .1 .1 .1)

:print result);

resr8=%res;



call print('real*16 results',:);

q=r8tor16(q);

k=r8tor16(k);

l=r8tor16(l);



one=kindas(q,1.0);

call nllsq(q,yhat :name res72

:parms g1 a v r

:maxit 500 :flam 1. :flu 10. :eps2 .1e-14

/$ :ivalue array(:.3053 1.0 1.85 .03)

:ivalue array(: .1 .1 .1 .1)

:print result);

resr16=%res;



diff=(resr8-r16tor8(%res));

call tabulate(resr8,resr16,diff);



%b34sif(&showgraph.eq.yes)%then;

call graph(r16tor8(%res));

call graph((resr8-r16tor8(%res)));

%b34sendif;



b34srun;



Notes:



The Nonlinear GLS jobs make use of the fact that if the yhat

variable contains less observations than the y variable,

observations will be automatically dropped off the beginning of

the y variable. The user can place other commands in the

PROGRAM to output values as the solution proceeds. This is

recommended since it gives a visual record of how the

nonlinear surface is "seen" by the software. If speed of the

solution is important, these fetures can be turned off with

the /$ command. It is NOT recommended that the * test ;

comment be used since this has to be "parsed" at each

iteration. A /; comment is stripped out.



Some Comments on nonlinear mdoeling:



NLLSQ can be used to provide initial values for use with

NL2SOL which provides an alternative way to do non-linear

least squares. It is recommended that both be used as a check.



Of the two programs, no one dominates. Interested users can

inspect and run the nonlinear jobs in stattest.mac that

implement a number of very hard nonlinear problems for which

there are known answers.



The whole issue of SE's for nonlinear least squares is up in

the air. While both NLLSQ and NL2SOL produce SE's that are

asymptotically the same, in limited samples differences will

show up. For these and other reasons it it recommended that

multiple software systems be used before final models are

published. It addition all results should report the software

used, the command used and the release of the software. It

additionn is is a good idea to saave scripts. Convergence

tolerance and other controls often make a substantial

difference. Beware of default values.



NL2SOL - Alternative Nonlinear Least Squares Estimation path.



The NL2SOL command uses the Dennis-Gay-Welsch (1981),

subroutine NL2SOL that was documented in

"An adaptive nonlinear least-squares algorithm," ACM Trans.

Math. Software, vol. 7, no. 3.



to minimize the sum of squares of a vector. The NL2SOL command

can be used for least squares problems and for maximum/minimum

problems provided that the dsqrt of the objective function can

be calculated.



Discussison: Given a p-vector x of parameters, an n-vector of

residuals corresponding to x r(x) is calculated using program

TEST.. r(x) probably arises from a nonlinear model involving p

parameters and n observations. NL2SOL seeks a parameter vector

x that minimizes the sum of the squares of (the components of)

r(x), i.e., that minimizes the sum-of-squares function



f(x) = (r(x) * r(x) / 2.



r(x) is assumed to be a twice continuously differentiable

function of x.



The subroutine NL2SOL is very complex and provides a number of

features for the expert user. NLLSQ is probably a better first

choice. Both routines can be used together. In many problems

NLLSQ works better, while in others NL2SOL works better.

The file stattest.mac has many problems where there are "known"

answers. NLLSQ, NL2SOL and RATS are tested using various

starting values. Users should study these setups closely. The

version of Rats used is most important. There have been

substantial changes in Rats since version 5.xx.



call nl2sol(res :name test :parms a1 a2 :print);



uses analytic derivatives while



call nl2sol(res j :name test1 test2 :parms a1 a2 :print);



provides derivatives in the program test2





Required arguments & keywords:



res - an existing real*8 or real*16 vector or

array of length n. n must be GE p where

p is the number of parameters.



:name pgmname - specifies a user PROGRAM to calculate

res using the parameters listed after

the required keyword :parms. If the

parameters are such that res(i) would

overflow, set %nf to 0.



:parms b1 b2 - Specifies parameters of nonlinear model.

The parameters can be set as scalars or

as a vector. If a vector is supplied,

only one vector can be used. For

purposes of discussion we assume there

are p parameters. If starting values

are not supplied, the program

automatically assumes .01. In some

cases this may not be a good choice.



Optional keywords include:



j - n by p array with the derivatives of the n element

residual vector with respect to the p parameters.

If j is used it must be allocated to the right size

prior to the call to nl2sol.



The derivatives are calculated with the program

test2. If the parameters are such that j(i,k) would

overflow, set %nf2 to 0.



:print - Print results.



:itprint - Print Iterations.



:ivalue r - Supplies a vector of initial values.



:maxfun i - gives the maximum number of function

evaluations. Default = 200.



:maxit i - gives the maximum number of iterations

allowed. Default = 150.



:isum i - Controls the number and length of

iteration summary lines printed.

i=0 means do not print any summary

lines. Otherwise, print a summary line

after each abs(iv(outlev)) iterations.

If iv(outlev) is positive, then summary

lines of length 117 are printed,

including the following:



The iteration and function evaluation

counts, current function value

(v(f) = half the sum of squares),

relative difference in function values

achieved by the latest step

(i.e., reldf = (f0-v(f))/f0, where f0

is the function value from the previous

iteration), the relative function

reduction predicted for the step just

taken (i.e., preldf = v(preduc) / f0,

where v(preduc) is described below),

the scaled relative change in x

(see v(reldx) below), the models used

in the current iteration (g =

gauss-newton, s=augmented), the

marquardt parameter stppar used in

computing the last step, the sizing

factor used in updating s, the 2-norm

of the scale vector d times the step

just taken (ref.), and npreldf, i.e.,

v(nreduc)/f0, where v(nreduc) is

described below. If npreldf is

positive, then it is the relative

function reduction predicted for a

newton step (one with stppar = 0). If

npreldf is zero, either the gradient

vanishes (as does preldf) or else the

augmented model is being used and its

hessian is indefinite (with preldf

positive). If npreldf is negative, then

it is the negative of the relative

function reduction predicted for a step

computed with step bound v(lmax0) for

use when testing for singular

convergence. If iv(outlev) is negative,

then lines of maximum length 79 are

printed, including only the first 6

items listed above (through reldx).



:afctol r - sets the absolute function convergence

tolerance. If nl2sol finds a point

where the function value (half

the sum of squares) is less than

afctol, program terminates.

Default = max(10**-20, machep**2)



:delta0 r - Factor used in choosing the finite-

difference step size used in computing

the covariance matrix. For component

i, step size = delta0 *

max(abs(x(i)), 1/d(i)) * sign(x(i))

where d is the current scale vector.

If this results a setting %nf=0,

then -0.5 times this step is also

tried.) default = machep**0.5,



:lmax0 r - gives the maximum 2-norm allowed for d

times the very first step that nl2sol

attempts. Default = 100.



:rfctol r - Sets the relative function convergence

tolerance.

Default = max(10**-10,machep**(2/3))



:tuner1 r - Helps decide when to check for false

convergence and to consider switching

models. Default = 0.1.



:xctol - Sets x-convergence tolerance.

Default = machep**0.5.



:xftol - Sets the false convergence tolerance.

If a step is tried that gives no more

than tuner1 times the predicted f

unction decrease and that has



reldx .le. xftol



we have false convergence tolerance.



Default = 100*machep.



Variables Created



%nparm - Coefficient names



%coef - Coefficient values



%se - Coefficient SE



%t - Coefficient t scores



%nob - # of opservations in %res



%k - # of coefficients



%covmat - Covariance Matrix



%scale - Scale vector



%grad - Gradiant



%nfcall - # function evaluations



%nfcov - # Calls to get covariance



%ngcall - # Gradiant calls



%niter - # Iterations



%res - Residual vector



%fss - final sum of squares



%see - final standard error of estimate

if DF > 0.



%resvar - residual variance if DF > 0.



%dgnorm - the 2-norm of (d**-1)*g, where g is the

most recently computed gradient and d

is the corresponding scale vector.

%dstnrm - the 2-norm of d*step, where step is the

most recently computed step and d is

the current scale vector.



%func - the current function value (half the

sum of squares).



%f0 - the function value at the start of the

current iteration.



%nreduc - if positive, is the maximum function

reduction possible according to the

current model, i.e., the function

reduction predicted for a newton step

(i.e.,step = -h**-1 * g, where

g = (j**t) * r is the current

gradient and h is the current

hessian approximation --

h = (j**t)*j for the gauss-newton

model and h = (j**t)*j + s for the

augmented model). %nreduc = 0.0 means h

is not positive definite. If %nreduc is

negative, then it is the negative of

the function reduction predicted for a

step computed with a step bound of

%lmax0 for use in testing for singular

convergence.



%preduc - the function reduction predicted (by

the current quadratic model) for the

current step. This (divided by %f0) is

used in testing for relative function

convergence.



%reldx - is the scaled relative change in x

caused by the current step, computed as

max(abs(d(i)*(x(i)-x0(i)),

1 .le. i .le. p) /

max(d(i)*(abs(x(i))+abs(x0(i))),

1 .le. i .le. p), where x = x0 + step.



%return - Integer coded



3 = x-convergence. The scaled relative

difference between the current

parameter vector x and a locally

optimal parameter vector is very

likely at most v(xctol).



4 = relative function convergence. The

relative difference between the

current function value and its

locally optimal value is very

likely at most v(rfctol).

5 = both x- and relative function

convergence hold.



6 = absolute function convergence. The

current function value is at most

v(afctol) in absolute value.



7 = singular convergence. The hessian

near the current iterate appears to

be singular or nearly so, and a

step of length at most v(lmax0) is

unlikely to yield a relative

function decrease of more than

v(rfctol).



8 = false convergence. The iterates

appear to be converging to a

noncritical point. This may mean

that the convergence tolerances

(v(afctol), v(rfctol), v(xctol))

are too small for the accuracy to

which the function and gradient are

being computed, that there is an

error in computing the gradient, or

that the function or gradient is

discontinuous near x.



9 = function evaluation limit reached

without other convergence

(see iv(mxfcal)).



10 = iteration limit reached without

other convergence (see iv(mxiter)).



11 = stopx returned .true.

=> external interrupt.



13 = f(x) cannot be computed at the

initial x.



14 = Bad parameters passed to assess

(which should not occur).



15 = The jacobian could not be computed

at x.



16 = n or p (or parameter nn to nl2itr)

out of range --

p .le. 0 or n .lt. p or nn .lt. n.



17 = restart attempted with n or p

(or par. nn to nl2itr) changed.

18 = iv(inits) is out of range.



19...45 = v(iv(1)) is out of range.



50 = iv(1) was out of range.







Example of Madsen Problem



b34sexec matrix;

* answers can switch sign;

* Results replicated by maxf1 & maxf2 for coefficients;

* SEs differ;

program test;

r(1)=x1**2. + x2**2. +x1*x2;

r(2)=dsin(x1);

r(3)=dcos(x2);

return;

end;



program test2;

j(1,1) = 2.0*x1 + x2 ;

j(1,2) = 2.0*x2 + x1 ;

j(2,1) = dcos(x1) ;

j(2,2) = 0.0 ;

j(3,1) = 0.0 ;

j(3,2) = (-1.0)*dsin(x2) ;

return;

end;



rvec=array(2:3., 1.0);

call echooff;

r=array(3:);

call nl2sol(r :name test :parms x1 x2

:ivalue rvec

:print :itprint);

rvec=array(2:3., 1.0);

call echooff;

r=array(3:);

j=array(3,2:);

call nl2sol(r j :name test test2 :parms x1 x2

:ivalue rvec

:print :itprint);

b34srun;



Example of NL2SOL vs NLLSQ. Here NL2SOL does a better job in

the e'e sense.



/$

/$ NL2SOL vs NLLSQ

/$

b34sexec options ginclude('b34sdata.mac')

member(res72); b34srun;

b34sexec matrix;

call loaddata;

* Sinai-Stokes RES Data --- Nonlinear Models ;

* Problem 1 is very very hard !!!!!! ;

* problem=1;



program res72;

call echooff;

yhat=a*(g1*k**r+(1.0-g1)*l**r)**(v/r);

res =q-yhat;

call outstring(3,3,'Coefficients');

call outstring(3,4,'g1 v r');

call outdouble(14,4,g1);

call outdouble(34,4,v);

call outdouble(50,4,r);

return;

end;



rvec =array(:.3053 1.0 1.85 .03);

call print(res72);

call timer(t1);

call nllsq(q,yhat :name res72 :parms g1 a v r

:maxit 50 :flam 1. :flu 10. :eps2 .004

:ivalue rvec

:print result

);



call timer(t2);

call print('NLLSQ took ',t2-t1:);



res1=%res;



call timer(t1);

call nl2sol(res :name res72 :parms g1 a v r

:ivalue rvec

:print

/$ :itprint

);

call timer(t2);

call print('NL2SOL took ',t2-t1:);

b34srun;



Example: Fooling nl2sol to "solve: banana



/;

/; Fooling Nl2sol to solve Banana

/;

b34sexec matrix;



program test;

func=-1.0*(100.*(x2-x1*x1)**2. + (1.-x1)**2.);

t=func;

t=-1.*dsqrt(dabs(t));

funcv=vector(3:t,0.0,0.0);

call outstring(3,3,'Function ');

call outdouble(36,3 func);

call outdouble(4, 4, x1);

call outdouble(36,4, x2);

return;

end;



call print(test);



rvec=array(2:-1.2 1.0);

call echooff;

/$ call maxf1(func :name test :parms x1 x2

:ivalue rvec :print);

x1=rvec(1);

x2=rvec(2);

call test;

call nl2sol(funcv:name test :parms x1 x2 :ivalue rvec

:print :itprint);



b34srun;



NLPMIN1 - Nonlinear Programming fin. diff. grad. DN2CONF.





call NLPMIN1(func g :name test :parms x1 x2 :ivalue rvec

:nconst m me :lower lvalues

:upper uvalues :print :maxit it

:iprint key);



Solves a nonlinear programming model where there is a finite

difference gradiant.



Required:



func - Function name



g - Constraint name



:name pgmname - Name of user program to determine

func



:parms v1 v2 - Parameters in the model. These

parameters must be in the function

in the user program pgmname that

determines func. The keyword

:parms MUST be supplied prior to all

keywords except :name.



:nconst M ME - M is the total number of constraints.

ME is the number of equality

constraints. M and ME can be set to

zero. In this case have a dummy

g(1)=0.0; statement in the test

subroutine. For this type of problem

the more specialized commands

cmaxf1, cmaxf2 and cmaxf3 should be

used.



Optional keywords for NLPMIN1 are:



:print - Print results



:ivalue rvec - Sets initial values. rvec must be a

vector containing the number of

elements equal to the number of

parameters supplied. Default = .1.



:lower rvec - Vector of lower values for

parameters. Default = -.1d+10



:upper rvec - Vector of upper values for

parameters. Default = .1d+10



:maxit int - Maximum number of iterations.

Default = 400



:noflag - Suppresses the error message :ERROR

returned by %error / iercd() to a

note.





:iprint key - where key is NONE, FINAL, ITPRINT,

DETAILED



NONE => No diagnostic output.

FINAL => Detail at Final iteration

only.

ITPRINR => One line of intermadiate

results.

DETAILED=> Detailed intermediate

results.





NLPMIN1 creates the following variables:



%coef - vector containing answers



%nparm - Vector with coefficient names.



%func - final value of function.



%error - returns IMSL iercd( ) code



0 solution OK

1 Search Direction uphill

2 Linear Search took more that 5 function calls

3 Max Iterations Exceeded

4 Search Direction close to zero

5 Constraints for problem not consustent



NLPMIN1 uses the real*8 variable %ACTIVE(i), for i=1,M to turn

on the active constraints of the problem.



Example:



Min (x1-2)**2 + (x2-1)**2



st x1-2*x2+1 EQ 0.0



-(x1**2)/4 -x2**2 + 1 GE 0.0





/$

/$ Uses IMSL dn2onf

/$

b34sexec matrix;

* Answers .8229 .9114 ;



program test;

func=(x1-2.)**2. + (x2-1.)**2. ;

if(%active(1)) g(1)=x1 - 2.0*x2 + 1. ;

if(%active(2)) g(2)=((-1.)*(x1**2.)/4.) - (x2**2.) + 1. ;

return;

end;



call print(test);



call echooff;



call NLPMIN1(func g :name test :parms x1 x2

:ivalue array(:2.,2.) :nconst 2 1

:lower array(:-1.d+6, -1.d+6)

:upper array(:-1.d+6, -1.d+6)

:print :maxit 100

:iprint final);





Notes: Array g(1) can be allocated before the command

call nlpmin1 is given. G must be of size mmax.

mmax = max(1,m). The size of G is tested after

program test returns.



**********************************************



Example to estimate a IGARCH(1,1) -- see GARCH_7 test job



/$ IGARCH(1,1) using NLPMIN1 - showsgeneral case



b34sexec options ginclude('b34sdata.mac')

member(garchdat);

b34srun;

b34sexec matrix ;

call loaddata;



y=sp500;



vstart=variance(y-mean(y));



arch=array(norows(y):)+ vstart;

res= y-mean(y);

call print('mean y ',mean(y):);

call print('vstart ',vstart :);



program test;

call garch(res,arch,y,func,1,nbad

:gar array(:gar) idint(array(:1))

:gma array(:gma) idint(array(:1))

:constant array(:a0 b0)

);

if(%active(1)) g(1)=gar+gma-1.;

func=(-1.)*func;

return;

end;



call print(test);



call echooff;



call NLPMIN1(func g :name test :parms gar gma a0 b0

:ivalue array(:.5,.5,mean(y),vstart)

:nconst 1 0

:lower array(: 1.d-6, 1.d-6, 1.d-6, 1.d-6)

:upper array(: 1.d+2, 1.d+2, 1.d+2, 1.d+2)

:print :maxit 100

:iprint final);

b34srun;



NLPMIN2 - Nonlinear Programming user supplied grad. DN2CONG.





call NLPMIN2(func g df dg :name test grad :parms x1 x2

:ivalue rvec :nconst m me

:lower lvalues :upper uvalues

:print :maxit it

:iprint key);



Performs Nonlinear Programming with a user supplied grad.



Required



func - Function name



g - Constraint name. m elements



df - Derivative of function name.

n elements where n = # of parameters.



dg - Derivative of gradiant name dim(m,n)



:name pgmname - Name of user program to determine func



:parms v1 v2 - Parameters in the model. These

parameters must be in the function in

the user program pgmname that

determines func. The keyword :parms

MUST be supplied prior to all keywords

except :name. N = number of parameter



:nconst M ME - M is the total number of constraints.

ME is the number of equality constraints



Optional keywords for NLPMIN2 are:



:print - Print results



:ivalue rvec - Determines initial values.

rvec must be a vector containing the

number of elements equal to the number

of parameters supplied. Default = .1.



:lower rvec - Vector of lower values for parameters.

Default = -.1d+10



:upper rvec - Vector of upper values for parameters.

Default = .1d+10



:maxit int - Maximum number of iterations.

Default = 400



:noflag - Suppresses the error message :ERROR

returned by %error / iercd() to a note.





:iprint key - where key is NONE, FINAL, ITPRINT,

DETAILED



NONE => No diagnostic output.



FINAL => Detail at Final iteration

only.



ITPRINR => One line of intermadiate

results.



DETAILED => Detailed intermediate

results.



NLPMIN2 automatically creates the following variables

%coef - vector containing answers



%nparm - vector with coefficient names.



%func - final value of function.



%error - returns IMSL iercd( ) code



0 solution OK

1 Search Direction uphill

2 Linear Search took more that 5 function calls.

3 Max Iterations Exceeded

4 Search Direction close to zero

5 Constraints for problem not consustent



NLPMIN2 uses the real*8 variable %ACTIVE(i) for i=1,M to turn

on the active constraints of the problem.



Example



Min (x1-2)**2 + (x2-1)**2



st x1-2*x2+1 EQ 0.0



-(x1**2)/4 -x2**2 + 1 GE 0.0



/$

/$ Uses IMSL dn2ong

/$

b34sexec matrix;

* Answers .8229 .9114 ;



program test;

func=(x1-2.)**2. + (x2-1.)**2. ;

if(%active(1)) g(1)=x1 - 2.0*x2 + 1. ;

if(%active(2)) g(2)=((-1.)*(x1**2.)/4.) - (x2**2.) + 1. ;

return;

end;



program grad;

df(1)=2.0*(x1-2.0) ;

df(2)=2.0*(x2-1.0) ;

if(%active(1))then;

dg(1,1)=1.;

dg(1,2)=-2.;

endif;

if(%active(2))then;

dg(2,1)= -.5 ;

dg(2,2)= -2. ;

endif;

return;

end;



call print(test,grad);

call echooff;

call nlpmin2(func g df dg :name test grad :parms x1 x2

:ivalue array(:2.,2.) :nconst 2 1

:lower array(:-1.d+6, -1.d+6)

:upper array(: 1.d+6, 1.d+6)

:print :maxit 100

:iprint final);



Notes: Array g(1) can be allocated before the command

call nlpmin2 is given. G must be of size mmax

where mmax = max(1,m).



The size of G is tested after program test returns.



Arrays df and dg can be allocated to size df(n) and

dg(mmax,n) before call nlpmin2 is given. After

program grad returns, the sizes are checked.



NLPMIN3 - Nonlinear Programming user supplied grad. DN0ONF.



NLPMIN3 Command





call NLPMIN3(func g df dg :name test :parms x1 x2

:ivalue rvec :nconst m me

:lower lvalues :upper uvalues

:print :maxit it

:iprint key);



Performs Nonlinear Programming with a user supplied grad.

The IMSL routine DN0ONF is used.



Required



func - Function name



g - Constraint name. m elements



df - Derivative of function name. n elements

where n = number of parameters



dg - Derivative of gradiant name array(m,n)



:name pgmname - Name of user program to determine func



:parms v1 v2 - Parameters in the model. These parameters

must be in the function in the user

program pgmname that determines func. The

keyword :parms MUST be supplied prior to

all keywords except :name.



:nconst M ME - M is the total number of constraints.

ME is the number of equality constraints

Optional keywords for NLPMIN3 are:



:print - Print results



:ivalue rvec - Determines initial values. rvec must

be a vector containing the number of

elements equal to the number of

parameters supplied. Default = .1.



:lower rvec - Vector of lower values for parameters.

Default = -.1d+10



:upper rvec - Vector of upper values for parameters.

Default = .1d+10



:maxit int - Maximum number of iterations.

Default = 400



:maxfun int - Maximum number of function evaluations.

Default = 100



:noflag - Suppresses the error message :ERROR

returned by %error / iercd() to a note.



:iprint key - where key is NONE, FINAL, ITPRINT,

DETAILED



NONE => No diagnostic output.

FINAL => Detail at Final iteration only

ITPRINR => One line of intermadiate

results.

DETAILED=> Detailed intermediate results.



NLPMIN3 automatically creates the following variables



%coef - vector containing answers.



%nparm - Vector with coefficient names.



%func - final value of function.



%hessian - (n+1) by (n+1) hessian matrix.



%dhess - (n+1) diagonal elements of hessian



%error - returns IMSL iercd( ) code



0 solution OK

1 Search Direction uphill

2 Linear Search took more that 5 function

calls

3 Max Iterations Exceeded

4 Search Direction close to zero

5 Constraints for problem not consustent

NLPMIN3 uses the real*8 variable %ACTIVE(i) for i=1,M to turn

on the active constraints of the problem.



Example:



Min (x1-2)**2 + (x2-1)**2



st x1-2*x2+1 EQ 0.0



-(x1**2)/4 -x2**2 + 1 GE 0.0



/$

/$ Uses IMSL dn0onf

/$

b34sexec matrix;

* Answers .8229 .9114 ;

program test;

func=(x1-2.)**2. + (x2-1.)**2. ;

if(%active(1)) g(1)=x1 - 2.0*x2 + 1. ;

if(%active(2)) g(2)=((-1.)*(x1**2.)/4.) - (x2**2.) + 1. ;

return;

end;



program grad;

df(1)=2.0*(x1-2.0) ;

df(2)=2.0*(x2-1.0) ;

if(%active(1))then;

dg(1,1)=1.;

dg(1,2)=-2.;

endif;

if(%active(2))then;

dg(2,1)= -.5 ;

dg(2,2)= -2. ;

endif;

return;

end;



call print(test,grad);



call echooff;

call nlpmin3(func g df dg :name test grad :parms x1 x2

:ivalue array(:2.,2.) :nconst 2 1

:lower array(:-1.d+6, -1.d+6)

:upper array(: 1.d+6, 1.d+6)

:print :maxit 100

:iprint final);





Notes: Array g(1) can be allocated before the command

call nlpmin2 is given. G must be of size mmax where

mmax = max(1,m). The size of G is tested after

program test returns.

Arrays df and dg can be allocated to size df(n) and

dg(mmax,n) before call nlpmin3 is given. After

program grad returns, the sizes are checked.





NLSTART - Generate starting values for NL routines.



call nlstart(a,b,k,s);



The NLSTART command allows generation of a grid of starting

values that can be passed to the nonlinear routines to

systematically test for a local vs global minimum.



Arguments:



a = Vector or array of N points which define the lower

bounds on the search region for parameter i.



b = Vector or array of N points which define the upper

bounds on the search region for parameter i.



k = Number of points to be generated.



s = n by k matrix containing the values to be used as

initial guess to nonlinear routine.



Useage: Assuming the model contained 2 parameters, the code



n=2;

k=10;

a=array(n:1. 1.);

b=array(n:3. 2.);

call nlstart(a,b,k,s);

do i=1,k

ss=s(,i);

call nllsq(y,yhat :name test1 :parms aa bb :ivalue ss

:print result);

enddo;



will test the results starting from 10 positions in the grid.



NLVARCOV Nonlinear LS Variance Covariance



call nlvarcov(resvar,pcorr,se,varcov);



Nonlinear LS Variance Corariance





subroutine nlvarcov(resvar,pcorr,se,varcov);

/;

/;

/; resvar = Residual variance %RESVAR from NLLSQ

/;

/; pcorr = Correlation Matrix of Coef %CORRMAT from NLLSQ

/;

/; se = SE of parameters. %SE from NLLSQ

/;

/; varcov = Variance Covariance Matrix



For a test case see Gallant(1987) p 34



s^2*c(i,j)=se(i)*se(j)*p(i,j)



Usage call nlvarcov(%resvar,%corrmat,%se,varcov);



Test Program: tnllsq





/$ OLS Model estimated using nonlinear methods

/$ Model taked from Gallant (1987) page 35

b34sexec options ginclude('b34sdata.mac')

member(rgtab_1); b34srun;

b34sexec matrix;

call loaddata;

call load(nlvarcov);



* R. Gallant (1987) Page 35 --- Nonlinear Models ;

* Parameters SE ;

* -0.02588970 .01262384 ;

* 1.01567967 .00993793 ;

* -1.11569714 .16354199 ;

* -0.50490286 .02565721 ;

* Starting values suggested by Gallant ;

program model1;

call echooff;

yhat=t1*x1 + t2*x2 + t4*dexp(t3*x3);

call outstring(3,3,'Coefficients');

call outstring(3,4,'t1 t2 t3 t4');

call outdouble(14,4,t1);

call outdouble(34,4,t2);

call outdouble(50,4,t3);

call outdouble(14,5,t4);

return;

end;



call print(model1);



/$ Note: Without The Gallant starting values we go to a

/$ local minimum

/$ Can start with .0001 .0001 and -1. -1. to get to

/$ answers. This is close to what Gallant suggests



call nllsq(y,yhat :name model1 :parms t1 t2 t3 t4

:eps2 .1d-13 :eps1 .1d-13

/$ These are Gallant's starting values

/$ :ivalue

/$ array(4:-.048866,1.03884,-.73792,-.51362)

/$ If parameter # 3 is not set problems

/$ :ivalue array(4: .0001,.0001,-1.0,-1.0)

:ivalue array(4:.1, 1., -.1, .1)

:diff array(4: .1d-9 .1d-9 .1d-9 .1d-9)

/$ :flam 1.0 :flu 20.

:print result residuals);



call graph(%res);



/$ call print(nlvarcov);



* See Gallant (1987) page 36 ;



call nlvarcov(%resvar,%corrmat,%se,varcov);

call print(varcov);



b34srun;

NOHEADER Turn off header



call noheader;



Turns off page numbering inside matrix command.



call header;



Turns on page numbering a forces a new page.



OLSQ - Estimate OLS, MINIMAX and L1 models.



call olsq(x x1 x2);



Does OLS and optionally L1 and MINIMAX. The variables

x, x1 and x2 can be real*8 or real*16. Real*16 capability is

designed to handle difficult problems. Cholesky factorization

is used to perform calculations although the QR approach is an

option. Recursive residuals can be optionally calculated. The

recursive residual options gives both moving coefficients and t

scores.



Options:



:print - to print results



:noint - to estimate model without intercept.



:diag - to print diagnostic data



:L1 - to perform L1 estimation.



:Minimax - to perform Minimax estimation



:qr - Use QR to get OLS results. This option

takes more space and is slower and should

only be used when more accuracy is needed.

The LINPACK routines DTALSQ, DQRDC and

DQRSL are used. SE's use the Cholesky R

from the QR and DPODI. As needed real*16

versions of the above routines are used.



:eps - Rank check in QR for stable problem.

The Fortran function epsilon( ) is used

to set the eps to use in real*8 and

real*16 calculations. On an Intel chip

these values are 2.220446049250313E-16 and

1.9259299443872358530559779425849273E-0034

for real*8 and real*16 respectively. The

below listed code isolates the stable

problem



k=0

m=min0(n,p)

do kk=1,m

if(dabs(x(kk,kk)).le.eps*dabs(x(1,1)))

* go to 30

k=kk

enddo

30 continue



In practice eps may have been set too

aggressively. As a result care must be

taken and coefficients must be inspected

closely. The advantage os this "aggressive"

setting of eps is that the multicolinear

coefficients will be obvious.



:white - Get White SE and t and save in %whitese and

%whitet.



:white1 - Get White SE and t using variant formula

# 1. Results saved in %whitese and %whitet.



:white2 - Get White SE and t using variant formula

# 2. Results saved in %whitese and %whitet.





:white3 - Get White SE and t using variant formula

# 3. Results saved in %whitese and %whitet.



For details on alternative formulas see

Davidson-MacKinnon (2004) page 199-200.

See also Greene (2003) page 220 which gives

added detail.



Note: Newey-West SE for OLS models with autocorrelation can be

calculated with the NW_SE subroutine which can be loaded

from the staging2.mac library. The routine can be called

directly or can be called with the RNW_SE program. For

an example see below.

:savex - Saves the X matrix in %X. This is useful

for TAR modeling.



:sample mask - Specifies a mask real*8 variable that

if = 0.0 drops that observation.

Unless the mask is the number of obs

after any lags, an error message will

be generated. The sample variable

must be used with great caution when there

are lags. A much better option is

:holdout.



:holdout n - Sets number of observations to hold out.

This is useful for model validation

purposes.



Note: :sample option cannot be used with :holdout.



Note: The :influence command which is an alias for the :outlier

command provides a number of tests to determine if the

results are unduely sensitive to a given observation.

This capability is also available in SAS in the REG

command.



:outlier - Calculates a number of leverage tests

for the effect of a single observation.

For details see Greene (2000, 263-264).

If this option is given, :savex is

automatically enabled.



Note: Values calculated with this option are:



%YHAT_I - Predicted Y given beta

%HI - A N element vector consisting of the diagonal

elements of x(i)'(X'X)**-1 x(i) where X'X

is defined over the full sample. This is what

SAS reports for HI

%HI_I - Same as %HI except X'X is calculated dropping

the ith observation.

%STD_I - e(i)/sqrt(sigmasq*(1-%HI_I))

SAS uses

%std2_e =(%y-%yhat)/dsqrt(%resvari*1.0-%HI);

%BETA_I - N by K matrix of beta values calculated

without ith observation.

%E_I - Error Vector calculated using %y-%X*%ALT_BETA

%RESVARI - Sigma squared using %E_I

%DEFITS - (%yhat - %yhat_I) /sqrt(%RESVARI*%HI_I)).

SAS uses

(%yhat - %yhat_I) /sqrt(%RESVARI*%HI))

%VAR_E_I - %SI_SQ*(1-%HI_I)

%E2_i - %E_I / sqrt(%RESVARI*(1-%HI_I))

:rr maxord - Calculates recursive residuals for up to

maxord for the problem solved with OLS.



Note: For a discussion of recursive residuals see the RR

command and Stokes (1997) Chapter 9. Values calculated

with this option are:



%RROBS - Recursive residual observation base.



%RR - a (N-K) by maxord matrix of recursive

residuals.



%RRSTD - a (N-K) by maxord matrix of standardized

recursive residuals.



%RRCOEF - a (N-K) by K matrix of resursive

coefficients.



%RRCOEFT - a (N-K) by K matrix of t statistics



%SSR1 - e'e going forward. N-2K obs



%SSR2 - e'e going backwards. N-2K obs



Note: Due to the fact that t's are calculated, the speed of the

:RR option is such that if the number of observations is

> 10,000 there will be a substantial speed loss on

the order of being 3 times slower than RR command. Full

condition checking is done to insure there is less

likelihood of accuracy issues. The RR command uses

update formulas wherever possible.



See RRPLOTS subroutine for Graphical display of results.



Lags can be entered as



x{1} or x{1 to 20}



Values automatically saved are:



%YVAR - Name of left hand variable.



%NAMES - Names of exogenous variables.



%LAG - Lag of exogenous variable.



%COEF - Vector of coefficients.



%SE - SE of Coefficients.



%WHITESE - White SE is calculated if :white has been set.



%WHITET - White T is calculated if :white has been set.

%VARCOV2 - White calculation of Variance-Covariance

Note usual varcov = %resvar*%xpxinv



%T - t values of coef.



%RSS - Residual sum of sq.



%SUMRE - Sum absolute residuals



%REMAX - Maximum absolute residual



%RESVAR - Residual Var.



%RSQ - Center R**2



%LLF - Log Likelihood. Calculated as:

(T/2)*(dlog(2*pi()) + dlog(%rss/T) + 1.0)



%ADJRSQ - Adjusted R**2.

Note: %adjrsq=%rsq -(((K-1)/(T-K))*((1.-%rsq)



%RCOND - 1 / Condition of XPX



%NOB - # of obs in model.



%K - # right hand var.



%XPXINV - (X'X)**-1



%YHAT - Estimated Y



%Y - Y variable. Same # obs as YHAT



%X - X matrix. Saved if :savex in effect.



%RES - Residual



%F - F Test F=F(%K-1,%nob-%K)



%FSIG - Significance of %F



%AMXLK - -2 * ln(MLF)



%AICSTAT - Akaike (1973)



%SICSTAT - Scwartz (1978)



%FPETEST - Akaike (1970) Finite Prediction Error



%GVCTEST - Generalized Cross Validation



%HGTEST - Hannan - Quinn (1979)



%SHTEST - Shibata

%RICETST - Rice Test



Note: If lags are present then based on minimum lag the

following is saved. This will not occur if future

right hand side variables are present and :holdout

is not present.



%XFOBS - Observation number.



%XFUTURE - Same as %x but for out of sample data that is

available.



Values created if :L1 option given



%L1COEF - L1 Coefficients



%L1SUMRE - Sum absolute error for L1



%L1RES - L1 Residuals



%L1YHAT - L1 estimated y



%L1RSS - L1 Residual Sum of squares



%L1REMAX - L1 Maximum abs(residual)



Values created if :MINIMAX option given



%MMCOEF - MINIMAX Coeficients



%MMSUMRE - Sum absolute error for Minimax



%MMRES - MINIMAX Residuals



%MMYHAT - MINIMAX estimated y



%MMRSS - MINIMAX Residual sum of squares



%MMREMAX - MINIMAX Maximum abs(residual)



For further detail see Ramanathan (1998, page 165). No output

is given unless an error has occured. The following code might

be used to display results:



call print('Model of ',%yvar);

call tabulate(%names,%LAG,%coef,%se,%t);

call tabulate(x,%yhat,%res);



If printing is desired, use form



call olsq(x x1 x2 :print);



The OLSQ command can be used to filter data. For example to

filter with an AR(20) model and display the results:



call olsq(x x{1 to 20});

call graph(%res);

call graph(acf(x));

call graph(acf(%res));



If a matrix is used for the right hand side, no additional

variables can be supplied as vectors or arrays.



Example of a mask to remove males from the data to be used:



notmale = (sex .eq. 1.);

call olsq(y xx x2 x3 :sample notmale :print);



Note: The mask must be the same number of observatioins as the

final number of observations.



The subroutines QUANTREG and MINIMAX use MAXF2 to

estimate L1 and MINIMAX models. These routines produce

SE's but are substantially slower than the built in

MINIMAX and L1 commands.



Examples:



1. Use of sample facility to estimate a TAR Model. See

applpgm.mac member TAR_2. Note that the dataset is built

BEFORE the mask is applied to insure that all lags are

proper. In order to build mask we save the data

using :savex. Due to differences in the lags in the four

equation example, the mask has to be adjusted. This is done

by adding a 0 at the end and doing a rolldown to place it at

the beginning.



b34sexec scaio readsca

/$ file('/usr/local/lib/b34slm/findat01.mad')

file('c:\b34slm\findat01.mad')

dataset(d_gnp82); b34srun;



b34sexec matrix;

call loaddata;

call names;



call olsq(d_gnp82 d_gnp82{1 to 2} :savex :print);



* replicate Pena-Tiao-Tsay (2002) page 276 - 279 ;

mask1=(%x(,2).le.0.0);

mask2=(%x(,2).gt.0.0);



* replicate Pena-Tiao-Tsay(2002) page 279 ;

mask11=((%x(,1).le.%x(,2)).and.(%x(,2).le.0.0));

mask21=((%x(,1).gt.%x(,2)).and.(%x(,2).le.0.0));

mask31=((%x(,1).le.%x(,2)).and.(%x(,2).gt.0.0));

mask41=((%x(,1).gt.%x(,2)).and.(%x(,2).gt.0.0));

* adjust mask11,mask31, mask41 for length;

* Note that these equations have only one lag!!;

* 0.0 in obs # 1 of mask => that that obs is killed;



nnew=norows(mask11)+1;

mask11(nnew)=0.0; mask11=rolldown(mask11);

mask31(nnew)=0.0; mask31=rolldown(mask31);

mask41(nnew)=0.0; mask41=rolldown(mask41);

call tabulate(mask11,mask21,mask31,mask41);

call olsq(d_gnp82 d_gnp82{1 to 2}

:sample mask1 :print);

call olsq(d_gnp82 d_gnp82{1 to 2}

:sample mask2 :print);

call olsq(d_gnp82 d_gnp82{1 }

:sample mask11 :print);

call olsq(d_gnp82 d_gnp82{1 to 2 }

:sample mask21 :print);

call olsq(d_gnp82 d_gnp82{1 }

:sample mask31 :print);

call olsq(d_gnp82 d_gnp82{1 }

:sample mask41 :print);



b34srun;



2. Recursive Residual Analysis



b34sexec options ginclude('b34sdata.mac') macro(eeam88)$

b34seend$



b34sexec matrix;

call loaddata;

call load(rrplots);



call olsq( lnq lnk lnl :rr 1 :print);

call print(%rrcoef,%rrcoeft);

list=0;

call rrplots(%rrstd,%rss,%nob,%k,%ssr1,%ssr2,list);

b34srun;



3. Forecasting



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

r16gasin=r8tor16(gasin);

r16gasot=r8tor16(gasout);

idumpmat=0;



call olsq(gasout gasin :savex :print);

xxr8=%x;

call olsq(r16gasot r16gasin :savex :print);

xxr16=%x;

if(idumpmat.ne.0)call print(xxr8,xxr16);

maxlag=9;

do i=1,4;

call print('******** Forecasts out ',i:);

call olsq(gasout gasout{i to maxlag},

gasin{i to maxlag} :savex :print);

xx1=%x;

if(idumpmat.ne.0)call print(xx1,%xfobs,%xfuture);

f1=%xfuture*%coef;

call tabulate(%xfobs,f1);

call olsq(r16gasot r16gasot{i to maxlag}

r16gasin{i to maxlag} :savex

:print);

xx2=%x;

if(idumpmat.ne.0)call print(xx2,%xfobs,%xfuture);

ff1=%xfuture*%coef;

ff1=r16tor8(ff1);

call tabulate(%xfobs,ff1);

enddo;



b34srun;



4. Newey-West SE Example from Greene (ed 4)



b34sexec options ginclude('greene.mac')

member(a13_1); b34srun;



b34sexec matrix;

call loaddata;

call load(rnw_se :staging);



call olsq(realnvst realgnp realint

:white :savex :print);

call echooff;

call rnw_se;



/$ Direct call user sets lag to 5



lag=5;

damp=1.0;

call nw_se(%names,%lag,%coef,%xpxinv,%res,

damp,%x,%se,%whitese,%nwse,lag,nw,white,1);



b34srun;



5. Outlier Detection



/; Job identifies that obs 19 seems to make a difference



%b34slet runsas=0;

%b34slet runr16=1;

b34sexec options ginclude('b34sdata.mac') member(res72);

b34srun;

b34sexec matrix;

call loaddata;



call olsq(lnq lnl lnk :print :outlier );

/; get SAS defits and std of error

%defits2=(afam(%yhat)-afam(%yhat_i))/

dsqrt(afam(%resvari)*afam(%hi));

%std2_e =afam(%y-%yhat)/

dsqrt(afam(%resvari)*afam(1.0-%hi));



call tabulate(%hi,%hi_i,%std_e,%std2_e,%e_i,%defits,

%defits2,%e2_i,%yhat_i,%resvari);

call print(%beta_i);



%b34sif(&runr16.eq.1)%then;

lnq=r8tor16(lnq);

lnl=r8tor16(lnl);

lnk=r8tor16(lnk);

call olsq(lnq lnl lnk :print :outlier :print);

call tabulate(%hi,%hi_i,%std_e,%std2_e,%e_i,%defits,

%defits2,%e2_i,%yhat_i,%resvari);

call print(%beta_i);

%b34sendif;



b34srun;



%b34sif(&runsas.eq.1)%then;

b34sexec options open('testsas.sas') unit(29)

disp=unknown$ b34srun$

b34sexec options clean(29) $ b34seend$

b34sexec pgmcall idata=29 icntrl=29$

sas $

* sas commands next ;

pgmcards$

proc reg; model lnq=lnk lnl/ influence; run;

b34sreturn$

b34srun $

b34sexec options close(29)$ b34srun$





b34sexec options dodos('start /w /r sas testsas' )

dounix('sas testsas' )

$ b34srun$

b34sexec options npageout noheader

writeout(' ','output from sas',' ',' ')

writelog(' ','output from sas',' ',' ')

copyfout('testsas.lst')

copyflog('testsas.log')

dodos( 'erase testsas.sas',

'erase testsas.lst',

'erase testsas.log')

dounix('rm testsas.sas',

'rm testsas.lst',

'rm testsas.log')

$ b34srun$

b34sexec options header$ b34srun$

%b34sendif;



6. Future value examples. The theory underlying many models

requires future values on the right. This will drop the most

recent data values. An example of this follows. Note that

the form x{-6 to -1} will not work since the parser will

attempt to calculate "to -1" and find to non a variable. The

solution is:



x{6 to sfam(-1)}



that forces conversion of the -1 value to a temp variable.



%b34slet dorats=1;

b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;



/; usual case



call olsq(gasout gasin{1 to 6} gasout{1 to 6}

:print :savex);

/; future only



call olsq(gasout gasin{-1} :print :savex);



/; Lags both directions



call olsq(gasout gasin{-6 to 6} gasout{-6 to sfam(-1)}

gasout{1 to 6} :print :savex);

b34srun;



%b34sif(&dorats.ne.0)%then;

b34sexec options open('rats.dat') unit(28) disp=unknown$

b34srun$

b34sexec options open('rats.in') unit(29) disp=unknown$

b34srun$

b34sexec options clean(28)$ b34srun$

b34sexec options clean(29)$ b34srun$



b34sexec pgmcall$

rats passasts

pcomments('* ',

'* Data passed from B34S(r) system to RATS',

'* ',

"display @1 %dateandtime() @33 'Version ' %ratsversion()"

'* ') $



PGMCARDS$

*

linreg gasout

# constant gasin{1 to 6} gasout{1 to 6}

linreg gasout

# constant gasin{-1}



linreg gasout

# constant gasout{-6 to -1} gasout{1 to 6} gasin{-6 to 6}

b34sreturn$

b34srun $



b34sexec options close(28)$ b34srun$

b34sexec options close(29)$ b34srun$

b34sexec options

dodos('start /w /r rats32s rats.in /run')

dounix('rats rats.in rats.out')$ B34SRUN$



b34sexec options npageout

WRITEOUT('Output from RATS',' ',' ')

COPYFOUT('rats.out')

dodos('ERASE rats.in','ERASE rats.out','ERASE rats.dat')

dounix('rm rats.in','rm rats.out','rm rats.dat')

$

B34SRUN$



OLSPLOT Plot of Fitted and Actual Data & Res



subroutine olsplot(yhat,y,res,cc);

/;

/; Builds a residual and data and fitted plot

/; Graph placed on clipboard

/;

/; yhat - forefast series

/; y - actual series

/; res - residual

/; cc - Character String

/;

/; *******************************************

/;



Builds a residual, data and fitted plot



OLSPLOT is a subroutine and requires



call load(olsplot);



be given to load the command.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call load(olsplot);



call olsq(gasout gasin{1 to 6} gasout{1 to 6});

call character(cc,'Gasout Model');

call olsplot(%yhat, %y, %res, cc);

b34srun;



OPEN - Open a file and attach to a unit.



call open(n,'file');



Opens file for reading on unit n.

It is suggested that units above 70 be used. If a unit used by

b34s is used, unpredictable results can occur!



Example:



call open(71,'c:\mydata\proj1.dat');





OUTDOUBLE - Display a Real*8/real*16 value at a x, y on screen.



call outdouble(ix,iy,d);



Outputs real*8 or real*16 value d at col ix and row iy.



Uses help window unless screenouton is in effect and OUTDOUBLE

is disabled. SETWINDOW can redirect window.



VPA data can also be displayed if it is converted to real*8

ot real*16.



Examples:



call outdouble(1,2,d);



call outstring(1,2,'Rsquare');

call outdouble(10,2,d);



The default format is g16.8. An optional 4th argument can

control the format.



call outdouble(ix,iy,d,'(f8.2)');



Note: The b34s2 batch command will produce graphs in a batch

job but will not display the results of matrix commands

on the screen because the proper windows have not been

open. To use OUTDOUBLE requires that B34S be in the

Display Manager.



Example:



b34sexec matrix;

call message('Illustrates MESSAGE','Testing Message',jj);

call print('Message returns',jj);

call cls(3);

/$ clear message

call cls(2);

call outstring(3,3,'This is at 3,3',:);

call cls(4);

call outstring(3,4,'This is at 3,4');

call cls(5);

call outstring(3,5,'This is at 3,5');

call cls(6);

call outstring(3,6,'int 123 at 40,6');

jj=123;

call outinteger(40,6,jj);

call stop(pause);

xx=dsqrt(12.88);

call outstring(3,2,'(12.88)**.5 printed on 3-6 rows');

do i=3,6;

call cls(i);

call outdouble(3,i,xx);

enddo;

call stop(pause);

b34srun;

OUTINTEGER - Display an Integer*4 value at a x, y on screen.



call outinteger(ix,iy,int);



Outputs integer int at col ix and row iy. Uses help window

unless screenouton is in effect and OUTINTEGER is disabled.

SETWINDOW can redirect window.



Examples:



call outinteger(1,2,n);



call outstring(1,2,'Iteration');

call outinteger(10,2,int);





Assuming int = 10, the above writes



Iteration 10



The default format is I10.



An optional 4th argument controls the # of digits.

Use with caution to avoid overflows.



Note: The b34s2 batch command will produce graphs in a

batch job but will not display the results of

of matrix commands on the screen because the

proper windows have not been open. To use

OUTDOUBLE requires that B34S be in The Display

Manager.



Example:



b34sexec matrix;

call message('Illustrates MESSAGE','Testing Message',jj);

call print('Message returns',jj);

call cls(3);

/$ clear message

call cls(2);

call outstring(3,3,'This is at 3,3',:);

call cls(4);

call outstring(3,4,'This is at 3,4');

call cls(5);

call outstring(3,5,'This is at 3,5');

call cls(6);

call outstring(3,6,'int 123 at 40,6');

jj=123;

call outinteger(40,6,jj);

call stop(pause);

xx=dsqrt(12.88);

call outstring(3,2,'(12.88)**.5 printed on 3-6 rows');

do i=3,6;

call cls(i);

call outdouble(3,i,xx);

enddo;

call stop(pause);

b34srun;





OUTSTRING - Display a string value at a x, y point on screen.



call outstring(ix,iy,char);



Outputs string char at col ix and row iy. Uses help window

unless screenouton is in effect and OUTSTRING is disabled.

SETWINDOW can redirect window. If the character : is

placed last, internal window info is placed in log.



Example:



call outstring(1,2,'Working on solution');



Note: The b34s2 batch command will produce graphs in a batch

job but will not display the results of matrix commands

on the screen because the proper windows have not been

open. To use OUTDOUBLE requires that B34S be in the

Display Manager.



Example:



b34sexec matrix;

call message('Illustrates MESSAGE','Testing Message',jj);

call print('Message returns',jj);

call cls(3);

/$ clear message

call cls(2);

call outstring(3,3,'This is at 3,3',:);

call cls(4);

call outstring(3,4,'This is at 3,4');

call cls(5);

call outstring(3,5,'This is at 3,5');

call cls(6);

call outstring(3,6,'int 123 at 40,6');

jj=123;

call outinteger(40,6,jj);

call stop(pause);

xx=dsqrt(12.88);

call outstring(3,2,'(12.88)**.5 printed on 3-6 rows');

do i=3,6;

call cls(i);

call outdouble(3,i,xx);

enddo;

call stop(pause);

b34srun;



PAD Pad a 1D Real*8 Series on both ends



call pad(oseries,nseries,nleft,nright,value);



Routine pads series to line up with another series



subroutine pad(oseries,nseries,nleft,nright,value);

/;

/; Routine pads oseries to line up with another series

/; oseries => Old series

/; nseries => New Series

/; nleft => # to pad on left

/; nright => # to pad on right

/; value => pad value, usually missing

/;





Example:



b34sexec options ginclude('gas.b34'); b34srun;



b34sexec matrix;

call loaddata;

call load(pad);

call print(pad);



call pad(gasout,ngasout,10,20,missing());

call tabulate(gasout,ngasout);

b34srun;



Test Program: TPAD



PCOPY - Copy an object from one pointer address to another



call pcopy(n,ipt1,inc1,ipt2,inc2,kind);



Copies from pointer ipt1 to pointer ipt2.

Inc1 and inc2 are usually 1 and represent the incrument.

Kind is set:



-1 character*1

-4 integer

4 real*4

8 real*8

-8 character*8

16 complex*16



Pcopy should be used with caution. Ipt1 and ipt2 addresses are

NOT checked. The built in function pointer can be used to

obtain the address of a variable to copy. This routine is

intended for the expert b34s user.



See also the command



call(copy(in,out);





Example # 1:



b34sexec matrix;

x=array(:integers(20));

newx=array(30:);

ip1=pointer(x);

ip2=pointer(newx);

call print('pointer(x)',ip1,'pointer(newx)',ip2);

call print(pointer(x,4));

* places x 1-10 in locations starting at 4 in newx;

call pcopy(10,pointer(x),1,pointer(newx,4),1,8);

call tabulate(x,newx);

b34srun;



b34sexec matrix;

* Illustrates pointer and pcopy ;

n=3;

x=matrix(n,n:1 2 3 4 5 6 7 8 9);

call print(x);

y=55.;

call pcopy(1,pointer(y),1,pointer(x,2),1,8);

call print(x);

call pcopy(2,pointer(y),0,pointer(x,4),2,8);

call print(x);

b34srun;



Example # 2:



/$

/$ Shows moving a real*16 value in a real*8 work array

/$ Uses a real*8 array to look at bits!!

/$

b34sexec matrix;

x=array(2:);

y=10.0;

y=r8tor16(y);

yy=y;

y=r8tor16(12.8);

call print('is yy 10.? ',yy);

call pcopy(2,pointer(y),1,pointer(x), 1,8);

call pcopy(2,pointer(x),1,pointer(yy),1,8);

call print('is yy 12.8.? ',yy);

call displayb(x);

call names(all);

call displayb(yy);

b34srun;





PERMUTE - Reorder Square Matrix



call permute(oldm,newm,1,2);



Reorders a square matrix



subroutine permute(oldmat,newmat,jold,jnew);

/$

/$ Reorder square matrix

/$

/$ oldmat = old matrix

/$ newmat = new matrix

/$ iold = old col

/$ inew = new col

/$

/$ Built 7 May 2003 by Houston H. Stokes





Example:



b34sexec matrix;

call load(permute);

* Problem 5 in Greene (2003) Chapter 15;

* Illustrates ols from moment matrix;

* Assume 25 obs;

* y1=g1*y2 + b11*x1 ;

* y2=g2*y1 + b22*x2 + b32*x3 ;

* matrix order is y1 y2 x1 x2 x3 ;

mm=matrix(5,5: 20 6 4 3 5

6 10 3 6 7

4 3 5 2 3

3 6 2 10 8

5 7 3 8 15);



* OLS ;

x1 =submatrix(mm,2,3,2,3);

x1py1=submatrix(mm,2,3,1,1);

call print(x1,x1py1);

d1=inv(x1)*x1py1;

call print('OLS eq 1 ',d1 );

call print('Answers .439024 .536585':);



* We reorder Moment Matrix;

* Old Order y1 y2 x1 x2 x3;

* New Order y2 y1 x2 x3 x1;



call echooff;

call permute(mm,mm2, 1,2);

call permute(mm2,mm3,3,4);

call permute(mm3,mm4,4,5);

call print(mm,mm2,mm3,mm4);

call echoon;



x2 =submatrix(mm4,2,4,2,4);

x2py2=submatrix(mm4,2,4,1,1);

call print(x2,x2py2);



d2=inv(x2)*x2py2;

call print('OLS eq 2 ',d2 );

call print('Answers .193016 .384127 .19746':);

b34srun;



PISPLINE - Pi Spline Nonlinear Model Building



call pispline(y x1 x2;



Controls estimates of a underlying smooth function of M

variables (x(1),...,x(m)) using noisy data based on methods

suggested by Leo Breiman. Basic references are:



Breiman, Leo, "The PI Method for Estimating Multivariate

Functions From Noisy Data," Technometrics, May 1991, Vol.

33, No. 2. pp 125 - 160. Note that this citation includes

comments by Friedman, Gu, Hastie & Tibshirani and a reply

by Breiman.



Lags can be entered as



x{1} or x{1 to 20}



Notes: The PISPLINE command allows the user to optionally save

or reread an estimated model. The advantage of saving models

is that forecasts can be calculated without having to estimate

the model again if in subsequent steps the get model option is

used. In order to preserve variable storage, the order and

number of the variables on forecast matrix MUST be the same as

the initially saved model for a saved model to be used.





Technical Notes: Each right hand side variable is discretized

into NG equispaced values. XG(i,j,k) gives the value at the ith

point of the transform of the jth variable in the kth product.



yhat =prod(XG(i1,1,1 )*XG(i2,2,1 ),..,XG(in,MV,1))

+ ... + prod(XG(i1,1,NG)*XG(i2,2,NG),..,XG(in,MV,NG))



%yg yg(ng,ng) measures the surface fit.

This option is only possible if there

are exactly 2 variables on the right.





Options for PISPLINE sentence.





:print If this is not set there is no output.



:sample mask - Specifies a mask real*8 variable that

if = 0.0 drops that observation.

Do not use this option with lags.

Use :holdout instead.



:holdout n - Sets number of observations to hold out.



Note: :sample cannot be used with :holdout.





:outputxg - Produces %xg



:outputyg - Produces %yg



:pmodel - Produces model description matrices.



:savemodel - Saves the estimated model on unit

modelunit.



:murewind - Rewinds MODELUNIT before the model is

saved.



:getmodel - Rereads a saved model off unit MODELUNIT.





:center=r1 - r1 is substracted from each Y-value before

the the fitting process and added back in

later in the evaluation. If CENTER is not

set, the mean of Y is used.



:kmb i1 - Lower bound on number of knots to try

fitting. Must be > 1. Default=2.



:kmt i2 - Upper bound on knots to try fitting.

Default=kmb + 5.



:mnfit i3 - Maximum number of products to be fitted.

Default=3.



:ng i4 - Number of equispaced values at which the

unidimensional fits are evaluated.

Default = 50. Minimum = 20. The larger NG,

the better the forecast approximation.



:jrdf i5 - Deletion is terminated when the remaining

degrees of freedom falls below or is

equal to jrdf. Default=-1.



:th r2 - Parameter in the criterion for convergence

of the iteration. A smaller th leads to

more iterations. Default = .02D+00.



:edth r3 - A parameter used in deletion. The smaller

edth the less likely multiple knots will

be deleted in one pass. Default = .1D+00.



:cpth r4 - A parameter used in selecting models.

Must be in range 0-10. A higher cpth

causes more deleted models to be

selected. Default = 0.0D+00.



:radd r5 - A parameter that governs how many products

are selected. Larger values favor selection

of fewer products. Default = 1.0D+00.





:modelunit i6 - Sets save/get model unit. Default = 60.



:smodeln k1 - Sets the model name. Default =

'PISPMODEL'.

A max of 10 characters can be supplied.



:mcomments array - Allows user to set model comments when

the model is saved. A maximum of 10,

lines of a max of 80 characters is

allowed. The command



call char1(c,'Line one'

'line two'

'line three');



can be used to make the array.



:forecast xmatrix - The forecast option allows users

to supply observations on the

right hand side variables outside

the sample period so that forecasts

can be calculated. The same number

of observations must be supplied for

all right hand series. Due to the

way that splines are calculated, it

is imperative that any values of

the x variables NOT lie outside the

ranges of the original data.



The forecast sentence produces the

%fore variable the %foreobs variable.





:nointerpol - The default setting is to interpolate

the XG(N,M,IT) values before the

products indicated in the discussion

of :outputxg are performed. If

:nointerpol is specified, then no

interpolation is performed.

In general the larger NG, the less

interpolation is needed. Since

forecasts are produced from the XG

matrix, if actual values are supplied,

the "forecasts" will differ from

the "residuals" for the same

observation

because of the use of the XG matrix.



:nocorner - The default is to set right-hand side

variables outside their ranges for

the training dataset to their upper

or lower bounds, give a message and

calculate a forecast. If :nocorner

is set, a message is given and

the forecast is set to missing.



Variables Created



%YVAR - Name of left hand var.



%NAMES - Names of exogen. var.



%LAG - Lag of independent variable



%K - # on right



%NOB - # of observations in model



%RSS - Residual sum of sq.



%SUMRE - Sum absolute residuals



%REMAX - Maximum absolute residual



%RESVAR - Residual Var.



%YHAT - Estimated Y



%Y - Y variable. Same # obs as YHAT



%RES - Residual



%NAMES - Names of exogen. var.

%LAG - Lag of independent variable



%K - # on right



%xg - xg(n,m,it) n=1,ng

m = 1, numvar,

it=1,nproducts



%ng - Dimension # 1 of %xg



%numvar - Dimension # 2 of %xg



%nprod - Dimension # 3 of %xg



In these examples both PISPLINE and Matrix PISPLINE shown



Simple Example



b34sexec options ginclude('b34sdata.mac') member(gas);

b34srun;



/$ Both PISPLINE Commands shown



b34sexec pispline;

model gasout = gasin;

b34srun;



b34sexec matrix;

call loaddata;

call pispline(gasout gasin :print);

call names(all);

call graph(%res :heading 'Residual from pispline');

call graph(%y %yhat:heading 'Fit from Pispline');

b34srun;



Example using Forecasting without a saved model.

Second example uses a saved model



b34sexec options ginclude('b34sdata.mac') member(breiman);

b34srun;



/$ both pispline commands shown



b34sexec pispline center=2.526 pmodel$

forecast c_ratio(12. 12.) e_ratio(.907 .761)$

model y = e_ratio c_ratio$ b34seend$



b34sexec matrix;

call loaddata;

* We forecast 2 insample data points ;

npred=2;



xin=matrix(npred,3:);

xin(1,1)=.907 ;

xin(1,2)= 12. ;

xin(1,3)= 1.0 ;

xin(2,1)=.761 ;

xin(2,2)= 12. ;

xin(2,3)= 1.0 ;



call print(xin );

call names(all);

call pispline(y e_ratio c_ratio :pmodel :print

:center 2.526 :forecast xin );



/$ Saved Model setup



call tabulate(%y %yhat %res y e_ratio c_ratio);

call tabulate(%fore %foreobs);

call open(60,'junk.mod');

call pispline(y e_ratio c_ratio :print :center 2.526

:savemodel :murewind);

call pispline(y e_ratio c_ratio :print :center 2.526

:getmodel :forecast xin );

call tabulate(%fore %foreobs);

b34srun;



PLOT - Line-Printer Graphics



call plot(x,y :opts)



Line printer plots. PLOT command should be used if high

resolution graphics are not available. Up to ten series can be

passed. All series must be same length.



Advanced PLOT features



:xyplot plots series 2,..,8 against x



:heading 'Up to 72 characters'



:xlabel 'Up to 36 characters'



:ylabel 'Up to 36 characters'



:char 'abcdefghi' sets plot char



:col132 plot using 132 columns



Examples of PLOT command



call plot(x,y);

call plot(x,y,z :xyplot);

call plot(x,y :char 'xy')



For a related command see graph.



POLYFIT Fit an nth degree polynomial

call polyfit(x,y,n,coef,printit);



Fit an nth degree polynomial



subroutine polyfit(x,y,n,coef,printout);

/;

/; x => input

/; y => output

/; n => order

/; coef => coefficients

/; printout => =0 no print, =1 print results

/;



Example:



b34sexec matrix;

call load(polyfit);

call load(polyval);



call print(polyfit,polyval);



/$ Test case from Mastering Matlab 6



x=dfloat(integers(0,10))/10.;

y=array(11:-.447,1.978,3.28,6.16,7.08,7.34,

7.66,9.56,9.48,9.30,11.2);

xx=x*x;

call olsq(y,x,xx:print);

call tabulate(%yhat);



call echooff;



call polyfit(x,y,2,coef,1);



call polyval(coef,x,yhat);

call tabulate(x,y,yhat);

b34srun;



POLYMCONV Convert storage of a polynomial matrix



call polymconv(:byorderin old iold new);



call polymconv(:byvarin old new inew);



Converts storage of a polynomial matrix



:byorderin old index - sets old as pointing to a

row * col * (order+1) object



:byvarin old - sets old as row * (row*(order+1)





Required :byvarin or :byorderin

Note: For a :byorder object if we know the # rows

and # cols and # of elements in the object

we know the order. However the object pointed

to can be a 1-D object.



Example:



b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;



b34sexec matrix;



call loaddata;

call echooff;



ibegin=1;

iend=296;

nlag=2;

call olsq(gasin gasin{1 to nlag}

gasout{1 to nlag} :print);

b1=%coef;

call olsq(gasout gasin{1 to nlag}

gasout{1 to nlag} :print);

b2=%coef;

beta=matrix(2,norows(%coef):);

beta(1,)=vfam(b1);

beta(2,)=vfam(b2);

/;

/; Convert both ways

/;

call polymconv(:byvarin beta new inew);

call polymconv(:byorderin new inew beta2);

call print(beta,new,inew,beta2);



call polymdisp(:display new inew);

b34srun;



POLYMDISP Display/Extract/Load a polynomial matrix



call polymdisp(:display old iold);



call polymdisp(:extract old iold oldterm

index(irow icol iorder));



call polymdisp(:load old iold newterm

index(irow icol iorder));



Display/Extract/Load a polynomial matrix



old is assumed to be saved in :byorder form.

iold is a three element integer array describing

# rows # cols and # orders for old.

If any one of the three integers supplied in index( )

is zero, the whole vector is extracted/loaded.



Example:



b34sexec matrix;

* problem from Enders page 158;

a=array(:2,1,0,6,1,0,1,1);

ia=index(2,2,2);

nterms=10;

call echooff;

call polymdisp(:display a ia);

call polyminv(a,ia,ainv,iainv,nterms);

call names(all);

call print(%p,%det);

call polymdisp(:display ainv iainv);

call polymdisp(:display %adj %iadj);

call polymmult(a ia ainv iainv test itest);

call polymdisp(:display test itest);

call polymdisp(:extract ainv iainv vec1 index(1,1,0));

call polymdisp(:extract ainv iainv vec2 index(2,1,0));

call polymdisp(:extract ainv iainv vec3 index(1,2,0));

call polymdisp(:extract ainv iainv vec4 index(2,2,0));

call names(all);

call tabulate(vec1,vec2,vec3,vec4);

b34srun;





POLYMINV Invert a Polynomial Matrix



call polyminv(a,ia,ainv,iainv,nterms);



Invert a Polynomial Matrix



a = n by n polynomial matrix of degree m

where a is n*n*(m+1)



ia = 3 element integer array where

ia(1)=n

ia(2)=n

ia(3)=m+1



ainv = n by n polynomial of degree nterms-1

iainv = 3 element integer array where

ia(1)=n

ia(2)=n

ia(3)=nterms



Variables created:



%adj adjoint of a



%iadj index array for %adj

%p Characteristic polynomial of a



%ip index of %p



%det determinant of a



If nterms is not supplied, 20 is assumed.



a is assumed to be saved in :byorder form.



Example:



b34sexec matrix;

* problem from Enders page 158;

a=array(:2,1,0,6,1,0,1,1);

ia=index(2,2,2);

nterms=10;

call echooff;

call polymdisp(:display a ia);

call polyminv(a,ia,ainv,iainv,nterms);

call names(all);

call print(%p,%det);

call polymdisp(:display ainv iainv);

call polymdisp(:display %adj %iadj);

call polymmult(a ia ainv iainv test itest);

call polymdisp(:display test itest);

call polymdisp(:extract ainv iainv vec1 index(1,1,0));

call polymdisp(:extract ainv iainv vec2 index(2,1,0));

call polymdisp(:extract ainv iainv vec3 index(1,2,0));

call polymdisp(:extract ainv iainv vec4 index(2,2,0));

call names(all);

call tabulate(vec1,vec2,vec3,vec4);

b34srun;





POLYMMULT Multiply a Polynomial Matrix



call polymmult(a,ia,b,ib,c,ic);



Note: a and b are assumed to be in :byorder form.





Example:



b34sexec matrix;

* problem from Enders page 158;

a=array(:2,1,0,6,1,0,1,1);

ia=index(2,2,2);

nterms=10;

call echooff;

call polymdisp(:display a ia);

call polyminv(a,ia,ainv,iainv,nterms);

call names(all);

call print(%p,%det);

call polymdisp(:display ainv iainv);

call polymdisp(:display %adj %iadj);

call polymmult(a ia ainv iainv test itest);

call polymdisp(:display test itest);

call polymdisp(:extract ainv iainv vec1 index(1,1,0));

call polymdisp(:extract ainv iainv vec2 index(2,1,0));

call polymdisp(:extract ainv iainv vec3 index(1,2,0));

call polymdisp(:extract ainv iainv vec4 index(2,2,0));

call names(all);

call tabulate(vec1,vec2,vec3,vec4);

b34srun;



POLYVAL Evaluates a nth degree polynomial



call polyfit(coef,x,yhat);



Evaluates a nth degree polynomial



coef - Estimated coefficients from polyval

x - Input series

yhat - Output forecast



Note: Polyval is a subroutine and must be loaded prior to use.



Example:



b34sexec matrix;

call load(polyfit);

call load(polyval);

call print(polyfit,polyval);



/$ Test case from Mastering Matlab 6



x=dfloat(integers(0,10))/10.;

y=array(11:-.447,1.978,3.28,6.16,7.08,7.34,

7.66,9.56,9.48,9.30,11.2);

xx=x*x;

call olsq(y,x,xx:print);

call tabulate(%yhat);



call echooff;



call polyfit(x,y,2,coef,1);



call polyval(coef,x,yhat);

call tabulate(x,y,yhat);

b34srun;



PP - Calculate Phillips Perron Unit Root test



call pp(x,d);



Returns Phillips Perron Test. Added options:

:app n => augmented PP test

:appt n => augmented PP with trend

:zform => uses z-form of test

:print => Print value and significance



Automatic Variable Created



%PPPROB - Probability of PP t test

.05 => Cannot reject unit root at 95%

.10 => Cannot reject unit root at 90%



Example: The .05 critical value for N=100

is -1.95. This suggests that if the

value found was -2.0 (-1.95) we could

reject (could not reject) a unit root

at the 95% level. The .10 critical value

is -1.61. Using this standard we can

reject a unit root.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata; call echooff;

call print('Phillips-Perron Tests on Gasout');

call pp(gasout,p :print);

n=30;

app=array(n:); appt=array(n:); lag=array(n:);

do i=1,n;

call pp(gasout,a1:app i);

call pp(gasout,a2:appt i);

app(i)=a1;

appt(i)=a2;

lag(i)=dfloat(i);

enddo;

call print('Phillips-Perron test':);

call tabulate(lag,app,appt);

b34srun;



PRINT - Print text and data objects.



call print(x);



Prints variables and text in any order. Examples include:



call print('Some Message here');



call print('X was found to be ',x);



Up to 400 objects can be printed with one statement.

Print format is set with display=key on the statement



b34sexec matrix;

Optional keyword:



:line - Prints text or text variable on one line.

Variable must be kind=0 and must be real*4,

real*8 or integer.



Example



call print('OLS Estimation' :line);

call print('Using LINPACK ' :line);

call print('Rsquared ',rsq :line);

call print('# of Obs ',n :line);



See also eprint and epprint.



For printing under total user control, see fprint command.



Note: If the option :line is used, there is no , before :line.

If this is not followed there will be no print.



Arrays and vectors are printed without numbers. Arrays and

vectors can be repackaged as k,1 of 1,k 2-D objects if

numbers are desired. As an example see



x=rn(array(100:));

call print(x,matrix(100,1:x),matrix(1,100:x));





PRINTOFF - Turn off Printing



call printoff;



Turns off printing of results. The command



call printon;



starts the printing again. If screen output in in effect, this

will be displayed. Unless call printon; is given, no output

will be seen for B34S routines using the call byplin( )

routines. For the matrix command this is 100% of the commands.



Note that



call echooff;



only turns off command listing, not printing.



Example



b34sexec matrix;

do i=1,10;

call print(i);

enddo;

* Now we run silently ;

call echooff;

call printoff;



do i=1,10;

call print(i);

enddo;



call printon;

call print('We are done!!');

b34srun;



PRINTON - Turn on Printing (This is the default)



call printon;



Turns off printing of results. The command



call printon;



starts the printing again. If screen output in in effect, this

will be displayed. If



call printoff;



is given, unless call printon; is given later, no output will

be seen for B34S routines using the call byplin( ) routines.

For the matrix command this is 100% of the commands.



Note that



call echooff;



only turns off command listing, not printing.



Example



b34sexec matrix;



do i=1,10;

call print(i);

enddo;



* Now we run silently ;

call echooff;

call printoff;



do i=1,10;

call print(i);

enddo;



call printon;

call print('We are done!!');

b34srun;

PRINTALL - Lists all variables in storage.



call printall;



Lists all variables currently in storage. This command is

usually not used by anyone who is not a developer.



See also call names(all);



PROBIT Estimate a Probit Model on (0-1) data.



call probit(y x1 x2);



does Probit estimation. The variables y, x1 and x2 must be

real*8. If only one right hand side variable is supplied it

can be a matrix. The right hand side variables can be

specified as x{1 to 4} to indicate lags.



Options:



:print - Print results.



:printvcv - Print Variance - Coveriance matrix



:secd - if want output of second derivatives matrix



:nstrt i1 - beginning observation for output of

calculated and actual dependent variable

and density if nstrt = 0 program defaults

to l



:nstop i2 - ending observation for output of

calculated and actual dependent variable

and density. if nstop = 0 program defaults

# of observations.



:tola r1 - convergence tolerence,default = .0000l



:iitlk - print log of likehood after each

iteration



:iiesk - print estimates after each iteration



:savex - Saves the X matrix in %x.



:sample mask - Specifies a mask real*8 variable that

if = 0.0 drops that observation.

Unless the mask is the number of obs

after any lags, an error message will

be generated. The sample variable

must be used with great caution when there

are lags. A much better option is

:holdout.

:holdout n - Sets number of observations to hold out.



Variables created:



%yvar - Name of left hand variable.



%y - y variable adjusted for observations

dropped



%yhat - predicted y



%names - Names of exogenous variables.



%lag - Lag of exogenous variable.



%coef - Estimated Coefficient.



%se - Estimated SE.



%t - Estimated t.



%func - -2.0 times Log Likehood



%funcsig - Significance of %func



%dffunc - Degrees of freedom of %func



%limits - # of zero dependent variables



%rcond - 1 / conditon of variance covariance matrix.



%hessian - Hessian matrix



Note: If lags are present then based on minimum lag the

following is saved



%XFOBS - Observation number.



%XFUTURE - Same as %x but for out of sample data that is

available.





Note: PROBIT analysis is only used when the left hand variable

is 0 or 1 . For a further discussion of the Probit

technique see Theil (1971) pp. 630-1. If the left hand

variable has more than 2 categories, the MPROBIT option

(b34sexec mprobit) can be used. The matrix call probit

command uses the same logic as the b34sexec probit

command



Example showing all options:



Note use of

yhat=probnorm(%x*%coef);



to generate forecasts.



b34sexec options ginclude('b34sdata.mac') macro(murder)$

b34seend$



b34sexec matrix;

call loaddata;

call load(tlogit :staging);



call echooff;

call probit(d1 t y lf nw :print );

call tabulate(%names,%lag,%coef,%se,%t);

upper=.5;

lower=.5;

iprint=1;

call character(cc,'Tests on probit Model 1');

call tlogit(%y ,%yhat,upper,lower,cc,ntruer,ntruep

nfalser,nfalsep,nunclear,ptruer,pfalser,iprint);



call probit(d1 t{1} y{1} lf{1} nw{1} :print);

call print('Probit model':);

call tabulate(%names,%lag,%coef,%se,%t);

upper=.5;

lower=.5;

iprint=1;

call character(cc,'Tests on probit Model 2');

call tlogit(%y ,%yhat,upper,lower,cc,ntruer,ntruep

nfalser,nfalsep,nunclear,ptruer,pfalser,iprint);

call print(%func,%funcsig,%dffunc,%limits,

%rcond,%hessian);



call probit(d1 t y lf nw :print :secd :tola .1e-14 :iitlk

:iiesk :savex :holdout 2);

call print('Testing Y yhat error');

%error=%y-%yhat;

yyhat=probnorm(%x*%coef);

error=%y-yyhat;

call names(all);

call tabulate(%y,%yhat,%error,yyhat,error);



call print(%xfuture);



call print(probnorm(%xfuture*%coef));

b34srun;



PVALUE_1 Present value of $1 recieved at end of n years



call pvalue_1(iend,r,amount);



Calculates the present value of $1.00 recieved at end of n

years. pvalue_1 is a subroutine and has to be loaded.

Arguments:



iend = end period

r = interest

amount = Present value of $1 recieved at end of n years



Usage



call pvalue_1(2,.02,a); => for two years



For a reference on usage see



'Managerial Economics' By Evan Douglas 4th Edition





Example:



b34sexec matrix;

call print('PV of $1 recieved at end of n years');

call print('See Douglas table 1',:);

call echooff;

call load(pvalue_1);

interest=.06;

n=20;

years=integers(n);

pv=array(n:);

do i=1,n;

call pvalue_1(i,interest,a);

pv(i)=a;

enddo;

call tabulate(years,pv :noobslist

:title 'Present value of 6% recieved after n years');

b34srun;





Test case: pvalue_1



PVALUE_2 Present Value of an Annuity of $1



call pvalue_2(iend,r,amount);



Gives the Present Value of an Annuity of $1



Arguments:



iend = end period

r = interest

amount = Present Value of an Annuity of $1



Usage



call pvalue2(2,.02,a); => for two years

Gets Present Value of an Annuity of $1



For detail see 'Managerial Economics By Evan Douglas 4th Ed.



Example:



b34sexec matrix;

call print('PV of an Annuity of $1 after n years');

call print('See Douglas table 2',:);

call echooff;

call load(pvalue_2);

call load(pvalue_1);

sum=0.0;

n=20;

interest=.06;

aa=array(n:);

do i=1,n;

call pvalue_2(i,interest,a);

aa(i)=a;

enddo;

yearpays=integers(n);

call tabulate(yearpays,aa :noobslist

:title 'Present value of 6% annuity after n years');

b34srun;



Test case: pvalue_2



PVALUE_3 Present value of $1 recieved throughout year



call pvalue_3(ibegin,iend,r,amount);



Calculates present value of $1 recieved throughout year.



ibegin => begin period



iend => end period



r => interest



amount => Present value of $1 recieved thoughout

Year on a Daily basis



Usage



call pvalue_3(1,2,.02,a); => for two years



Gets present value of $1. recieved throughout year



See 'Managerial Economics By Evan Douglas 4th Edition



Example:



b34sexec matrix;

call print(

'PV of $1 recieved througout year on daily basis',:);

call print('Years Hence',:);

call print('See Douglas table 3',:);

call echooff;

call load(pvalue_3);

interest=.06;

n=20;

years=integers(n);

pv=array(n:);

do i=1,n;

call pvalue_3(i,i,interest,a);

pv(i)=a;

enddo;

call tabulate(years,pv :noobslist

:title 'Present value of 6% annuity $1 daily');



b34srun;



Test case: pvalue_3





QPMIN - Quadratic Programming.



call qpmin(G,A,B,H neq);



Solves Quadratic Programing problem of the form:



min g'x + .5 * x'*Hx



s.t.



A1*x = b1

A2*x ge b2



Parameters:



G = n coefficients of objective function.



A = m by n equality (neq) and inequality

constraints. Equality constraints

are placed first.



B = m right hand side linear constraints.



H = n by n positive definite matrix.



Options



:print => Optionally will print results.



Automatic Variables:



%sol = Vector of length n containing solution

%diag = scalar equal to multiple of identity

matrix added to H to make it positive

definite.



%nact = Final # of active constraints.



%iact = Location of final active constraints.



%alamda = Vector of length n containing lagrange

multiplier estimates of the final

active constraints in first %nact

locations.



Example:



b34sexec matrix;

* answers should be vector of 1. ;

* Problem came from IMSL ;

ncon=2;

nvar=5;

neq= 2;

a=matrix(ncon,nvar: 1., 1., 1., 1., 1.,

0., 0., 1.,-2.,-2.);

b=vector(ncon : 5.,-3.);

g=vector(nvar :-2., 0., 0., 0.);

h=matrix(nvar,nvar: 2., 0., 0., 0., 0.

0., 2.,-2., 0., 0.

0.,-2., 2., 0., 0.

0., 0., 0., 2.,-2.

0., 0., 0.,-2., 2.);

call qpmin(g,a,b,h,neq :print);

b34srun;





The QPMIN command uses the IMSL routine DQ2ROG



QUANTILE - Calculate interquartile range.



call quantile(x,q,qvalue);



Calculates the interquartile range.



x = vector of elements to be tested.

q = quantile value.

qvalue = the quantile value.



call quantile(x,.95,qvalue);



gives the value of x such that 95% of the values are less than

or equal to this value.



To calculate the median give command.



call quantile(x,.50,median);

Optional arguments 4 and 5 give smaller and larger datum values.



call quantile(x,q,qvalue,xlow,xhigh);



QUANTREG - Calculate Quantile Regression.



call quantreg;



Calculates a Quantile Regression



Note: quantreg is a program contained in matrix2.mac.

Before use it must be loaded with:



call load(quantreg);



Example of use:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call echooff;

call loaddata;

call olsq(gasout gasin :l1 :minimax :print);

call load(quantreg);

* See if can get L1;

iprint=1;

theta=.5;

y=gasout;

x=matrix(norows(gasin),2:);

x(,1)=1.0;

x(,2)=vfam(gasin);

call quantreg;

call print('Sum absolute errors L1 (Theta = .5)',

sumabs:);

b34srun;



Note: Only four arguments are required:



iprint set = 0,1 for printing

y left hand side

x X matrix

theta Theta value in range .01 - .99





For further detail see full QUANTREG example in matrix.mac and

help document under TOOLKIT



READ - Read data directly into MATRIX workspace from a file.



call read(x,n);



Reads defined object x from unit n. Optionally a format can be

specified as the third argument. X must be real*8, real*4,

real*16, integer*4, character*8 or character*1.

VPA data of the form fm, fp, im, ip, zm & zp can be read. For

an example see the test problem VPA1.





If the buffer is greater than the number of data points

the excess length is set to:



For real*8, real*4, real*16 missing



For integer*4, integer*8 -999999999



For Character*8 and Character*1 reads, a message is given if an

end of file is found.



The example files read1 and read2 illustrate advanced

features of the read/write facility.



I/O Package. If it is desired to read complex*16, or

complex*32 the data can be read as real*8 or real*16

respectively and converted.



Example I/O job from read1:



b34sexec matrix;

* Tests I/O package ;

* Real*8, Integer, Character*1 & Character*8

are written and read back ;

* Note: Before reading, structure of object

must be known;

n=1000;

test=rn(array(n:));

call open(70,'testdata');

call write(test,70);

tmean=mean(test);

call print(tmean);

i=integers(1,20);

call write(i,70);

call character(cc,'This is a test');

call write(cc,70);

a=array(3:'joan','Margo','Nancy');

call write(a,70);

call names(all);

call free(test);

call rewind(70);

call close(70);

call open(71,'testdata');

test2=array(n:);

call character(cc,'this is less ');

call read(test2,71);

i=i+100;

call read(i,71); call print(i);

call read(cc,71);

call print(cc);

a(1)='bob';

call read(a,71);

call print(a);

tmean2=mean(test2);

call print(tmean2);

call names(all);

b34srun;



The job FORTRAN illustrates using the LF95 compiler to

build data which is loaded into the B34S MATRIX command.



The below listed job show trying to read more data than

is there:



b34sexec matrix;

* attempting a read for more data that is there;

n=10;

test=rn(array(n:));

ii=integers(n);

call open(70,'testdata');

call rewind(70);

call write(test,70);

tmean=mean(test);

call print(tmean);

call free(test);

call rewind(70);

call close(70);

call open(71,'testdata');

n=20;

test2=array(n:);

call read(test2,71);

call print(test2);

tmean2=mean(goodrow(test2));

call print(tmean2);

call names(all);



call open(70,'testdata');

call rewind(70);

call write(ii,70);

call print(ii);

call free(ii);

call rewind(70);

call close(70);

call open(71,'testdata');

n=20;

test2=idint(array(n:));

call read(test2,71);

call print(test2);

call names(all);

b34srun;



Example of reading from datacards



/;

/; Various data precision reads

/;



b34sexec matrix;

datacards;

1.25 4.11 4. 2.

b34sreturn;

call load(ntokin :staging);

call load(getvpa :staging);

call echooff;



x8=array(4:);

x4=sngl(x8);

x16=r8tor16(x8);

x_vpa=vpa(x8);

call read(x4,4);



call rewind(4);

call read(x8,4);



call rewind(4);

call read(x16,4);



call rewind(4);

c=c1array(72:);

call read(c,4);

call print(c);

call ntokin(c,nn,0,ibad);

call getvpa(c,nn,x_vpa,i);





call print(x4,x8,x16,x_vpa);

b34srun;



REAL16 - Input real*16 variable in a Character String



Creates a real*16 variable from Character string. This allows

calculations to be made without the accuracy loss if real*8

data is moved to real*16.



r16=real16('.9q+00');



Example:



b34sexec matrix;

r16= real16('.9q+00');

r16a=r8tor16(.9);

call print('R16', r16:);

call print('R16A' r16a:);

call print('Difference ',(r16a-r16):);

b34srun;



REAL16INFO - Obtain Real16 info

call real16info;



Obtains real16 setting. For a test case look at Filippelli

dataset in stattest.mac.



REAL16OFF - Turn off Real16 add



call real16off;



Turns off real16add in ddot, dsum and dasum etc.

For a test case look at Filippelli dataset in stattest.mac.



REAL16ON - Turn on extended accuracy



call real16on;



Turns on extended accuracy add in a number of BLAS routines

using IMSL routines dqadd and dqmult. If the argument

:real16math is added:



call real16on(:real16math);



then internally full real*16 is used. This is slower due to the

fact that real*16 math is not built into the chip and the mods

to DDOT, DSUM and DASUM etc distroy the speed gains built into

BLAS. The gain is increased accuracy in extreme problems.



For a test case look at Filippelli dataset in stattest.mac.

In many cases there will be no gain from increased accuracy

in the calculation.



REAL32OFF - Turn off Real*16 add



call real32off;



Turns off real*32 accuracy in in ddot, dsum and dasum etc.

For a test case look at Filippelli dataset in stattest.mac.



REAL32ON - Turn on extended accuracy for real*16 and complex*32



call real32on;



Turns on extended accuracy add in a number of BLAS routines.

For a test case look at Filippelli dataset in stattest.mac.



REAL32_VPA - Turn on extended accuracy for real*16 using VPA.



call real32_vpa;



Turns on extended accuracy add in a number of BLAS routines.

At a later date this may be extended to complex*32 improvements

using VPA. This option slows down execution. For a test case

look at Filippelli dataset in stattest.mac.

RENAME - Rename an object



call rename(x,object(x,2));



Renames an object.



Example: Given x = existing object



object(x,2) resolves to x2



The command



call rename(x,object(x,2));



causes x to be renamed x2. Note the name x2 is not known at

parse time.



Note that the arguments to object can themselves be computed.



xx='aa';

call rename(x,object(argument(xx),2));



renames x to aa2.



Optional arguiment



:global => place series at global level



Note the name x2 is not known at parse time.



Note:



call rename(x,y);



does not copy x into a variable y but rather copies x into a

name contained in the variable y. This name should be a

valid name.



Example:



b34sexec matrix;

test1=object(x,y);

test2=object(x,y,1);

call names;

call print(test1,test2);

x=10.;

y=40.;

call rename(x,test1);

call rename(y,object(p,v,0));

call names;

call print(xy,pv0);

b34srun;



Note: eval is used to extract data from a "pointer.:

test1=40.;

cc='TEST1';

call print(eval(cc));



prints 40



since object builds a name on the fly.



RESET - Calculate Ramsey (1969) regression specification test.



call reset(x,rtest,ip,ik,prob)



Calculates modified Ramsey (1969) reset (regression

specification test) for the residual. The RES69 command is used

for the usual RESET test



The argument :print is optional.



x => series

rtest => reset test

ip => # of lags. Must be in the range 1 - N-3*ip-3*ik

ik => # of eq 2 powers on the lagged residual

prob => Probability of test. (Optional argument)

:print => Will give printed output.



Notes: Takes the estimated residual and runs



Eq 1 e(t) = f(e(t-1),...,e(t-ip)) + v

Eq 2 e(t) = f(e(t-1),...,e(t-ip),((e(t-1)**2),...,

(e(t-ip)**2),..., (e(t-1)**ik),...,

(e(t-ip)**ik) + u



Uses F test to test sig



F(ik-1,n-ik) = ((v'v - u'u)/(ik-1)) /(v'v/(n-ik))





Reference: Ramsey, J. 'Tests for Specification Errors in

Classical Linear Least Squares Regression Analysis',

Journal of the Royal Statistical Society, Series B:

350-371



Example:



b34sexec matrix;

call echooff;

call loaddata;



call olsq(gasout gasin{1 to 6}:print);

rr=%res;

lower=2;



do ik=2,6;

do ip=lower,18;

call reset(rr,tt,ip,ik,pp);

j=ip-lower+1;

test(j) =tt;

prob(j) =pp;

order(j)=ip;

enddo;



call print('Ramsey (1969) test for',ik);

call tabulate(order,test,prob);

enddo;



/; alternate



lower=2;



do ik=2,6;



do ip=lower,18;

call reset(rr,tt,ip,ik :print);

enddo;

enddo;



b34srun;



RESET69 - Calculate Ramsey (1969) regression specification test.



call reset69(y,x,rtest,prob,iorder,iprint)



Calculates Ramsey (1969) reset (regression specification test)

for the prior equation. The RES69 command is nopt the same as

the RESET test which is a modification for the residual.



y => left hand variable

x => Original right hand side

rtest => reset test

prob => Probability of test

iorder => Must be in range 2-(N-k)

:print => Will give printed output.



Notes: Takes the estimated residual and runs



Eq 1 y(t) = f(x1,...,xk) + v

Eq 2 y(t) = f(x1,...,xk) +(yhat(t)**2),...,

yhat(t)**iorder) +u



Uses F test to test sig



F(iorder-1,n-k-iorder-1) =



((v'v - u'u)/(ik-1)) /(v'v/(n-k-iorder+1))

Reference: Ramsey, J. 'Tests for Specification Errors in

Classical Linear Least Squares Regression Analysis',

Journal of the Royal Statistical Society, Series B:

350-371



Example:





b34sexec options ginxclude(

b34sexec matrix;

call echooff;

call loaddata;

call load(reset69)



call olsq(gasout gasin{1 to 6}:print);

x=%x;

y=%y;

iprint=1;



do iorder=2,3;

call reset69(y,x,rtest,prob,iorder,iprint)

enddo;



b34srun;



RESET77 - Thursby - Schmidt Regression Specification Test



call reset77(indata,maxp,maxk,treset77,preset77,printit);



Calculates (Thursby-Schmidt, JASA, 1977) RESET(1977) Test



y = b1*x_t-1 + ...+ bp*x_t-p + e rss1 =e'e

e = f(x, x^2,...,x^h)+ u rss2 =u'u



(rss1-rss2)/(h-1)

F(h-1,n-m-p-h)~ -----------------

rss2/(n-m-p-h)



where m=p*h





Reference: "Some Properties of Tests for Specification Error

in a Linear Regression Model" JASA September 1977

Vol 72 Number 359 pp 635-641



Arguments:



indata => real*8 series to be tested

maxp => integer*4 max ar order

maxk => integer*4 max order of test

treset77 => reset77 statistic. reset77 is a maxk-1 array

preset77 => probability of reset statistic. preset77 is a

maxk-1 array

printit => integer switch.

1 => print table of test

2 => print OLS and table of test





Note: RESET77 is a SUBROUTINE and must be loaded with the

command



call load(reset77);



Example of use:



b34sexec matrix ;

call echooff ;



call load(reset77);



/; Build an AR model



n=10000 ;

ncases=5;

ar=0.25 ;

call free(ma);

const=0.0; start=.1;

wnv=1.0;

nout=200;



do i=1,ncases ;

ar1yt =genarma(ar,ma,const,start,wnv,n,nout);

call reset77(ar1yt,1,4,res77,pres77,1);

enddo ;



b34srun ;



RESTORE - Load data in MATRIX facility from external save file.





call restore;



Restores the workspace from the default name. Alternative

options can be passed with :keywords.



Keywords supported include:



:file - to pass a file name



:var - to restrict what variables are restored. Do not

place, between the names of variables.



:list - to list what is in the file.



Examples:



call restore(:list);

call restore(:list :file 'myrin.psv');



call restore(:var x y);



call restore(:var x y :file 'mystuff.psv');



For related commands see save and checkpoint.



REVERSE - Test a vector for reversibility in Freq. Domain



call reverse(x : options)



Performs Hinich-Rothman(1998) for reversals.



x => series (must be real*8).



Optional commands



:print => Prints test.



:freq => Sampling rate in kHz. Default is periods.



:sr r1 => Sampling rate. Default = 1.

If freq is in effect sampling rate in

multiple of milsec (1/khz)



:rb r2 => Sets resolution bandwidth in hz. default = 5.



:sb r3 => Sets spectral smoothing bandwidth in hz.

sb > rb. If sb not set => spectrun not

smoothed.



:norm k => if k = divide => divide bispectrun at (f1,f2)

by sqrt[S(f1)S(f2)S(f1+f2)]



if k = no => do not normalize bispectrum

Here bispectrum divided by

cube of sample SD. This

option used if series is

white noise.



if k- filter => Filter out frequency

components in range (0,fl) and

above fu.



Warning. Unless series is white noise the default :norm no

should NOT be used since the bispectrum will not be

correct.



:fl r4 => Lower frequency for analysis. Default = 0.

Note fl must never be set lt 0.0.



:fu r5 => Upper frequency for analysis. Default = .475

which is the upper limit.

:pt r6 => % taper of frames for sidelong reduction.

Range 0.0 LE pt LT 25. Default = 0.0.



:bandpass => Bandpass filter the series using fl and fu.

All frequency info below fl and above fu will

be removed.



:save - Saves for further processing:



%br - Real part of bispectrum

%bi - Imag part of bispectrum

%b1 - Real part counters

%b2 - Imag part counters

%sp - Spectrum

%freq - Freq vector for plotting %sp

%period - Period vector for plotting %sp

%cr - Real Cum2

%ci - Imag Cum2

%c1 - Real Cum2 pointers

%c2 - Imag Cum2 pointers



Notes: Irreversibility can stem from two sources:



1. Underlying model can be nonlinear even though

innovations are symmetrically (perhaps normally)

distributed.



2. Underlying innovations may be drawn from a

non-Gaussian probability distribution while the model

is linear.



3. With small numbers of observations it may not be

possible to get consistent estimates without having

too low a blocksize.



Variables Created



%t1 - Sig of sum of squares of real bispectrum



%t2 - Sig of Sum of squares of imag bispectrum.

Significance => No reversibility or

business cycle asymmetry



%tc - Cum2 stationarity test.



%tcs - Probability of Cum2 test



%ts - Stationarity test



%alm - average noncentrality lamda for

bispectrum



%sgl - SD for %alm

Sample jobs



b34sexec options ginclude('b34sdata.mac')

member(rothtr1); b34srun;



b34sexec matrix;

call loaddata;

call reverse(nomgnp :print);

call rothman(nomgnp :order 5 :print);

b34srun;



b34sexec options ginclude('b34sdata.mac')

member(rothtr2); b34srun;

b34sexec matrix;

call loaddata;

call reverse(gnpdefl :print);

call rothman(gnpdefl :order 5 :print);

b34srun;



REWIND - Rewind logical unit.



call rewind(n);



Rewinds unit n.



Example:



call rewind(72);



ROTHMAN - Test a real*8 vector for reversibility in Time Domain



call rothman(x :options);



The rothman sentence performs various time reversibility tests

suggested Rothman using the TR1 and TR2 programs.



For refeneces see BTIDEN command help file.



The TR1 program is designed to calculate Ramsey and Rothman

(1996) standardized TR test statistics for a raw series. An

ARMA model is fitted to the series to estimate the standard

deviation of the statistics. The Rothman (1994) portmanteau

test is also calculated.



The TR2 program is designed to calculate the TR test for

residuals using equation (10) of Ramsey and Rothman (1996). If

the series is not white noise, it can be filtered. The Rothman

(1994) portmanteau test is also calculated. A Monti Carlo

simulation is run to estimate the p-values of the maximum (in

absolute value) of the standardized TR test statistics and of

the portmanteau statistic.



Required

x => Series to be tested. Must be a 1

dimensional real*8 object.



Optional



:test key => key = tr1 => use TR1 program.

key = tr2 => use TR2 program.

TR2 is the default.



:order maxk => Sets order of test. Default 5.



:print => Prints a detailed list of the assumptions

of the test. This is usually not needed.



:print2 => Prints the ARMA estimation results. This

is rarely needed.



:ar ip => max order of ar filter.



:ma iq => max order of ma filter



If TR1 ARMA model used to get sd.

If TR2 ARMA model used to filter data.



:tran key => Provides optional transformations of the

data. Key can be set as:



raw - Use raw data (default).

log - Use log of data/

diflog - First difference of log of

data

dif - First difference of data

logdt - Log detrended data

rawdt - Raw detrended data



:iseed ii => Sets the seed. This option is not usually

set. It is useful only in replication

testing.



:maxit i => Sets maximum iterations for simulations.

Default = 100.



:maxit2 j => Sets maximum iterations for arma

modeling. Default = 200.



:rerror d => Sets the relative error for arma

termination. Default = 0.0



:maxbc i => Set maximum lag backforecasting.

Default=0.



:tolbc r => Sets convergence for backforecasting.

:tolss r => Sets convergence for nonlinear least

squares. Must be in range 0.0 - .9999



Test makes:



%tr1 => TR1 test - Abs of Max Standardized TR

Statistic

%tr2 => TR2 test - Abs of Max Standardized TR

Statistic

%tr1prob => Probability of TR1 test

%tr2prob => Probability of TR1 test

%tr1pt => Portmanteau test from TR1 run

%tr2pt => Portmanteau test from TR2 run

%tr1ptp => Portmanteay test probability for %tr1pt

%tr2ptp => Portmanteay test probability for %tr2pt



Samples of Rothman Test



b34sexec options ginclude('b34sdata.mac') member(rothtr1);

b34srun;



b34sexec matrix;

call loaddata;

call rothman(nomgnp :maxit 100

:test tr1

:order 5

:ar 1

:tran logdif

:iseed 25443332 :print);

b34srun;

b34sexec options ginclude('b34sdata.mac') member(rothtr2);

b34srun;



b34sexec matrix;

call loaddata;

call rothman(nomgnp :maxit 100

:test tr2

:order 5

:ar 1

:tran logdif

:iseed 25443332 :print);

b34srun;



RMATLAB - Runs Matlab





call rmatlab;



Runs Matlab from a file passed in to the Matrix comamnd with

DATACARDS; or PGMCARDS; The command rmatlab is a program and

must be loaded.



Example

/$ Running Matlab script under B34S Matrix

/$ First define matlab commands

/$

b34sexec matrix;

datacards;

% The example runs a matlab problem under B34S Matrix

% page 10-24 Graphics

load earth

sphere;

h= findobj('TYPE','surface');

hem=[ones(257,125),X,ones(257,125)];

set(h,'CData',flipud(hem),'FaceColor','texturemap')

colormap(map)

axis equal

view([90 0])

set(gca,'CameraViewAngleMode','manual')

view([65 30])

pause

quit

b34sreturn;



* Here load all commands ;



call load(rmatlab);

call rmatlab;

b34srun;



Notes: Since datacards; and pgmcards; write to unit 4, an

alternative method of operating is to write the Matlab

command in the b34s matrix command on unit 4 and then call

rmatlab.



The rmatlab program may have to be modified if the

user uses a non-standard Matlab setup.





RRPLOTS - Plots Recursive Residual Data



call rrplots(rrstd,rss,nob,k,sumsq1,sumsq2,list);



Plots Recursive Residual output from OLSQ



Arguments



rrstd => Standardized Recursice Residual

rss => Residual sum of squares fopr OLS

nob => Number of Observations for OLS

k => Number of right hand side variables

sumsq1 => Sum of squares # 1

sumsq2 => Sum of squares # 2

list => =0 no list, =1 list results



The following plot files are automatically made:

rr.wmf

cusum.wmf

cusumsq.wmf

ql.wmf



This command must be loaded.



Example:



b34sexec options ginclude('b34sdata.mac') macro(eeam88)$

b34srun$



b34sexec matrix;

call loaddata;

call load(rrplots);



call olsq( lnq lnk lnl :rr 1 :print);

call print(%rrcoef,%rrcoeft);

call rrplots(%rrstd,%rss,%nob,%k,%ssr1,%ssr2,1);

b34srun;



RTEST - Test Residuals of Model



call rtest(res1,y,nacf);



Tests the residuals of a Model. This is single equation version

of GTEST. The RTEST command must be loaded. If plots are not

needed see RTEST2.



subroutine rtest(res1,y,nacf);

/;

/; res1 => First Moment Residual

/; y => Input Series

/; nacf => Number acf terms

/;

/; Plots made:

/;

/; acfa.wmf => acf of residual Moment 1

/; acfb.wmf => acf of residual Moment 2

/; acfy.wmf => acf of y series

/; mqa.wmf => Q stats residual Moment 1

/; mqb.wmf => Q stats residual Moment 2

/; pacfa.wmf => pacf of residual Moment 1

/; pacfb.wmf => pacf of residual Moment 2

/; pacfy.wmf => pacf of y series

/; resa.wmf => Plot of residual Moment 1

/; resb.wmf => Plot of residual Moment 1

/;



Example:



/$ Illustrates incomplete and complete Model

b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

call loaddata;

call load(rtest);

call olsq(gasout gasin:print :diag);

call rtest(%res,gasout,48);

call olsq(gasout gasin{1 to 6} gasout{1 to 6} :print);

call rtest(%res,gasout,48);

b34srun;



RTEST2 - Test Residuals of Model - No RES and Y Plots



call rtest2(res1,y,nacf);



Tests the residuals of an OLS Model. This is single equation

version of GTEST. The RTEST2 command must be loaded. If plots

are desired, use RTEST.





subroutine rtest2(res1,y,nacf);

/;

/; res1 => First Moment Residual

/; y => Input Series

/; nacf => Number acf terms



Example:



/$ Illustrates incomplete and complete Model

b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

call loaddata;

call load(rtest2);

call olsq(gasout gasin:print :diag);

call rtest2(%res,gasout,48);

call olsq(gasout gasin{1 to 6} gasout{1 to 6} :print);

call rtest2(%res,gasout,48);

b34srun;



RUN - Terminates the matrix command being in "manual" mode.



call run;



Gets out of manual mode.



call manual; - Allows user to enter commands at the

terminal. This command works only

with the Display Manager.





SAVE - Save current workspace in portable file format.



call save;

Will save the workspace with a default name. Alternative

options can be passed with :keywords.



Keywords supported include:



:file - to pass a file name.

Default name is 'matrix.psv'.



:var - to restrict saving to a list of

variables. Do not place ,

between names. If variable is known

at the local and global level, the

local copy is saved. This means that

formula results not formulas are saved.

If :var is not present all objects will

be saved.



:speakeasy - Only pass data, no programs. If this option

is used, the save file can be read by the

Speakeasy(r) program. The



call checkpoint;



command automatically assumes this option. As

a result real*16 and complex*32 variables are

saved as real*8 and complex*16 respectively.

If



call save;



is used, then this conversion is not made.

Here the save file will preserve real(16 and

complex*32 variables but will not work with

Speakeasy!



:ndigits4 - Sets save format e12.4



:ndigits8 - Sets save format e16.8.



:ndigits16 - Sets save format e24.16. This is the default.



:ndigits32 - Sets save format e40.32



Examples:



call save(:var x y z);



call save(:var x y z :file 'myrun.psv');



call save(:file 'myrun.psv');



call save(:var x y :file 'mygood.psv' :speakeasy);



If you are running with Speakeasy, it is suggested that you use

the ending *.psv.



The SAVE and RESTORE commands use a subset of the Speakeasy

EXPORTALL & IMPORTALL format and are designed to facilitate

moving objects from one system to another. Since B34S MATRIX

PROGRAMS, SUBROUTINES and FUNCTIONS will not work on Speakeasy,

the keyword :speakeasy MUST be used to save into a file that

will be read by Speakeasy(r).



VPA data can not be directly saved in a savefile. However VPA

data can be hidden in a real*8 variable so VPA numbers can be

saved with checkpoints etc using the command



call vpaset(vpa r8 :saveasr8);



The variable r8 can be reloaded into a VPA variable with



call vpaset(r8 vpa :saveasvpa);



The first four elements give kind, nr8, norows, nocols.





For related commands see restore and checkpoint.



SCHUR - Performs Schur decomposition



call schur(a,s,u);



factors real*8 matrix A such that



A=U*S*transpose(U)



and S is upper triangular. For complex*16 the equation is



A=U*S*transpose(dconj(U))



U is an orthogonal matrix such that for real*8



u*transpose(u) = I



Real*8 Eigenvalues of A are along diagonal of S.



An optional calling sequence for real*8 is



call schur(a,s,z,wr,wi);



where wr and wi are the real and imaginary parts, respectively,

of the computed eigenvalues in the same order that they appear

on the diagonal of the output Schur form s. Complex conjugate

pairs of eigenvalues will appear consecutively with the

eigenvalue having the positive imaginary part first.



The optional calling sequence for complex*16 is

call schur(a,s,z,w);



where w contains the complex eigenvalues.



The Schur decomposition can be performed on many real*8 and

complex*16 matrices for which eigenvalues cannot be found. For

detail see the Matlab manual page 4-36.



The schur command uses the lapack version 3 routines dgees and

zgees.



Example:



b34sexec matrix;

* Example from Matlab - General Matrix;

a=matrix(3,3: 6., 12., 19.,

-9., -20., -33.,

4., 9., 15.);

call schur(a,s,u);

call print(a,s,u);

is_ident=u*transpose(u);

is_a =u*s*transpose(u);



* Positive Def. case ;

aa=transpose(a)*a;

call schur(aa,ss,uu);

ee=eigenval(aa);

call print(aa,ss,uu,ee);



* Expanded calls;

call schur(a,s,u,wr,wi);

call print('Real and Imag eigenvalues');

call tabulate(wr,wi);



* Testing Properties;

call print(is_a,is_ident);



* Random Problem ;

n=10;

a=rn(matrix(n,n:));

call schur(a,s,u);

call print(a,s,u);

is_ident=u*transpose(u);

is_a =u*s*transpose(u);

call schur(a,s,u,wr,wi);

call print('Real and Imag eigenvalues');

call tabulate(wr,wi);

call print(is_a,is_ident);



* Complex case ;

a=matrix(3,3: 6., 12., 19.,

-9., -20., -33.,

4., 9., 15.);

ca=complex(a,2.*a);

call schur(ca,cs,cu,cw);

call print(ca,cs,cu,

'Eigenvalues two ways',cw,eigenval(ca));

is_ca=cu*cs*transpose(dconj(cu));

call print(is_ca);

b34srun;



SCREENCLOSE - Turn off Display Manager



call screenclose;



Turns of Display Manager prior to a



call dounix( );



command. Use



call screenopen;



after the external command finishes/ends, b34s returns to

the Display Manager.



SCREENOPEN - Turn on Display Manager



call screenon;



For detail on use see screenclose.



SCREENOUT1 - Turn screen output off.



call screenoutoff;



Turns off screenout output.



SCREENOUT2 - Turn screen output on.



call screenouton;



Directs most matrix output to screen. When MATRIX command

ends, b34s returns to Display Manager.



SET - Set all elements of an object to a value.



call set(name,value);



Sets all elements of name to value. Name cannot be a structured

object. The commands setrow and setcol are used for setting

rows and columns.



c=rtoch(array(3:));

call set(c,'text');



places 'text' in character*8 array c. The commands

d=array(4:);

call set(d,1.0);



put 1.0 in all elements of d.



SETCOL - Set column of an object to a value.



call setcol(name,row,value);



Sets a col of name to value. Name cannot be a structured

object. The command



call setcol(x,5,6.);



sets col 5 of x to 6.0. An alternative is



x(,5)=6.0;



Warning: While setcol checks for type



x(,1)=88; '



Redefines x as an integer matrix!!



SETLABEL - Set the label of an object.



call setlabel(x,'x is sin(xx)/2. ');



Sets label for object x. The string can be up to 40 characters.



b34sexec matrix;

short=10.;

long= 20;

call names;

call setlabel(short,'test');

call setlabel(long, 'This is a long label');

call names;

call print('Label for long' ,label(long),

'Label for short',label(short));

b34srun;



SETLEVEL - Set level.



call setlevel(key);



Sets the level of the program.



Arguments:



key = up => Move data save level up 1



key = down => Move data save level down 1



key = base => Move data save level to base level

key = now => prints level now.



This command is rarely used. It is for custom jobs where more

than a two level link is used.



This command is NOT for the faint at heart!!



Warning: If you change the level in a subroutine then it

cannot access data unless it is at global level.



If used in open code the user may get a object

not found message unless the object is at the

global level. Inside a do loop it is imperative that

the level not be changed from top to bottom or else

the counter will not be found.



SETNDIMV - Sets value in an N Dimensional Object



call setndimv(index(4 5 6),index(2 3 4),xx,value);



places value in element 2 3 4 of the 4 by 5 by 6 dimensioned

variable xx.



Example:



b34sexec matrix;

mm=index(4,5,6:);

xx=rn(array(mm:));

idim =index(4,5,6);

idim2=index(2,2,2);

call setndimv(idim,idim2,xx,10.);

vv= getndimv(idim,idim2 ,xx);

call print(xx,vv);

b34srun;



SETROW - Set row of an object to a value.



call setrow(name,row,value);



Sets a row of name to value. Name cannot be a structured

object.



call setrow(x,5,6.);



sets row 5 of x to 6.0



An alternative is



x(5,)=6.0;



Warning: While setrow checks for type



x(5,)=88; '

Redefines x as an integer matrix/array!!



SETTIME - Sets the time info in an existing series



call settime(series,timebase,tstart,freq);



Sets the time info in an existing series



Arguments



series => existing series



timebase => integer year base



tstart => integer period base



freq => real*8 frequency



Example:



call settime(x,1960,1,12.);



Sets the time info in series x



More complex Example:



b34sexec matrix;

x=rn(array(120:));

call settime(x,1960,1,12.);

jdate=makejul(x);

year=fyear(jdate);

call graph(year,x :plottype xyplot);

b34srun;



SETWINDOW - Set window to main(1), help(2) or error(3).



call setwindow(i);



Sets to the current window. Use with caution.



i=1 => main window

i=2 => help window

i=3 => error window



SIGD - Set print digits. Default g16.8



call sigd(5);



Sets the default print to g16.5. If argument > 8 then width

increases. The command fprint( ) can override format.



Example:

b34sexec matrix;

r=pi();

do i=1,8;

call print('sigd was ',i);

call sigd(i);

call print('pi was ',pi() :line);

call print('pi was ',pi());

enddo;

b34srun;

/$ Illustrates OLS Capability under Matrix Command

/$ # digits changed



b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;



b34sexec matrix sigd(4);

call loaddata;

call olsq(gasout gasin:print :diag);

call sigd(10);

call olsq(gasout gasin:print :diag);

b34srun;







SIMULATE - Dynamically Simulate OLS Model



call simulate(yhat,coef,x,nerror);



call simulate(yhat,coef,x,nerror :lags n ny);



Required inputs



yhat => Calculated by routine



coef => Coefficient vector ususlly calculated by OLSQ



x => X matrix saved as x1 x2 x3 x4 x5 const

if y is lagged, ylags are placed first in

dataset and are changed on the fly



nerror => Input error. Usually calculated as bootv(%res)

where %res was from the origional OLS equatoion



Optional inputs



:lags nlag ny

:MA maparm maorder



Model estimated



yhat = coef*transpose(x)



For a good reference see Enders(2004) page 235-238.

Assume a model y=a + b1*x1 + b2*x2 + e



1. First estimate model and save coef. Coef are a,

b1, and b2 and estimated error is e.



2. Form new y (y*) = a+b1*x1 +b2*x2 + e*

where e* is selected from e with replacement.



3. Run y* on x1 and x2 and save coef.



Repeat steps 2 and 3 over and over. If y has lags on the

right, we have to dynamically update these values.

The call simulate( ) does step # 2 above.



Example of use where there are lag lags of the left hand

variable.



if(lag.ne.0)then;

lagorder=integers(lag);

do ii=1,nboot$

nerror=bootv(error);

ny =bootv(y);

call simulate(ywork,coef,x,nerror :lags lag ny);

call olsq(ywork x :noint);

%hcoef(ii,)=%coef$

%hse(ii,) =%se$

%hrsq(ii) =%rsq$

call outstring(3,3,'Time Series Bootstrap #');

call outinteger(14,4,ii);

enddo$

endif;



Without lags on the y variable use:



do ii=1,nboot$

nerror=bootv(error);

ny =bootv(y);

call simulate(ywork,coef,x,nerror);

call olsq(ywork x :noint);

%hcoef(ii,)=%coef$

%hse(ii,) =%se$

%hrsq(ii) =%rsq$

call outstring(3,3,'Bootstrap #');

call outinteger(14,4,ii);

enddo$

endif;



Note: See bootols in staging.mac for a running example.



SMOOTH - Do exponential smoothing.





call smooth(x :options);

Allows calculation of many exponential smoothing methods.

The smooth command can be made to "automatically" forecast

large numbers of series.



Options. Note if :method key is supplied it MUST be first.



:method nce => no change extrapolation (default)

ncept => no change + trend

avetd => average to date

mave => moving average

dmave => double moving average

es => exponential smoothing

des => double exponential smoothing

holt => holts method

winters=> winters' method



:lag n => sets lag. n determines number of

forecasts for nce, ncept, dmave,

des, Holt and Winters methods. For

Winters method max lag = nma.



:nma nn => Number of terms for moving average.

Default=4. If method set to winters,

nma = lag on S



:alpha d => Alpha for es, des, holt and winters

method. Default = .3 0 Beta for Holt and Winters method.

Default = .2 0 Gamma for Winters method.

Default = .1. Gamma is the smoothing

constant for the seasonality estimate.



:astart a0 => Used for double exponential smoothing.

Default = x(1)



:bstart b0 => Used for double exponential smoothing.

Default=0.0



:ia a => Initial A for Holt and Winters Method.

Initial yhat for es. Default = x(1)

or data value for Holt. For Winters

use OLS.



:itrend itrend => Initial Trend for for Holt and Winters

Method. Default =0.



:print => prints summary data to evaluate the

lag = 1 forecast.

Notes: Initial values of a0 and b0 for double exponential

smoothing, Winters and Holt method established using

OLS on the trend.



Variables created



%xhatmat => Forecasts. Saved as Obs # actual lag1

forecast ... lagn forecast.



%xhat => lag 1 forecast for observations for which

there are data.



%xhatobs => xhat obs vector. Useful for tabulation.



%actual => Actual data with one obs missing



%error => Error of Model for lag1



%rss => residual sum of squares for nlags



%mad => sum(dabs(x-xhat))/n for n lags



%mse => rss/n



%mape => sum(dabs(x-xhat)/X)/n how large forecast

is in relation to series



%mpe => sum((x-xhat)/x)/n + and - tests if over

or under



%corr => Correlation between x and xhat using usual

formula.



Notes: %xhatmat contains duplicate data but in addition

contains forecasts. Col 1 is obs #, Col 2 is actual.

Col 3.. lag+2 contain lag = 1 ,..., lal = lag

forecasts.



For detail on the methods used see Hanke & Reitsch

(1998) page 171-172.



The advantage of the smooth command is the forecasts are

automatic and can be done for large number of series.

If user model building is possible, VARMA and BJ methods

usually will be superior. The constrained minimize

commands can be used to optimize the selection of alpha,

beta and gamma as needed.



Calculation notes on methods used:



nce => yhat(t+1) = y(t)



ncept => yhat(t+1) = y(t)+(y(t)-y(t-1))

avedt => yhat(t+1) = average(y(t),..,y(1))



mave => yhat(t+1) = average(y(t),..,y(t-nma))



dmave => yhat(t+p) = a(t) + b(t)*p

a(t) = 2*M(t) - MP(t)

b(t) = (2/(n-1))*(M(t)-MP(t))

MP(t) = (M(t) + M(t-1) + ...

M(t-nma+1))/n



es => yhat(t+1) = alpha*y(t) + (1-alpha)*yhat(t)



des => yhat(t+p) = a(t) + b(t)*p

A(t) = alpha*y(t) + (1-alpha)*y(t-1)

AP(t) = alpha*A(t) + (1-alpha)*AP(t-1)

a(t) = 2*A(t) - AP(t)

b(t) = (alpha/(1-alpha))*(A(t)-AP(t))

A(0) = a(0) - ((1-alpha)/alpha)*b(0)

AP(0) = a(0) - 2*A(t) - AP(t)



holt => yhat(t+p) = A(t) + p*T(t)

A(t) = alpha*y(t)+

(1-alpha)*(A(t-1)+T(t-1))

T(t) = beta*(A(t)-A(t-1))+

(1-beta)*T(t-1)



winters => yhat(t+p) = (A(t)+p*T(t))*S(t-nma+p)

A(t) = alpha *(y(t)/S(t-nma)) +

(1-alpha)*(A(t-1)+T(t-1))

T(t) = beta*(A(t)-A(t-1))+

(1-beta)*T(t-1)

S(t) = gamma*



Use notes:



Double exponential smoothing (Brown's Method) useful for a

series with a trend.



Holt's method smoothes the trend and the slope directly.



Winters' method is useful if there is seasonality in the

data. The Winter's method assumes the data is positive.

If Data is LE 0.0 an error message is given.



Example Forecasts of gasout using moving average:



call smooth(gasout :method mave :print);

call tabulate(%xhatobs, %xhat, %actual, %error);





SOLVEFREE - Set frequency of freeing temp variables.



call solvefree(i)

Sets frequency of freeing temp variables for SOLVE and FORMULA

variables.



The alternative command:



call solvefree(:print);



displays current settings.



************************************************



Advanced temp variable options. If you do not completely

understand these options, do not use them. Their purpose is to

give the end user more control over the workspace.



Inside a do loop or if structure it is possible to run out of

temp variables. The commands:



call solvefree(:alttemp);



call solvefree(:cleantemp);



placed inside a do loop can be used to clean temp variables of

the form %%______



It is important that these commands be used in pairs at the

right spot.



For example:



do i=1,largenum;

call solvefree(:alttemp);

* many statements here !! ;

call solvefree(:cleantemp);

enddo;



will work but



call solvefree(:alttemp);

do i=1,large num;

* many statements here !! ;

call solvefree(:cleantemp);

enddo;



will fail since variables to control the do loop will be opened

using the %%____ temp variables and then before the do loop

is ended the temps may be lost when they are cleaned. This will

cause unpredictable results.



Using :cleantemp ## temps are cleaned at or above the current

level. If at level 100, then level 1 temps are cleaned.



Once :cleantemp is found the default ##____ temp variable is

reset.



It is possible to set %%______ then clean every k times.



For example



do i=1,nbig;

if(i.eq.1)call solvefree(:alttemp);



* statements here;



if(dmod(i,10000).eq.0)then;

call solvefree(:cleantemp);

call solvefree(:alttemp);

endif;



enddo;



/$ be sure we are in default temp mode



call solvefree(:cleantemp);



*******************************************



The alternative commands



call solvefree(:basetemp);



sets ## temp without cleaning.



call solvefree(:cleantemp1);



cleans user (##) temps at or above the current level but does

not reset to ##______ temp.



call solvefree(:cleantemp2);



cleans user (%%) temps at or above

the current level. but does not reset

the default temp.



If this command is used, a call



call solvefree(:cleantemp);



or



call solvefree(:basetemp);



is needed to get back in ##_____ temp mode!!



call solvefree(:gettemp ii);



returns in ii a 0 or 1 depending on the current

temp variable setting.



Warning: The calls



call solvefree(:alttemp);



* commands here;



call solvefree(:basetemp);



will waste space in the allocator since the

%% temp variables have not been cleaned.



SORT - Sort a real vector.



call sort(x);



Sorts x in place. X can be real*8, character*8 or character*1.

If x is character*1, it is sorted by row. Real*8 data can also

be sorted by the use of ranker. Data is sorted in ascending

order unless : is present.



SPECTRAL - Spectral analysis of a vector or 1d array.



call spectral(x,sinx,cosx,px,sx,freq:weights);



Does spectral analysis on one series. The spectral command has

6 or 7 arguments depending on whether weights are supplied. The

command:





call spectral(x,sinx,cosx,px,sx,freq:weights);



calculates for series x



sinx - sine transform

cosx - cosine transform

px - Periodogram

sx - Spectrum

freq - Frequency



where x = input series and the number of weights is odd.

The period can be calculated as period = 1/freq;



The spectral command calculates both periodogram, spectrum and

sine and cosine transfoms. If only the periodogram is needed

use the function spectrum



px=spectrum(gasout);



If only the spectrun is needed, use



sx=spectrum(gasout:1 2 3 2 1)

For this command



call spectral(gasout,sinx,cosx,px,sx,freq:1 2 3 2 1);



or



w=array(:1 2 3 2 1);

call spectral(gasout,sinx,cosx,px,sx,freq:w);



work the same way.



The call:



call spectral(gasout,sinx,cosx,px,sx,freq:1);



sets sx=px/.07958



which implies no smoothing.





Using the graph command, the calculation can be calculated and

displayed with



call graph(spectrum(gasout:1 2 3 2 1)

:heading 'Spectrum of Gasout');







Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call spectral(gasin,sinx,cosx,px,sx,freq);

freq2=freq/(2.0*pi()); period=vfam(1.0/afam(freq2));

call tabulate(freq freq2 period sinx cosx px sx);

call spectral(gasin,sinx,cosx,px,sx,freq:1 2 3 2 1);

call tabulate(freq freq2 period sinx cosx px sx);

call graph(freq2,sx :heading 'Spectrum of Gasin'

:plottype xyplot);

b34srun;



For more than one series see cspectral command.



STOP - Stop execution of a program.



call stop;



Stops matrix command running. Usual use is



if(%error.ne.0)call stop;



Alternative use to pause execution

call stop(pause);



The command



call stop(return);



will terminate a subroutine function or program and return to

manual mode.



The command



call stop(stopb34s);



terminates the b34s and is usually not used.





SUBRENAME - Internally rename a subroutine.



call subrename(name1);



Internally renames object name1 to name1 where name1 must be a

defined PROGRAM, SUBROUTINE, FORMULA or FUNCTION. Assuming user

has a SUBROUTINE MYSUB1. The command:



mysub2=mysub1;



creates an object mysub2 which is an exact copy of mysub1. If

the old header was



subroutine mysub1(i,j);



it will not be changed. The command



call subrename(mysub2);



will fix the name in place.



Examples:



/$ Tests SUBRENAME command

/$ Command renames a routine in place

b34sexec matrix;



subroutine test(x);

call print(x);

return;

end;



x=rn(array(10:));

call test(x);



newtest=test;

call names(all);

call free(test);

call names(all);

call print(newtest);



call subrename(newtest);



call print(newtest);

call names(all);

call newtest(x);

b34srun;



/$ Job Part # 2



b34sexec matrix ;

* Shows use of formulas in simple case;



function test(i);

x=i*i;

return(i);

end;



formula double = gasout*2.;



call names;

call print(double);

call printall;

call save;

b34srun;



b34sexec matrix;

call restore;

call names(all);

call printall;

y=double;

call print('This has a bad copy ',y);



tt=test;

call printall;

call subrename(y);

call print('This is a good copy',y);

b34srun;



SUSPEND - Suspend loading and Execuiting a program



call suspend(pgm,file,iwait);



pgm - name of a program in a mac file

file - file name for mac file

iwait - # of centtiseconds to wait. Default=50



The purpose is this is to leave b34s open to get more commands.



Example of delayed execution

b34sexec matrix;

call suspend(doit 'c:\b34slm\matrix.mac',100);



/; alternatives without a wait

/; call load(doit );

/; call doit;

/; -------------------------------------------------------



b34srun;



Listing of doit in matrix.mac



==DOIT Used to test call suspend( );

program doit;

/; testing of call suspend(doit,'c:\b34slm\matrix.mac');

call print('this is from program doit');

x=rn(matrix(3,3:));

call print(x,inv(x),x*inv(x));

call print('Program doit returns.');

return;

end;

==



SYSTEM - Issue a system command.



call system('command');



Runs a system command. The alternate:



call system;



gets the user into the command line where commands can be

entered at the terminal.



Note: The form



call system(' command');



should be used if "silent" operation is desired. If the

command writes any output, the form



call system('command',:);



should be used.



If what is desired is for B34S to terminate and the

program called to be active, the command



call system('command',::);



should be used.



SWARTEST - Stock-Watson VAR Test

call swartest(x,ibegin1,iend1,ibegin2,iend2,

sigma1,sigma2,psi1,ipsi1,psi2,ipsi2,iprint,

nterms,nlag,test11,test12,test21,test22

var1,var2,varxhat1,varxhat2,rsq1,rsq2);



Test of change in structure of VAR model based on work by

Stock-Watson "Has the Business Cycle changed and Why?"

NBER Working Paper 9127 December 2002



x n by k matrix of the series in var model

-

ibegin1 Start of period 1

-

iend1 End of period 1

-

ibegin2 Start of period 2

-

iend2 End of period 2

-

sigma1 Variance Covariance of errors period1

-

sigma2 Variance Covariance of errors period2

-

psi1 psi weights period 1

-

ipsi1 index to read psi weights 1

-

psi2 psi weights period 2

-

ipsi2 index to read psi weights 2

-

iprint set 1 to print estimation results

-

2 to print estimation results and

psi matrix

-1 or -2 if want summary printed only

nterms - # of terms in psi matrix

nlag - lag for VAR

test11 - psi1 & sigma1

test12 - psi1 & sigma2

test21 - psi2 & sigma1

test22 - psi2 & sigma2

var1 - k element variance of series in period 1

var2 - k element variance of series in period 2

varxhat1 - k element variance of xhat in period 1

varxhat2 - k element variance of xhat in period 2

rsq1 - k element centered R**2 in period 1

rsq2 - k element centered R**2 in period 2



Routine developed 1 November 2002

Arguments added 31 January 2003

**********************************************



Example:



b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;





b34sexec matrix;

call loaddata;

call load(buildlag);

call load(varest);

call load(swartest);

call echooff;

ibegin1=1;

iend1=200;

ibegin2=201;

iend2=296;

nlag=6;

nterms=20;

iprint=1;

x=catcol(gasin,gasout);



call swartest(x,ibegin1,iend1,ibegin2,iend2,

sigma1,sigma2,psi1,ipsi1,psi2,ipsi2,iprint,

nterms,nlag,test11,test12,test21,test22,

var1,var2,varyhat1,varyhat2,rsq1,rsq2);



call print(test11,test12,test21,test22,

var1,var2,varyhat1,varyhat2,rsq1,rsq2);

b34srun;

TABULATE - List vectors in a table.



call tabulate(x y);



Lists x and y in a table. Variables must be 1d objects. If

data is not available, missing is shown. Max of 10 series

can be listed.



Optional setup to write to a file



This file can be read into Excel.



call open(71 'mydata.dat');

call tabulate(x,y,z :unit 71);



Other options



:unit n Set unit number

:cdf use comma delimited form

:nonames Suppress names

:title 'string ' list a title

:noobslist Turns off Obs list

:format '(f10.4)' Sets a format for real*4, real*8

and complex*16. Length of result of

format must be LE 12. Length of

format string LE 20. Default g12.4.

:ljname Left justify names over Col.

:rjname Right justify names over col.

:cname Center Names over Col



Example:



b34sexec matrix;

n=12;

rad=array(n:);

ss=array(n:);

cc=array(n:);

call echooff;



do i=1,n;

rad(i)=dfloat(i)*pi()/6.;

ss(i)=dsin(rad(i));

cc(i)=dcos(rad(i));

enddo;



/$ Write to output and file



call open(71,'tab.txt');

call tabulate(rad,ss,cc:title 'Test of Tabulate');

call tabulate(rad,ss,cc:unit 71 :cdf);

call close(71);



/$ Change Format

/$ Note use of " " to allow 'A ' inside format

/$

/$ Warning: Result must not be > 12. This may be

/$ changed in later releases



call tabulate(rad,ss,cc :format '(f10.4)');

call tabulate(rad,ss,cc :format "('A ',f6.2)");

b34srun;



Note: The STATA program can read a tabulate file provided that

the option :cdf is used. If more than 10 variables need

to be passed to STATA, load the data back in b34s

and use PGMCALL.



See also call print.



TESTARG - Lists what is passed to a subroutine or function.



call testarg( );



Lists what is passed. Useful for debugging subroutines

and functions.



Example:



a=1.0;

b=rn(matrix(10,10:));

call testarg(a,b,c);



TIMER - Gets CPU time.



call timer(x);



Gets a CPU time value in real*8.



Example:

call timer(base);

xinv=inv(x);

call timer(base2);

call print('Inverse took ',base2-base);



TRIPLES - Calculate Triples Reversability Test



call triples(x :options);



Basic code built by: Randal J. Verbrugge



Reference: Randles, Fligner, Policello and Wolfe

'An Asymptotically distribution-free test for symmetry vs.

Asymmetry' JASA 75 (March 1980) 168-172



The null of the test is a symmetric distribution. This test

cannot detect asymmetric distributions with median=mean.

Test requires a minimum of 5 data points.



call triples(x :options);



Variables created:



%eta = the estimated variable

%vareta = variance of eta

%triples = eta/sqrt(variance),

%prob = probability of %triples



Example:



b34sexec matrix ;

* Correct Answers should be: ;

* eta =-.23333 ;

* vareta = .01333 ;

* Stat =-2.0207 ;

n=6;

x=vector(n: 2.373, 3.339, 1.980, 3.102, 0.000 3.335) ;

call triples(x :print);

n=100;

x=rn(vector(n:));

call triples(x :print);

b34srun ;



The test code triples_2 uses the matrix command to validate

the calculations for the test.



Notes: This test is very slow for large n.



TSAY - Calculate Tsay nonlinearity test.



call tsay(x,m,tsaytest,probf)



Calculates Tsay (1986) test.

x = series to be tested

m = the degree of the test,

tsaytest = is the Tsaytest F(M(M+1)/2,(T-M(M+3)/2)-1)

probf = the significance of tsaytest.



The Tsay test code was obtained from Douglas Patterson.

Major improvements were made. As setup the first stage

prewhitening filter has not been implemented. Hence this test

must be applied to prewhiten data such as residuals, not raw

series. If raw series are to be analysed, they should be

filtered first.



Example:





b34sexec options ginclude('gas.b34'); b34srun;

b34sexec reg;

model gasout=gasin{0 to 12} gasout{1 to 12};

bispec iauto iturno bds tsay tsayorder=10; b34srun;

b34sexec options ginclude('b34sdata.mac') member(blake);

b34srun;

b34sexec matrix;

* Both TSAY and BDS tests illustrated ;

call loaddata;

call bds(blake,.5,5:);

call tsay(blake,20,tsaytest,prob:);

call print('Random Data');

x=rn(array(5000:));

call tsay(x,20,tsaytest,prob:);

b34srun;



TSD - Interface to TSD Data set



The below listed commands provide an interface into the

Alphametrtics tsd data base convention. Not all options are

supported for put's at this time. The TSD format is supported

in Eviews and other systems. The command



call tsd(:info :file 'tsd1.tsd');



will list what is in a TSD database.



The command



call tsd(:load :file 'mytsd.tsd');



will load all series currently in the tsd database. If the

key word

:print



if given, then :load includes :info.



If the series name is > 8 characters, a message is given and

the name %ser___n is assigned.

All series have an associated time variable %tsd____n unless

the key



:notime



is added. The option



:nodate



can be used in place of :notime to save space. Since a julian

date can be obtained from any time series by the command



jdate=makejul(x);



where x is a time series, what is the need to automatically

create a date julian? The answer is that if there are special

data loaded from the tsd option that involve only 5 days out

of a week etc, then the automatic julian routine makejul( )

will not work and a custom date vector is needed. If the custon

date vector is not needed, then code :notime or :nodate on

the command line.



If names extend over 8 characters, then a name %ser___n will

be created and a message given.



A specific series can be loaded with



call tsd(:get name :file 'mytsd.tsd');



Optional arguments



:rename newname



:datename dtname



:nodate



:notime



:nomessage - Turn off recode message for long names.



Series can be loaded from b34s into a tsd database with





call tsd(:put name

:timeseries juldaydmy(iday,imonth,iyear) freq

:file 'mytsd.tsd');



Optional arguments



:timeseries juldaydmy(iday,imonth,iyear) freq

:add

:new (default)

If the series is not a "time series," it can be hidden inside

the tsd database and passed as if it had a date. This feature

is good for saving residuals, forecasts etc.



Examples:



b34sexec matrix;



/; List what is in Libraries



call tsd(:info :file 'c:\b34slm\tsd1.tsd');

call tsd(:info :file 'c:\b34slm\tsd2.tsd');

call tsd(:info :file 'c:\b34slm\tsd3.tsd');

/; call tsd(:info :file '/usr/local/lib/b34slm/tsd1.tsd');

/; call tsd(:info :file '/usr/local/lib/b34slm/tsd2.tsd');

/; call tsd(:info :file '/usr/local/lib/b34slm/tsd3.tsd');



/; Load all series



call tsd(:load :file 'c:\b34slm\tsd1.tsd');

call tsd(:load :file 'c:\b34slm\tsd3.tsd');

call tsd(:load :file 'c:\b34slm\tsd2.tsd');

/; call tsd(:load :file '/usr/local/lib/b34slm/tsd1.tsd');

/; call tsd(:load :file '/usr/local/lib/b34slm/tsd3.tsd');

/; call tsd(:load :file '/usr/local/lib/b34slm/tsd2.tsd');



year=fyear(%tsd_142);

call tabulate(%tsd_142,year,%ser_142 :format '(f10.4)');

call names;



/; Building and testing



x=dfloat(integers(10));

y=x*x;

call print(mean(x));

call tsd(:put x :file 'new.tsd' :new);

call tsd(:put y :file 'new.tsd' :add

:timeseries juldaydmy(1,1,1960) 4.);

call tsd(:put ce :file 'new.tsd' :add);

call free(x,ce);

call tsd(:load :file 'new.tsd' :print);

call clearall;



call tsd(:get ce :file 'new.tsd' :print);

call tsd(:get x :file 'new.tsd' :rename newx :print

:datename newxdate);

call names;

b34srun;



Advanced Example



/;

/; Shows line up and purging time series data.

/; Due to possible missing data inside the series the

/; timestart and timebase have not been set. However a

/; date variable can be added to preserve the date of each

/; observation

/;

b34sexec matrix;

call tsd(:get c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);

call tsd(:get c96c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);

call tsd(:get cd :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);



call names(:);

/; do i=1,norows(%names%);

/; call print(argument(%names%(i)));

/; enddo;

call names;

call tabulate(c c96c cd);

call tslineup(c c96c cd);

call tabulate(c c96c cd);

call align(c c96c cd);

call tabulate(c c96c cd);

call names;



/; Using a date variable



call clearall;



call tsd(:get c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a1);

call tsd(:get c96c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a2);

call tsd(:get cd :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a3);

call names(:);

/; do i=1,norows(%names%);

/; call print(argument(%names%(i)));

/; enddo;

call names;

call tabulate(c a1 c96c a2 cd a3);

call tslineup(c a1 c96c a2 cd a3);

call tabulate(c a1 c96c a2 cd a3);

call align( c a1 c96c a2 cd a3);

call tabulate(c a1 c96c a2 cd a3);

call names;



b34srun;





TSLINEUP Line up Time Series Data



call tslineup(ts1,ts2);

The align command trims series that are the same length

initially but contain missing data. The align command is

usually used after the tslineup command has been used to

process the data.



call tslineup(ts1,ts2);



After this command runs ts1 and ts2 are the same length but

may contain missing data. The tslineup command requires that

the series are time series of type 1d. A date vector %julian%

is automatically created to help with lineing up the series.



Example:



/;

/; Shows line up and purging time series data.

/; Due to possible missing data inside the series the

/; timestart and timebase have not been set. However a

/; date variable can be added to preserve the date of each

/; observation

/;

b34sexec matrix;

call tsd(:get c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);

call tsd(:get c96c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);

call tsd(:get cd :file 'c:\b34slm\tsd3.tsd' :print

:nomessage);



call names(:);

/; do i=1,norows(%names%);

/; call print(argument(%names%(i)));

/; enddo;

call names;

call tabulate(c c96c cd);

call tslineup(c c96c cd);

call tabulate(c c96c cd);

call align(c c96c cd);

call tabulate(c c96c cd);

call names;



/; Using a date variable



call clearall;



call tsd(:get c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a1);

call tsd(:get c96c :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a2);

call tsd(:get cd :file 'c:\b34slm\tsd3.tsd' :print

:nomessage :datename a3);

call names(:);

/; do i=1,norows(%names%);

/; call print(argument(%names%(i)));

/; enddo;

call names;

call tabulate( c a1 c96c a2 cd a3);

call tslineup( c a1 c96c a2 cd a3);

call tabulate( c a1 c96c a2 cd a3);

call align( c a1 c96c a2 cd a3);

dates=chardate(a1);

call tabulate(dates,c,a1,c96c,a2,cd,a3

:title 'Lined up Data with a Date Variable');

call names;

year=fyear(a1);

call graph(year,c c96c cd :plottype xyplot

:Heading 'TSD Data');

b34srun;



VAREST - VAR Modeling



call varest(x,nlag,ibegin,iend,beta,t,sigma,corr,

residual,iprint,a,ai,varx,varxhat,rsq);



VAR Estimation in Matrix Command



x(n,k) - n,k matrix of data values

nlag - Number of lags

ibegin - Begin Data point

iend - End Data Point

beta - nlag+1 (k+1),matrix of coefficients

t - nlag+1 (k+1),matrix of t tests coefficients

sigma - Sigma (k by k) for that period

corr - correlation (k by k) for that period

Residual - nn by k matrix of residuals where

nn = iend-ibegin+1-nlag

iprint - 0 => do not print, ne 0 => print

a - (I - P(B)) if a is inverted gets Psi Weights

P(B) are ar terms.

ai - Index for a

varx - k element variance of x series

varxhat - k element variance of xhat

rsq - Centered R**2





Built 10 October 2002

Arguments added 31 January 2003



Note: User must load the routine buildlag



Note: VAREST is a subroutine.

-----------------------



Example:



b34sexec options ginclude('b34sdata.mac') member(gas);

b34srun;

b34sexec matrix;

call loaddata;

call load(buildlag);

call load(varest);

call echooff;



ibegin=1;

iend=296;

nlag=2;

x=catcol(gasin,gasout);



call varest(x,nlag,ibegin,iend,beta,t,sigma,

corr,residual,1,a,ai,varx,varxhat,rsq);

call print(beta,t,sigma,corr,varx,varxhat,rsq);

call polymdisp(:display a ai);

b34srun;



VOCAB - List built-in subroutine vocabulary.



call vocab(c);



Places in c, a n by 12 character variable containing all

current vocabulary for call statements. The command



f=vocab();



does the same for analytical statements. The variants



call vocab(c:);



f=vocab(:);



list with command internal number.



VPASET - Set Variable Precision Math Options



call vpaset(:info);



Lists the current settings in the B34S Variable Precision Math

module that was developed using the fm_zmlib.f library from

David M. Smith. The library is documented in



Algorithm 693, ACM Transactions on Mathematical Software,

Vol. 17, No. 2, June 1991, pages 273-283.



Other options available include:



call vpaset(:ndigits 70);



to set the precision of calculation to 70. Unless a futher

command is given, the display will default to 70 digits. The

sequence



call vpaset(:ndigits 70);

call vpaset(:jform2 10);



will use 70 digits for the calculation but only prints 10.

The setting :ndigits can be set as high as 1750 using the

default b34s VPA code.





call vpaset(:settings);



to place in memory



%ndig



%lunpck1



%lpack1



%lunpkz1



%lpackz1



The option



call vpaset(fm1 fm2 ndig_old ndig_new :convert);



will convert fm1 with ndig_old to fm2 with ndig_new.

The call vpaset(:settings); will supply the correct

values.



VPA data can be saved as r8 so VPA numbers can be saved with

checkpoints etc using the command



call vpaset(vpa r8 :saveasr8);



The variable r8 can be reloaded into a VPA variable with



call vpaset(r8 vpa :saveasvpa);



The first four elements give kind, nr8, norows, nocols.

There is no accuracy lost using this approach. The alternative



dp=vpa(fm :to_dp);



converts fm a VPA number to the real*8 dp and loses accuracy.



The option



call vpaset(:jform1 n1);



will set the output format as:



n1 = 0 => E format ( .314159M+6 )

n1 = 1 => 1PE format ( 3.14159M+5 )

n1 = 2 => F format ( 314159.000 )

call vpaset(:jform2 n2);





Sets the number of digits to display if n1=0 or n1=2. If

n2=0, then a default number of digits is chosen. The default

is roughly the full precision of the number. If n1=2, then

n2 sets the number of digits after the decimal point





call vpaset(:jformz n3);



Sets complex output:



JFORMZ = 1 => 1.23 - 4.56 i

= 2 => use capital I : 1.23 - 4.56 I

= 3 => parenthesis format ( 1.23 , -4.56 )





call vpaset(:jprntz n4);



controls whether to print real and imaginary parts on one line

whenever possible.



JPRNTZ = 1 => print both parts as a single string :

1.23456789M+321 - 9.87654321M-123 i

= 2 => print on separate lines without the 'i' :

1.23456789M+321

-9.87654321M-123



call vpaset(:stringout nn);



sets the length of stringoutput in statements such as



ss=vpa(fm1 :to_str);



Internal debug info from the library can be obtained by



call vpaset(:trace nn2);



which sets the trace level. The usual settings for trace is

nn2=2 or nn2=1.



nn2=0 => No printout except warnings and errors.

nn2=1 => The result of each call to one of the routines

is printed in base 10, using FMOUT.

nn2=-1 => The result of each call to one of the routines

is printed in internal base MBASE format.

nn2=2 => The input arguments and result of each call to

one of the routines is printed in base 10, using

FMOUT

nn2=-2 => The input arguments and result of each call to

one of the routines is printed in base MBASE

format.

Termination messages can be modified with the parameter



call vpaset(:kwarn nn);



The usual setting is nn=1. Other options are



nn = 0 => Execution continues and no message is printed.

nn = 1 => A warning message is printed and execution

continues. This is the default

nn = 2 => A warning message is printed and execution

stops.





vp (variable precision) data is saved in the B34S matrix

command workspace using real*8 data. Assuming



ndigmx=256

lpack = (ndigmx+1)/2+1 +1

lunpck = (6*ndigmx)/5+20 +1

lpackz = 2*lpack+1+1

lunpkz = 2*lunpck+1+1

lunpcki= (6*ndigmx)/5+20 +1



LPACK = number of real*8 data points for VPA real/integer

packed data.

LUNPCK = number of real*8 data points for VPA real

unpacked data.

LPACKZ = number of real*8 data points for VPA complex packed

data.

LUNPCK = number of real*8 data points for VPA complex unpacked

data.

LUNPCK = number of real*8 data points for integer unpacked

data.



For example if the internal B34S has been set to ndigmx=256



lpack =130.5 => 131

lunpck =328.2 => 328

lpackz =263 => 263

lunpkz =658.4 => 658

lunpcki=328.2 => 328



For further detain on the VPA capability see info on the vpa

command. An example of VPA math is shown below.



Example:



/;

/; Shows gains in accuracy of the inverse with vpa

/;

b34sexec matrix;



call echooff;

n=6;

x=rn(matrix(n,n:));

ix=inv(x,rcond8);

r16x=r8tor16(x);

ir16x=inv(r16x,rcond16);

call print('Real*4 tests', sngl(x),

inv(sngl(x)),

sngl(x)*inv(sngl(x)));

call print('Real*8 tests',x, ix, x*ix);

call print('Real*16 tests',r16x,ir16x,r16x*ir16x);

vpax=vpa(x);

ivpax=inv(vpax,rcondvpa);

detvpa=%det;

call print(rcond8,rcond16,rcondvpa,det(x),

det(r16x),detvpa);

call print('Default accuracy');

call print('VPA Inverse ',vpax,ivpax,vpax*ivpax);



/; call vpaset(:info);



/; Accuracy imporvements 100 - 1800



do i=100,1850,100;

call vpaset(:ndigits i);

call vpaset(:jform2 10);



call print('******************************************':);

vpax=mfam(dsqrt(dabs(vpa(x))));

call vpaset(:jform2 i);

call print('vpax(2,1) given ndigits was set as ',i:);

call print(vpax(2,1));

ivpax=inv(vpax);

call print('VPAX and Inverse VPAX at high accuracy ',

vpax,ivpax,vpax*ivpax);

call print('******************************************':);



enddo;

b34srun;



WRITE - Write an object to an external file.



call write(x,n);



Writes defined object on open unit n. Optionally a third

argument can be supplied to contain a format.



I/O Examples:



n=70;

call open(n,'c:\junk\mydata');

x=array(100:);

call read(x,n);

call close(n);

n=70;

call open(n,'c:\junk\mydata');

x=rn(array(100:));

call write(x,n);

call close(n);





X must be real*8, integer*4, real*4, character*8 or

character*1 of size le 130. The example files write1 and write2

illustrate advanced features of the write facility.



VPA data of the form fm, fp, im, ip, zm & zp can be written.

For an example see the test problem VPA1.



I/O Package. If it is desired to write complex*16 or complex*32

data, the data can be written as as real*8 or real*16 as a eral

and imag array.







Built in Matrix Command functions that return values.



For futher examples, see problems in matrix.mac



There can be a number of commands on the same line. For example



x=sin(y); z=tan(q);



ACF - Calculate autocorrelation function of a 1d object.



acf_x=acf(x,n);



Calculates ACF for n lags of real*8 variable x.



Alternative calls are:



acf_x=acf(x,n,se);

acf_x=acf(x,n,se,pacf);

acf_x=acf(x,n,se,pacf,mq);

acf_x=acf(x,n,se,pacf,mq,probq);



where



se = SE of ACF



pacf = the partial autocorrelation



mq = Modified Q (Ljung-Box Statistic)



probq= Probability of modified q



For small sample acf use forms



acfsmall=acf(x,n:);

acfsmall=acf(x:);

Example:



b34sexec options ginclude('gas.b34')$ b34srun$

b34sexec matrix;

call loaddata;

acf1=acf(gasout,24,se1,pacf1);

acfsmall=acf(gasout,24:);

call tabulate(acf1,acfsmall);

call graph(acf1,pacf1

:heading 'ACF & PACF of Gasout');

call graph(acf(dif(gasout),24)

:heading 'ACF of Gasout(1-B)');

call graph(acf(dif(gasout,2,1),24)

:heading 'ACF of Gasout(1-B)**2');

acf2=acf(gasin,24,se2,pacf2);

call graph(acf2,pacf2

:heading 'ACF & PACF of Gasin');

call graph(acf1,SE1

:heading 'ACF and SE of ACF of Gasout');

i=integers(24);

call tabulate(i,acf1,acf2,se1,se2,pacf1,pacf2);

n=400; rr=rn(array(n:));



call graph(acf(rr,24)

:heading 'ACF of Random series');

call graph(acf(dif(rr) ,24)

:heading 'ACF of rn(1-B)');

call graph(acf(dif(rr,2,1),24)

:heading 'ACF of rn(1-B)**2');

b34srun$





AFAM - Change a matrix or vector to be an array class object.



x=afam(y);



Creates an array from object y



Example - Converts vector v and matrix xx into arrays



v=vector(4:1 2 3 4);

xx=matrix(2,2:v);

call print(xx);

ax=afam(x);

call print(ax);

av=afam(v);

call print(v);



ARGUMENT - Unpack character argument at run-time



argument(cc)



Will place character string cc at run time. Since cc can be

built at run time this command allows the user to modify

program logic at runtime.



Uses:



argument(string)



allows:



- Passing of arguments to programs.



- Changing arguments to a command of a running

program " on the fly."



- An easy way to "duplicate" arguments to a function

or subroutine.





Examples:



call character(in,'x');

call character(out,'y);

call copy(argument(in),argument(out));



in place of



argument(out)=argument(in);



which will fail.



call copy(argument('x'),argument('y'));



"hard wires" an assingment statement but allows charging what

is being assingned. For example



call character(x,'q**2.');

call character(y,'Y');

call copy(argument(x),argument(y));



executes



Y=q**2.;



while



call character(x,'dsqrt(x/z)');

call character(y,'Y');

call copy(argument(x),argument(y));



executes



Y=dqsrt(x/z);



Simple Example

b34sexec options ginclude('b34sdata.mac') member(gas);

b34srun;

b34sexec matrix;

call loaddata;

call character(cc, 'gasout gasin{1 to 10}');

call print(cc);



call testarg(argument('gasout gasin') :print);

call olsq(argument('gasout gasin') :print);

call names;

call testarg(argument(cc) :print);

call olsq(argument(cc) :print);

call names;

b34srun;



More comprehensive Example



/$ argument



b34sexec options ginclude('b34sdata.mac') member(gas);

b34srun;

b34sexec matrix;

call loaddata;



call testarg(argument('GASOUT GASIN') :print);



call olsq(argument('gasout gasin') :print);

call olsq(argument('gasout gasin{1 to 6}') :print);



call character(cc, 'gasout gasin{1 to 10}');

call print(cc);



call testarg(argument(CC) :print);

call olsq(argument(cc) :print);

/$

/$ advanced features allowing generating y=x real time

/$

x=10.;

call character(c1,'X*4.');

call character(c2,'Y');

call character(c4,'y');

call names;

call testarg(argument(c1),argument(c2));

call copy(argument(c1),argument(c2));

call print(argument(c1));

call print(argument(c2));

call print(argument(c4));

x=9.;

call print('two ways to get same answer':);



call copy(argument('x*2.'),argument('y'));

call print(y);

call copy(argument('X*2.'),

argument('y '));

call print(y);



/$

/$ Passing a comand string to a routine

/$ allows selective printing known variables at run time

/$

/$ String can be changed at run time.



subroutine tprint(cc);

x=10;

y=20;

call print(argument(cc));

return;

end;



call character(cctest,'This is a test');

call tprint('x');

call tprint('y');



call names(all);



b34srun;



ARGUMENT being used to pass arguments to a program. The

advantage of a PROGRAM is that all variables are local!



b34sexec options ginclude('b34sdata.mac')

member(res72);

b34srun;

b34sexec matrix;

call loaddata;

program testit;

/;

/; needs

/;

/; call character(reg,'lnq lnk lnl');

/; call character(plotvar,'lnq lnl lnk');

/;

/; before being called

/;



call olsq(argument(reg) :l1 :minimax :print);

call graph(argument(plotvar));

return;

end;



call character(reg,'lnq lnk lnl');

call character(plotvar,'lnq lnl lnk');

call testit;



b34srun;

Passing names selectively into a routine



/; Illustrate passing names info into a subroutine

/; First we pass in the name of a global variable.

/; Next we rename a local variable a name we pass in



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;



subroutine test(nn,xx);



/; Illustrate name passing



call names(all);

call print(nn);



/; This prints a global variable



call print(argument(nn(1)));



/; Renames a local variable



n=namelist(argument(nn(3)));

call copy(xx,argument(nn(3)));

call graph(argument(n));

call graph(argument(nn(3)));

call names(all);

return;

end;



/; This namelist passes two global variables plus one

/; name 'funny'. Funny does not exist but we want to use

/; it inside the subroutine. We pass in lgas and by use

/; of the copy command copy this variable is moved to a

/; name we want that is saved in the n variable name....

/; From now on we use the argument command



n1=namelist(gasout,gasin,funny);

call makeglobal(gasout);

call makeglobal(gasin);



lgas=gasout;

call names(all);

call print(n1);

call test(n1,lgas);

b34srun;





Example showing use of eval( ) and argument( )



/; argument(h) same as eval(h:)

b34sexec matrix;

x=9;

h='X';

call print(argument(h));

call print(eval(h));

call print(eval(h:));



/; To get around augument(h)=999.; which is not allowed



call copy(3.* 333.,argument(h));

call print(x);



call copy(3.*333. ,eval(h:));

call print(x);



b34srun;



Produces:



=> X=9$





=> H='X'$





=> CALL PRINT(ARGUMENT(H))$







X = 9



=> CALL PRINT(EVAL(H))$







9



=> CALL PRINT(EVAL(H:))$







X = 9



=> CALL COPY(3.* 333.,ARGUMENT(H))$





=> CALL PRINT(X)$







X = 999.00000



=> CALL COPY(3.*333. ,EVAL(H:))$

=> CALL PRINT(X)$







X = 999.00000



B34S Matrix Command Ending. Last Command reached.



ARRAY - Define a 1d or 2d array.



x=array(i:);



Creates an array of i elements. Data can be entered after :.



For example



x=array(3:1 2 3);



creates an array {1. 2. 3.}



x=array(i,j:);



Creates an i by j array. Data can be entered after the :).



Examples include



x=array(3,3:1 2 3 4 5 6 7 8 9);



or



x=array(3,3:1. 2. 3. 4. 5. 6. 7. 8. .9);



which creates



1. 2. 3.

4. 5. 6.

7. 8. 9.



since for the array command 1 will be converted to real*8.



When loading a 1-D object into a 2-D object we load by rows.



When loading a 2-D object to a 1-D object we load by address.



ax=array(:array(3,3:1 2 3 4 5 6 7 8 9));



produces



1. 4. 7.

2. 5. 8.

3. 6. 9.

vv=x(2,);



produces a 1 d array containing 2. 5. 8.



vv2=x(,2);



produces a 1 d array containing 4. 5. 6.





For character data:



call character(cc,'abcdefghi');

x=array(3,3:cc);



Note that



x=array(3,3:'abcdefghi');



is allowed since 'abcdefghi' is a character*1 array.



x=array(2,2:'1234');



will not work as intended since '1234' is a character*8 by

convention. (Any string LE 8 is places in a character*8.) The

correct way to proceed is:



call character(cc,'1234');

x=array(2,2:cc);



For info on character*8 and character*1 array creation, see

c8array and c1array commands.



To create a n dimensional array, first create a 1 d array of

the needed size:



b34sexec matrix;

mm=index(4,5,6:);

xx=rn(array(mm:));

/; Note: mm is 120 elements (4*5*6 = 120)

call names;

idim =index(4,5,6);

idim2=index(2,2,2);

call setndimv(idim,idim2,xx,10.);

vv= getndimv(idim,idim2 ,xx);

/; vv will be 10.0

call print(xx,vv);

b34srun;





BETAPROB - Calculate a beta probability.



x=betaprob(x1,x2,x3);



Computes probability x that a variable having a beta

distribution having parameters x2 and x3 is le x1.

x2 and x3 must be gt 0



Example:



b34sexec matrix;

* problem from IMSL page 914 ;

pin=12.0;

qin=12.0;

x=.6;

p=betaprob(x,pin,qin);

call print('Probability x is less than 6.',p);

call print('Answer should have been .8364');

tt=p-betaprob(.5,pin,qin);

call print('Probability x is between .5 and .6',tt);

call print('Answer should have been .3364');

b34srun;





BINDF - Evaluate Binomial Distribution Function



pr=bindf(k,n,p);



Evaluates binominal distribution function for



k => (integer)

n => (integer) # of Bernoulli trials

p => probability of success on each trial.





Example:



b34sexec matrix;

k=3;

n=5;

p=.95;

pr=bindf(k,n,p);

call print('Evaluate Binomial Distribution Function ':);

call print('Probability that X is LE 3 = ',pr:);

call print('Note: Answer should be .0226':);

b34srun;



BINPR - Evaluate Binomial Probability Function



pr=binpr(k,n,p);



Evaluates binominal probability function for



k => (integer)

n => (integer) # of Bernoulli trials

p => probability of success on each trial.





Example:

b34sexec matrix;

k=3;

n=5;

p=.95;

pr=binpr(k,n,p);

call print('Evaluate Binomial Probability Function':);

call print('Probability that X is 3 = ',pr:);

call print('Note: Answer should be .0214':);

b34srun;



BOOTI - Calculate integers to be used with bootstrap.



bindex=booti(n);



Generates an integer vector bindex containing integers in

the range 1 - n. Replacement is used. The integer vector bindex

can be used to permutate a matrix or array of any type. Use

the command bootv the to operate directly on a vector. The

command



newx=bootv(x);



and



newx=x(booti(norows(x));



are logically the same except that the seeds change as the

commands run.



An alternative call



bindx2=booti(n,n2);



generates an integer vector of length n2 with integers from

range 1-n with replacement.



bindx2=booti(n,n);



is the same as



bindx2=booti(n);



Routine uses Numerical Recipes routine nusami which uses the

ran1 uniform generator. If RECVER on the OPTIONS command is set

as RECVER=k, where K =:



k=IMSL_1 uses IMSL Version 10 16807 Generator

k=IMSL_2 uses IMSL Version 10 16807 Generator Shuffled

k=IMSL_3 uses IMSL Version 10 397204094 Generator

k=IMSL_4 uses IMSL Version 10 397204094 Generator Shuffled

k=IMSL_5 uses IMSL Version 10 960706376 Generator

k=IMSL_6 uses IMSL Version 10 960706376 Generator Shuffled

k=IMSL_7 uses IMSL Version 10 Recursion option

The IMSL rectangular generators are used inside booti.



If replacement of x is not desired, use the commands



nsamp=norows(x);

ii=idint(array(nsamp:));

call i_rnper(ii);

jj=integers(nsamp);

xsamp=x(ii(jj));



to sample x without replacement.





Example:



b34sexec matrix;

n=26;

index1=booti(n);

call print(index1);

test=grid(1.0,20.,1.0);

index2=booti(norows(test));

newx=test(index2);

call tabulate(test,index2,newx);

b34srun;



BOOTV - Bootstraps a vector with replacement.



bootx=bootv(x)



Bootstraps the vector x with replacement. x must be real*8.



n alternative call



bootx=bootv(x,n2);



generates a real vector bootx of length n2 with elements from x

with replacement.



bootx=bootv(x,rorows(x));



is the same as



bootx=bootv(x);



Routine uses Numerical Recipes routine nusamp which uses the

ran1 uniform generator. If RECVER on the OPTIONS command is set

as RECVER=k, where K =:



k=IMSL_1 uses IMSL Version 10 16807 Generator

k=IMSL_2 uses IMSL Version 10 16807 Generator Shuffled

k=IMSL_3 uses IMSL Version 10 397204094 Generator

k=IMSL_4 uses IMSL Version 10 397204094 Generator Shuffled

k=IMSL_5 uses IMSL Version 10 960706376 Generator

k=IMSL_6 uses IMSL Version 10 960706376 Generator Shuffled

k=IMSL_7 uses IMSL Version 10 Recursion option



The IMSL rectangular generators are used inside bootv.



Example:



b34sexec matrix;

test=grid(1.0,20.0,1.);

btest=bootv(test);

call tabulate(test,btest);

x=rn(matrix(4,4:));

newx=bootv(x);

call print(x,newx);

b34srun;



For an alternative see BOOTI and the variant using I_RNPER

that does not use replacement.





BOXCOX - Box-Cox Transformation of a series given lamda.



y=boxcox(x,lamda);



For lamda ne 0 and x > 0



y=(x**lamda)/lamda



For lamda = 0



y=dlog(x)



For x real*8 series of length n



k => order of knot



optional third argument



maxit => maximum number of iterations. Default = 50.



xknot => computer knot sequence of length n + k



IMSL routine DB2OPK is used.



Example:

b34sexec matrix;

* Test Example from IMSL(10) ;

call echooff;

n=20;

i=integers(n);

xx1=dfloat(i-1)/dfloat(n-1);

x=1.0-(xx1*xx1);

f=dsin(10.0*x*x*x);

call free(xx);



* study which knots do best;



do korder=3,8;

xknot1 =bsnak(x,korder);

xknot2 =bsopk(x,korder);

bscoef1=bsint(x,f,xknot1);

bscoef2=bsint(x,f,xknot2);



* Test using new data;



ii=integers(100);

xx=dfloat(ii-1)/99.;

st1=bsder(0,xx,xknot1,bscoef1);

st2=bsder(0,xx,xknot2,bscoef2);

ff=dsin(10.*xx*xx*xx);

dif1=dabs(ff-st1);

dif2=dabs(ff-st2);

ddmax1=dmax(dif1);

ddmax2=dmax(dif2);



call print('For korder ',korder:);

call print('bsnak max error ',ddmax1:);

call print('bsopk max error ',ddmax2:);

enddo;

b34srun;



BSINT - Compute 1-D spline interpolant given knots



bscoef=bsint(x,f,xknot);



Computes a spline interpolant of f(x) given knot sequence.



x => real*8 abscissas size n



f => data point ordinates size n



xknot => xknot sequence of length n + k

calculated by bsnak or bsopk



bscoef=> b spline values for 1-d object

size n+8



Last 8 locations of bscoef are:

1 => missing

2 => n1 size of series 1

3 => k1 # knots for series 1

4 => n2 size of series 2

5 => k2 # knots for series 2

6 => n3 size of series 3

7 => k3 # knots for series 3

8 => missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of the bscoef

array.



IMSL routine DB2INT is used.



Example:



b34sexec matrix;



* Test Example from IMSL(10) ;

call echooff;



ndata=50;

i=integers(ndata);

xdata=dfloat(i-1)/dfloat(ndata-1);

f=dsqrt(xdata);

xknot = bsnak(xdata,8);

bscoef= bsint(xdata,f,xknot);



ndata=101;

j=integers(2,ndata);



x=dfloat(j-1)/dfloat(ndata-1);

actf=dsqrt(x);

actder=(.5/dsqrt(x));

xhat=bsder(0,x,xknot,bscoef);

xder=bsder(1,x,xknot,bscoef);

error1=actf - xhat;

error2=xder - actder;



call print('Evaluation of Data and Derivative':);

call tabulate(x,actf,xhat,actder,xder,error1,error2);

b34srun;



BSINT2 - Compute 2-D spline interpolant given knots



bscoef2=bsint2(x,y,f,xknot,yknot);



Computes a spline interpolant of f(x,y) given knot sequences

for x and y.



x => real*8 abscissas in x direction size n1

y => real*8 abscissas in y direction size n2



f => data point ordinates size n1 by n2



xknot => xknot sequence of length n1 + k1

calculated by bsnak or bsopk



yknot => yknot sequence of length n2 + k2

calculated by bsnak or bsopk



zknot => zknot sequence of length n3 + k3

calculated by bsnak or bsopk



bscoef2 => b spline values for 1-d object

size n1 by n2 + 8. Last 8 values

determine size. Saved as 1-d array.



Last 8 locations of bscoef are:



1 => missing

2 => n1 size of series 1

3 => k1 # knots for series 1

4 => n2 size of series 2

5 => k2 # knots for series 2

6 => n3 size of series 3

7 => k3 # knots for series 3

8 => missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of the bscoef

array.



IMSL routine DB22IN is used.



Example:



b34sexec matrix;

* Test Example from IMSL(10) ;

call echooff;

nxdata=21;

nydata=6;

kx=5;

ky=2;

i=integers(nxdata);

j=integers(nydata);

xdata=dfloat(i-11)/10.;

ydata=dfloat(j-1)/5.;

f=array(nxdata,nydata:);



do ii=1,nxdata;

do jj=1,nydata;

f(ii,jj)=(xdata(ii)*xdata(ii)*xdata(ii)) +

(xdata(ii)*ydata(jj));

enddo;

enddo;



xknot=bsnak(xdata,kx);

yknot=bsnak(ydata,ky);



bscoef2=bsint2(xdata,ydata,f,xknot,yknot);



nxvec=4;

nyvec=4;

i=integers(nxvec);

j=integers(nyvec);

xvec=dfloat(i-1)/3.;

yvec=dfloat(j-1)/3.;

xx=array(nxvec,nyvec:);

yy=xx;

ff=xx;

ffhat=ff;

error=xx;



do i=1,nxvec;

do j=1,nyvec;

xx(i,j)=xvec(i);

yy(i,j)=yvec(j);

ff(i,j)=(xvec(i)*xvec(i)*xvec(i))

+ (xvec(i)*yvec(j));

ffhat(i,j)=

bsder2(0,0,xvec(i),yvec(j),xknot,yknot,bscoef2);

error(i,j)=ff(i,j)-ffhat(i,j);

enddo;

enddo;



xx=array(:xx);

yy=array(:yy);

ff=array(:ff);

ffhat=array(:ffhat);

error=array(:error);

call tabulate(xx,yy,ff,ffhat,error);

b34srun;



BSINT3 - Compute 3-D spline interpolant given knots



bscoef3=bsint3(x,y,z,f,xknot,yknot,zknot);



Computes a spline interpolant of f(x,y,z) given knot sequences

for x, y and z.



x => real*8 abscissas in x direction size n1



y => real*8 abscissas in y direction size n2



z => real*8 abscissas in y direction size n2



f => data point ordinates size n1 by n2 by n3

xknot => xknot sequence of length n1 + k1

calculated by bsnak or bsopk



yknot => yknot sequence of length n2 + k2

calculated by bsnak or bsopk



zknot => zknot sequence of length n3 + k3

calculated by bsnak or bsopk



bscoef3=> b spline values for 1-d object

size n1 by n2 by n3 + 8. The last 8 values

determine size. Saved as 1-d array



Last 8 locations of bscoef are:



1 => missing

2 => n1 size of series 1

3 => k1 # knots for series 1

4 => n2 size of series 2

5 => k2 # knots for series 2

6 => n3 size of series 3

7 => k3 # knots for series 3

8 => missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of the bscoef

array.



IMSL routine DB23IN is used.



Example:



b34sexec matrix;

* Test Example from IMSL(10) ;

call echooff;

kx=5;

ky=2;

kz=3;

nxdata=21;

nydata=6;

nzdata=8;



nxvec=4;

nyvec=4;

nzvec=2;

i=integers(nxdata);

j=integers(nydata);

k=integers(nzdata);

xdata=dfloat(i-11)/10. ;

ydata=dfloat(j-1) /dfloat(nydata-1);

zdata=dfloat(k-1) /dfloat(nzdata-1);

xknot=bsnak(xdata,kx);

yknot=bsnak(ydata,ky);

zknot=bsnak(zdata,kz);

maxii=index(nxdata,nydata,nzdata:);

f=array(maxii:);



do ii=1,nxdata;

do jj=1,nydata;

do kk=1,nzdata;

ii2=index(nxdata,nydata,nzdata:ii,jj,kk);

f(ii2)=(xdata(ii)**3.)

+ (xdata(ii)*ydata(jj)*zdata(kk));

enddo;

enddo;

enddo;



bscoef3=bsint3(xdata,ydata,zdata,f,xknot,yknot,zknot);

i=integers(nxvec);

j=integers(nyvec);

k=integers(nzvec);

xvec=2.*(dfloat(i-1)/3.)-1. ;

yvec=dfloat(j-1)/3.0;

zvec=dfloat(k-1);

maxjj=index(nxvec,nyvec,nzvec:);

fit =array(maxjj:);

error =array(maxjj:);

actual=array(maxjj:);

xx =array(maxjj:);

yy =xx;

zz =xx;



do ii=1,nxvec;

do jj=1,nyvec;

do kk=1,nzvec;

ii2=index(nxvec,nyvec,nzvec:ii,jj,kk);

fit(ii2)=bsder3(0,0,0,xvec(ii),yvec(jj),zvec(kk),

xknot, yknot, zknot,bscoef3);

actual(ii2)= (xvec(ii)**3.)

+ (xvec(ii)*yvec(jj)*zvec(kk));

xx(ii2)=xvec(ii);

yy(ii2)=yvec(jj);

zz(ii2)=zvec(kk);

error(ii2)=actual(ii2)-fit(ii2);

enddo;

enddo;

enddo;



call tabulate(xx,yy,zz,fit,actual,error);

b34srun;



BSDER - Compute 1-D spline values/derivatives given knots



der=bsder(ider,xpoint,xknot,bscoef);



Computes a spline derivative of f(x) given knot sequence.

ider order of derivative. If set to

0, get value of spline at point



xpoint real*8 value where derivative is evaluated.

xpoint can be a 1-D array.



xknot xknot sequence of length n + k

calculated by bsnak or bsopk



bscoef b spline values for 1-d object

size n + 8



Last 8 locations of bscoef are:



1 missing

2 n1 size of series 1

3 k1 # knots for series 1

4 n2 size of series 2

5 k2 # knots for series 2

6 n3 size of series 3

7 k3 # knots for series 3

8 missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of

the bscoef array.



IMSL routine DB2DER is used.



Example:



b34sexec matrix;



* Test Example from IMSL(10) ;

call echooff;



ndata=5;

i=integers(ndata);

xdata=dfloat(i)/dfloat(ndata);

f=dsqrt(xdata);

xknot = bsnak(xdata,3);

bscoef= bsint(xdata,f,xknot);



ndata=101;

j=integers(2,ndata);



x=dfloat(j-1)/dfloat(ndata-1);

actf=dsqrt(x);

actder=(.5/dsqrt(x));

xhat=bsder(0,x,xknot,bscoef);

xder=bsder(1,x,xknot,bscoef);

error1=actf - xhat;

error2=xder - actder;



call print('Evaluation of Data and Derivative':);

call tabulate(x,actf,xhat,actder,xder,error1,error2);

b34srun;





BSDER2 - Compute 2-D spline values/derivatives given knots



der=bsder2(id1,id2,xpoint,ypoint,xknot, yknot,bscoef2);



Computes a spline derivative of f(x) given knot sequence.



id1 sets order of derivative for x.

If set to 0, get value of spline at point.



id2 sets order of derivative for y.

If set to 0, get value of spline at point.





xpoint real*8 value where derivative is evaluated.



ypoint real*8 value where derivative is evaluated.



xpoint and ypoint must be 1-D arrays of the

same length.



xknot xknot sequence of length nxdata + k1

calculated by bsnak or bsopk



yknot yknot sequence of length nydata + k2

calculated by bsnak or bsopk



bscoef2 b spline values for 2-d object

size nxdata*nydata + 8.



Last 8 locations of bscoef are:



1 missing

2 n1 size of series 1 nxdata

3 k1 # knots for series 1

4 n2 size of series 2 nydata

5 k2 # knots for series 2

6 n3 size of series 3 nzdata

7 k3 # knots for series 3

8 missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of

the bscoef array.



IMSL routine DB22DR is used.

Example:



b34sexec matrix;

* Test Example from IMSL(10) ;

call echooff;

nxdata=21;

nydata=6;

kx=5;

ky=3;

i=integers(nxdata);

j=integers(nydata);

xdata=dfloat(i-11)/10.;

ydata=dfloat(j-1)/5.;

f=array(nxdata,nydata:);



do ii=1,nxdata;

do jj=1,nydata;

f(ii,jj)=(xdata(ii)**4.) +

((xdata(ii)**3.)*(ydata(jj)**2.));

enddo;

enddo;



xknot=bsnak(xdata,kx);

yknot=bsnak(ydata,ky);



bscoef2=bsint2(xdata,ydata,f,xknot,yknot);



nxvec=4;

nyvec=4;

i=integers(nxvec);

j=integers(nyvec);

xvec=dfloat(i-1)/3.;

yvec=dfloat(j-1)/3.;

xx=array(nxvec,nyvec:);

yy=xx;

ff=xx;

ffder=ff;

error=xx;

f21=xx;



do i=1,nxvec;

do j=1,nyvec;

xx(i,j) = xvec(i);

yy(i,j) = yvec(j);

ff(i,j) = (xvec(i)**4.)

+ (xvec(i)*yvec(j));

ffder(i,j)=

bsder2(2,1,xvec(i),yvec(j),xknot,yknot,bscoef2);

f21(i,j) = 12.*xvec(i)*yvec(j);

error(i,j)= f21(i,j)-ffder(i,j);



enddo;

enddo;

xx =array(:xx);

yy =array(:yy);

ffder=array(:ffder);

f21=array(:f21);

error=array(:error);



call tabulate(xx,yy,ffder,f21,error);

b34srun;



BSDER3 - Compute 3-D spline values/derivatives given knots



der=bsder3(id1,id2,id3,xpoint,ypoint,zpoint,

xknot,yknot,zknot,bscoef3);



Computes a spline derivative of f(x) given knot sequence.



id1 sets order of derivative for x.

If set to 0, get value of spline at point.



id2 sets order of derivative for y.

If set to 0, get value of spline at point.



id3 sets order of derivative for z.

If set to 0, get value of spline at point.



xpoint real*8 value where derivative is evaluated.



ypoint real*8 value where derivative is evaluated.



zpoint real*8 value where derivative is evaluated.



xpoint, ypoint and xpoint must be 1-D

arrays of the same length.



xknot xknot sequence of length nxdata + k1

calculated by bsnak or bsopk



yknot yknot sequence of length nydata + k2

calculated by bsnak or bsopk



zknot yknot sequence of length nzdata + k3

calculated by bsnak or bsopk





bscoef3 b spline values for 3-d object

size nxdata*nydata*nzdata + 8.



Last 8 locations of bscoef are:



1 missing

2 n1 size of series 1

3 k1 # knots for series 1

4 n2 size of series 2

5 k2 # knots for series 2

6 n3 size of series 3

7 k3 # knots for series 3

8 missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of

the bscoef array.



IMSL routine DB23DR is used.



Example:



b34sexec matrix;

* Test Example from IMSL(10) ;

call echooff;

kx=5;

ky=2;

kz=3;

nxdata=21;

nydata=6;

nzdata=8;



nxvec=4;

nyvec=4;

nzvec=2;



i=integers(nxdata);

j=integers(nydata);

k=integers(nzdata);



xdata=dfloat(i-11)/10. ;

ydata=dfloat(j-1) /dfloat(nydata-1);

zdata=dfloat(k-1) /dfloat(nzdata-1);



xknot=bsnak(xdata,kx);

yknot=bsnak(ydata,ky);

zknot=bsnak(zdata,kz);



maxii=index(nxdata,nydata,nzdata:);

f=array(maxii:);



do ii=1,nxdata;

do jj=1,nydata;

do kk=1,nzdata;

ii2=index(nxdata,nydata,nzdata:ii,jj,kk);

f(ii2)=(xdata(ii)**4.) +

((xdata(ii)**3.)*ydata(jj)*(zdata(kk)**3.));

enddo;

enddo;

enddo;



bscoef3=bsint3(xdata,ydata,zdata,f,xknot,yknot,zknot);

i=integers(nxvec);

j=integers(nyvec);

k=integers(nzvec);



xvec=2.*(dfloat(i-1)/3.)-1. ;

yvec=dfloat(j-1)/3.0;

zvec=dfloat(k-1);



maxjj=index(nxvec,nyvec,nzvec:);



fit =array(maxjj:);

error =array(maxjj:);

actual=array(maxjj:);

xx =array(maxjj:);

yy =xx;

zz =xx;



do ii=1,nxvec;

do jj=1,nyvec;

do kk=1,nzvec;

ii2=index(nxvec,nyvec,nzvec:ii,jj,kk);



fit(ii2)= bsder3(2,0,1,xvec(ii),yvec(jj),zvec(kk),

xknot, yknot, zknot,bscoef3);

actual(ii2)=18.*xvec(ii)*yvec(jj)*zvec(kk);

xx(ii2)=xvec(ii);

yy(ii2)=yvec(jj);

zz(ii2)=zvec(kk);

error(ii2)=actual(ii2)-fit(ii2);

enddo;

enddo;

enddo;



call print('Shows 2,0,1 derivative, actual and error':);

call tabulate(xx,yy,zz,fit,actual,error);

b34srun;



BSITG - Compute 1-D spline integral given knots



itegral=bsitg(l,u,xknot,bscoef);



Computes the integral of a spline interpolant of f(x)

knot sequence.



l lower value of integral



u upper value of integral



xknot xknot sequence of length n + k

calculated by bsnak or bsopk



bscoef b spline values for 1-d object

size n+8

Last 8 locations of bscoef are:



1 missing

2 n1 size of series 1

3 k1 # knots for series 1

4 n2 size of series 2

5 k2 # knots for series 2

6 n3 size of series 3

7 k3 # knots for series 3

8 missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of

the bscoef array.



IMSL routine DB2ITG is used.



Example:



b34sexec matrix;

* Test Example from IMSL(10) ;

ndata=21;

korder=5;

i =integers(ndata);

xdata =dfloat(i-11)/10.;

f =xdata**3.;



xknot =bsnak(xdata,korder);

bscoef=bsint(xdata,f,xknot);

a =0.0;

b =1.0;

val =bsitg(a,b,xknot,bscoef);



* fi(x)= x**4./4.;



exact =(b**4./4.)-(a**4./4.);

error=exact-val;

call print('Test of bsitg ***********************':);

call print('Lower = ',a:);

call print('Upper = ',b:);

call print('Integral = ',val:);

call print('Exact = ',exact:);

call print('Error = ',error:);



b34srun;



BSITG2 - Compute 2-D spline integral given knots



integral=bsitg2(l1,u1,l2,u2,xknot,yknot,bscoef2);



Computes a spline integral of f(x,y) given knot sequences for

x and y and po.

l1 lower value of integral for x



u1 upper value of integral for x



l2 lower value of integral for y



u2 upper value of integral for y



xknot xknot sequence of length n1 + k1

calculated by bsnak or bsopk



yknot yknot sequence of length n2 + k2

calculated by bsnak or bsopk





bscoef2 b spline values for 2-d object

size n1 by n2 + 8. Last 8 values

determine size. Saved as 1-d array.



Last 8 locations of bscoef2 are:



1 missing

2 n1 size of series 1

3 k1 # knots for series 1

4 n2 size of series 2

5 k2 # knots for series 2

6 n3 size of series 3

7 k3 # knots for series 3

8 missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of

the bscoef array.



IMSL routine DB22IG is used.



Example:



b34sexec matrix;

* Test Example from IMSL(10) ;

call echooff;

nxdata=21;

nydata=6;

kx=5;

ky=2;

i =integers(nxdata);

j =integers(nydata);

xdata=dfloat(i-11)/10.;

ydata=dfloat(j-1)/5.;

f =array(nxdata,nydata:);



do ii=1,nxdata;

do jj=1,nydata;

f(ii,jj)= (xdata(ii)**3.) + (xdata(ii)*ydata(jj));

enddo;

enddo;



xknot=bsnak(xdata,kx);

yknot=bsnak(ydata,ky);



bscoef2=bsint2(xdata,ydata,f,xknot,yknot);



a=0.0;

b=1.0;

c=.5;

d=1.0;

val=bsitg2(a,b,c,d,xknot,yknot,bscoef2);

exact=.25*((b**.4-a**.4)*(d-c)+(b*b-a*a)*(d*d-c*c));

error=val-exact;



call print('Test of bsitg2 ***********************':);

call print('Lower 1 = ',a:);

call print('Upper 1 = ',b:);

call print('Lower 2 = ',c:);

call print('Upper 2 = ',d:);

call print('Integral = ',val:);

call print('Exact = ',exact:);

call print('Error = ',error:);



b34srun;



BSITG3 - Compute 3-D spline integral given knots



integral=bsitg3(l1,u1,l2,u2,l3,u3,

xknot,yknot,zknot,bscoef3);



Computes a spline integral of f(x,y,z) given knot sequences for

x and y and po.



l1 lower value of integral for x



u1 upper value of integral for x



l2 lower value of integral for y



u2 upper value of integral for y



l3 lower value of integral for z



u3 upper value of integral for z



xknot xknot sequence of length n1 + k1

calculated by bsnak or bsopk



yknot yknot sequence of length n2 + k2

calculated by bsnak or bsopk

zknot yknot sequence of length n2 + k2

calculated by bsnak or bsopk



bscoef3 b spline values for 3-d object

size n1 by n2 by n3 + 8. Last 8 values

determine size. Saved as 1-d array.



Last 8 locations of bscoef3 are:



1 missing

2 n1 size of series 1

3 k1 # knots for series 1

4 n2 size of series 2

5 k2 # knots for series 2

6 n3 size of series 3

7 k3 # knots for series 3

8 missing



For 1-d analysis the 4-7 locations are missing.

For 2-d analysis the last 6-7 locations are missing.

The last 8 locations allow internal checking of

the bscoef array.



IMSL routine DB23IG is used.



Example:



b34sexec matrix;

* Test Example from IMSL(10) ;

call echooff;

nxdata=21;

nydata=6;

nzdata=8;

kx=5;

ky=2;

kz=3;

i=integers(nxdata);

j=integers(nydata);

k=integers(nzdata);

xdata=dfloat(i-11)/10.;

ydata=dfloat(j-1)/5.;

zdata=dfloat(k-1)/dfloat(nzdata-1);



iimax=index(nxdata,nydata,nzdata:);



f=array(iimax:);



do ii=1,nxdata;

do jj=1,nydata;

do kk=1,nzdata;

ii3=index(nxdata,nydata,nzdata:ii,jj,kk);

f(ii3)=(xdata(ii)**3.) + (xdata(ii)*ydata(jj)*zdata(kk));

enddo;

enddo;

enddo;



xknot=bsnak(xdata,kx);

yknot=bsnak(ydata,ky);

zknot=bsnak(zdata,kz);



bscoef3=bsint3(xdata,ydata,zdata,f,xknot,yknot,zknot);



a=0.0;

b=1.0;

c=.5;

d=1.0;

e=0.0;

ff=.5;

val=bsitg3(a,b,c,d,e,ff,xknot,yknot,zknot,bscoef3);



g =.5*(b**4.-a**4.);

h =(b-a)*(b+a);

ri=g*(d-c);

rj=.5*h*(d-c)*(d+c);

exact=.5*(ri*(ff-e)+.5*rj*(ff-e)*(ff+e));

error=val-exact;



call print('Test of bsitg3 ***********************':);

call print('Lower 1 = ',a:);

call print('Upper 1 = ',b:);

call print('Lower 2 = ',c:);

call print('Upper 2 = ',d:);

call print('Lower 3 = ',e:);

call print('Upper 3 = ',ff:);



call print('Integral = ',val:);

call print('Exact = ',exact:);

call print('Error = ',error:);



b34srun;



C1ARRAY - Create a Character*1 array



c1=c1array(n,k:);



Creates a 2D n by k character*1 object.



c1=c1array(n:);



creates a 1D n element character*1 array.



Example: To place character*1 in character*1



call character(cc,'abcdefghi');

cx =array(3,3:cc);

* place character*1 in character*1 ;

cx1 =c1array(3,3:cc);

Example: Move from Character*8 to Character*1



* place character*1 in character*8 ;

call character(cc,'1234567812345678abcdefghABCDEFGH');





Example:





b34sexec matrix;

/$

/$ Job shows creating char*8 and char*1 variables

/$ and moving data between the variable types

/$

c8=c8array(3,3:);

c1=c1array(3,8:);

call names;

c8(1,1)='John';

c8(1,2)='Carol';

c8(1,3)='Sue';

call character(cc1,'12345678');

call character(cc2,'abcdefgh');

c1(1,)=cc1;

c1(2,)=cc2;

call print(c1,c8);

/$

/$ Move from Character*8 to Character*1

/$ Note the user of kind = -1 to force LCOPY

/$

/$ want to place 'John' on line three of c1

call names;

call pcopy(4,pointer(c8),1,

pointer(c1)+2,norows(c1),-1);

call print(c1);

b34srun;



Example showing array vs c1array and c8array



b34sexec matrix$

x=array(3,3:);

x=rn(x);

call print(x);

xfromi_4=array(2,2:1 2 3 4);

xfromr_8=array(2,2:1. 2. 3. 4.);

xd1=array(3:);

xd1=rn(xd1);

call print(xd1,xfromi_4,xfromr_8);



/$ Character options



call character(cc,'abcdefghi');

cx =array(3,3:cc);

* place character*1 in character*1 ;

cx1 =c1array(3,3:cc);

* place character*1 in character*8 ;

call character(cc,'1234567812345678abcdefghABCDEFGH');

cx8 =c8array(2,2:cc);

call print(cx,cx1,cx8);

* recode cx8 into one row and character*1 ;

* Two ways to do the same thing ;

newcx8 = array(4:cx8);

newcx8_1=c8array(4:cx8);

* place character*8 into character*1 ;

newcx8_2=c1array(32:cx8);

* recode a character*1 array;

newch1=c1array(norows(cc),1:cc);

call print(newcx8,newcx8_1,newcx8_2,newch1);

call names(all);

b34srun;



C8ARRAY - Create a Character*8 array



c8_2d=c8array(n,k);



creates a n by k Character*8 array



c8_1d=c8array(n:);



creates a n element character*8 array



Example:



b34sexec matrix;

/$

/$ Job shows creating char*8 and char*1 variables

/$ and moving data between the variable types

/$

c8=c8array(3,3:);

c1=c1array(3,8:);

call names;

c8(1,1)='John';

c8(1,2)='Carol';

c8(1,3)='Sue';

call character(cc1,'12345678');

call character(cc2,'abcdefgh');

c1(1,)=cc1;

c1(2,)=cc2;

call print(c1,c8);

/$

/$ Move from Character*8 to Character*1

/$ Note the user of kind = -1 to force LCOPY

/$

/$ want to place 'John' on line three of c1

call names;

call pcopy(4,pointer(c8),1,

pointer(c1)+2,norows(c1),-1);

call print(c1);

b34srun;



Examples showing array vs c1array and c8array



b34sexec matrix$

x=array(3,3:);

x=rn(x);

call print(x);

xfromi_4=array(2,2:1 2 3 4);

xfromr_8=array(2,2:1. 2. 3. 4.);

xd1=array(3:);

xd1=rn(xd1);

call print(xd1,xfromi_4,xfromr_8);



/$ Character options



call character(cc,'abcdefghi');

cx =array(3,3:cc);

* place character*1 in character*1 ;

cx1 =c1array(3,3:cc);

* place character*1 in character*8 ;

call character(cc,'1234567812345678abcdefghABCDEFGH');

cx8 =c8array(2,2:cc);

call print(cx,cx1,cx8);

* recode cx8 into one row and character*1 ;

* Two ways to do the same thing ;

newcx8 = array(4:cx8);

newcx8_1=c8array(4:cx8);

* place character*8 into character*1 ;

newcx8_2=c1array(32:cx8);

* recode a character*1 array;

newch1=c1array(norows(cc),1:cc);

call print(newcx8,newcx8_1,newcx8_2,newch1);

call names(all);

b34srun;



CATCOL - Concatenates an object by columns.



new=catcol(x1 x2 x3);



Concatenates objects x1, x2, x3 by col. Objects must have same

# of rows and be vectors, 1-d or 2-d arrays or matrices.



If x1 x2 x3 were vectors of size n, new is a n by 3 matrix.



To add another col we use either



new(,4)=newv;



or



new=catcol(new,matrix(n,1:newv));



The advantage of catcol is that it can be easily placed in an

expression. For example



beta=inv(transpose(catcol(x1,x2,x3))*catcol(x1,x2,x3))*

transpose(catcol(x1,x2,x3))*y;



gets beta using 100% temp variables. A better (faster) approach

is



x=mfam(catcol(x1 x2 x3));

beta=inv(transpose(x)*x)*transpose(x)*mfam(y);



which will always work and allows x1, x2, x3 and y to

come in the matrix command as vectors or 1-D arrays.



A useful command to take things appart is submatrix.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

newdata=catcol(gasin gasout lag(gasin,1),lag(gasin,2));

call print(newdata);

gcol=goodcol(newdata);

grow=goodrow(newdata);

call print(gcol,grow);

crow3=catrow(gasin gasout lag(gasin,1),lag(gasin,2));

call print(crow3);



x1=rec(matrix(3,3:));

x2=rec(matrix(3,3:));

call print(x1,x2,catcol(x1,x2));



b34srun;





CATROW - Concatenates an object by rows.



new=catrow(x1 x2 x3);



Concatenates objects x1, x2, x3 by row. Objects must have same

# of rows and be vectors, 1-d arrays 2-d arrays, or matrices.



If all objects are 1-d, then the # of elements in each object

goes into the rows of the new matrix. The 1-d objects are seen

as 1-d norows objects



If the objects are matrices, then they are stacked.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

newdata=catcol(gasin gasout lag(gasin,1),lag(gasin,2));

call print(newdata);

gcol=goodcol(newdata);

grow=goodrow(newdata);

call print(gcol,grow);

crow3=catrow(gasin gasout lag(gasin,1),lag(gasin,2));

call print(crow3);



x1=rec(matrix(3,3:));

x2=rec(matrix(3,3:));

call print(x1,x2,catrow(x1,x2));



b34srun;



CCF - Calculate the cross correlation function on two

objects.



ccf=ccf(x,y,n);



Calculates cross correlation function for n lags of x and y.



Alternate call is:



ccf=ccf(x,y,n,lags);



to save the lag numbers in lags.



Note: For lags > 0 ccf uses time series formula.



For a simple correlation use call



corr=ccf(x,y);



If a n by k matrix is passed, ccf will return the k by k cross

correlation matrix. It is assumed that the correlation between

a series with itself is 1.0 whether the series has variance or

not. A series with no variance that is correlated with a series

that has variance is assumed to have a 0.0 correlation. Note

that some packages assign missing values to these situations.



xx=catcol(x,y,z);

call print('Correlation Matrix ',ccf(xx));



Example:



b34sexec options ginclude('gas.b34')$ b34srun$

b34sexec matrix;

/$ Illustrates and tests ccf function

call loaddata;

ccf1=ccf(gasin gasout,24);

call graph(ccf1:heading 'CCF of Gasin-Gasout');

call print(ccf1);

call names;

ccf1=ccf(gasin,gasout,24,lags);

* Same series passed to show ACF and CCF give same answer;

ccf2=ccf(gasin,gasin ,24,lags);

acf1=acf(gasin,24);

call tabulate(ccf1,ccf2,acf1,lags);

b34srun$



CFUNC - Call Function



ii= cfunc('NAME', arguments :options)



Options



:lengthargs intarray( )



:list lists all supported routines





Comment: This routine is for the expert user to provide access

to function argument lists. A call is made to

b34smatcfunc subroutine in sourc16.f. This provides a

link to a possible DLL function. Hooks are in but

code is not implemented at this time.



CHAR - Convect a integer in range 0-127 to Character.



This fortran function is not available as a function. See



call igetchari(ii,string);

call igetichar(string,ichar);



to convert an integer to a character and back.



Example:



/; From Integer get char value

/; Next characters are "bumped" by 1

b34sexec matrix;

call character(astring,'ABCDEFG');

call igetichar(astring,ichar);

ichar2=ichar+1;

call igetchari(ichar2,newstr);

call print(astring,ichar,ichar2,newstr);

b34srun;



CHARDATE - Convert julian variable into character date dd\mm\yy.



chxnew=chardate(juldate);



Produces dd\mm\yy



Example:



b34sexec matrix;

call echooff;

base=juldaydmy(1,1,1992);

n=50;

hour = array(n:);

second = array(n:);

minute = array(n:);

fday = array(n:);

cbase = rtoch(array(n:));

cbase2 = rtoch(array(n:));

base2 = array(n:);



do i=1,n;

base=base+.11;

base2(i)=base;

hour(i) =gethour(base);

second(i) =getsecond(base);

minute(i) =getminute(base);

cbase(i) =chardate(base);

cbase2(i) =chardatemy(base);

fday(i) =fdayhms(hour(i),minute(i),second(i));

enddo;



call tabulate(cbase,base2,hour,second,minute,fday);

b34srun;



CHARDATEMY - Convert julian variable into character data mm\yyyy.



chxnew=chardatemy(juldate);



Produces mm\yyyy



Example:



b34sexec matrix;

call echooff;

base=juldaydmy(1,1,1992);

n=50;

hour = array(n:);

second = array(n:);

minute = array(n:);

fday = array(n:);

cbase = rtoch(array(n:));

cbase2 = rtoch(array(n:));

base2 = array(n:);



do i=1,n;

base=base+.11;

base2(i)=base;

hour(i) =gethour(base);

second(i) =getsecond(base);

minute(i) =getminute(base);

cbase(i) =chardate(base);

cbase2(i) =chardatemy(base);

fday(i) =fdayhms(hour(i),minute(i),second(i));

enddo;

call tabulate(cbase,base2,hour,second,minute,fday);

b34srun;



CHARTIME - Converts julian variable into character date hh:mm:ss



chxnew=chartime(juldate);



Produces hh:mm:ss



Example:



b34sexec matrix;

call echooff;

base=juldaydmy(1,1,1992);

n=50;

hour = array(n:);

second = array(n:);

minute = array(n:);

fday = array(n:);

cbase = rtoch(array(n:));

cbase2 = rtoch(array(n:));

base2 = array(n:);

time = rtoch(array(n:));

do i=1,n;

base=base+.11;

base2(i)=base;

hour(i) =gethour(base);

second(i) =getsecond(base);

minute(i) =getminute(base);

cbase(i) =chardate(base);

cbase2(i) =chardatemy(base);

time(i) =chartime(base);

fday(i) =fdayhms(hour(i),minute(i),second(i));

enddo;



call tabulate(cbase,base2,hour,second,minute,fday,time);

b34srun;



CHISQPROB - Calculate chi-square probability.



x=chisqprob(x1,x2);



Calculates the probability that x1 having chi-squared

distribution with degress of freedom x2 is le x1.



x1 => Chisq value (x1 ge 0.0)

x2 => DF (x2 ge .5)



Example:



b34sexec matrix;

* Sample problem from IMSL page 919;

df = 2.0;

chisq = .15;

p=chisqprob(chisq,df);

call print('The probability that chi-squared with df',df,

'is less than ',chisq,' is ', p,

'The answer should be .0723');

chisq = 3.0;

p=1.0 - chisqprob(chisq,df);

call print('The probability that chi-squared with df',df,

'is greater than',chisq,' is ',p,

' Answer should be .2231');

b34srun;



CHTOR - Convert a character variable to a real variable.



r8=chtor(ch8);



Converts character*8 to real*8. Use with caution. Allows saving

character*8 in a real*8 matrix. Printing will not work.



Example:



b34sexec matrix;

x=array(5:1 2 3 4 5); call print(x);

cx=rtoch(x); call names;

newx=chtor(cx);

call tabulate(x,newx);

b34srun;



COMB - Combination of N objects taken M at a time.





inum=comb(n,m);



Determines # of combinations of n elements taken m at a time.

inum = n!/(m!*(n-m)!)



element=comb(n,m,i);



Determines ith element. Note 1 LE i LE inum



Example # 1



b34sexec matrix;

n=6;

call echooff;

do m=1,4;

jj=comb(n,m);

call print('N ',n,'M ',m,'# ',jj);

test=idint(matrix(jj,m:));



do kk=1,jj;

test(kk,)=comb(n,m,kk);

enddo;

call print(test);

enddo;

b34srun;



Example # 2 Using Bounds Analysis



/$ Bounds analysis - Code template.

/$ Data is in xold(n,upperi)

/$ Want to keep first loweri-1 including constant

/$ (in col 1) in model

/$ Want to see how other variables change "focus"

/$ coefficients in cols 1-loweri-1.

/$ upperi outer limit on xold index

/$ loweri lower limit on xold =>

/$ we always use col 1-(loweri-1)

/$ **********************************************

/$ build test data ** User call data routine here

/$ User sets n, upperi loweri



/$ If n=300 will not get significance due to low

/$ single / noise ratio.

/$ If n = 30000 we can get significance!!

/$ This shows effect of sample size on the estimation.

/$ The range of the coef will tighten up estimates!



n=300;

upperi=10;

loweri=4;

xold=rn(matrix(n,upperi:));

xold(,1)=1.0;

b=vector(upperi:)+2.;

b(1)=1.0;

y=vector(n:);

y=xold*b + 100.* rn(y);



/$ **********************************************

/$ start analysis



oldcoef=vector(loweri-1:);

maxcoef=vector(loweri-1:);

mincoef=vector(loweri-1:);

call olsq(y xold :noint :print);

i=integers(loweri-1);

oldcoef(i)=%coef(i);

maxcoef(i)=%coef(i);

mincoef(i)=%coef(i);



call echooff;

nn=upperi-loweri+1;



do num_in=1,(upperi-loweri+1);

kk=loweri-1+num_in;

newx=matrix(n,kk:);

/$ load the data that does not change



newx(,i)=xold(,i);



/$ num_in = number in each eq

/$ numpass = number of combinations given num_in



numpass=comb((upperi-loweri+1),num_in);



/$ estimation block



jjin=integers(loweri,kk);



do ii=1,numpass;

iv=comb(nn,num_in,ii) + loweri-1;



/$ This can be turned on



/$ call print(iv);



/$ Code is slower than a vectorized setup but more clear



do jjcopy=1,norows(iv);

j1=jjin(jjcopy);

j2=iv(jjcopy);

newx(,j1)=xold(,j2);

enddo;



/$ If want to test t, l1, minimax then in place of %coef

/$ use another vector

/$ Can turn on here if want to see the output

/$ at every step

/$ call olsq(y newx :noint :print);



call olsq(y newx :noint);



do kk=1,norows(maxcoef);

if(%coef(kk).gt.maxcoef(kk))maxcoef(kk)=%coef(kk);

if(%coef(kk).lt.mincoef(kk))mincoef(kk)=%coef(kk);

enddo;

enddo;



/$ End estimation block ***************************

call print(' ');

call print('Coef Distribution given # in was ',num_in:);

call tabulate(mincoef,oldcoef,maxcoef);

enddo;



b34srun;



COMPLEX - Build a complex variable from two real*8 variables.



x=complex(r1,r2);

Makes a complex number.





r1 => real part

r2 => complex part.



Example:



x=complex(r1,0.0)



puts r1 in the real part of the complex number and 0.0 in the

complex part.



CSPLINEFIT - Fit a 1 D Cubic Spline using alternative models





fit=csplinefit(x,f,xpoints,ider :type key );



Fit a 1 D Cubic Spline using alternative models. This command

uses the IMSL routine DSPLEZ. For more info consult the IMSL

documentation.



x = data point abscissae

f = data ordinates

xpoints = x points that spline values are desired

ider = 0 for function points

= 1 for first derivative values

= k for k th derivative



:itype key must be set as number



CSINT 1 Assume not a knot (default)

CSAKM 2 Uses Akima method

CSCON 3 Assumes data concavity

BSINT_BSNAK_2 4 Assumes spline of order 2

BSINT-BSNAK_3 5 Assumes spline of order 3

BSINT-BSNAK_4 6 Assumes spline of order 4

BSINT-BSNAK_5 7 Assumes spline of order 5

BSINT-BSNAK_6 8 Assumes spline of order 6

CSSCV 9 Smooth spline on noisey data

BSLSQ_2 10 LS spline order 2

BSLSQ_3 11 LS spline order 3

BSLSQ_4 12 LS spline order 4

BSVLS_2 13 LS variable knot spline order

2

BSVLS_3 14 LS variable knot spline order

3

BSVLS_4 15 LS variable knot spline order

4





Example:



b34sexec matrix;

n=21;

ntest=(n*2)-1;

* problem from IMSL;

x=3.0*grid(0.0, 1.0,(1.0/dfloat(n-1) ));

f=dsin(x*x);

x2=3.0*grid(0.0,1.0,(1.0/dfloat(ntest-1)));

ftest =dsin(x2*x2);

testder=2.*x2*dcos(x2*x2);

maxerr1=array(15:);

maxerr2=array(15:);



do i=1,15;

fit =csplinefit(x,f,x2,0 :type i);

fitder=csplinefit(x,f,x2,1 :type i);

maxerr1(i)=dmax(dabs(ftest-fit)) ;

maxerr2(i)=dmax(dabs(testder-fitder));

enddo;



type=integers(15);

call print('maxerr1 is fit error. ');

call print('maxerr2 = derivative error');

call tabulate(type,maxerr1,maxerr2);

b34srun;



CSPLINE - Calculate a cubic spline for 1 D data



spline=cspline(x,f :type key);



Calculates a spline for x and f. Given that x and f have n

elements,



spline=array(n,5:);



where col 1 is the break points and col 2-5 are the spline

coefficients.



x = data point abscissae



f = data ordinates



:type key

CSINT Assume not a knot (default)

CSAKM Uses Akima method

CSCON Assumes data concavity

CSSCV Smooth spline on noisey data





:equal If present and type=csscv => data is

equally spaced.



:maxit maxit Optionally set if type=cscon.

Default = 400



Example:

b34sexec matrix;

n=11;

ntest=(n*2)-1;



* problem from IMSL for csint and csakm;



x=grid(0.0, 1.0,(1.0/dfloat(n-1) ));

f=dsin(15.*x);



x2=grid(0.0,1.0,(1.0/dfloat(ntest-1)));

ftest =dsin(15.*x2);

testder=2.*x2*dcos(x2*x2);

maxerr1=array(15:);

maxerr2=array(15:);



spline1 =cspline(x,f :type csint);

spline2 =cspline(x,f :type csakm);

fit1 =csplineval(spline1,x2);

fit2 =csplineval(spline2,x2);



err1=fit1-ftest;

err2=fit2-ftest;

call tabulate(x2,ftest,fit1,err1,fit2,err2);



* Problem for cscon ;

* Results tested for csint;



x=array(9: 0.0 .1 .2 .3 .4 .5 .6 .8 1.);

f=array(9: 0.0 .9 .95 .9 .1 .05 .05 .2 1.);



spline1=cspline(x,f :type cscon);

spline2=cspline(x,f :type csint);



call print('Note: Break points in Col. 1':);

call print('cscon results ',spline1);

call print('csint results ',spline2);



fit1=csplineval(spline1,x2);

fit2=csplineval(spline2,x2);

call tabulate(fit1,fit2);

call graph(fit1,fit2);



* Problem for csscv;



n=300;

x=grid(0.0, 3.0,(1.0/dfloat(n-1) ));

f=1.0/(.1+(3.0*(x-1.0))**4.) ;

call i_rnset(1234579);

f = f+ (2.*rec(x :imsl10)) -1.;

spline=cspline(x,f :type csscv :equal);

testx=array(10:);



do i=1,10;

testx(i)=90.*dfloat(i-1)/dfloat(n-1);

enddo;



sval = csplineval(spline,testx) ;

actual= 1.0/(.1+(3.0*(testx-1.0))**4.) ;

error = sval-actual;

call tabulate(testx,actual,sval,error);



b34srun;





CSPLINEVAL - Calculate spline value given spline



value=csplineval(spline,xpoints);



Calculates spline value given spline



spline = calculated with cspline.



xpoints = x points that spline values are desired



Example:



b34sexec matrix;

n=11;

ntest=(n*2)-1;



* problem from IMSL for csint and csakm;



x=grid(0.0, 1.0,(1.0/dfloat(n-1) ));

f=dsin(15.*x);



x2=grid(0.0,1.0,(1.0/dfloat(ntest-1)));

ftest =dsin(15.*x2);

testder=2.*x2*dcos(x2*x2);

maxerr1=array(15:);

maxerr2=array(15:);

spline1 =cspline(x,f :type csint);

spline2 =cspline(x,f :type csakm);

fit1 =csplineval(spline1,x2);

fit2 =csplineval(spline2,x2);

err1=fit1-ftest;

err2=fit2-ftest;

call tabulate(x2,ftest,fit1,err1,fit2,err2);

b34srun;



CSPLINEDER - Calculate spline derivative given spline value



der=csplineval(spline,xpoints,ider);



Calculates spline derivative given spline value



spline = calculated with cspline.

xpoints = x points that spline values are desired



ider = order of derivative. ider = 0

=> get value out



Example:



b34sexec matrix;

n=10;

ntest=(n*2);



* problem from IMSL for csint;



x =grid(0.0, 1.0,(1.0/dfloat(n-1) ));

x2=grid(0.0,1.0,(1.0/dfloat(ntest-1)));

f = dsin(15.*x);

df =15.0 *dcos(15.*x2);

ddf=-225.*dsin(15.*x2);



spline =cspline(x,f :type csint);

cf =csplineder(spline,x2,0);

ff =csplineval(spline,x2);

cdf1 =csplineder(spline,x2,1);

cddf1 =csplineder(spline,x2,2);



err0=ff-cf;

err1= df-cdf1;

err2=ddf-cddf1;

call tabulate(x2,cf,err0,df, cdf1, err1,

ddf,cddf1,err2);

b34srun;



CSPLINEITG - Calculate integral of a cubic spline



integ=csplineitg(lower,upper,spline);



Calculates integral of a cubic spline



lower = lower range of integral



upper = upper range of integral



spline = calculated with cspline.



Example:



b34sexec matrix;

* problem from IMSL ;

n=10;

ntest=(n*2)-1;



* problem from IMSL for csint and csakm;



x =grid(0.0, 1.0,(1.0/dfloat(n-1) ));

x2=grid(0.0,1.0,(1.0/dfloat(ntest-1)));

f = x*x;

fi = x*x*x/3.;



spline =cspline(x,f :type csint);

lower=0.0;

upper=.5;

cfi=csplineitg(lower,upper,spline);

exact=upper*upper*upper/3.;

err=cfi-exact;



call print('Problem # 1 ':);

call print('Lower range ',lower:);

call print('Upper range ',upper:);

call print('Integral ',cfi:);

call print('Exact ',exact:);

call print('Error ',err);



upper=.2;

cfi=csplineitg(lower,upper,spline);

exact=upper*upper*upper/3.;

err=cfi-exact;



call print('Problem # 2 ':)

call print('Lower range ',lower:);

call print('Upper range ',upper:);

call print('Integral ',cfi:);

call print('Exact ',exact:);

call print('Error ',err);



b34srun;



CUSUM - Cumulative sum.



s=cusum(x);



Cumulative sum of x.



Assume x has n elements. As a check note that



s(n)=sum(x);



Example:



b34sexec matrix;

n=10;

a=dfloat(integers(n));

ccusum=cusum(a);

ccusumsq=cusumsq(a);

call tabulate(a,ccusum,ccusumsq);

call print(sum(a),sumsq(a));

b34srun;



CUSUMSQ - Cumulative sum squared.

s=cumsumsq(x);



Cumulative sum of squares of x.



Assume x has n elements. Note that as a check



s(n)=sumsq(x);



Example:



b34sexec matrix;

n=10;

a=dfloat(integers(n));

ccusum=cusum(a);

ccusumsq=cusumsq(a);

call tabulate(a,ccusum,ccusumsq);

call print(sum(a),sumsq(a));

b34srun;



CWEEK - Name of the day in character.



chxnew=cweek(juldate);



Produces 'Monday' etc



See extensive Y2 date/time testing in examples.mac.



C16TOC32 - Convert Complex*16 to Complex*32



c32=c16toc32(c16);



Changes kind of c16 to c32.



Example:



b34sexec matrix;

x=rn(matrix(3,3:));

y=rn(x);

c16=complex(x,y);

c32=c16toc32(c16);

testc16=c32toc16(c32);

call print(c16,c32,testc16);

b34srun;



C32TOC16 - Convert Complex*32 to Complex*16



c32=c16toc32(c16);



Changes kind of c32 to c16.



Example:



b34sexec matrix;

x=rn(matrix(3,3:));

y=rn(x);

c16=complex(x,y);

c32=c16toc32(c16);

testc16=c32toc16(c32);

call print(c16,c32,testc16);

b34srun;



DABS - Absolute value of a real*8 or integer variable.



y=dabs(x);



Absolute value of x in y. The name abs can be used.



Example:



b34sexec matrix;

ints=integers(20); ints=ints-10;

reals=dfloat(ints);

aints=dabs(ints);

areals=dabs(reals);

call tabulate(ints,aints,reals,areals);

b34srun;





DARCOS - Arc cosine of a real*8 variable.



y=darcos(x);



Sets y to arc cosine of x.



Example:



b34sexec matrix;

x=array(:-1., -.5, 0.0, .5, 1.0);

asin=darsin(x);

acos=darcos(x);

atan=datan(x);

call tabulate(x,asin,acos,atan);

b34srun;



DARSIN - Arc sine of a real*8 variable.



y=darsin(x);



Sets y to arc sin of x.





Example:



b34sexec matrix;

x=array(:-1., -.5, 0.0, .5, 1.0);

asin=darsin(x);

acos=darcos(x);

atan=datan(x);

call tabulate(x,asin,acos,atan);

b34srun;



DATAN - Arc tan of a real*8 variable.



y=datan(x);



Sets y to arc tan of x.



x must be real*8.



Example:



b34sexec matrix;

x=array(:-1., -.5, 0.0, .5, 1.0);

asin=darsin(x);

acos=darcos(x);

atan=datan(x);

call tabulate(x,asin,acos,atan);

b34srun;



DATAN2 - Arc tan of real*8 x / y. Signs inspected.



y=datan2(x1,x2);



Sets y to arc tan of x1/x2. x and y must be real*8.



Example:



b34sexec matrix;

x=array(:-1., -.5, 0.0, .5, 1.0);

y=array(norows(x):)+2. ;

asin=darsin(x) ;

acos=darcos(x);

atan=datan(x);

atan2=datan2(x,y);

call tabulate(x,y,asin,acos,atan,atan2);

b34srun;



DATENOW - Date now in form dd:mm:yy



cc=datenow();



Places date in form dd/mm/yy in cc.



Example:



b34sexec matrix;

call print('Date now is ',datenow():);

call print('Time now is ',timenow():);

b34srun;

DBLE - Convert real*4 to real*8.

r8=dble(r);



Converts a real*4 to real*8.



Example:



b34sexec matrix;

x=dfloat(integers(20));

xreal4=sngl(x);

xreal8=dble(xreal4);

call names(all);

call tabulate(x,xreal4,xreal8);

b34srun;



DCONJ - Conjugate of complex argument.



xx=dconjg(x);



Calculates conjugate of object x. Object x must be complex*16,

complex*32 or complex VPA.



Example:



b34sexec matrix;

cc=complex(dfloat(integers(10)),

dsqrt(dfloat(integers(10))));

call tabulate(cc,dconj(cc));

b34srun;



DCOS - Cosine of real*8 argument.



y=dcos(x);



Cosine of argument.



Example:



b34sexec matrix;

n=10.;

test=grid(0.0,pi()*n,.1);

cc =dcos(test);

ss =dsin(test);

tt =dtan(test);

cc16=dcos(r8tor16(test));

ss16=dsin(r8tor16(test));

tt16=dtan(r8tor16(test));

call tabulate(test,cc,ss,tt,cc16,ss16,tt16);

call graph(test,cc,ss :heading 'Cosine & Sine'

:plottype xyplot);

b34srun;





DCOSH - Hyperbolic cosine of real*8 argument.

y=dcosh(x);



Sets y to hyperbolic cos of x.



Example:



b34sexec matrix;

x=dfloat(integers(-10,10));

dcosh2 =dcosh(x);

dsinh2 =dsinh(x);

dtanh2 =dtanh(x);

dcosh216=dcosh(r8tor16(x));

dsinh216=dsinh(r8tor16(x));

dtanh216=dtanh(r8tor16(x));

call tabulate(x,dcosh2, dsinh2, dtanh2,

dcosh216,dsinh216,dtanh216);

b34srun;



DDOT - Inner product to two vectors.



cc=ddot(x,y);



Calculates product. x and y must be real*8.



This command calls BLAS Level I routine with the same name.

If optional argument : is added, then an element by element

operation is performed.



cc=ddot(x,y);



and



cc=vfam(x)*vfam(y);



get same result.



For one series



test1=sumsq(x);



and



test2=ddot(x,x);



get same result.



For complex case see ZTOTC and ZTOTU.



DERF - Error function of real*8/real*16 argument.



y=derf(x);



Sets y to error function of x. x must be real*8 or real*16.

Example:



b34sexec matrix;

x=grid(.1, 5., .2);

derf1 =derf(x);

derf1c=derfc(x);

test=derf1 + derf1c;

call tabulate(x,derf1,derf1c,test);

b34srun;



DERFC - Inverse of error function.



y=derfc(x);



Sets y to inverse error function of x. x must be real*8 or

real*16.



Example:



b34sexec matrix;

x=grid(.1, 5., .2);

derf1 =derf(x);

derf1c=derfc(x);

test=derf1 + derf1c;

call tabulate(x,derf1,derf1c,test);

b34srun;



DERIVATIVE - Analytic derivative of a vector.



deriv=derivative(fx,x);



Calculates the derivative of fx with respect to x.

FX and X can be complex OR real. Each must have at least 4

elements.



The code for this command came from Speakeasy. The developer

of b34s is greatful for this assistance.



Example:



b34sexec matrix;

* model is f(x) = 10. -.5*x + .001*x**2 ;

x=afam(grid(.01,10.,.01));

fx=10. -.5*x + .001*x**2.;

dd=derivative(fx,x);

call graph(fx,dd);

test=-.5+.002*x;

call tabulate(x,fx,dd,test);

b34srun;





DET - Determinate of a matrix.



d=det(x);

Determinant of x. Data types supported include real*8, real*16,

complex*16, complex*32. xinv=inv(vpadata) will automatically

produce %det and %rcond. Thus det( ) not supported for vpa

data.





Example:



b34sexec matrix;

x=matrix(3,3:0.1 1. 2. 9. 8. 7. 5. 4. 0.2);

call print(x,inv(x),det(x),det(r8tor16(x)));

cx=complex(x,dsqrt(x));

call print(cx,inv(cx),det(cx),det(c16toc32(cx)));

call print(rcond(x),rcond(r8tor16(x)));

call print(rcond(cx),rcond(c16toc32(cx)));

b34srun;



b34sexec matrix;

x=matrix(3,3:0.1 1. 2. 9. 8. 7. 5. 4. 0.2);

call print(x,inv(x),det(x));

cx=complex(x,dsqrt(x));

call print(cx,inv(cx),det(cx));

b34srun;





DEXP - Exponential of a real*8 argument.



expx=dexp(x);



Calculates exponential of a real*8, real*16, complex*16,

complex*32 or vpa argument.



Example:



b34sexec matrix;

x=grid(0.0001 100. .1);

log10x=dlog10(x);

lnx =dlog(x);

testx1=10.**log10x;

testx2=dexp(lnx);

call tabulate(x,log10x,lnx,testx1,testx2);

* Complex case;

cx=complex(x,dsqrt(x));

lncx =dlog(cx);

testcx =exp(lncx);

call tabulate(cx,lncx,testcx);

b34srun;





DFLOAT - Convert integer*4 to real*8.



r8=dfloat(i);

Converts integer*4 i to real*8.



Example:



b34sexec matrix;

r8g=grid(.1,6.,.3) ;

i=integers(norows(r8g));

r4i= float(i) ;

r8i=dfloat(i) ;

i4idint=idint(r8g) ;

i4idnint=idnint(r8g) ;

i4fromr4=int(r4i) ;

r8dint=dint(r8g) ;

call names(all) ;

call tabulate(i,r4i,r8i,r8g,i4idint,i4idnint,

i4fromr4,r8dint);

b34srun;





DGAMMA - Gamma function of real*8 argument.



y=dgamma(x);



Sets y to gamma of x.



Example:



b34sexec matrix;

x=grid(1.,30.,.5);

g=dgamma(x);

call tabulate(x,g);

b34srun;



DIAG - Place diagonal of a matrix in an array.



x=diag(xx);



Places the diagonal of xx in x. XX must be square.



Example:



b34sexec matrix;

n=5;

x=rn(matrix(n,n:));

call print(X,'Diagonal ',diag(x));

cx=complex(x,x*2.);

call print(cx,'Diagonal ',diag(cx));

b34srun;



DIAGMAT - Create diagonal matrix.



x=diagmat(y);



Creates a diagonal matrix with y along the diagonal.

Example:



b34sexec matrix;

x=vector(6:1 2 3 4 5 6);

dm=diagmat(x);

call print(dm);

b34srun;



DIF - Difference a series.





difx=dif(x);



Calculates difference of x. Alternate call is:



difx=dif(x,nd,iod);



where



nd = # of differences

iod = order difference



Note:



difx=dif(x) => difx=dif(x,1,1)



For fractional differencing see FRACDIF.



Example:



b34sexec matrix;

n=8;

c=array(n:integers(1,n));

dc=dif(c);

cc=rn(array(n:));

dcc=dif(cc);

d2d1cc=dif(cc,2,1);

call tabulate(c,dc,cc,dcc,d2d1cc);

* Tests of First Difference for Various N;

n=2000; nn2=200000;

xx=rn(array(n:)); xx2=rn(array(nn2:));

call print('Dif. of White Noise has acf(1)=-.5':);

call tabulate(acf(xx,20),acf(dif(xx),20),

acf(dif(xx2),20));

call print('Seasonal Differencing effects':);

call tabulate(acf(xx,20),acf(dif(xx,1,12),20),

acf(dif(xx2,1,12),20));

call print('Seasonal and First Difference Effects':);

call tabulate(acf(dif(dif(xx ,1,12)),20) ,

acf(dif(dif(xx2,1,12)),20));

b34srun;



Example where we difference one col and line up the rest

b34sexec matrix;

x=rn(array(10,4:));

call print(x);

x1=dif(x(,1));

newx=x;

newx(1,)=array(4:)+missing();

newx=goodrow(newx);

newx(,1)=x1;

call print(x,newx);

b34srun;



DINT - Integer part of real*8



r8=dint(r);



Places integer part of r in real*8 number r1.



Example:



b34sexec matrix;

r1=dint(3.0);

r2=dint(3.9);

call print('puts 3.0 in r1 and r2',r1,r2);

b34srun;



DNINT - Nearest integer part of real*8 in real*8



r8=dnint(r);



Places integer part of r in real*8 number r1.



Example:



b34sexec matrix;

r1=dnint(3.0);

r2=dint(3.9);

r3=dnint(3.9);

call print('puts 3.0 in r1 and r2 and 4 in r3',r1,2,r3);

b34srun;



DIVIDE - Divide with an alternative return.





y=divide(top,bot);

y=divide(top,bot,bad);



Allows a divide and traps bot=0.0 by placing a missing in

y if there are two arguments and a bad value if there are three

elements.



top = numerator (real*8 or real*16)

bot = denominator (real*8 or real*16)

bad = optional bad return value (must be same kind as

top and bot).



Warning: Divide should be used when the user knows exactly

what to do if the denominator is 0.0. The command divide is

supported for real*8 and real*16.



Example:



b34sexec matrix;

top=array(6:)+1.0;

bot=array(6:1. 0. 2 0. 3. 0.);

call print('divide',divide(top,bot));

call print('divide',divide(top,bot,0.0));

top=r8tor16(top);

bot=r8tor16(bot);

call print('divide',divide(top,bot));

call print('divide',divide(top,bot,0.0));

b34srun;







Notes: The command



where(x.ne.0.0)y=a/x;



will fail if x is 0.0 since the right hand side is done

before the logical statement is evaluated and the mask

applied. The "solution" to automatically trap all divides

will not help the user flag logic problems.





DLGAMMA - Natural log of gamma function.



y=dlgamma(x);



Sets y to log gamma of x.



Example:



b34sexec matrix;

x=array(:1.,10.,100.,1000.,10000.,100000.,1000000);

g=dlgamma(x);

call tabulate(x,g);

b34srun;



DLOG - Natural log.



y=dlog(x);



Calculates the natural log of a number. x can be real*8,

real*16, complex*16, complex*32 or real or complex vpa.



Example:

b34sexec matrix;

x=grid(0.0001 100. .1);

log10x=dlog10(x);

lnx =dlog(x);

testx1=10.**log10x;

testx2=dexp(lnx);

call tabulate(x,log10x,lnx,testx1,testx2);

* Complex case;

cx=complex(x,dsqrt(x));

lncx =dlog(cx);

testcx =exp(lncx);

call tabulate(cx,lncx,testcx);

b34srun;



DLOG10 - Base 10 log.



y=dlog10(x);



Base 10 log of argument. x must be real*8, real*16 or real VPA.



Example:



b34sexec matrix;

x=grid(0.0001 100. .1);

log10x=dlog10(x);

lnx =dlog(x);

testx1=10.**log10x;

testx2=dexp(lnx);

call tabulate(x,log10x,lnx,testx1,testx2);

b34srun;



DMAX - Largest element in an array.



newxx=dmax(x);



Largest element in x. Works for real*8, real*16 and integer.

For a related command, see dmax1.



The optional form



newxx=dmax(x:);



ignores missing data



Example:



b34sexec matrix;

* Command finds max element ;

n=20; reals=rec(array(n:))*100.;

ints=idint(reals);

maxint=dmax(ints); maxreal=dmax(reals);

call print(ints,maxint,reals,maxreal);

b34srun;

DMAX1 - Largest element between two arrays.



y=dmax1(x1,x2);



Set y to max of element in x1 or x2. x1 or x2 can be a scaler.



dmax1 works for real*8, real*16, VPA and integer.



For a related command see dmax.



Example:



b34sexec matrix;

* Command finds max of two vectors;

n=20;

reals1=rec(array(n:))*100.; ints1=idint(reals1);

reals2=rec(array(n:))*100.; ints2=idint(reals2);

maxint=dmax1(ints1,ints2) ; maxreal=dmax1(reals1,reals2);

call tabulate(ints1,ints2,maxint,reals1,reals2,maxreal);



x=array(6:1. 2. 3. 4. 5. 6.);

bigx=dmax1(x,3.);

minx=dmin1(x,3.);

vbigx=dmax1(vpa(x),vpa(3.));

vminx=dmin1(vpa(x),vpa(3.));

call tabulate(x,bigx,minx,vbigx,vminx);



b34srun;

DMIN - Smallest element in an array.



newx=dmin(x);



Smallest element in x. Works for real*8, real*16 and integer

inputs.



For a related command, see dmin1.



The optional form



newxx=dmin(x:);



ignores missing data



Example:



b34sexec matrix;

* Command finds min element ;

n=20; reals=rec(array(n:))*100.;

ints=idint(reals);

minint=dmin(ints);

minreal=dmin(reals);

call print(ints,minint,reals,minreal);

b34srun;

DMIN1 - Smallest element between two arrays.



y=dmin1(x1,x2);



Set y to min of element in x1 or x2.



dmin1 works for real*8, real*16, VPA and integer.



For a related command see dmin.





Example:



b34sexec matrix;

* Command finds min of two vectors;

n=20;

reals1=rec(array(n:))*100.; ints1=idint(reals1);

reals2=rec(array(n:))*100.; ints2=idint(reals2);

minint=dmin1(ints1,ints2) ; minreal=dmin1(reals1,reals2);

call tabulate(ints1,ints2,minint,reals1,reals2,minreal);



x=array(6:1. 2. 3. 4. 5. 6.);

bigx=dmax1(x,3.);

minx=dmin1(x,3.);

vbigx=dmax1(vpa(x),vpa(3.));

vminx=dmin1(vpa(x),vpa(3.));

call tabulate(x,bigx,minx,vbigx,vminx);

b34srun;



DMOD - Remainder.



y=dmod(xold1,xold2);



Returns a vector of remainders. dmod works for real*8 and

integer*4.



Example:



b34sexec matrix;

ints=integers(20);

reals=dfloat(ints);

imods=dmod(ints,3);

rmod =dmod(reals,3.0);

call tabulate(ints,imods,reals,rmod);

b34srun;





DROPFIRST - Drops observations on top or array.



newy=dropfirst(y,n);



Drops first n obsrvations.



Note: this is the same as

newy=keeplast(y,(norows(y)-n));



Assume one wants a model



y = f(y(t-1),y(t-2))



Two ways to proceed:



maxlag=2;

newy=dropfirst(y,maxlag);

lagy1=dropfirst(lag(y,1),maxlag);

lagy2=dropfirst(lag(y,2),maxlag);

call olsq(newy lagy1 lagy2 :print);



or



call olsq(y y{1 to maxlag} :print);



Note: At present lag, keeplast,keepfirst droplast and

dropfirst only support real*8 variables.



Example:



b34sexec matrix;

n=10;

maxlag=2;

x=array(n:integers(n));

lag1x=lag(x,1:nomiss);

lag2x=lag(x,2:);

last2=keeplast(x,2);

first2=keepfirst(x,2);

dropl2=droplast(x,2);

dropf2=dropfirst(x,2);

call tabulate(x,lag1x,lag2x,last2,first2,dropl2,dropf2);

b34srun;



DROPLAST - Drops observations on bottom of an array.



newy=droplast(y,n);



Drops last n observations.



Note: this is the same as



newy=keepfirst(y,(norows(y)-n));



Example:



b34sexec matrix;

n=10;

maxlag=2;

x=array(n:integers(n));

lag1x=lag(x,1:nomiss);

lag2x=lag(x,2:);

last2=keeplast(x,2);

first2=keepfirst(x,2);

dropl2=droplast(x,2);

dropf2=dropfirst(x,2);

call tabulate(x,lag1x,lag2x,last2,first2,dropl2,dropf2);

b34srun;



DSIN - Calculates sine.



y=dsin(x);



Sin of argument.



Example:



b34sexec matrix;

n=10.;

test=grid(0.0,pi()*n,.1);

cc=dcos(test); ss=dsin(test);

call tabulate(test,cc,ss);

call graph(test,cc,ss

:heading 'Cosine & Sine'

:plottype xyplot);

b34srun;





DSINH - Hyperbolic sine.



y=dsinh(x);



Sets y to hyperbolic sin of x.



Example:



b34sexec matrix;

x=dfloat(integers(-10,10));

dcosh2 =dcosh(x);

dsinh2 =dsinh(x);

dtanh2 =dtanh(x);

dcosh216=dcosh(r8tor16(x));

dsinh216=dsinh(r8tor16(x));

dtanh216=dtanh(r8tor16(x));

call tabulate(x,dcosh2, dsinh2, dtanh2,

dcosh216,dsinh216,dtanh216);

b34srun;







DSQRT - Square root of real*8 or complex*16 variable.



y=dsqrt(x);



Square root of argument.

Example:



b34sexec matrix;

call screenouton;

a=array(4:1,-2,3,-6);

ac=complex(a,a*2.);

ar=grid(1.,10.,1.);

sqrtar=dsqrt(ar);

test1=sqrtar*sqrtar;

call tabulate(ar,sqrtar,test1);

sqrtac=dsqrt(ac);

test2=sqrtac*sqrtac;

call print(ac,sqrtac);

call tabulate(ac,sqrtac,test2);

b34srun;





DTAN - Tangent.



y=dtan(x);



Tangent of argument. Works for real*8, real*16 and VPA.



Example:





b34sexec matrix;

n=10.;

test=grid(0.0,pi()*n,.1);

cc=dcos(test);

ss=dsin(test);

tt=dtan(test);

call tabulate(test,cc,ss,tt);

b34srun;





DTANH - Hyperbolic tangent.



y=dtanh(x);



Sets y to hyperpolic tan of x. x can be real*8 or real*16.



Example:



b34sexec matrix;

x=dfloat(integers(-10,10));

dcosh2 =dcosh(x);

dsinh2 =dsinh(x);

dtanh2 =dtanh(x);

dcosh216=dcosh(r8tor16(x));

dsinh216=dsinh(r8tor16(x));

dtanh216=dtanh(r8tor16(x));

call tabulate(x,dcosh2, dsinh2, dtanh2,

dcosh216,dsinh216,dtanh216);

b34srun;







EIG - Eigenvalue of matrix.



e=eigenval(x);



Calculates eigenvalues (e) of matrix x. x must be real*8,

real*16, complex*16 or complex*32.



eig can be used in place of eigenval.



The call



e=eig(x,evec);



calculates "right" eigen values defined such that



x= evec * diagmat(e) * inv(evec)



If x is symmetric, then



evec*transpose(evec) = I





EISPACK RG and CG are used for calculations and evec is not

scaled.



Advanced options.



The calls



e2=eig(x:lapack);

e2=eig(x,evec2 :lapack);

e2=eig(x,evec2,evec22 :lapack);



use the LAPACK routines DGEEV and ZGEEV



x is balanced and evec2 and evec22 are scaled such that the

Euclidean norm equals 1 and the largest component real. In

general evec ne evec2



but



x*evec2 = evec2 * diagmat(e2)



The option :lapack seems to fail for very large complex*16

matrices. The reasons for this are not clear but are under

investigation.



If :lapack2 is supplied LAPACK routines DGEEVX and ZGEEVX are

used. These have scaling and permuting turned off and might be

used in cases where the matrix is unusually scaled. Scaling and

permuting seems to fail for large complex matrices. :lapack2 is

the safest way to go but things are still under investigation.



For real*8 matrices, :lapack seems to work OK.



e3=eig(x:lapack2);

e3=eig(x,evec3 :lapack2);

e3=eig(x,evec3,evec33 :lapack2);



Advanced switches. In place of :LINPACK2 the following options

can be used



:lapackn => Do not diagonally scale or permute;

:lapackp => Perform permutations to make the matrix

more nearly upper triangular. Do not

diagonally scale;

:lapacls => Diagonally scale the matrix, ie. replace

X by D*X*D**(-1), where D is a diagonal

matrix chosen to make the rows and

columns of X more equal in norm. Do not

permute;

:lapackb => Both diagonally scale and permute X.



For the current release :linpack2 = :linpackn



Speed: eig_7 has a number of speed tests. For large systems

(>150) there is an increasing advantage of using LAPACK. In

addition because of the way LAPACK scales eigenvectors, the

results are 100% compatible with Matlab. To be sure that

balancing will not overflow, use :lapack for large systems.



The addition of Lapack came with b34s 8.67e.

The Eispack results are now not normalized as were the results

in IMSL.



Notes on Theory:



e=eig(x,v);



In General



v*diagmat(e) = complex(x,0.0)*v



complex(x,0.0) = v*diagmat(e)*inv(v)



where v is the right eigenvalue.



If x is positive definite then



transpose(v)*v = I

v*transpose(v) = I



if eigenvectors are scaled, other wise we get a diagonal

matrix.



Assume u is the left eigenvalue. Here



'evec22**h * a = lamda * evec22**h'



transpose(dconj(evec22))*complex(a,0.0),



diagmat(e2)*transpose(dconj(evec22))



'test factorization for left hand side'



inv(transpose(dconj(evec22)))*

diagmat(e2)*transpose(dconj(evec22)));





Example:



b34sexec matrix;

* Test for Real*8 Matrix from IMSL Math (10) pp 295-297;

* Eigenvectors have NOT been normalized;

* Eigenvectors tested below;

a=matrix(3,3:8.,-1.,-5.,-4., 4.,-2.,18.,-5.,-7.);

call print('A Matrix',a);

e=eigenval(a);

call print('Eigenvalues of a', e,

'Sum of the eigenvalues of General Martix A',sum(e),

'Trace of General Matrix A',trace(a),

'Product of the eigenvalues of Martix A',prod(e),

'Determinant of Matrix A',det(a));

ee=eigenval(a,evec);

call print('Non scaled Eigenvectors',evec);

ee=eigenval(a,evec:lapack2);

call print('Scaled Eigenvectors',evec);

call print('Test transpose(evec)*evec ',

transpose(evec)*evec ,

' '

'Test evec*transpose(evec) ',

evec*transpose(evec)) ;

* Complex Case See IMSL Math (10) pp 302-304 ;

r=matrix(4,4:5., 5.,-6.,-7.,

3., 6.,-5.,-6.,

2., 3.,-1.,-5.,

1., 2.,-3.,0.0);

i=matrix(4,4:9., 5.,-6.,-7.,

3.,10.,-5.,-6.,

2., 3., 3.,-5.,

1., 2.,-3., 4.);

ca=complex(r,i);

call print('CA Complex Matrix',ca);

ce=eigenval(ca,cevec);

call print('Non scaled Eigenvectors of CA',cevec);

ee=eigenval(ca,cevec:lapack2);

call print('Scaled Eigenvectors of CA',cevec);

call print('Eigenvalues of ca', ce,

'Sum of the eigenvalues of General Martix CA',sum(ce),

'Trace of General Matrix CA',trace(ca),

'Product of the eigenvalues of Martix CA',prod(ce),

'Determinant of Matrix CA',det(ca));

b34srun;



b34sexec matrix;

* Example from Limdep 7.0 Manual page 376 ;

* Eigen analysis of Klein Model 1 ;

r=matrix(3,3:.172,-.051,-.008,1.511,.848,

.743,-.287,-.161,.818);

call print(r,eigenval(r));

b34srun;





EIGENVAL - Eigenvalue of real*8 or complex*16 matrix.



e=eigenval(x);



Eigenvalue of real*8, real*16, complex*16 or complex*16 matrix.



For detail see help for eig.





EPSILON Positive value such that 1.+x ne 1.



ee=epsilon(x);



Positive number such that 1.+x ne 1.

Value = 2**(1-p) where p = # of bits

in fractional part of physical representation

of x. x can be real*4 or real*8.



Example:



b34sexec matrix;

i=1;

i8=i4toi8(i);

x=1.;

x16=r8tor16(x);

y=sngl(x);

call print('Largest integer*4 ',huge(i):);

call print('Largest real*4 ',huge(y):);

call print('Largest real*8 ',huge(x):);

call print('Largest real*16 ',huge(x16):);

call print('Smallest real*4 ',tiny(y):);

call print('Smallest real*8 ',tiny(x):);

call print('Smallest real*16 ',tiny(x16):);

call print('Epsilon real*4 ',epsilon(y):);

call print('Epsilon real*8 ',epsilon(x):);

call print('Epsilon real*16 ',epsilon(x16):);

call print('Precision real*4 ',precision(y):);

call print('Precision real*8 ',precision(x):);

call print('Precision real*16 ',precision(x16):);



x=.1d+00;

x16=r8tor16(x);

y=sngl(x);

j=1;

call echooff;

do i=1,1000,100;

x=x*dfloat(i);

y=float(i)*y ;

x16=x16*r8tor16(dfloat(i));

spx(j) =spacing(x);

spy(j) =spacing(y);

spx16(j) =spacing(x16);

nearpr8(j) =nearest(x, 1.);

nearmr8(j) =nearest(x,-1.);

nearpr16(j)=nearest(x16, r8tor16(1.));

nearmr16(j)=nearest(x16,r8tor16(-1.));



nearpr4(j)=nearest(y, 1.);

nearmr4(j)=nearest(y,-1.);

testnum(j)=x;

j=j+1;

enddo;



call print('Spacing for Real*8, Real*16 and Real*4');

call print(spx16,nearpr16,nearmr16);

call tabulate(testnum,spx,spy,spx16,nearpr8, nearmr8,

nearpr4,nearmr4

nearpr16,nearmr16);



call names(all);

call graph(testnum,spx :plottype xyplot

:heading 'Spacing');

b34srun;



EVAL - Evaluate a Character Argument



xx=eval(h);



where



h='jj';



forms



xx=jj



This command is useful if a variable name is

input into a string. If the form



xx=eval(h);



is used a temp is used

If the form



x=eval(h:);



is used



then the internal name is used.



Example:



b34sexec matrix;

test1=10.;

pp='TEST1';

call print(eval(pp));

b34srun;



prints 10.0 or the contents of pp



call print(eval(pp:));



prints



test1=10.



If



y=namelist(x1 x2);



call tabulate(eval(y(1)),eval(y(2)));



uses temp names while



call tabulate(eval(y(1):),eval(y(1):));



will produce headings of x1 and x2.



Example:



b34sexec matrix;

test1=40.;

cc='TEST1';

call print(eval(cc));

call print(eval(cc:));

b34srun;



Examples of Namelist to Argument Processing



b34sexec matrix;



/$ illustrate namelist to argument



x=namelist(x1 x2 x3);

y =rn(array(10:));

x1=rn(array(10:));

x2=rn(array(10:));

x3=rn(array(10:));

call olsq(y,x1,x2,x3:print);



/$ : not needed here



xnew=eval(x(1));



do i=2,norows(x);

xnew=catcol(xnew,eval(x(i)));

enddo;

call olsq(y,xnew :print);



/$ : needed here to get names!



call olsq(y,eval(x(1):),eval(x(2):),eval(x(3):)

:print);

b34srun;



EXP - Exponential of real*8 or complex*16 variable.



y=exp(x);



Calculates y=e**x.



DEXP also works.



X can be real*8 or complex*16



Example:



b34sexec matrix;

x=grid(0.0001 100. .1);

log10x=dlog10(x);

lnx =dlog(x);

testx1=10.**log10x;

testx2=dexp(lnx);

call tabulate(x,log10x,lnx,testx1,testx2);

* Complex case;

cx=complex(x,dsqrt(x));

lncx =dlog(cx);

testcx =exp(lncx);

call tabulate(cx,lncx,testcx);

b34srun;



EXTRACT - Extract elements of a character*1 variable.



chxnew=extract(charvar,i,j)$



Does the same as the fortran command



chxnew=charvar(i:j)

i, j must be integers.



Example:



b34sexec matrix;

call character(cc2,'abcdefghijklmnop');

do i=1,10;

j=10;

newc=extract(cc2,i,j);

call print(cc2,i,j,newc);

enddo;

cc8=namelist(mary sue judy Diana);

cc82=extract(cc8,2,3);

call print('col 2-3');

call tabulate(cc8,cc82);



do i=1,8;

newc=place(cc2,1,i);

call print(cc2,newc,i);

enddo;

b34srun;



FACT - Factorial.



f=fact(i);



Factorial of i. i can be integer or real*8.



Example:



b34sexec matrix;

x=integers(20);

call tabulate(x,fact(x));

b34srun;



FDAYHMS - Gets fraction of a day.



xnew=fdayhms(hour,minute,second);



Gets fraction of a day



Example:



b34sexec matrix;

call echooff;

base=juldaydmy(1,1,1992);

n=50;

hour = array(n:);

second = array(n:);

minute = array(n:);

fday = array(n:);

cbase = rtoch(array(n:));

cbase2 = rtoch(array(n:));

base2 = array(n:);

do i=1,n;

base=base+.11;

base2(i)=base;

hour(i) =gethour(base);

second(i) =getsecond(base);

minute(i) =getminute(base);

cbase(i) =chardate(base);

cbase2(i) =chardatemy(base);

fday(i) =fdayhms(hour(i),minute(i),second(i));

enddo;



call tabulate(cbase,base2,hour,second,minute,fday);

b34srun;



Note: The commands gethour, getminute, getsecond

and fdayhms truncate hour, minute and second to

integer values in the ranges (0-24), (0-60) and

(0-60) respectively.



FFT - Fast fourier transform.



fftx=fft(x);



Calculates FFT of real*8 or complex*16 x.



The alternative command



bb=fft(fft:BACK);



will back transform the FFT values calculated with

FFT(x).

The command



new=fft(fft(x:back);



multiplies x by n. FFTPACK is used for calculations.



Examples:



b34sexec matrix;

call screenouton;



* Example from IMSL (10) Math Page 707-709;

n=7.;

ifft=grid(1.,n,1.);

xfft=dcos((ifft-1.)*2.*pi()/n);

rfft=fft(xfft);

bfft=fft(rfft:back);

call tabulate(xfft,rfft,bfft);



* Complex Case See IMSL(10) Math Page 715-717;

cfft=complex(0.0,1.);

hfft=(complex(2.*pi())*cfft/complex(n))*complex(3.0);

xfft=dexp(complex(ifft-1.)*hfft);

cfft=fft(xfft);

bfft=fft(cfft:back);

call tabulate(xfft,cfft,bfft);



* Simple Real Problem IMSL (10) Math 710-12;

ffxin=array(7:);

ffxin=ffxin+1.0;

ffxout=fft(ffxin);

bffxout=fft(ffxout:back);

bffxout2=bffxout/dfloat(norows(bffxout));

call tabulate(ffxin,ffxout,bffxout,bffxout2);



* Simple Problem IMSL (10) Math 718-720 ;

fft2=fft(ifft);

bfft2=fft(fft2:back);

bfft2_2=bfft2/dfloat(norows(fft2));

call tabulate(ifft,fft2,bfft2,bfft2_2);

fft2=fft(complex(ifft));

bfft2=fft(fft2:back);

bfft2_2=bfft2/complex(dfloat(norows(fft2)));

call tabulate(ifft,fft2,bfft2,bfft2_2);

b34srun;



b34sexec matrix;

/$ Test Problem of FFT from MATLAB page 6-32

x=array(8:4., 3., 7., -9., 1., 0., 0., 0.);

call print(x,fft(x));

b34srun;



b34sexec matrix;

* Uses FFT to High and Low Pass Random Series;

* Illustrate with random numbers;

n=296;

test=rn(array(n:));

spec=spectrum(test,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random series');



cfft=fft(complex(test,0.0));

* low pass ;

nlow1 =1;

nlow2 =64;

nhigh1=51;

nhigh2=150;



fftlow =cfft*complex(0.0,0.0);

ffthigh =cfft*complex(0.0,0.0);

i=integers(nlow1,nhigh1);

fftlow(i) = cfft(i);

i=integers(nlow2,nhigh2);

ffthigh(i) = cfft(i);

call tabulate(cfft,fftlow,ffthigh);

low =afam(real(fft(fftlow :back)))*

(1./dfloat(norows(test)));

high=afam(real(fft(ffthigh :back)))*

(1./dfloat(norows(test)));



call tabulate(low,high,fft(ffthigh:back));



spec=spectrum(low,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random after Low

Pass');



spec=spectrum(high,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random after High

Pass');



b34srun;



b34sexec matrix;

* Uses FFT to Band Pass Random Series;

* Illustrate with random numbers;

* Middle Frequencies are passed;

n=400;

nlow=64;

nupper=192;

x=rn(array(n:));

spec=spectrum(x,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random series');



cfft =fft(complex(x,0.0));

fftnew =cfft*complex(0.0,0.0);



i=integers(nlow,nupper);

fftnew(i) = cfft(i);

nseries=afam(real(fft(fftnew

:back)))*(1./dfloat(norows(x)));

call tabulate(x,nseries);

call graph(freq,spectrum(nseries,freq) :plottype

xyplot

:heading 'Spectrun of filtered Random

Series');



b34srun;



FIND - Finds location of a character string.



int =find(charvar,' ')$



Finds location of ' ' where one character is

specified.

If char*8 used in place of ' ', first character used.

If CHARVAR is a structured object, int will have same

structure.



Example:



b34sexec matrix;

cc=namelist(mary sue joan);

wherea=find(cc,'a');

wherea2=find(cc,'A');

call tabulate(wherea,cc,wherea2);

call character(cc2,'abcdefghijklmnop');

call print('Where is a?',cc2,find(cc2,'a'));

call print('Where is b?',cc2,find(cc2,'b'));

b34srun;



See also command notfind.

FLOAT - Converts integer*4 to real*4.



r4=float(i);



Converts an integer i to real*4.



Example:



b34sexec matrix;

r8g=grid(.1,6.,.3);

i=integers(norows(r8g));

r4i= float(i);

r8i=dfloat(i);

i4idint=idint(r8g);

i4idnint=idnint(r8g);

i4fromr4=int(r4i);

r8dint=dint(r8g);

call names(all);

call tabulate(i,r4i,r8i,r8g,i4idint,i4idnint,

i4fromr4 r8dint);

b34srun;



FPROB - Probability of F distribution.



x=fprob(x1,x2,x3);



F distribution probability



Calculates probability that F(x2,x3) is LE x1.



x1 = f value (ge 0)



x2 = df numerator (gt 0)



x3 = df denominator (gt 0)



Example:



b34sexec matrix;

* IMSL page 925 ;

f=648.0;

dfn=1.0;

dfd=1.0;

p=1.0-fprob(f,dfn,dfd);

call print(

'Probability that F(1,1) variable is GE ',f,' is ',p,

'Answer should be .0250');

b34srun;



FRACDIF - Fractional Differencing



fdx=fracdif(x,d,nterms);





x - Input series

d - Fractional differercing order

nterms - Number of terms. If the number

of terms is made very large, the DGAMMA

function will overflow. This is trapped on

Windows, Linux and Sun. A message will be

placed in the b34s log. On these machines

nterms must be LE 170. The value of d will

modify this limit.



fdx - Filtered series is not padded with missing

values.



Variables Created



%FDMCOEF - Fractional Differencing MA Coefficients

%FDACOEF - Fractional Differencing AR Coefficients



fdx = %FDACOEF*x



For references see Hamilton (1994) page 448.

Baillie "Journal of Econometrics" 73,1,1966, pp.5-59

Greene (2000) p. 786.

Campbll-Lo-MacKinkey "The Econometrics of Financial

Markets" 1997 page 55-60



((1-L)**d)*y(t) = e(t)

y(t) = ((1-L)**(-d))*e(t)



Following Cambell-Lo-MacKinley Coefficients are:





MA coefficients are DGAMMA(k +

d)/(dgamma(d)*dgamma(k+1))

AR coefficients are DGAMMA(k - d)/(dgamma(-

d)*dgamma(k+1))



acf(k) = (DGAMMA(k+d)*DGAMMA(1-d))/(DGAMMA(k-

d+1)*DGAMMA(d))

Note: If AR coefficients are calculated for d and

applied to

white noise series, the resulting ACF of the

series

is for -d. For an example see FRACDIF example in

matrix.mac



See the supplied subroutine FDIFINFO for ways to

calculate

AR MA and P(k). Note restrictions on the DGAMMA

function

that arguments are inside a range.



The term "fractionally differenced of order d" is

equivalent

"fractionally integrated of order -d." For purposes

of this

command the d input is from (1-L)**d.



A problem of using the DGAMMA formulation is that

there is an

upper limit of the arguments to the gamma function.



An alternative is the binomial expansion



(1-L)**d = (1 -dL +d(d-1)L**2/2! -d(d-1)(d-2)L**3/3!



which does not have this limit.



Example



fdgas = fracdif(gasout,.4,10);



Full Example:



b34sexec options ginclude('b34sdata.mac') member(gas);

b34srun;

b34sexec matrix;

call loaddata;

fdgas=fracdif(gasout,.4,11);

call tabulate(%fdmacoef.%fdarcoef);

acf1=acf(gasout,12);

acf2=acf(fdgas ,12);

call tabulate(acf1,acf2);

call graph(acf1,acf2 :Heading 'ACF of GASOUT and FD

GASOUT');

b34srun;



FREQ - Gets frequency of a time series.



freqx=freq(x);



Gets frequency of x.

Example:



b34sexec options ginclude('b34sdata.mac')

member(theil);

b34srun;

b34sexec matrix;

call loaddata;

call print(timebase(ct),timestart(ct),freq(ct));

b34srun;



FYEAR - Gets fraction of a year from julian date.



xnew=fyear(juldate);



Gets fraction of a year (1958.5)



GENARMA - Generate an ARMA series given parameters.





x=genarma(ar,ma,const,start,wnv,noob,nout)



Generate ARMA model where:



ar = AR paramaters (can be null)



ma = MA parameters (can be null)



const = constant in model



start = Starting values



wnv = white noise variance. Usually 1.0



noob = # of obs in series



nout = # to throw out at start. If this parameter is

not

supplied it is assumed to be 200



Example generate AR(1) with parameter .9 and 2000 obs.



call free(ma);

ar=.9;

start=.1;

xnew=genarma(ar,ma,0.0,start,1.0,2000);



Note: The GENARMA command uses the IMSL routine FTGEN

which calls GGNML in default mode. Data built

with

the GENARMA command can be estimated with the

ARIMA

command.

GETDAY - Obtain day of year from julian series.



day=getday(juldate);



Gets day of year



See extensive example for this command.



GETHOUR - Obtains hour of the day from julian date.



xnew=gethour(juldate);



Gets hour of day.



Example:



b34sexec matrix;

call echooff;

base=juldaydmy(1,1,1992);

n=50;

hour = array(n:);

second = array(n:);

minute = array(n:);

fday = array(n:);

cbase = rtoch(array(n:));

cbase2 = rtoch(array(n:));

base2 = array(n:);



do i=1,n;

base=base+.11;

base2(i)=base;

hour(i) =gethour(base);

second(i) =getsecond(base);

minute(i) =getminute(base);

cbase(i) =chardate(base);

cbase2(i) =chardatemy(base);

fday(i) =fdayhms(hour(i),minute(i),second(i));

enddo;



call tabulate(cbase,base2,hour,second,minute,fday);

b34srun;



Note: The commands gethour, getminute, getsecond

and fdayhms truncate hour, minute and second to

integer values in the ranges (0-24), (0-60) and

(0-60) respectively.





GETMINUTE - Obtains minute of the day from julian date.



xnew=getminute(juldate);



Gets Minute of day

Example:



b34sexec matrix;

call echooff;

base=juldaydmy(1,1,1992);

n=50;

hour = array(n:);

second = array(n:);

minute = array(n:);

fday = array(n:);

cbase = rtoch(array(n:));

cbase2 = rtoch(array(n:));

base2 = array(n:);



do i=1,n;

base=base+.11;

base2(i)=base;

hour(i) =gethour(base);

second(i) =getsecond(base);

minute(i) =getminute(base);

cbase(i) =chardate(base);

cbase2(i) =chardatemy(base);

fday(i) =fdayhms(hour(i),minute(i),second(i));

enddo;



call tabulate(cbase,base2,hour,second,minute,fday);

b34srun;



Note: The commands gethour, getminute, getsecond

and fdayhms truncate hour, minute and second to

integer values in the ranges (0-24), (0-60) and

(0-60) respectively.



GETMONTH - Obtains month from julian date.



month=getmonth(juldate);



Gets month of year.



See extensive example for this command.



GETNDIMV - Get an value from an n dimensional object



x=genndimv(index(4 5 6),index(1 2 3),xx);



places the 1 2 3 element of the 4 by 5 by 6

dimensioned array xx in x.



Example:



b34sexec matrix;

x=rn(array(index(4,4,4:):));

call print(x,getndimv(index(4,4,4),index(1,2,1),x));

do k=1,4;

do i=1,4;

do j=1,4;

test=getndimv(index(4,4,4),index(i,j,k),x);

call print(i,j,k,test);

enddo;

enddo;

enddo;



b34srun;

GETQT - Obtains quarter of year from julian date.



quarter=getqt(juldate);



Gets quarter.



See extensive example file for this command.



GETSECOND - Obtains second from julian date.



xnew=getsecond(juldate);



Gets Second of day



Example:



b34sexec matrix;

call echooff;

base=juldaydmy(1,1,1992);

n=50;

hour = array(n:);

second = array(n:);

minute = array(n:);

fday = array(n:);

cbase = rtoch(array(n:));

cbase2 = rtoch(array(n:));

base2 = array(n:);



do i=1,n;

base=base+.11;

base2(i)=base;

hour(i) =gethour(base);

second(i) =getsecond(base);

minute(i) =getminute(base);

cbase(i) =chardate(base);

cbase2(i) =chardatemy(base);

fday(i) =fdayhms(hour(i),minute(i),second(i));

enddo;



call tabulate(cbase,base2,hour,second,minute,fday);

b34srun;



Note: The commands gethour, getminute, getsecond

and fdayhms truncate hour, minute and second to

integer values in the ranges (0-24), (0-60) and

(0-60) respectively.



GETYEAR - Obtains year.



year=getyear(juldate);



Gets year.



See extensive example for this command.



GOODCOL - Deletes all columns where there is missing data.



new=goodcol(x);



Creates an object new that contains cols from x

that do not contain missing data.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

newdata=catcol(gasin gasout lag(gasin,1),

lag(gasin,2));

call print(newdata);

gcol=goodcol(newdata);

grow=goodrow(newdata);

call print(gcol,grow);

crow3=catrow(gasin gasout lag(gasin,1),

lag(gasin,2));

call print(crow3);

b34srun;



GOODROW - Deletes all rows where there is missing data.



new=goodrow(x);



Creates an object new containing rows from X that

do not contain missing data.



Example:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

newdata=catcol(gasin gasout lag(gasin,1),

lag(gasin,2));

call print(newdata);

gcol=goodcol(newdata);

grow=goodrow(newdata);

call print(gcol,grow);

crow3=catrow(gasin gasout lag(gasin,1),

lag(gasin,2));

call print(crow3);

b34srun;





GRID - Defines a real*8 array with a given increment.



x=grid(begin,end,rinc);



Defines a grid from begin to end with incrument rinc.



Alternate



x=grid(begin,end);



101 points including begin and end



For example



x=grid(1.,10.,2.);



is the same as



x=array(5:1. 3. 5. 7. 9.);



While the command



i=integer(5);



creates an integer array {1 2 3 4 5},

grid creates a real*8 vector.



grid(1,3,.5);



creates



{1. 1.5 2. 2.5 3.}



Example:



b34sexec matrix;

g=grid(-2.0,2.0,.1);

call print(g);

b34srun;



HUGE Largest number of type



big=huge(x);



Gets largest number of type x. X can be integer

real*4, real*16 or real*8.



Example:



b34sexec matrix;

i=1;

i8=i4toi8(i);

x=1.;

x16=r8tor16(x);

y=sngl(x);

call print('Largest integer*4 ',huge(i):);

call print('Largest integer*8 ',huge(i8):);

call print('Largest real*4 ',huge(y):);

call print('Largest real*8 ',huge(x):);

call print('Largest real*16 ',huge(x16):);

call print('Smallest real*4 ',tiny(y):);

call print('Smallest real*8 ',tiny(x):);

call print('Smallest real*16 ',tiny(x16):);

call print('Epsilon real*4 ',epsilon(y):);

call print('Epsilon real*8 ',epsilon(x):);

call print('Epsilon real*16 ',epsilon(x16):);

call print('Precision real*4 ',precision(y):);

call print('Precision real*8 ',precision(x):);

call print('Precision real*16 ',precision(x16):);



x=.1d+00;

x16=r8tor16(x);

y=sngl(x);

j=1;

call echooff;

do i=1,1000,100;

x=x*dfloat(i);

y=float(i)*y ;

x16=x16*r8tor16(dfloat(i));

spx(j) =spacing(x);

spy(j) =spacing(y);

spx16(j) =spacing(x16);

nearpr8(j) =nearest(x, 1.);

nearmr8(j) =nearest(x,-1.);

nearpr16(j)=nearest(x16, r8tor16(1.));

nearmr16(j)=nearest(x16,r8tor16(-1.));



nearpr4(j)=nearest(y, 1.);

nearmr4(j)=nearest(y,-1.);

testnum(j)=x;

j=j+1;

enddo;



call print('Spacing for Real*8, Real*16 and Real*4');

call print(spx16,nearpr16,nearmr16);

call tabulate(testnum,spx,spy,spx16,nearpr8, nearmr8,

nearpr4,nearmr4

nearpr16,nearmr16);



call names(all);

call graph(testnum,spx :plottype xyplot

:heading 'Spacing');

b34srun;

HYPDF - Evaluate Hypergeometric Distribution Function



pr=hypdf(k,n,m,l);



Evaluates the hypergeometric distribution

function where:



k (integer) argument K GE 0



n (integer) sample size



m (integer) number of defectives in lot



l (integer) lot size



Note: k LT n

l GE n

l GE m



Example:



b34sexec matrix;

k=7;

n=100;

m=70;

l=1000;

pr=hypdf(k,n,m,l);

call print(

'Evaluate Hypergeometric Distribution Function ':);

call print('Probability that X is LE 7 = ',pr:);

call print('Note: Answer should be .5995':);

b34srun;



HYPPR - Evaluate Hypergeometric Probability Function



pr=hyppr(k,n,m,l);



Evaluates the hypergeometric probability

function where:



k (integer) argument K GE 0



n (integer) sample size



m (integer) number of defectives in lot



l (integer) lot size



Note: k LT n

l GE n

l GE m



Example:

b34sexec matrix;

k=7;

n=100;

m=70;

l=1000;

pr=hyppr(k,n,m,l);

call print(

'Evaluate Hypergeometric Probability Function':);

call print('Probability that X is 7 = ',pr:);

call print('Note: Answer should be .1628':);

b34srun;



I4TOI8 - Move an object for integer*4 to integer*8



i8=i4toi8(i4obj);



Creates an integer*8 object i8 having vakue of i4obj.



Example:





/;

/; Tests integer*8 capability

/;

b34sexec matrix;

i4=123;

call print(i4*i4,123.*123.,i4toi8(i4)*i4toi8(i4));



i8=integer8('1234567678900987654');

ii8=i8;

call print(i8,ii8,i8/kindas(i8,10));

iv4=integers(1,6);

iv8=i4toi8(iv4);

call names(all);

new=i8toi4(iv8);

i4mat=idint(10.*rn(matrix(4,4:)));

i8mat=i4toi8(i4mat);

new8 =i8toi4(i8mat);

call print(i8,iv4,iv8,new,i4mat,i8mat,new8);

call print(kindas(new,i8));

call print(kindas(i8, iv4));

i8=integer8('123');

i4=i8toi4(i8);

call names(all);



call print(i8,i4,i4*i4,i8*i8,i4*i4);

i4array=afam(i4mat)+10;

i8array=i4toi8(i4array);

call print(i4array,i8array);

call print(i4mat+i4mat,i8mat+i8mat);

call print(i4mat-i4mat,i8mat-i8mat);

call print(i4array+i4array,i8array+i8array);

call print(i4array-i4array,i8array-i8array);

call print(i4array*i4array,i8array*i8array);

call print((2*i4array)/i4array,

(kindas(i8,2)*i8array)/i8array);



ivp=vpa('12345678');

call print(vpa(ivp :to_int ));

call print(vpa(ivp :to_int8));



b34srun;



I8TOI4 - Move an object for integer*8 to integer*4



i4=i8toi4(i8obj);



Creates an integer*4 object i4 having value of i8obj provided

that limit not exceeded.



Example:





/;

/; Tests integer*8 capability

/;

b34sexec matrix;

i4=123;

call print(i4*i4,123.*123.,i4toi8(i4)*i4toi8(i4));



i8=integer8('1234567678900987654');

ii8=i8;

call print(i8,ii8,i8/kindas(i8,10));

iv4=integers(1,6);

iv8=i4toi8(iv4);

call names(all);

new=i8toi4(iv8);

i4mat=idint(10.*rn(matrix(4,4:)));

i8mat=i4toi8(i4mat);

new8 =i8toi4(i8mat);

call print(i8,iv4,iv8,new,i4mat,i8mat,new8);

call print(kindas(new,i8));

call print(kindas(i8, iv4));

i8=integer8('123');

i4=i8toi4(i8);

call names(all);



call print(i8,i4,i4*i4,i8*i8,i4*i4);

i4array=afam(i4mat)+10;

i8array=i4toi8(i4array);

call print(i4array,i8array);

call print(i4mat+i4mat,i8mat+i8mat);

call print(i4mat-i4mat,i8mat-i8mat);

call print(i4array+i4array,i8array+i8array);

call print(i4array-i4array,i8array-i8array);

call print(i4array*i4array,i8array*i8array);

call print((2*i4array)/i4array,

(kindas(i8,2)*i8array)/i8array);



ivp=vpa('12345678');

call print(vpa(ivp :to_int ));

call print(vpa(ivp :to_int8));



b34srun;



INTEGER8 - Cleates an integer*8 object from a string



i8=integer8('1234567898');



Creates an integer*8 object i8 having value of

1234567898.



Example:





/;

/; Tests integer*8 capability

/;

b34sexec matrix;

i4=123;

call print(i4*i4,123.*123.,i4toi8(i4)*i4toi8(i4));



i8=integer8('1234567678900987654');

ii8=i8;

call print(i8,ii8,i8/kindas(i8,10));

iv4=integers(1,6);

iv8=i4toi8(iv4);

call names(all);

new=i8toi4(iv8);

i4mat=idint(10.*rn(matrix(4,4:)));

i8mat=i4toi8(i4mat);

new8 =i8toi4(i8mat);

call print(i8,iv4,iv8,new,i4mat,i8mat,new8);

call print(kindas(new,i8));

call print(kindas(i8, iv4));

i8=integer8('123');

i4=i8toi4(i8);

call names(all);



call print(i8,i4,i4*i4,i8*i8,i4*i4);

i4array=afam(i4mat)+10;

i8array=i4toi8(i4array);

call print(i4array,i8array);

call print(i4mat+i4mat,i8mat+i8mat);

call print(i4mat-i4mat,i8mat-i8mat);

call print(i4array+i4array,i8array+i8array);

call print(i4array-i4array,i8array-i8array);

call print(i4array*i4array,i8array*i8array);

call print((2*i4array)/i4array,

(kindas(i8,2)*i8array)/i8array);

ivp=vpa('12345678');

call print(vpa(ivp :to_int ));

call print(vpa(ivp :to_int8));



b34srun;



ICHAR - Convect a character to integer in range 0-127.



See



call getichar(int,string);



ICOLOR - Sets Color numbers. Used with Graphp.



call print(icolor(RED));



Used with GRAPHP command.



Colors supported:



black, blue, green, bblue, red, magenta,

cyan, white gray yellow bgreen bcyan,

bred, bmagenta byellow bwhite







IDINT - Converts from real*8 to integer*4.



i4=idint(r8);



Converts real*8 r8 to integer with trucation.



Example:



b34sexec matrix;

r8g=grid(.1,6.,.3);

i=integers(norows(r8g));

r4i= float(i);

r8i=dfloat(i);

i4idint=idint(r8g);

i4idnint=idnint(r8g);

i4fromr4=int(r4i);

r8dint=dint(r8g);

call names(all);

call tabulate(i,r4i,r8i,r8g,i4idint,i4idnint,

i4fromr4 r8dint);

b34srun;





INLINE - Inline creation of a program



testp=inline('f=x**2.+y**2.;':testp);



creates an program testp having

statements



program testp$

f=x**2. +y**2.$

return$

end$



Inline can contain more than one argument

for the program



If the :name argument is left off, the name

%INLINE_ is used. The inline command is useful

for function plotting.



Warning: The command



testp=inline('f=x**2.+y**2.;':testp2);



will save in the name testp



program testp2;

f=x**2. +y**2.;

return;

end;



The program can be renamed on the fly with the

command



call subrename(testp);



Notes: The b34s INLINE command differs in a number of

important ways from the Matlab inline command.

First a program is created, not a subroutine or

a function. This allows the user to specify a

function that contains more than two arguments but

in a fplot routine call just gives two names. This

is the same as plotting one slice of a 3 dimensional

surface.



Example:



/$ MAXF2 is used to minimize a function

/$ Answers should be x1=.9999 and x2=.9999

b34sexec matrix;

* MAXF2 is used to minimize a function ;

* Answers should be x1=.9999 and x2=.9999 ;

call echooff;

call maxf2(func

:name inline('func=-1.0*(100.*(x2-x1*x1)**2.

+ (1.-x1)**2.);')

:parms x1 x2

:ivalue array(2:-1.2,1.0)

:print);

b34srun;

IDNINT - Converts from real*8 to integer*4 with rounding.



i4=idnint(r8);



Converts real*8 r8 to integer with rounding.



Example:



b34sexec matrix;

r8g=grid(.1,6.,.3);

i=integers(norows(r8g));

r4i= float(i);

r8i=dfloat(i);

i4idint=idint(r8g);

i4idnint=idnint(r8g);

i4fromr4=int(r4i);

r8dint=dint(r8g);

call names(all);

call tabulate(i,r4i,r8i,r8g,i4idint,i4idnint,

i4fromr4 r8dint);

b34srun;



IMAG - Copy imaginary part of complex*16 number into real*8.



r2=imag(cnumber);



Copies the imag part of complex number cnumber into

r2.



example:

b34sexec matrix;

xr=matrix(2,2:1 2 3 4);

xi=dsqrt(xr);

cc=complex(xr,xi);

call print(cc,real(cc),imag(cc));

b34srun;



INDEX - Define integer index vector.



This command does not allow inputs LE 0 if : is

present.



ii=index(1 2 3);



creates an integer array



ii=index(1 2 3:);



sets ii to the product of 1 2 3.



ii=index(4 5 6:1 2 3);



creates a pointer to the 1 2 3 element of

a 4 by 5 by 6 array.



Example:



b34sexec matrix;

xx=index(1,2,3,4,5,4,3);

call names(all);

call print(xx);



call print('Integer*4 Array ',index(1 2 3 4 5 4 3));

call print('# elements in 1 2 3 4 is 24',

index(2 3 4:));

call print('Position of 1 2 in a 4 by 4 is 5',

index(4 4:1 2):);



call print('Integer*4 Array ',

index(1,2,3,4,5 4 3));

call print('# elements in 1 2 3 5 is 30',

index(2,3,5:));

call print('Position of 1 3 in a 4 by 4 is 9',

index(4,4:1,3):);



* bigger example showing large matrix;



maxsize=index(4,5,6:);



xbig =array(maxsize:integers(maxsize));

call print(xbig);



ii2 =index(4,5,6:1 1 2);

subx=xbig(integers(ii2,ii2+20-1));

call print(subx);



b34srun;

INFOGRAPH - Obtain Interacter Graphics INFO



r=infograph(n);



n in range 1-14



1 => Current x plotting position

2 => Current y plotting position

3 => Current character width

4 => Current character height

5 => Mouse x position

6 => Mouse y position

7 => Left limit on graphics area

8 => lower limit on graphics area

9 => Right limit on main graphics area

10 => Upper limit on main graphics area

11 => Lower x co-ordinate limit

12 => Lower y co-ordinate limit

13 => Upper x co-ordinate limit

14 => Upper y co-ordinate limit

r is real*8



Note: This routine must be used on distinct

call graphp(:cont calls )



to me updated properly.



This routine has no use outside graphp.



INT - Copy real*4 to integer*4.



i4=int(r4);



Copy real*4 to integer.



Example:



b34sexec matrix;

r8g=grid(.1,6.,.3);

i=integers(norows(r8g));

r4i= float(i);

r8i=dfloat(i);

i4idint=idint(r8g);

i4idnint=idnint(r8g);

i4fromr4=int(r4i);

r8dint=dint(r8g);

call names(all);

call tabulate(i,r4i,r8i,r8g,i4idint,i4idnint,

i4fromr4 r8dint);

b34srun;



INTEGERS - Generate an integer vector with given interval.





i=integers(j);



Creates i = 1,...,j where j is an integer.



Alternative forms are:



integers(istart,iend,inc);



Examples:



integers(0,6,2); => {0 2 4 6}



integers(0,6) => {0 1 2 3 4 5 6}



INV - Inverse of a real*8 or complex*16 matrix.



y=inv(x);



Inverts x where X is a real*8 or complex*16 matrix. Real*16,

complex*32 and VPA data type (88, 888, 160 & 1600) are

supported for Linpack.



For VPA data



xx=inv(vpadata);



automatically produces %rcond and %det.



xx=inv(vpadata,rr); automatically places %rcond in rr.



inv( ) also supports the real*4 data type for purposes of

testing the accuracy of a real*4 calculation. The datatype

complex*8 is not supported. Users should use complex*16 or

complex*32. The real*4 data type is not recommended for

calculations that are used in a serious application.



Alternative calls are:



y=inv(x,rcond);

y=inv(x,rcond:key);

y=inv(x:key);



Where key = GMAT

SMAT

PDMAT

PDMAT2

REFINE

REFINEE

FORCEGM

FORGEPD



GMAT => General matrix (default).

Uses LINPACK DGECO-DGEDI or

ZGECO-ZGEDI

If GMAT is present, LAPACK is used.

DGETRF-DGECON-DGETRI or

ZGETRF-ZGECON-ZGETRI

This is a change over the pre 8.67D

release.

SMAT => Symmetric matrix. Uses LINPACK

DSICO-DSIDI or ZSICO-ZSIDI

PDMAT => Positive Definate matrix use LINPACK

dpoco-dpodi, or zpoco-zpodi.

PDMAT2 => Positive Definate matrix use LAPACK.

DPOTRF-DPOCON-DPOTRI or

ZPOTRF-ZPOCON-ZPOTRI

REFINE => Refine General matrix solution

using LAPACK DGESVX and ZGESVX.

This will take much more space and

time and is usually not needed.

REFINEE => Equlibrates matrix.

FORCEGM => Tries to invert matrix even in

case where condition test not met.

This option can bring down the B34S.

It is intended to be used for

accuracy testing for extream cases.

LINPACK is used. Warning message

given.

FORCEPD => Tries to invert matrix even in

case where condition test not met.

This option can bring down the B34S.

It is intended to be used for

accuracy testing for extream cases.

LIMPACK is used. If matrix not PD,

then will stop. Warning message

given.



Example # 1:



/$ This job does not print very much n can be increased

b34sexec matrix;

n=4; x=rn(matrix(n,n:)); x=transpose(x)*x;

t1=(1.0/x); t2=inv(x);

test1=x*t1; test2=x*t2;

* Test how well we did ;

call print('dmax( (matrix(n,n:)+1.)- (x*t1) )',

dmax( (matrix(n,n:)+1.) - (x*t1) ),

'dmax( (matrix(n,n:)+1.)- (x*t2) )'

dmax( (matrix(n,n:)+1.)- (x*t1) ) );

cx=complex(x,2.*x);

ct1=(complex(1.0,0.0)/cx); ct2=inv(cx);

ctest1=cx*ct1; ctest2=cx*ct2;

call print(ct1,ct2,ctest1,ctest2);

b34srun;



Example # 2:



/$ Job illustrates inverse of PDMATRIX 4 ways

b34sexec matrix;

n=4; x=rn(matrix(n,n:)); x=transpose(x)*x;

t1=(1.0/x); t2=inv(x);

test1=x*t1; test2=x*t2;

cx=mfam(complex(afam(x),dsqrt(dabs(afam(x)))));

scx=transpose(cx)*cx;

cx=dconj(transpose(cx))*cx;

ct1=(complex(1.0,0.0)/cx); ct2=inv(cx);

ctest1=cx*ct1; ctest2=cx*ct2;

call print(x,t1,t2,cx,ct1,ct2,ctest1,ctest2);

t2a=inv(x:smat);t2b=inv(x:pdmat);

call print(t1,t2,t2a,t2b);

ct2a=inv(scx:smat);

tct2a=complex(1.0,0.0)/scx;

ct2b=inv(cx:pdmat);

call print(cx,ct1,ct2,ct2b);

call print(

'Note that Complex Symmetric matrix NE PD Complex');

call print(scx,ct2a,tct2a);

b34srun;



Note: The INV( ) command uses LINPACK due to the fact that

most problems are under 150 by 150. The LAPACK LU factorization

code has been implemented in the commands call gmfac( );

call gminv( ); and call gmsolv( ); .



Speed differenves can be seen by running the job gminv_2 and

gminv_3. The gminv_3 job is listed next



b34sexec matrix;

* At 150 LINPACK is faster ;

* At 300 and 600 LAPACK wins ;

* For this reason the inv( ) command uses LINPACK;

n=150;

call print('size ',n);

x=rn(matrix(n,n:));



call timer(t1);

xx=inv(x);

call timer(t2);

call print('GM time',t2-t1);

call compress;



call timer(t1);

call gminv(x,xx);

call timer(t2);

call print('LAPACK',t2-t1);

call compress;



n=300;

call print('size ',n);

x=rn(matrix(n,n:));



call timer(t1);

xx=inv(x);

call timer(t2);

call print('GM time',t2-t1);

call compress;



call timer(t1);

call gminv(x,xx);

call timer(t2);

call print('LAPACK',t2-t1);

call compress;



n=600;

call print('size ',n);

x=rn(matrix(n,n:));

call timer(t1);

xx=inv(x);

call timer(t2);

call compress;

call print('GM time',t2-t1);

call timer(t1);

call gminv(x,xx);

call timer(t2);

call print('LAPACK',t2-t1);



b34srun;



INVBETA - Inverse beta distribution.



x=invbeta(x1,x2,x3);



Inverse of beta distribution x1 is probability.



Example:



b34sexec matrix;

* Sample problem from IMSL page 915 ;

pin= 12.0;

qin= 12.0;

p = .9 ;

test=invbeta(p,pin,qin);

call print('X is less than ',p,' with probability

',test,

'Answer should be .6299');

b34srun;



INVCHISQ - Inverse Chi-square distribution.



x=invchisq(x1,x2);



Inverse chi-squared.

0 le x1 le 1.0.

.5 le x2 200000



Example:



b34sexec matrix;

* Sample problem from IMSL page 921 ;

df1 = 2.0;

p = .99 ;

test1=invchisq(p,df1);

df2 = 64.;

test2=invchisq(p,df2);

call print('The ',p,

' percentage point of Chi-square with df ',df1,test1,

'Answer should be 9.210'

'The ',p,

' percentage point of Chi-square with df ',df2,test2,

'Answer should be 93.217');

b34srun;





INVFDIS - Inverse F distribution.

x=invfdis(x1,x2,x3);



Inverse F distribution



x1 = probability (in range 0.0 1.0)



x2 = df numerator (gt 0.0)



x3 = df denominator (gt 0.0)



Example:



b34sexec matrix;

* IMSL page 927 ;

p=.99;

dfn=1.;

dfd=7.0;

f=invfdis(p,dfn,dfd);

call print('F(1,7) critical value at .01 is GE ',f,

'Answer should be 12.246');

n1=100; n2=10;

ftab=array(n1,n2:);

call echooff;

do i=1,norows(ftab);

do j=1,nocols(ftab);

ftab(i,j)=invfdis(.95,dfloat(i),dfloat(j));

enddo;

enddo;

call print('F table at 95% probability',ftab);

b34srun;



INVTDIS - Inverse t distribution.



x=invtdis(x1,x2)$



Inverse t distribution



x1 = probability



x2 = df (gt 0.0)



Note: the 95 confidence interval for 100000

observations



t=invtdis(.975,100000.);



probit(.975) & invtdis(.975,1000000.)



produce same value





Example:

b34sexec matrix;

p=.950;

df=6.;

t=invtdis(p,df);

call print('The two sided t(',df,') value is ',t,

'Correct value should be 2.447');



n=100;

pval=array(4:.975 .95,.90,.85);

tval=array(n,norows(pval):);

call echooff;

do j=1,norows(pval);

do i=1,n;

df=dfloat(i);

tval(i,j)=invtdis(pval(j),df);

enddo;

enddo;

at975=tval(,1);

at95 =tval(,2);

at90 =tval(,3);

at85=tval(,4);

df=integers(n);

call tabulate(df,at975,at95,at90,at85);

b34srun;



IQINT - Converts from real*16 to integer*4.



i=iqint(r16);



Example:





b34sexec matrix;

r16g=r8tor16(grid(.1,6.,.3)) ;

i=integers(norows(r16g));

r4i =float(i);

r16i=qfloat(i) ;

i4iqint=iqint(r16g) ;

i4iqnint=iqnint(r16g) ;

i4fromr4=int(r4i) ;

r16qint=qint(r16g) ;

r16qnint=qnint(r16g) ;

call names(all) ;

call tabulate(i,r4i,r16i,r16g,i4iqint,i4iqnint,

i4fromr4 r16qint r16qnint);

b34srun;



IQNINT - Converts from real*16 to integer*4 with rounding.



i=iqnint(r16);



Example:

b34sexec matrix;

r16g=r8tor16(grid(.1,6.,.3)) ;

i=integers(norows(r16g));

r4i =float(i);

r16i=qfloat(i) ;

i4iqint=iqint(r16g) ;

i4iqnint=iqnint(r16g) ;

i4fromr4=int(r4i) ;

r16qint=qint(r16g) ;

r16qnint=qnint(r16g) ;

call names(all) ;

call tabulate(i,r4i,r16i,r16g,i4iqint,i4iqnint,

i4fromr4 r16qint r16qnint);

b34srun;



ISMISSING - Sets to 1.0 if variable is missing



i=ismissing(x);



- i=0 if x not missing, =1 is missing



IWEEK - Sets 1. for monday etc.



xnew=iweek(juldate);



Sets xnew =1 for Monday etc



See extensive example file that tests for Y2K etc.

JULDAYDMY - Given day, month, year gets julian value.



juldate=juldaydmy(day,month,year);



Gets julday from day, month, year



See extensive example file for this command.

JULDAYQY - Given quarter and year gets julian value.



juldate=juldayqy(quarter,year);



Gets julday from Qt / year



See extensive example file for this command.



JULDAYY - Given year gets julian value.



juldate=juldayy(year);



Gets julday from year



See extensive example file for this command.



KEEPFIRST - Given k, keeps first k observations.



newy=keepfirst(y,n);

Keeps first n observations.



Note: this is the same as



newy=droplast(y,(norows(y)-n));



Example:



b34sexec matrix;

n=10;

maxlag=2;

x=array(n:integers(n));

lag1x=lag(x,1:nomiss);

lag2x=lag(x,2:);

last2=keeplast(x,2);

first2=keepfirst(x,2);

dropl2=droplast(x,2);

dropf2=dropfirst(x,2);

call

tabulate(x,lag1x,lag2x,last2,first2,dropl2,dropf2);

b34srun;



KEEPLAST - Given k, keeps last k observations.



newy=keeplast(y,n);



Keeps last n observations.



Note: this is the same as



newy=dropfirst(y,(norows(y)-n));



Example:



b34sexec matrix;

n=10;

maxlag=2;

x=array(n:integers(n));

lag1x=lag(x,1:nomiss);

lag2x=lag(x,2:);

last2=keeplast(x,2);

first2=keepfirst(x,2);

dropl2=droplast(x,2);

dropf2=dropfirst(x,2);

call

tabulate(x,lag1x,lag2x,last2,first2,dropl2,dropf2);

b34srun;



KIND - Returns kind of an object in integer.



kindx=kind(x);



Gets kind of x. Kind is coded:

character*1 = -1

integer = -4

real*4 = 4

real*8 = 8

real*16 =-16

complex*16 = 16

complex*32 = 32

program = 1

subroutine = 2

function = 3

character*8 = -8

formula = 33

not defined = 0



Example:



b34sexec matrix;

x=rn(matrix(3,3:));

ii=idint(2.0);

cc=complex(1.2,3.3);

call print(kind(x), kind(ii),kind(cc),

klass(x),klass(ii),klass(cc));

b34srun;



Note: The commands kind, klass, norows, nocols and

noels are especially useful in checking arguments

to functions or subroutines





KINDAS - Changes kind of argument 2 to kind argument one.



one=kindas(x,1.0);



If x is real*8, one is real*8. If x is real*16

one will be real*16.



Arguments can only be real*8 or real*16. The purpose

of this command is to be able to put constants in

code that will run as real*8 or real*16.



Example:



b34sexec matrix;

x=10.;

one1=kindas(x,1.0);

one2=kindas(r8tor16(x),1.0);

call names(all);

b34srun;

KPROD - Kronecker product



x=kprod(a,b);



calculates the Kronecker product of a and b.

a = K by L matrix



b = m by n matrix



x = K*m by L*m result



Example:

b34sexec matrix;

* Example from Greene (2000) page 35;

a=matrix(2,2:3 0 5 2);

b=matrix(2,2:1 4 4 7);

x=kprod(a,b);

call print('Answer matrix(2,2: 3*b , 0*b ',

' 5*b , 2*b)' );

call print(a,b,x);

* Complex case;

aa=complex(a,-1.*dsqrt(a));

bb=complex(b,-1.*dsqrt(b));

cx=kprod(aa,bb);

call print(aa,bb,cx);

* Matlab 11-1 case;

x=matrix(2,2:1. 2. 3. 4.);

y=matrix(2,2:)+1.;

call print(x,y,kprod(x,y),kprod(y,x));

b34srun;

KLASS - Returns klass of an object in integer.



klassx=klass(x);



Gets klass of x. Klass is coded:



scalar = 0

vector = 1

matrix = 2

1 dim array = 5

2 dim array = 6



Example:



b34sexec matrix;

x=rn(matrix(3,3:));

ii=idint(2.0);

cc=complex(1.2,3.3);

call print(kind(x), kind(ii),kind(cc),

klass(x),klass(ii),klass(cc));

b34srun;





Note: The commands kind, klass, norows, nocols and

noels are especially useful in checking arguments

to functions or subroutines



LABEL - Returns label of a variable.

labelx=label(x);



Gets label for x. Saved in character*8

array with 5 terms.



b34sexec matrix;

short=10.;

long= 20;

call names;

call setlabel(short,'test');

call setlabel(long, 'This is a long label');

call names;

call print('Label for long' ,label(long),

'Label for short',label(short));

b34srun;





LAG - Lags variable. Missing values propagated.





y=lag(x,i);



lags x i periods. i can be > or ( x matrix set by OLSQ

%res => Set by OLSQ. if 0.0 passed assumes uu'=1

%lag => Variable Lags. Set by user

%damp => Causes expression to be multiplied by

[(L+1-abs(k))/(L+1)]**damp where L is mag lag

ifsquare => =0 uses u'u. ne 0 uses u. Note that if

ifsqrate ne 0 => cannot set lag > 0.







Example



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

/; Use to test if call mcovf

/; call load(mcovf :staging);

call olsq(gasout gasin :savex);



call print('usual case no lag',mcov(%x,%res,0,0.0,0));

call print('usual case v ',mcov(%x,%res,0,0.0,1));

call print('no residual ',mcov(%x,0.0 ,0,0.0,0));

call print('no residual lag=3',mcov(%x,0.0 ,3,0.0,0));

call print('lag = 1 ',mcov(%x,%res,1,0.0,0));

call print('lag = 3 ',mcov(%x,%res,3,0.0,0));

call print('lag = 2 damp=1. ',mcov(%x,%res,2,1.0,0));

b34srun;



MEAN - Average of a 1d object.



mean=mean(x);



Mean of object x. x must be Real*8.



Example:



b34sexec options ginclude('gas.b34')$

b34srun$

b34sexec matrix;

call loaddata;

mgasin=mean(gasin);

mgasout=mean(gasout);

call print('Gasin Mean',mgasin);

call print('Gasout Mean',mgasout);

vgasin=variance(gasin);

vgasout=variance(gasout);

call print('Gasin Variance',vgasin);

call print('Gasout Variance',vgasout);

b34srun$





MFAM - Set 1d or 2d array to vector or matrix.



x=mfam(y);



Creates a vector or matrix from array y.

By changing the klass of an object the

math operations change.



Example - Create a matrix from a 2D array:



b34sexec matrix$

x=rn(array(3,3:));

call print(x);

mx=mfam(x);

call print(mx);

b34srun;



MISSING - Returns missing value.

x=missing();



Sets x(1) to missing. To set all x values to missing.



x=missing(x);



Missing data is only supported for real*8 data.

For arrays, +, -, * / and ** calculations will trap

missing data. For vector and matrix calculations,

+ and - calculations trap missing data.

Matrix inverse and product calculations donot trap

missing data. Users are encouraged to use the commands

goodrow and goodcol to adjust matrix and vector data.



Example:



b34sexec matrix;

x=0.0; xmiss=missing(); call print(x,xmiss);

y=grid(1.,20.,1.); oldy=y;



do i=1,norows(y);

if(dmod(y(i),2.).eq.0.0)y(i)=missing();

enddo;



test=ismissing(y);

call tabulate(oldy,y,test);

b34srun;



MLSUM - Sums log of elements of a 1d object.



func=mlsum(x);



Sums the log of the elements of x.

if x LE 0.0, then -700 is added.

Alternative arguments are



func=mlsum(x,n,add);



n = # of bad cases.



add = what to add in bad cases.



Default = -700.



Other optional arguments include



:dlog10 to use log10 in place of ln



:dexp to use dexp. In this case any value > 174.673

is

set dexp(174.673)

Note: mlsum is useful in ML estimation and in cases

where

range testing for dlog10, dlog and dexp is

needed.



Example:



b34sexec matrix;

* mlsum useful in ML estimation ;

* Can also be used to trap bad dlog values ;

a=array(5:1 2 3 4 5);

s=sum(dlog(a));

call print('Sum of log of 1 2 3 4 5',s,

'MLSUM',mlsum(a));

a(2)=-10.;

s2=mlsum(a,n);

call print('Sum of bad data ',s2,' # bad cases ',n);

s2=mlsum(a,n,0.0);

call print('Sum of bad data using zero ',s2,

' # bad cases ',n);



* log 10 cases ;

a=array(5:1 2 3 4 5);

s=sum(dlog10(a));

call print('Sum of log10 of 1 2 3 4 5',s,'MLSUM',

mlsum(a :dlog10));

a(2)=-10.;

s2=mlsum(a,n:dlog10);

call print('Sum of bad data ',s2,

' # bad cases ',n);

s2=mlsum(a,n,0.0:dlog10);

call print('Sum of bad data using zero ',s2,

' # bad cases ',n);



* dexp cases ;

a=array(5:1 2 3 4 5);

s=sum(dexp(a));

call print('Sum of log of 1 2 3 4 5',s,

'MLSUM',mlsum(a :dexp));

a(2)=800d+00;

s2=mlsum(a,n :dexp);

call print('Sum of bad data ',s2,' # bad cases ',n);

s2=mlsum(a,n,0.0:dexp);

call print('Sum of bad data using zero ',s2,

' # bad cases ',n);



b34srun$





MOVELEFT - Moves elements of character variable left.



chxnew=moveleft(charvar,n)$



charvar moved left n. n must be integer.

Example:



b34sexec matrix;

call character(cc2,'abcdefghijklmnop');

test='12345678';

call print(test,'right 4',moveright(test,4),'left 3',

moveleft(test,3));

do i=1,10;

newcc2=moveleft(cc2,i);

call print('Moveleft',cc2,i,newcc2);

enddo;

do i=1,10;

newcc2=moveright(cc2,i);

call print('Moveright',cc2,i,newcc2);

enddo;

b34srun;





MOVERIGHT - Move elements of character variable right.





chxnew=moveright(charvar,n)$



charvar moved right n. n must be integer



Example:



b34sexec matrix;

call character(cc2,'abcdefghijklmnop');

test='12345678';

call print(test,'right 4',moveright(test,4),'left 3',

moveleft(test,3));

do i=1,10;

newcc2=moveleft(cc2,i);

call print('Moveleft',cc2,i,newcc2);

enddo;

do i=1,10;

newcc2=moveright(cc2,i);

call print('Moveright',cc2,i,newcc2);

enddo;

b34srun;



NAMELIST - Creates a namelist.



n=namelist(name1 name2);



Creates a name list in n. The command



n=namelist(x1 x2 x3);



puts names in n(1) ... n(3).



The commands:

w=array(3:100.,120.,130.);

n=namelist(Sue,Jane,Diana);

call tabulate(n,w);



will print the names and weights of three people.



NCCHISQ - Non central chi-square probability.



x=ncchisq(x1,x2,x3);



Non central chi-square

x1 = variable (ge 0.0) for which to calculate

probability

x2 = degress of freedom (ge .5)

x3 = non centratity (5 le (x2+x3) le 200000)



Example:



b34sexec matrix;

* Test problem from IMSL page 923 ;

chsq=8.642; df=2.0; alam=1.0;

p=ncchisq(chsq,df,alam);

call print(

'Prob. that a noncentral chi-square random var. with',

'DF and noncentrality ',df,alam,' is less than ',

chsq,' is ',p,' Answer should be .950');

b34srun;



NEAREST Nearest distinct number of a given type



nx=nearest(x,z);



Nearest distinst number in the direction on infinity

with the same sign as z.



nx=nearest(x);



can be given in place of



nx=nearest(x,1.0);



x and z can be real*4 or real*8. Z does not have to

be same size as x.



Example:



b34sexec matrix;

i=1;

x=1.;

y=sngl(x);

call print('Largest integer ',huge(i):);

call print('Largest real*4 ',huge(y):);

call print('Largest real*8 ',huge(x):);

call print('Smallest real*4 ',tiny(y):);

call print('Smallest real*8 ',tiny(x):);

call print('Epsilon real*4 ',epsilon(y):);

call print('Epsilon real*8 ',epsilon(x):);



x=.1d+00;

y=sngl(x);

j=1;

call echooff;

do i=1,1000,100;

x=x*dfloat(i);

y=float(i)*y ;

spx(j)=spacing(x);

spy(j)=spacing(y);

nearpr8(j)=nearest(x, 1.);

nearmr8(j)=nearest(x,-1.);

nearpr4(j)=nearest(y, 1.);

nearmr4(j)=nearest(y,-1.);

testnum(j)=x;

j=j+1;

enddo;



call print('Spacing for Real*8 and Real*4');

call tabulate(testnum,spx,spy,nearpr8,nearmr8,

nearpr4,nearmr4);



call names(all);

call graph(testnum,spx :plottype xyplot

:heading 'Spacing');



g=grid(1000.,10000.,1000.);

nl=nearest(g,-1.);

nu=nearest(g,1. );

diff=nu-nl;

call tabulate(g,nl,nu,diff);



b34srun;



NOCOLS - Gets number of columns of an object.



nc=nocols(x);



Determines the number of cols of x and

saves as an integer.



Example:



b34sexec matrix;

i=integers(1,20);

x=rn(matrix(5,6:));

call print(norows(i),norows(x),

nocols(i),nocols(x),

noels(i), noels(x));

b34srun;

Note: The commands kind, klass, norows, nocols and

noels are especially useful in checking arguments

to functions or subroutines



NOELS - Gets number of elements in an object.





nel=noels(x);



Determines number of elements in x and

saves as an integer



Example:



b34sexec matrix;

i=integers(1,20);

x=rn(matrix(5,6:));

call print(norows(i),norows(x),

nocols(i),nocols(x),

noels(i), noels(x));

b34srun;



Note: The commands kind, klass, norows, nocols and

noels are especially useful in checking arguments

to functions or subroutines



NORMDEN - Normal density.



x=normden(xold);



Sets x = densitity of normal at xold.

x = dexp(-1.*z*z/2)/dsqrt(2*pi)



Example:



b34sexec matrix$

z=grid(-4.5,4.5,.01);

prob=probnorm(z);

den=normden(z);

call tabulate(z,prob,den);

call graph(prob,den

:htitle 1.5 1.5

:heading ' Normal Probabily and

Density');

b34srun;



NOROWS - Gets number of rows of an object.



nr=norows(x);



Determines the number of rows of x and

saves as an integer.

b34sexec matrix;

i=integers(1,20);

x=rn(matrix(5,6:));

call print(norows(i),norows(x),

nocols(i),nocols(x),

noels(i), noels(x));

b34srun;



Note: The commands kind, klass, norows, nocols and

noels are especially useful in checking arguments

to functions or subroutines



NORMDIST - 1-norm, 2-norm and i-norm distance.



x=normdist(x,y,1);

x=normdist(x,y,2);

x=normdist(x,y);



compute the 1-norm, 2-norm and i-norm distance

between vectors x and y.



1-norm => sum dabs(x(i)-y(i))

2-norm => sqrt( sum((x(i)-y(i))**2)

i-norm => max dabs(x(i)-y(i))



x = 1d array # 1

y = 1d array # 2

Arg3 = 1 => 1-norm

2 => 2-norm

ne 1 and ne 2 or not present => i-norm



Example:



b34sexec matrix;

x=array(:1.,-1.,0.0, 2.);

y=array(:4., 2.,1. ,-3.);

call tabulate(x,y);

call print('1-norm ',normdist(x,y,1));

call print('2-norm ',normdist(x,y,2));

call print('i-norm ',normdist(x,y) );

call print(' ');

call print('answers should be 12., 6.63325 and 5.0');

b34srun;

NOTFIND - Location where a character is not found.



int =notfind(charvar,' ')$



Location where ' ' not found.

Only one char is specified.



Example:



b34sexec matrix;

* note that namelist makes all names upper case;

cc=namelist(mary sue aron);

nota =notfind(cc,'a');

nota2=notfind(cc,'A');

call tabulate(nota,cc,nota2);

call character(cc2,'abcdefghijklmnop');

call print('Where is a not?',cc2,notfind(cc2,'a'));

b34srun;



See command find.



OBJECT - Put together character objects.



nn=object(nn1 nn2 nn3);



Puts together objects.



Example assuming



X='Y';



nn=object(x,1);



places Y1 in nn.



nn2=object(x,'A');



places YA in nn2.



PDFAC - Cholesky factorization of PD matrix.





r=pdfac(x);



Performs Cholesky decomposition of positive

definite matrix x.



x=transpose(r)*r;



For complex case



x=conj(transpose(r))*r;



Optionally be called as



r=pdfac(x,rcond);



r=pdfac(x,rcond,ibad);



ibad set ne 0 if problems



Example:



b34sexec matrix;

* Problem from 'Applied Numerical Analysis using

Matlab';

* by Laurene Fausett page 174;

a=matrix(3,3:1. 4. 5.

4. 20. 32.

5. 32. 64.);

call print(a, pdfac(a));

n=4;x=rn(matrix(n,n:));pdx=transpose(x)*x;

r=pdfac(pdx);

call print('Positive Definite Matrix',pdx,

'Factorization',r,

'Test if the Factorization was OK',

'transpose(r)*r',

transpose(r)*r,

' ','Complex Case');

cpdx=complex(pdx,mfam(dsqrt(dabs(pdx))));

cpdx=dconj(transpose(cpdx))*cpdx;

cr=pdfac(cpdx);

i=integers(norows(cpdx));

cpdx(i,i)=complex(real(cpdx(i,i)),0.0);

call print('Positive Definite Matrix',cpdx,

'Factorization', cr,

'Test if the Factorization was OK',

'dconj(transpose(cr))*cr',

dconj(transpose(cr))*cr,' ');

r=pdfac(pdx,r1);cr=pdfac(cpdx,r2);

call print(' ',

'Condition of Real Matrix ',r1,

' ',

'Condition of Complex Matrix',r2);

* Problem from Introduction to Scientific Computing by

Charles VN Loan (page 242 ;

test=matrix(3,3: 4.,-10., 2.,

-10., 34.,-17.,

2.,-17.,18. );

call print(test);

p=pdfac(test);

call print(p);

call print('Validate ',transpose(p)*p);

b34srun;





PDFACDD - Downdate Cholesky factorization.



newr=pdfacdd(r,x);



Downdates the factorization of a positive definite

matrix by removing the row x. An alternative and

slower method would be to use pdfac on newa.



newa = a -(x*transpose(x));

newr=pdfac(newa);



pdfacdd can be called as

newr=pdfacdd(r,x,ibad);



ibad set ne 0 if a problem.



Example:



b34sexec matrix;

* IMSL # 10 Page 274;

a=matrix(3,3:10., 3., 5. ,

3., 14., -3. ,

5., -3., 7. );

x=vector(3:3.0 ,2.0 , 1.0);

b=vector(3:53.0,20.0,31.0);

fac=pdfac(a);

call print(a,fac);

call print('Solve system ',pdsolv(fac,b));

newfac=pdfacdd(fac,x);

call print('New Factorization',newfac);

call print('Solve New system ',pdsolv(newfac,b));

b34srun;





PDFACUD - Update Cholesky factorization.



newr=pdfacud(r,x);



Updates the factorization r of a positive definite

matrix after a new row x has been added.

An alternative and slower method would be to use

pdfac on newa. For example:



newa = a +(x*transpose(x));

rewr=pdfac(newa);



Example:



b34sexec matrix;

* IMSL # 10 Page 271;

a=matrix(3,3:1., -3., 2. ,

-3., 10., -5. ,

2., -5., 6.0);

x=vector(3:3.0 ,2.0 , 1.0);

b=vector(3:53.0,20.0,31.0);

fac=pdfac(a);

call print(a,fac);

call print('Solve system ',pdsolv(fac,b));

newfac=pdfacud(fac,x);

call print('New Factorization',newfac);

call print('Solve New system ',pdsolv(newfac,b));

b34srun;





PDINV - Inverse of a PD matrix.

inv=pdinv(r);



Calculates the inverse of a positive definate

matrix factored into r.



Optionally can be called as



inv=pdinv(r,det);



Example:



b34sexec matrix;

n=4;x=rn(matrix(n,n:));pdx=transpose(x)*x;

r=pdfac(pdx);inv=pdinv(r);

call print('Positive Definite

Matrix',pdx,'Factorization',

r,'Inverse ',inv,

'Inverse using MATRIX math',(1.0/pdx),

'Test if inverse was OK',

inv*pdx,' ','Complex Case');

cpdx=complex(pdx,mfam(dsqrt(dabs(pdx))));

cpdx=dconj(transpose(cpdx))*cpdx;

i=integers(norows(cpdx));

cpdx(i,i)=complex(real(cpdx(i,i)),0.0);

cr=pdfac(cpdx); cinv=pdinv(cr);

call print('Positive Definite

Matrix',cpdx,'Factorization',

cr,'Inverse ',cinv,

'Inverse using MATRIX

math',(complex(1.0)/cpdx),

'Test if inverse was OK',

cinv*cpdx,' ');

inv1=pdinv(pdfac(pdx),d1);inv2=pdinv(pdfac(cpdx),d2);

call print('Determinate of pdx ',d1,

'Determinate of cpdx',d2);

call print('Determinate of pdx using det(pdx)

',det(pdx),

'Determinate of cpdx using

det(cpdx)',det(cpdx));

b34srun;



PDSOLV - Solution of a PD matrix given right hand side.



a=pdsolv(r,b);



Solves symmetric linear system a*x=b.



PDFAC is used to factor x into r. The right hand

side can be a vector or a matrix.



Example:



b34sexec matrix;

n=4;x=rn(matrix(n,n:));pdx=transpose(x)*x;

r=pdfac(pdx); v = rn(vector(norows(pdx):));

ans=pdsolv(r,v);

call print('Positive Definite

Matrix',pdx,'Factorization',

r,'Right hand side',v

'Solution ',

'pdsolv(pdfac(pdx),v)',

pdsolv(pdfac(pdx),v)

'test of solution'

(1.0/pdx)*v,

' ','Complex Case');

cpdx=complex(pdx,mfam(dsqrt(dabs(pdx))));

cpdx=dconj(transpose(cpdx))*cpdx;

i=integers(norows(cpdx));

cpdx(i,i)=complex(real(cpdx(i,i)),0.0);

cr=pdfac(cpdx); cv=complex(v,2.0*v);

ans=pdsolv(cr,cv);

call print('Positive Definite

Matrix',cpdx,'Factorization',

cr,'Right hand side',cv

'Solution ',

'pdsolv(pdfac(cpdx),cv)',

pdsolv(pdfac(cpdx),cv),

'test of solution',

(complex(1.0)/cpdx)*cv);

b34srun;



PI - Pi value.



x=pi();



Sets x(1) to pi. To set all all values of x to pi



x=pi(x);



Example:



b34sexec matrix;

x=pi();

y=array(4:);

y=pi(y);

call print(x,y);

b34srun;





PINV - Generalized Inverse



ginv=pinv(x);



calculates the generalized inverse of x.



x = m by n matrix.

Optional calls are:



ginv=pinv(x,irank);





ginv=pinv(x,irank,toll);



where:



irank = an estimate of the rank of x



toll = tolerance that is used to set the singular

values to zero.



At present pinv works for a real*8 matrix x.



IMSL routine DLSGRR is used for the calculation.



Assume x is n by p



The Generalized inverse of A is



V(k) * inv(s) * transpose(U(k))



where there are k non zero singular values.



If the generalized inverse is need for a complex

matrix, the SVD command can be used.





Example:



b34sexec matrix;

* IMSL example ;

a=matrix(3,2:1., 0., 1., 1., 100.,-50.);

ginv=pinv(a);

call print(a,ginv);

* Test with a full rank system;

n=5;

xx=rn(matrix(n,n:));

inv1=inv(xx);

inv2=pinv(xx,rank);

call print(rank,xx,inv1,inv2,xx*inv1,xx*inv2);

b34srun;





PLACE - Places characters inside a character array.



chxnew=place(charvar,i,j)$



Works the same as the fortran statement



chxnew(i:i+j-1)=charvar(1:j-i+1)

i, j must be integer. Blanks are placed in 1:i-1.



If optional argument cold is present, the old data in

cold is first copied before the new data is moved.



chnew=place(charvar,i,j,cold);



The results are as if the fortran statements



chxnew=cold

chxnew(i:i+j-1)=charvar(1:j-i+1)



had been used.





Example:



b34sexec matrix;

call character(cc2,'abcdefghijklmnop');

do i=1,10;

j=10;

newc=extract(cc2,i,j);

call print(cc2,i,j,newc);

enddo;

do i=1,8;

newc=place(cc2,1,i);

call print(cc2,newc,i);

enddo;



/$ Tests 4th argument



call character(cc2,'abcdefghijklmnop');

call character(cc3,'1234567890987654');

do i=1,8;

newc=place(cc2,1,i,cc3);

call print(cc2,cc3,newc,i);

enddo;



name='Mary';

name2='Rho';

call names(all);

newname1=place(name2,6,8,name);

newname2=place('Sue',6,8,name);

call print(name,newname1,newname2);



b34srun;



POIDF - Evaluate Poisson Distribution Function



pr=poidf(k,theta);



evaluates the Poisson distribution function

where

k (integer) argument for poisson function



theta mean of possion distribution.



Example:



b34sexec matrix;

k=7;

theta=10.;

pr=poidf(k,theta);

call print('Evaluate Poisson Distribution Function':);

call print('Probability that X is LE 7 = ',pr:);

call print('Note: Answer should be .2202':);

b34srun;



POIPR - Evaluate Poisson Probability Function





pr=poipr(k,theta);



evaluates the Poisson probability function

where



k (integer) argument for poisson function



theta mean of possion distribution.



Example:



b34sexec matrix;

k=7;

theta=10.;

pr=poipr(k,theta);

call print('Evaluate Poisson Probability Function':);

call print('Probability that X is 7= ',pr:);

call print('Note: Answer should be .0901':);

b34srun;



POINTER - Machine address of a variable.



i=pointer(x);



Saves the absolute address of x. A variant



i= pointer(x,4);



gets the address for the 4th element.



The pointer command can be used with the subroutine

PCOPY

and is intended for expert users. PCOPY has no

internal

checking. A pointer that is not used correctly could

bring

down the system. The long term goal of the POINTER

capability is to allow movement of objects into DLL's

and

the ability to modify systems variables.



Example of use:



b34sexec matrix;

x=array(:integers(20));

newx=array(30:);

ip1=pointer(x);

ip2=pointer(newx);

call print('pointer(x)',ip1,'pointer(newx)',ip2);

call print(pointer(x,4));

* places x 1-10 in locations starting at 4 in newx;

call pcopy(10,pointer(x),1,pointer(newx,4),1,8);

call tabulate(x,newx);

* Character examples including dup copies ;

n=namelist(mary sue Diana);

nn=namelist(a b c d e);

nn2=nn;

* mary placed in 4 places ;

call pcopy(4,pointer(n),0,pointer(nn),1,-8);

call pcopy(3,pointer(n),1,pointer(nn2),1,-8);

call tabulate(n,nn,nn2);

b34srun;



POLYDV - Division of polynomials.



result =polydv(top,bot,nterms);



top = Top polynomial. Must set zero, order

term



bot = Bottom polynomial. Zero order term must

not be 0.0



nterms = Number of terms in result.



Example:



To calculate



1/(1-.9B)



Prove multiplier is 10



Express ARMA(1,1) in Pure MA and Pure AR form



b34sexec matrix;

top=1.0;

bot=array(2:1.0, -.9);

result=polydv(top,bot,20);

i=integers(20);

call tabulate(i,result);



call print('Prove Multiplier',

sum(polydv(top,bot,200)):);



/$ Get close to unit root by making ar1 = .99

/$ See effect on MA part of model. Adjust nterms



ar1=-.9;

ma1= .9;

nterms=40;

top=array(2:1.,ar1);

bot=array(2:1.,ma1);



call print(' (1-ar1*B)*y(t)=(1.-ma1*B)*e(t) ');

call print('AR1 = ',ar1);

call print('MA1 = ',ma1);

ar=polydv(top,bot,nterms);

ma=polydv(bot,top,nterms);

call print('arma(1,1) AR form ',ar);

call print('arma(1,1) MA form ',ma);

call graph(ar :heading 'arma(1,1) AR form ');

call graph(ma :heading 'arma(1,1) MA form ');



b34srun;



POLYMULT - Multiply two polynomials



result=polymult(a,b);



a - Polynomial

b - polynomial



result = a*b



Example:



b34sexec matrix;

a=array(2:1., .9);

b=array(3:1., -.4, .3);

c=polymult(a,b);

call print('(1+.9B)*(1.-.4B+.3B**2)',

'= (1.-.4B+.3B**2+.9B-.36B**2+.27B**3)',

'= (1.+.5B-.06B**2-.27B**3)',

a,b,c);

top=1.;

long=polydv(top,a,200);

test=polymult(long,a);

call print(test,long);

b34srun;



POLYROOT - Solution of a polynomial.



roots=polyroot(x);

Calculates roots of real*8 or complex*16 polynomial.



To solve x**2 -x-12=0 give command



root=polyroot(vector(3:-12,-1,1));



Example:



b34sexec matrix$

coef=array(3:-12.,-1.,1.);

roots=polyroot(coef);

call print('Tests Real Polynomial Solution'

'x**2-x-12=0',

coef,roots);

ccoefr=array(4:10., -8.,-3.,1. );

ccoefi=array(4:0.0, 12.,-6.,0.0);

ccoef=complex(ccoefr,ccoefi);

croots=polyroot(ccoef);

call print('Tests Complex Polynomial Solution'

'x**3-(3+6i)*x**2-(8-12i)*x+10.=0',

ccoef,croots);



* Big problem ;



n=30;

coef=rn(array(n:));

roots=polyroot(coef);

call print('Tests Large Real Polynomial Solution'

coef,roots);

ccoefi=rn(array(n:));

ccoef=complex(coef,ccoefi);

croots=polyroot(ccoef);

call print('Tests Large Complex Polynomial Solution'

ccoef,croots);



b34srun$



PROBIT - Inverse normal distribution.





x=probit(y);



Inverse normal of y. y must be in range [0,1].



x=probit(.975);



produces 1.9599664



probit(.975) & invtdis(.975,1000000.)



produce same value



Example:

b34sexec matrix;

n=20;

* Tests on rec distribution ;

test=rec(array(n:)); pp=probit(test);

call tabulate(test,pp);



test=array(:.1 .2 .3 .4 .5 .6 .7 .8 .9 .95 .99);

pp=probit(test);

call tabulate(test,pp);

b34srun;



PROBNORM - Probability of normal distribution.



y=probnorm(x);



Sets y to probability of normal distribution.



Example:



b34sexec matrix$

z=grid(-4.5,4.5,.01);

prob=probnorm(z);

den=normden(z);

call tabulate(z,prob,den);

call graph(prob,den

:htitle 1.5 1.5

:heading ' Normal Probabily and

Density');

b34srun;





PROBNORM2 - Bivariate probability of Nornal distribution.



p=probnorm2(x,y,rho);



Sets p to the probability that a bivariate normal

random

variable with zero mean and sd = 1 with correlation

RHO

takes a value less than or equal to X and less than or

equal to Y.



Example:



b34sexec matrix$

x=-2.0;

y=0.0;

rho=.90;

prob=probnorm2(x,y,rho);

call print('Probability ',prob);

x =array(:0.0 0.0 0.0);

y =array(:0.0 0.0 0.0);

rho=array(:0.0 1.0 .5);

prob=probnorm2(x,y,rho);

call tabulate(x,y,rho,prob);

b34srun;



PROD - Product of elements of a vector.



p=prod(x);



Product of elements of x.



Example:



b34sexec matrix;

x=vector(5:1 2 3 4 5);

call print(x,prod(x));

xx=rn(matrix(6,6:));

e=eigenval(xx);

call print('We note: Product of eigenvalues = det',

det(xx),prod(e));

call print('We note: Sum of eigenvalues = trace',

sum(e),trace(xx));

b34srun;





QCOMPLEX - Build complex*32 variable from real*16 inputs.



Build a complex*32 variable from two real*16 inputs



qcq=qcomplex(r8tor16(2.2),r8tor16(3.1));



Example:



b34sexec matrix;

r=.3;

ii=.4;

cc=complex(r,ii);

x=rec(matrix(4,4:));

cx =complex(x);

cx2=complex(x,dsqrt(dabs(x)));

call names;

call print(r,ii,cc,x,cx,cx2);

call print('real*16 cases ************************':);



r =r8tor16(r);

ii=r8tor16(ii);

cc=qcomplex(r,ii);

x=r8tor16(rec(matrix(4,4:)));

cx =qcomplex(x);

cx2=qcomplex(x,dsqrt(dabs(x)));

call names;

call print(r,ii,cc,x,cx,cx2);

b34srun;

QFLOAT - Convert integer*4 to real*16.

r8=qfloat(i);



Converts an integer i to real*16.



Example:





QINT - Extract integer part of real*16 number



r8=qint(r);



Places integer part of r in real*16 number r1.



Example:



r1=dint(r8tor16(3.0));

r2=dint(r8tor16(3.9));



puts 3.0 in r1 and r2.



Extended example. Note that for big numbers



r2=qint(r16);



will not fail but



r2=qfloat(iqint(r16));



may.



Example:





b34sexec matrix;

r16g=r8tor16(grid(.1,6.,.3)) ;

i=integers(norows(r16g));

r4i =float(i);

r16i=qfloat(i) ;

i4iqint=iqint(r16g) ;

i4iqnint=iqnint(r16g) ;

i4fromr4=int(r4i) ;

r16qint=qint(r16g) ;

r16qnint=qnint(r16g) ;

call names(all) ;

call tabulate(i,r4i,r16i,r16g,i4iqint,i4iqnint,

i4fromr4 r16qint r16qnint);

b34srun;





QNINT - Extract nearest integer part of real*16 number



r8=qnint(r);



Places integer part of r in real*16 number r1.

Example:



r1=qnint(r8tor16(3.0));

r2=qnint(r8tor16(3.9));

r3=qnint(r8tor16(3.9));



puts 3.0 in r1 and 4. in r2 and 3 in r3.



Extended example. Note that for big numbers



r2=qnint(r16);



will not fail but



r2=qfloat(iqnint(r16));



may.



Example:





b34sexec matrix;

r16g=r8tor16(grid(.1,6.,.3)) ;

i=integers(norows(r16g));

r4i =float(i);

r16i=qfloat(i) ;

i4iqint=iqint(r16g) ;

i4iqnint=iqnint(r16g) ;

i4fromr4=int(r4i) ;

r16qint=qint(r16g) ;

r16qnint=qnint(r16g) ;

call names(all) ;

call tabulate(i,r4i,r16i,r16g,i4iqint,i4iqnint,

i4fromr4 r16qint r16qnint);

b34srun;



QREAL - Obtain real*16 part of a complex*32 number.



r1=qreal(cnumber);



Copies the real part of complex number cnumber into

r1.



Example:



b34sexec matrix;

xr=matrix(2,2:1 2 3 4);

xi=dsqrt(xr);

cc=complex(xr,xi);

cc=c16tor32(cc);

call print(cc,qreal(cc),qimag(cc));

b34srun;

QRFAC - Obtain Cholesky R via QR method.



r=qrfac(x);



Factors the matrix x into the upper triangular

matrix R. This is more accurate than the PDFAC

routine. x can be real*8, real*16, complex*16 or

complex*32.



Optionally the arguments



r=qrfac(x,qr,pivot);



will obtain the qr and pivot info that can be

used with the qrsolve command.



QRFAC uses the LINPACK DQRDC and ZQRDC routines. For

real*16 and complex*32 these are qqrdc and cqqrdc

respectively.



Note that the R calculated from QRFAC operates on

X while the R from PDFAC operates on

transpose(x)*x. Also there may be sign

differences.



Example:



b34sexec matrix;

n=4; x=rn(matrix(n,n:)); pdx=transpose(x)*x;

r1=pdfac(transpose(x)*x);

r2=qrfac(x);

call print('Positive Definite Matrix',pdx,

'Factorization from pdfac',r1,

'Factorization from qrfac',r2,

'Test if the Factorization was OK',

'transpose(r1)*r1',

transpose(r1)*r1,

'transpose(r2)*r2',

transpose(r2)*r2,

' ','Complex Case');



cpdx2=complex(pdx,mfam(dsqrt(dabs(pdx))));

cpdx =dconj(transpose(cpdx2))*cpdx2;

cr1=pdfac(cpdx);

cr2=qrfac(cpdx2);

i=integers(norows(cpdx));

cpdx(i,i)=complex(real(cpdx(i,i)),0.0);

call print('Positive Definite Matrix',cpdx,

'Factorization from pdfac', cr1,

'Factorization from qrfac', cr2,

'Test if the Factorization was OK',

'dconj(transpose(cr1))*cr1',

dconj(transpose(cr1))*cr1,' ',

'dconj(transpose(cr2))*cr2',

dconj(transpose(cr2))*cr2,' ');

b34srun;



QRSOLVE - Solve OLS using QR.



b=qrsolve(qr,pivot,y,info);



solves the OLS problem y = XB + res



If the problem is not able to be solved,

info set ne 0 to the first zero pivot in

R.



QR and pivot calculated from QRFAC.



QRSOLVE uses the LINPACK DQRSL / ZQRSL routines. For

real*16 and complex*32 these are qqrsl / cqqrsl.



Variables created include



%QY = QY vector



%QTY = QTY vector



%RES = Residual vector



%YHAT = XB vector



Note that the olsq command uses the same logic.



If the system is not singular info=0



Example:



b34sexec options ginclude('b34sdata.mac')

member(theil);

b34srun;

b34sexec matrix;

call loaddata;

call olsq(ct ri rpt :print);

res1=%res;

yhat1=%yhat;

x=matrix(norows(ct),3:);

x(,1)=1.;

x(,2)=ri;

x(,3)=rpt;

x=mfam(x);

r=qrfac(x,qr,pivot);

beta=qrsolve(qr,pivot,ct,info);

call tabulate(%coef,beta);

call tabulate(%qy,%qry,%res,%yhat,res1,yhat1);

b34srun;

RANKER - Index array that ranks a vector.

i=ranker(x);



Creates index of elements of x in ascending order.

X must be real*8. The command



sortedx=x(ranker(x));



sorts x. To sort character data see CALL SORT command.



Example:



b34sexec matrix;

n=10;

v=rn(vector(n:));

r=ranker(v);

test=v(r);

call tabulate(v r v(r) test);

b34srun;



Example using call sort command:



b34sexec matrix;

n=10;

x=rn(array(n:));

sx=x;

call sort(x);

call tabulate(x,sx);

n=namelist(:sue ann bobby houston);

cn=n

call sort(cn);

call tabulate(n,cn);

call character(cc:'abcd12343210');

cc2=array(6,1:cc);

call print(cc,cc2);



call vocab(cb);

ccb=cb;

call sort(ccb);

call print(cb,ccb);



cfb=vocab();

ccfb=cfb;

call sort(ccfb);

call print(cfb,ccfb);



b34srun;



RCOND - 1 / Condition of Matrix



rc=rcond(x);



Calculates the condition of matrix x. Matrix x can

be real*8, real*16, complex*16 or complex*32.

Linpack routine DGECO, ZGECO, QGECO or CQGECO are

used.



Other data types supported include vpa type 88, 888,

160 and 1600. xinv=inv(vpadata) will automatically

produce %det and %rcond. Thus rcond(vpadata) is not

supported for vpa data.





Note that there are differences between the rcond

estimate calculated by LAPACK & LINPACK.



Example:



b34sexec matrix;

x=matrix(3,3:0.1 1. 2. 9. 8. 7. 5. 4. 0.2);

call print(x,inv(x),det(x),det(r8tor16(x)));

cx=complex(x,dsqrt(x));

call print(cx,inv(cx),det(cx),det(c16toc32(cx)));

call print(rcond(x),rcond(r8tor16(x)));

call print(rcond(cx),rcond(c16toc32(cx)));

b34srun;



REAL - Obtain real*8 part of a complex*16 number.



r1=real(cnumber);



Copies the real part of complex number cnumber into

r1.



Example:



b34sexec matrix;

xr=matrix(2,2:1 2 3 4);

xi=dsqrt(xr);

cc=complex(xr,xi);

call print(cc,real(cc),imag(cc));

b34srun;



REAL16 - Creates a real*16 variable from Character string



r16= real16('.9q+00');



Creates real*16 variable from Character string



b34sexec matrix;

r16= real16('.9q+00');

r16a=r8tor16(.9);

call print('R16', r16:);

call print('R16A' r16a:);

call print('Difference ',(r16a-r16):);

b34srun;

REC - Rectangular random number.



x=rec(x);

Fills object x with random rectangular numbers



Note: The default generators are the old

IMSL routines GGUBS and GGNML.

Under the OPTIONS command the

RECVER and RNVER commands can be

used to set other default generators.



The optional keyword :IMSL10 can be used

to force use of the IMSL Version 10 rectangular

generator without having to set RECVER. This allows

both generators to be used.



If : is present :IMSL10 is assumed.



Examples (RANDOM1 and RANDOM2) in matrix.max:



b34sexec matrix;

n=5;

c= rn(array(n:)); c2 = rn(vector(n:));

r =rec(array(n:)); r2 = rec(vector(n:));

call tabulate(c,c2,r,r2);

b34srun;



b34sexec matrix;

n=100000;

x=rn(array(n:));

x=x(ranker(x));

call graph(x :Heading '100,000 Random Normal

Numbers');

x=rec(array(n:));

x=x(ranker(x));

call graph(x :Heading '100,000 Rectangular Numbers');

b34srun;



RECODE - Recode a real*8 or character*8 variable



newx=recode(x,find,newx);



Looks for the value find in x and replaces it with

newx.





x = real*8, integer*4 or character*8 input

variable



find = value to replace



newx = value to put in x





Example

b34sexec matrix;

x = array(:1 2 3 0 6 0);

cx = namelist(test1 test2 test3 test4 test5);

xi = index(1 2 3 4 5 4 3);

newx =recode(x,0.0,missing());

newcx=recode(cx,'TEST2','new2');

newxi=recode(xi,4,99);

call tabulate(x,newx,cx,newcx,xi,newxi);

b34srun;

RN - Normally distributed random number.



x=rn(x);



Fills object x with random normal numbers.



Note: The default generators are the

IMSL routines GGUBS and GGNML.

Under the OPTIONS command the

RECVER and RNVER commands can be

used to set other default generators.



The optional keywords :DRNNOA and :DRNNOR can be

used to force use of the IMSL Version 10 Normal

accectance/rejection and inverse CDF generators

without setting RNVER. This allows both generators

to be used.



Examples (RANDOM1 and RANDOM2) in matrix.max:



b34sexec matrix;

n=5;

c= rn(array(n:)); c2 = rn(vector(n:));

r =rec(array(n:)); r2 = rec(vector(n:));

call tabulate(c,c2,r,r2);

b34srun;



b34sexec matrix;

n=100000;

x=rn(array(n:));

x=x(ranker(x));

call graph(x :Heading '100,000 Random Normal

Numbers');

x=rec(array(n:));

x=x(ranker(x));

call graph(x :Heading '100,000 Rectangular Numbers');

b34srun;



Illustrates resetting the seed to get same string.



b34sexec matrix;

call i_rnget(i);

call print('seed at start',i:);

x=array(8:);

call print(rn(x :drnnoa));

call i_rnget(j);

call print('seed now is ',j:);

call i_rnset(i);

call print(rn(x:drnnoa));

b34srun;



ROLLDOWN - Moves rows of a 2d object down.



newx=rolldown(x);



Moves rows of X down one.



Example:



b34sexec matrix;

n=10;

v=rn(vector(n:));

downv=rolldown(v);

call tabulate(v downv);

x=rn(matrix(5,5:));

call print('Illustrates Rolldown',x,rolldown(x));

x=rn(matrix(5,6:));

call print('Illustrates Rolldown',x,rolldown(x));

b34srun;



ROLLLEFT - Moves cols of a 2d object left.



newx=rollleft(x);



Moves Cols of X one to left.



Example:



b34sexec matrix;

n=10;

v=rn(vector(n:));

leftv=rollleft(v);

call tabulate(v leftv);

x=rn(matrix(5,5:));

call print('Illustrates Rollleft',x,rollleft(x));

x=rn(matrix(5,6:));

call print('Illustrates Rollleft',x,rollleft(x));

b34srun;



ROLLRIGHT - Moves cols of a 2d object right.



newx=rollright(x);



Moves Cols of X one to right.



Example:



b34sexec matrix;

n=10;

v=rn(vector(n:));

rightv=rollright(v);

call tabulate(v rightv);

x=rn(matrix(5,5:));

call print('Illustrates Rollright',x,rollright(x));

x=rn(matrix(5,6:));

call print('Illustrates Rollright',x,rollright(x));

b34srun;



ROLLUP - Moves rows of a 2d object up.



newx=rollup(x);



Moves rows of X up one.



Example:



b34sexec matrix;

n=10;

v=rn(vector(n:));

upv=rollup(v);

call tabulate(v upv);

x=rn(matrix(5,5:));

call print('Illustrates Rollup',x,rollup(x));

x=rn(matrix(5,6:));

call print('Illustrates Rollup',x,rollup(x));

b34srun;



RTOCH - Copies a real*8 variable into character*8.



char=rtoch(r8);



Converts real*8 to character*8. Use with caution.

The following code makes a character*8 array



ch8=rtoch(array(10:));



R8TOR16 - Convert Real*8 to Real*16



r16=r8tor16(r8);



Changes kind of r8



Example:



b34sexec matrix;

x=rn(matrix(3,3:));

r16x=r8tor16(x);

testr8=r16tor8(r16x);

call print(x,r16x,testr8);

b34srun;

R16TOR8 - Convert Real*16 to Real*8



r8=r16tor8(r16);

Changes kind of r16



Example:



b34sexec matrix;

x=rn(matrix(3,3:));

r16x=`8tor16(x);

testr8=r16tor8(r16x);

call print(x,r16x,testr8);

b34srun;

REAL16 - Input a Real*16 Variable



r16=real16('.9q+00');



Places the number .9 into a real*16

variable without going through

a real*8 variable. The command



r16a=r8tor16(.9);



allows less digits (max of 16) to be put in.

The real16 command is usually not needed.



Example:



b34sexec matrix;

r16=real16('.9q+00');

r16a=r8tor16(.9);

call print('R16', r16:);

call print('R16A' r16a:);

call print('Difference ',(r16a-r16):);

b34srun;



Programming note:



Usually the below listed fortran is used

to convert from real*8 to real*16



real*8 r8

real*16 r16



r8=.9d+00

r16=r8





This will result in accuracy loss.

B34S uses the moire accurate but slower

code



subroutine r8tor16(x,y)

real*8 x

real*16 y

character*40 work

work=' '

write(unit=work,fmt=*)x

read(unit=work,fmt=*)y

return

end





SEIG - Eigenvalues of a symmetric matrix.



e=seig(x);



seigenval can be used in place of seig.



Calculates eigenvalues (e) of matrix x.

x must be real*8, real*16, complex*16 or complex*32

and a symmetric matrix.



If just eigenvalues are desired, for real*8/real*16

Eispack routines TRED1 and IMTQL1 (and their real*16

variants) are used.



To obtain eigenvectors use



e=seigenval(x,evecx).



EISPACK CG is used for complex*16/complex*32 and thus

does not not provide any gain over using the eig

command..



The EISPACK routines TRED2 and IMTQL2 are used for a

real*8/real*16.



The Eigenvectors are not normalized unless the form



eig(x,evecx :lapack2)



is used.



This command is faster than EIG but must be used

with caution since the matrix is not tested to

be symmetric.



Notes on Theory:



e=eig(x,v);



In General



v*diagmat(e) = complex(x),0.0)*v



complex(x,0.0) = v*diagmat(e)*inv(v)



If x is positive definate then

transpose(v)*v = I



Example:



b34sexec matrix;

* Test case for Real symmetric Matrix from ;

* IMSL Math (10) pp 309-311;

a=matrix(3,3:7.,-8.,-8.,-8.,-16.,-18.,-8.,-18.,13.);

call print('A Matrix',a);

e=seigenval(a);

call print('Eivenvalues of a', e,

'Sum of the eigenvalues of Symmetric Martix A',sum(e),

'Trace of Symmetric Matrix A',trace(a),

'Product of the eigenvalues of Symmetric Martix

A',prod(e),

'Determinant of Symmetrix Matrix A',det(a));

call print('Note: The eigenvalues have been

normalized');

ee=seigenval(a,evec);

call print(ee,evec);

call print('Test transpose(evec)*evec ',

transpose(evec)*evec ,

' '

'Test evec*transpose(evec) ',

evec*transpose(evec)) ;

b34srun;



SEIGENVAL - Eigenvalues of a symmetric matrix.





e=seigenval(x);



seig can be used in place of seigenval.



For help see seig.



SEXTRACT - Takes data out of a field.



agev= sextract(nn(2));



Places the structured variable # 2 in structure nn

in agev. If we assume that the command



nn=namelist(ssn,age,sex,inccome);



was given. The variant



agei = sextract(nn(2),3);



takes out the third data value of the second

structured array.



The process can be reversed. The command

call isextract(nn(2),data);



replaces all the values in the second structured

variable. The variant



call isextract(nn(2),data,3);



replaces data only in the third position. If the

object

is a matrix, then the exact storage location needs to

be

calculated.



SFAM - Creates a scalar object.



s=sfam(y(i));



Makes s a scalar. The command



s=y(i);



automatically does this.



sfam( ) is useful in expressions

to create temp variables.



SNGL - Converts real*8 to real*4.



r4=sngl(r);



Converts real*8 to real*4.

This should rarely be needed.



Example:



b34sexec matrix;

x=dfloat(integers(20));

xreal4=sngl(x);

call names(all);

call tabulate(x,xreal4);

b34srun;



SPACING Absolute spacing near a given number



number=spacing(x);



Gets didderence between dabs(x) and next largest

representable number. X can be real*4 or real*8.



Example:



b34sexec matrix;

i=1;

x=1.;

y=sngl(x);

call print('Largest integer ',huge(i):);

call print('Largest real*4 ',huge(y):);

call print('Largest real*8 ',huge(x):);

call print('Smallest real*4 ',tiny(y):);

call print('Smallest real*8 ',tiny(x):);

call print('Epsilon real*4 ',epsilon(y):);

call print('Epsilon real*8 ',epsilon(x):);



x=.1d+00;

y=sngl(x);

j=1;

call echooff;

do i=1,1000,100;

x=x*dfloat(i);

y=float(i)*y ;

spx(j)=spacing(x);

spy(j)=spacing(y);

nearpr8(j)=nearest(x, 1.);

nearmr8(j)=nearest(x,-1.);

nearpr4(j)=nearest(y, 1.);

nearmr4(j)=nearest(y,-1.);

testnum(j)=x;

j=j+1;

enddo;



call print('Spacing for Real*8 and Real*4');

call tabulate(testnum,spx,spy,nearpr8,nearmr8,

nearpr4,nearmr4);



call names(all);

call graph(testnum,spx :plottype xyplot

:heading 'Spacing');

b34srun;

SPECTRUM - Returns spectrum of a 1d object.



spec=spectrum(x:weights);



Calculates spectrum. Must supply an odd number of

weights.



For a more comprehensive command see



CALL SPECTRAL and CALL CSPECTRAL.



The variant



per=spectrum(x);



gives the periodogram. Other variants are



spec=spectrum(x,freq:weights);



per =spectrum(x,freq);

The period can be calculated as



period=1./freq;



if FREQ is scaled as:



freq= freq/(2*pi());





Example using spectrun:



b34sexec matrix;

* Uses FFT to High and Low Pass Random Series;

/$

/$ Illustrate with random numbers

/$

n=296;

test=rn(array(n:));

spec=spectrum(test,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random series');



cfft=fft(complex(test,0.0));

* low pass ;

nlow1 =1;

nlow2 =64;

nhigh1=51;

nhigh2=150;



fftlow =cfft*complex(0.0,0.0);

ffthigh =cfft*complex(0.0,0.0);

i=integers(nlow1,nhigh1);

fftlow(i) = cfft(i);

i=integers(nlow2,nhigh2);

ffthigh(i) = cfft(i);

call tabulate(cfft,fftlow,ffthigh);



low =afam(real(fft(fftlow :back)))*

(1./dfloat(norows(test)));

high=afam(real(fft(ffthigh :back)))*

(1./dfloat(norows(test)));



call tabulate(low,high,fft(ffthigh:back));



spec=spectrum(low,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random after Low

Pass');



spec=spectrum(high,freq);

call graph(freq,spec :plottype xyplot

:heading 'Spectrum of Random after High

Pass');

b34srun;



Example using call spectral:



b34sexec options ginclude('gas.b34'); b34srun;

b34sexec matrix;

call loaddata;

call spectral(gasin,sinx,cosx,px,sx,freq);

freq2=freq/(2.0*pi()); period=vfam(1.0/afam(freq2));

call tabulate(freq freq2 period sinx cosx px sx);

call spectral(gasin,sinx,cosx,px,sx,freq:1 2 3 2 1);

call tabulate(freq freq2 period sinx cosx px sx);

call graph(freq2,sx:heading 'Spectrum of Gasin'

:plottype xyplot);

b34srun;





SUBSET - Subset 1d, 2d array, vector or matrix under a mask.



newx=subset(x,mask);



X = input 1d, 2d array, vector or matrix

mask = vector 0.0 , 1.0



newx is x with mask=0.0 values removed



Note: This routine requires a statement



call load(subset);



It cannot be used as an argument to another

routine



Example:



b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

* Subset done two ways;

call loaddata;

call load(subset);

mask = (gasin .gt. 0.0);

call olsq(gasout gasin :sample mask

:print :diag :qr);

call olsq(gasout gasin

:sample mask :print :diag);



g2=subset(gasout,mask);

g1=subset(gasin,mask);

call olsq(g2,g1 :print);

b34srun;



Example using a matrix:

b34sexec options ginclude('b34sdata.mac')

member(gas); b34srun;

b34sexec matrix;

call echooff;

call loaddata;

call load(subset);

x=matrix(norows(gasout),3:);

x(,1)=1.;

x(,2)=vfam(gasin);

x(,3)=vfam(gasout);

mask = (gasin .gt. 0.0);

newx=subset(x,mask);

call print(x,newx);

b34srun;



SUBMATRIX - Define a Submatrix



Given x is a 6 by 10 matrix or array



sx=submatrix(x,1,3,2,5);



forms a new matrix sx containing



rows 1 to 3



cols 2 to 5





submatrix(mname,rowb,rowe,colb,cole);



mname => matrix or array name

mname can be real*8, real*16,

complex*16, complex*32, integer*4,

character*8 or character*1.



rowb => row begin



rowe => row end



colb => col begin



cole => col end



Example:



b34sexec matrix;

x=rec(matrix(6,10:));

sx=submatrix(x,1,3,2,5);

call print(x,sx);

b34srun;

SUM - Sum of elements.



s=sum(x);

Sum of x.



For a related command see mlsum.



Note: sum works for real*8, real*16, real*4,

integer*4, VPA, complex*16 and complex*32 objects.



Example:



b34sexec matrix;

a=array(5:1 2 3 4 5);

s=sum(a);

call print('Sum of 1 2 3 4 5',s);

b34srun$



SUMCOLS - Sum of columns of an object.



s=sumcols(x);



One dimensional vector of same class as x containing

the sum of the cols of x.



Example:



b34sexec matrix;

x=array(8,2:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);

call print(x,sumrows(x),sumcols(x));

call print(mfam(x),sumrows(mfam(x)),sumcols(mfam(x)));

b34srun;





SUMROWS - Sum of rows of an object.



s=sumrows(x);



One dimensional vector of same class as x

containing the sum of the rows.



Example:



b34sexec matrix;

x=array(8,2:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);

call print(x,sumrows(x),sumcols(x));

call print(mfam(x),sumrows(mfam(x)),sumcols(mfam(x)));

b34srun;



SUMSQ - Sum of squared elements of an object.



sumsq1=sumsq(x);



Sum of squared values of x.



if

s=cusumsq(x);



and x has n elements, then



s(n)=sumsq(x);



s1=ddot(x,x);



and



s2=sumsq(a);



produce same result.



For complex case see ZTOTC and ZTOTU.



Example:



b34sexec matrix;

a=array(5:1 2 3 4 5);

s=sumsq(a);s2=sum(a*a);

call print(s,s2);

b34srun$



SVD - Singular value decomposition of an object.



s=svd(x,ibad,job,u,v);



Calculates singular value decomposition of x.

x must be real*8, real*16, complex*16 or complex*32.

LINPACK routines DSVDC and ZSVDC are used. For

real*16 and complex*32 cases these routines have

been extended to QSVDC and CQSVDC restectively.



If the optional argument :lapack is added for real*8

and complex*16 case LAPACK routines DGESVD and ZGESVD

are used. These appear to be more accurate but take

more space. The option :linpack uses the LINPACL

routines and is the default for the time being.



Alternate calls:



s=svd(x);

s=svd(x,ibad);

s=svd(x,ibad,job,u);

s=svd(x,ibad,job,v);

s=svd(x,ibad,job,u,v);



s=svd(x :lapack);

s=svd(x,ibad :lapack);

s=svd(x,ibad,job,u :lapack);

s=svd(x,ibad,job,v :lapack);

s=svd(x,ibad,job,u,v :lapack);

s=svd(x :linpack);

s=svd(x,ibad :linpack);

s=svd(x,ibad,job,u :linpack);

s=svd(x,ibad,job,v :linpack);

s=svd(x,ibad,job,u,v :linpack);



ibad= 0 => all ok

job = 0 => only s calculated

job =10 => All left (U) vectors.

job =20 => First M left vectors.

job =11 => All left (u) and all right (V).

job =21 => First M left (U) vectors, all right.

job = 1 => All right (v) vectors.



Assume X(N,P) is real. => U(N,N) and V(P,P)



if N GE P => U'XV = D

0



if N LT P => U'XV = D 0



When job = 21 the first M left singular values placed

in U,



The generalized inverse = V*(1./D)*TRANSPOSE(U)



Example:



b34sexec matrix;

* SVD uses LINPACK DSVDC and ZSVDC $

* n sets rank for matrix tests;

* noob sets # of observations for PC tests ;

n=4;

noob=20;

x=rn(matrix(noob,n:));

s=svd(x,b,11,u,v);

call print('X',x,'Singular values',s,

'Left Singular vectors',U,

'Right Singular vectors',v);

call print('Test of Factorization. Is S along

diagonal?',

'Transpose(u)*x*v',transpose(u)*x*v,

'Is U orthagonal?','transpose(U)*U',

transpose(U)*U,

'Is V orthagonal?','transpose(V)*V',

transpose(V)*V,

' '

'Square Case');

n=4;

noob=4;

x=rn(matrix(noob,n:));

s=svd(x,b,11,u,v);

call print('X',x,'Singular values',s,

'Left Singular vectors',U,

'Right Singular vectors',v);

call print('Test of Factorization. Is S along

diagonal?',

'Transpose(u)*x*v',transpose(u)*x*v,

'Is U orthagonal?','transpose(U)*U',

transpose(U)*U,

'Is V orthagonal?','transpose(V)*V',

transpose(V)*V,

' '

'Complex Case');

x=afam(x);x=x*-1.;x=dsqrt(complex(x,0.0)) +

complex(x,0.0);

x=mfam(x);

s=svd(x,b,11,u,v);

call print('X',x,'Singular values',s,

'Left Singular vectors',U,

'Right Singular vectors',v);

call print('Test of Factorization. Is S along

diagonal?',



'dconj(transpose(u))*x*v',dconj(transpose(u))*x*v,

'Is U orthagonal?','dconj(transpose(U))*U',

dconj(transpose(U))*U,

'Is V orthagonal?','dconj(transpose(V))*V',

dconj(transpose(V))*V,

' '

'OLS Examples using SVD',' ');

* ####################### ;

x=rn(matrix(noob,n:));

call setcol(x,1,1.0); y=rn(vector(noob:));

call print(x,y,'OLS Results'

'(1.0/(transpose(x)*x))*transpose(x)*mfam(y)',

(1.0/(transpose(x)*x))*transpose(x)*mfam(y));

s=svd(x,b,21,u1,v);

call names;

call print('Singular values',s,

'X from SVD '

'U1*diagmat(s)*transpose(v)',

U1*diagmat(s)*transpose(v),

'Principle Component Coefficients'

'transpose(u1)*mfam(y)',

transpose(u1)*mfam(y)

' '

'Calculate OLS Coefficients using SVD

values'



'(V*(1./diagmat(s)))*(transpose(u1)*mfam(Y)) '



(V*(1./diagmat(s)))*(transpose(u1)*mfam(Y))

);

call print(diagmat(s));

A=transpose(u1)*mfam(y);

B=V*(1./diagmat(s))*A;

call print('A = PC Coefficients',A,

'B = OLS Coefficients',B);

pred1=u1*a;

pred2=x*b;

call print('We compare two ways to get predicted

values');

call tabulate(pred1,pred2);

b34srun;





TIMEBASE - Obtains time base of an object.



timebx =timebase(x);



Gets time base. If not available,

set to 0.



Timestart & timebase return integers.



Example:



b34sexec options ginclude('b34sdata.mac')

member(theil);

b34srun;

b34sexec matrix;

call loaddata;

call print(timebase(ct),timestart(ct),freq(ct));

b34srun;



TIMENOW - Time now in form hh:mm:ss



tt=timenow();



Places time in form hh:mm:ss in tt



Example:



b34sexec matrix;

call print('Date now is ',datenow():);

call print('Time now is ',timenow():);

b34srun;

TIMESTART - Obtains time start of an object.



timesx =timestart(x);



Gets time start of x.



Timestart & timebase return integers.



Example:



b34sexec options ginclude('b34sdata.mac')

member(theil);

b34srun;

b34sexec matrix;

call loaddata;

call print(timebase(ct),timestart(ct),freq(ct));

b34srun;



TINY Smallest number of type



tnumber=tiny(x);



Gets largest number of type x. X can be

real*4 or real*8.



Example:



b34sexec matrix;

i=1;

x=1.;

y=sngl(x);

call print('Largest integer ',huge(i):);

call print('Largest real*4 ',huge(y):);

call print('Largest real*8 ',huge(x):);

call print('Smallest real*4 ',tiny(y):);

call print('Smallest real*8 ',tiny(x):);

call print('Epsilon real*4 ',epsilon(y):);

call print('Epsilon real*8 ',epsilon(x):);



x=.1d+00;

y=sngl(x);

j=1;

call echooff;

do i=1,1000,100;

x=x*dfloat(i);

y=float(i)*y ;

spx(j)=spacing(x);

spy(j)=spacing(y);

nearpr8(j)=nearest(x, 1.);

nearmr8(j)=nearest(x,-1.);

nearpr4(j)=nearest(y, 1.);

nearmr4(j)=nearest(y,-1.);

testnum(j)=x;

j=j+1;

enddo;



call print('Spacing for Real*8 and Real*4');

call tabulate(testnum,spx,spy,nearpr8,nearmr8,

nearpr4,nearmr4);



call names(all);

call graph(testnum,spx :plottype xyplot

:heading 'Spacing');

b34srun;



TDEN - t distribution density.

x=tden(x1,x2)$



Density of t distribution



x1 = t value



x2 = df (gt 0.0).



Note: Routine uses loggamma function and logic

adapted from Matlab. X2 rounded to nearest integer

up and down and value interpolated. Matlab version

rounds to the nearest integer. This causes problems

in fat tail estimation.



Shows how tden converges to normden



Example:



b34sexec matrix;

t=grid(-4.0,4.0,.1);

df=array(norows(t):)+10.;

ttden =tden(t,df);

ttprob =tprob(t,df);

normden2 =normden(t);

call print('DF was ',df:);

call tabulate(t,ttden,ttprob,normden2);



df=array(norows(t):)+1000.;

ttden =tden(t,df);

ttprob =tprob(t,df);

normden2 =normden(t);

call print('DF was ',df:);

call tabulate(t,ttden,ttprob,normden2);



df=array(norows(t):)+100000.;

ttden =tden(t,df);

ttprob =tprob(t,df);

normden2 =normden(t);

call print('DF was ',df:);

call tabulate(t,ttden,ttprob,normden2);



b34srun;



TPROB - t distribution probability.



x=tprob(x1,x2)$



Probability of t distribution. Probability is

area in the tails.



x1 = t value



x2 = df (gt 0.0)

Example:



b34sexec matrix;

t=2.447;

df=6.;

p=tprob(t,df);

call print('The prob: that a t(',df,

') variate is GE abs(',

t,') is ',p,

'Note answer should be .9500');

b34srun;



TRACE - Trace of a matrix.



t=trace(x);



Trace of x.



Note: Trace works for real*8, real*16,

complex*16 and complex*32 objects.



Example:



b34sexec matrix;

m=matrix(3,3:1 2 3 4 5 6 7 8 9);

call names(all);

t=trace(m);

call print('Matrix M',m);

call print('Trace of M',t);

e=eigenval(m);

call print('Sum of eigenvalues =

trace',sum(e),trace(m));

b34srun;





TRANSPOSE - Transpose of a matrix.



tx=transpose(x);



Transposes x.



Command works for real*8, real*4, character*1,

character*8,

complex*16 and integer 2D objects.



Example:



b34sexec matrix;

real8=matrix(3,3:1 2 3 4 5 6 7 8 9);

call print('Matrix and its transpose',real8,

transpose(real8));

comp=complex(real8,real8);

call print('Matrix and its transpose',comp,

transpose(comp));

nn=namelist(a b c d e f g h i);

nn2=array(3,3:nn);

call print('Matrix and its transpose',nn2 ,

transpose(nn2 ));

call character(cc,'ABCDEFGHI'); ch1=array(3,3:cc);

call print('Matrix and its transpose',ch1 ,

transpose(ch1 ));

int4=idint(real8); real4=sngl(real8);

call print('Matrix and its transpose',int4,

transpose(int4));

call print('Matrix and its transpose',real4,

transpose(real4));

b34srun;





UPPERT - Upper Triangle of matrix.



newx=uppert(x);



Upper triangle. The optional keyword



:nodiag



will not copy the diagonal.



Example:

b34sexec matrix;

x=rn(matrix(6,6:));

call print(x);

call print(uppert(x));

call print(uppert(x :nodiag));

b34srun;



VARIANCE - Variance of an object.



var=variance(x);



Variance of object x. x must be Real*8.



Note: uses small sample approximation.



Example:



b34sexec options ginclude('gas.b34')$

b34srun$

b34sexec matrix;

call loaddata;

mgasin=mean(gasin);

mgasout=mean(gasout);

call print('Gasin Mean',mgasin);

call print('Gasout Mean',mgasout);

vgasin=variance(gasin);

vgasout=variance(gasout);

call print('Gasin Variance',vgasin);

call print('Gasout Variance',vgasout);

b34srun$



VECTOR - Create a vector.



y=vector(i:);



Creates an i element vector



Alternate form is



vector(3:1 2 3);



Examples include



x=matrix(3,3:1 2 3 4 5 6 7 8 9);



or



x=matrix(3,3:1. 2. 3. 4. 5. 6. 7. 8. .9);



which creates



1. 2. 3.

4. 5. 6.

7. 8. 9.



When loading a 1-D object into a 2-D object

we load by rows.



When loading a 2-D object to a 1-D object we load

by address.



vx=vector(:matrix(3,3:1 2 3 4 5 6 7 8 9));



produces



1. 4. 7.

2. 5. 8.

3. 6. 9.



Advanced tricks



b34sexec matrix ;

x=matrix(3,3:1 2 3 4 5 6 7 8 9);

v=vector(:1 2 3 4 5 6 7 8 9);

xx=matrix(3,3:v);

xx2=matrix(9,1:xx);

xx3=matrix(3,3:xx2);

call print(x,v,xx,xx2,xx3);

b34srun;



X = Matrix of 3 by 3 elements

1. 2. 3.

4. 5. 6.

7. 8. 9.



V = Vector of 9 elements



1. 2. 3. 4. 5. 6. 7. 8. 9.



XX = Matrix of 3 by 3 elements



1. 2. 3.

4. 5. 6.

7. 8. 9.



XX2 = Matrix of 9 by 1 elements



1.

4.

7.

2.

5.

8.

3.

6.

9.





XX3 = Matrix of 3 by 3 elements



1. 4. 7.

2. 5. 8.

3. 6. 9.







VFAM - Convert a 1d array to a vector.



y=vfam(i);



Takes object i and makes it a vector.



VOCAB - List built in functions.



f=vocab();



The variants



call vocab(c:);



f=vocab(:);



list with command internal number vocabulary for

subroutines and functions.

VPA - Variable Precision Math calculation



Assuming fm_ and fp_ are respectively real unpacked and packed

VPA numbers.



fm1=vpa(dp);

=vpa(sp);

=vpa('string');

=vpa(int)

=vpa(fp);

=fm;



will create a fm number. The commands



fp1=vpa(vpa(dp) :pack);

=vpa(fm :pack);

=vpa(vpa('string') :pack);

=fp;



will create a fp number. The commands



ip1=ip;



im1=im;



zm1=zm;



zp1=zp;



copy integer and complex vpa variables. The commands



dp=vpa(fm :to_dp);

dp=vpa(fp :to_dp);

dp=vpa(im :to_dp);

dp=vpa(ip :to_dp);



create dp variables while



int=vpa(fm :to_int);

int=vpa(fp :to_int);

int=vpa(im :to_int);

int=vpa(ip :to_int);

int=vpa(fm :to_int8);

int=vpa(fp :to_int8);

int=vpa(im :to_int8);

int=vpa(ip :to_int8);





create integer*4 and integer*8 variables. The commands



str=vpa(fm :to_str);

str=vpa(fp :to_str);

str=vpa(im :to_str);

str=vpa(ip :to_str);

str=vpa(zm :to_str);

str=vpa(zp :to_str);



create string data while the commands



sp=vpa(fm :to_sp);

sp=vpa(fp :to_sp);



create single precision data.



Complex data can be handled by:



zm =vpa(z);

zp =vpa(zm :pack);

z =vpa(zm :to_z);

z =vpa(zp :to_z);

str =vpa(zm :to_str);

str =vpa(zp :to_str)'

fmreal=vpa(zm :real);

fmimag=vpa(zm :imag);

fpreal=vpa(zp :real);

fpimag=vpa(zp :imag);

zm =vpa(fm1,fm1);

zp =vpa(fp1,fp2);

zm =vpa(vpa(i1) vpa(i2));

zm =vpa(vpa('string') vpa('string'));



Real*16 and complex*32 data is created by



r16 =vpa(fm :to_r);

r16 =vpa(fp :to_r);

z32 =vpa(zm :to_z32);

z32 =vpa(zp :to_z32);



Strings recognized are



1.23 + 4.56 I

1.23 + 4.56*I

2 + i

-i

1.23

4.56i

( 1.23 , 4.56 )







The following functions operate on fm, fp, ,im, ip, fm and fp

variables. Most have been implemented at of 20 February 2005.



Function Type arguments Comments:

ABS real complex

IABS integer

ACOS real complex

AIMAG complex

AINT real complex

ANINT real complex

ASIN real complex

ATAN real complex

ATAN2 real

CMPLX real

ICMPLX integer

CONJ complex

COS real complex

COSH real complex

INT real complex

IINT integer

LOG real complex

LOG10 real complex

MAX real

IMAX integer

MIN real

IMIN integer

MOD real

IMOD integer

NINT real complex

ININT integer

REAL real complex

IREAL integer

integer

SIGN real

ISIGN integer

SIN real complex

SINH real complex

SQRT real complex

TAN real complex

TANH real complex





In addition, most of the key matrix commands such as inv( )

catcol, catrow, det( ), rcond( ), diag( ) etc work. More

commands will be enabled as the need arises.



ZDOTC - Conjugate product of two complex*16 objects.



cc=zdotu(x,y);



Calculates product. x and y must be complex*16.

This command calls BLAS Level I routine with

same name. If optional argument : is added,

then an element by element operation is performed.





Example contrasts zdotu & zdotc:



b34sexec matrix;

n=10;

x=rn(vector(n:));

y=rn(x);

call print(x,y);

call print(x*y,ddot(x,y),afam(x)*afam(y),ddot(x,y:),

sum(afam(x)*afam(y)));



* Complex case ;



cx=complex(x,y);

cy=complex(y,x);

call print(cx,cy);

call

print(cx*cy,dconj(cx)*cy,zdotu(cx,cy),zdotc(cx,cy),

afam(cx)*afam(cy),dconj(afam(cx))*afam(cy),

zdotu(cx,cy:),zdotc(cx,cy:),

sum( afam(cx) *afam(cy)),

sum(dconj(afam(cx))*afam(cy)) );

b34srun;



ZDOTU - Product of two complex*16 objects.



cc=zdotc(n,x,y);



Calculates conjugate product. x and y must be

complex*16.

This command calls BLAS Level I routine with same

name.



cc=dconj(x)*y.



If optional argument : is added, then an element by

element operation is performed.



Example contrasts zdotu & zdotc:



b34sexec matrix;

n=10;

x=rn(vector(n:));

y=rn(x);

call print(x,y);

call print(x*y,ddot(x,y),afam(x)*afam(y),ddot(x,y:),

sum(afam(x)*afam(y)));



* Complex case ;



cx=complex(x,y);

cy=complex(y,x);

call print(cx,cy);

call

print(cx*cy,dconj(cx)*cy,zdotu(cx,cy),zdotc(cx,cy),

afam(cx)*afam(cy),dconj(afam(cx))*afam(cy),

zdotu(cx,cy:),zdotc(cx,cy:),

sum( afam(cx) *afam(cy)),

sum(dconj(afam(cx))*afam(cy)) );

b34srun;

ZEROL - Zero lower triangle.



newx=zerol(x);



Zeros out lower triangle. The optional keyword



:nodiag



will not zero out the diagonal.



Example:

b34sexec matrix;

x=rn(matrix(6,6:));

call print(x);

call print(zerol(x));

call print(zerol(x :nodiag));

b34srun;



ZEROU - Zero upper triangle.



newx=zerou(x);



Zeros out upper triangle. The optional keyword



:nodiag



will not zero out the diagonal.



Example:

b34sexec matrix;

x=rn(matrix(6,6:));

call print(x);

call print(zerou(x));

call print(zerou(x :nodiag));

b34srun;







The commands lpmin and lpmax can be used to solve linear

programming problems. The command qpmin is designed for

quadratic programming. For nonlinear programming a number

of commands are supplied to solve a problems of the form



min f(x)

st g(i)(x) = 0 for i=1,ME

g(j)(x) GE 0 for j=ME+1,m



The test case illustrated is



Min F(x) = (x1-x2)**2. -(x2-1)**2.



st g(1)(x) = x1 - 2.*x2 + 1 =0

g(2)(x) = -1.*((x1**2.)/4. -(x2**2.)+1. GE 0

Note that if just a min is needed, use MAXF2. If

the constraints are linear, use CMAXF2. The

commands NLPMIN1, NLPMIN2 and NLPMIN3 are

designed to handle really intractable problems.



NLPMIN1 => Solve a general nonlinear programming problem

using the successive quadratic programming

algorithm and a finite difference gradient.

This command is the easiest to use.

Uses IMSL DN2CONF.



NLPMIN2 => Solve a general nonlinear programming problem

using the successive quadratic programming

algorithm and a user supplied gradient.

If the gradiant is supplied, this is the

easiest command to use.

Uses IMSL DN2CONG.



NLPMIN3 => Solve a general nonlinear programming problem

using the successive quadratic programming

algorithm and a user supplied gradient with

reverse communication. Hessian is calculated.

Calling sequence in complex but many more

options are available. NLPMIN3 should be used

if very complex and difficult problems are

estimated. If the user supplied gradiant is

difficult to calculate, it is suggested that

MATLAB(r) is used to obtain the symbolic

derivative. Uses IMSL DN0ONF.



Subroutines and functions.



Subroutines and functions can be saved in user MAC files

or created in the job stream. The next example shows how to

create a subroutine in the job stream.



subroutine test1(x,y);

* ;

* The test1 subroutine will square each element of x and place in y;

* This will not run fast because of DO loop ;

* ;

y=vector(NOROWS(x):) ;

do i=1,norows(x) ;

y(i)=x(i)*x(i) ;

enddo ;

return ;

end ;



Notes:

1. If a subscript is used, then the array has to be

allocated prior to the command running.



2. Avoid do loops where ever possible.

A faster way to go would be



subroutine test2(x,y) ;

* ;

* The test2 subroutine will square each element of x and place in y;

*

y=x**2;

return;

end;



subroutine test2(x,y,z);

* ;

* The test2 subroutine will multiply each element of x by y;

* and place in z if X and y are of the array family;

* Otherwise matrix math is used;

* ;

z=y*x;

return;

end;





function ftest1(x);

* ;

* The ftest1 subroutine will square each element of x and place in y;

* This assumes that x is of the array family;

* ;

result=x*x;

return result;

end;





program doit;

/$C

/$C The doit program will print all names

/$C and their locations

/$C

call names;

call names(all);

return;

end;





A program. subroutine or function is called as if it were a built

in command. Subroutines, programs and functions not part of the

job stream have to be loaded. By requiring that routines be loaded,

library searches are not required and there is a speed up.



Order of search. If the user has created a variable the same name as a

built in function or subroutine, then the user name will be used. A

number of keywords must not be used: These include:

DO, IF, STOP, MATRIX, ARRAY, VECTOR, PRINT, FUNCTION, PROGRAM

SUBROUTINE, CALL, B34SRUN B34SEEND.

Note: It is not a good idea to use the name of a command as your

subroutine and function names.



The user can add libraries of SUBROUTINES and functions that can be

easily loaded from the TASKS menu.





sets up eight shell files:





File 1 = b34s shell file contain command fragments.

File 2 = b34s example file containing fully working examples

of b34s commands such as ROBUST

File 3 = b34s matrix example file containing fully working

examples of MATRIX commands

File 4 = Matrix command subroutines, that are loaded with the

matrix command



call load( );



can be used in user matrix programs. The TOOLKIT help

command

discusses these subroutines. Users can add to these

routines.



File 5 = B34S to Rats files

File 6 = Matlab files

File 7 = B34s test files

File 8 = B34S to SCA files





The above files can be accessed from the TASKS part of the display

manager. On the PC the below listed command gives the current names.



shname('c:\b34slm\b34sshel.mac',

'c:\b34slm\example.mac' ,

'c:\b34slm\matrix.mac' ,

'c:\b34slm\matrix2.mac',

'c:\b34slm\ratspgm.mac',

'c:\b34slm\matlab.mac',

'c:\b34slm\b34stest.mac',

'c:\b34slm\scapgm.mac')



Example # 1a User enters a matrix does an inverse



x=matrix(5,5;);

x=rn(x);

call print(x);

invx=inv(x);

call print('This is the inverse');

call print(invx);





Note: an alternative to

invx=inv(x);



is



invx=1./x;



Example # 1b User enters a matrix does an inverse

The program requires that the matrix is

allocated with the correct size.



x=matrix(3,3;);

x(1,)=vector(:1,2,3);

x(2,)=vector(:12,21,93);

x(3,)=vector(:71,12,13);

call print(x);

invx=inv(x);

call print('This is the inverse');

call print(invx);



Example # 2 User obtains data from x1 x2 x3 and places them in x



x(,1)=x1;

x(,2)=x2;

x(,3)=x3;

x(,4)=1

call print(x);



Here x1 can be a vector, array or scalar.





The FORMULA keyword allows user to specify an expression that

will be evaluated later observation at a time with the SOLVE statement.

A SOLVE and FORMULA statement can refer directly to itself but cannot

use a user function. This feature is in contrast to RATS that requires

"tricky" programming to get around a recursive reference. The reason

that user functions are not allowed is related to how the SOLVE

statements and FORMULAS are saved in memory.



FORMULAS and SOLVE statements MUST use the t subscript to

determine the element. For the left hand side, the current observation

is assumed. If a variable is used in a formula without the t

subscript, it must resolve to one observation. For example



formula wdata = x(t)/mean(x) ;



would be evaluated over the range set by the solve statement and mean(x)

would be calculated at each observation. This code would work as intended

BUT be slower. A better choice would be.



meanx=mean(x);

formula wdata = x(t) / meanx;

Note: These examples do not require the formula statement which is

designed

to handle recursive calculations. Since FORMULA and SOLVE

statements

are relatively slow, their use should be limited to the cases where

they

are needed.



Format of FORMULA statement



formula expression



Examples:



formula test = x(t-1)*2. + b(t-2)*y;



formula testhold=test(t-1) + beta;



The SOLVE keyword allows user to evaluate

FORMULAS one observation at a time if they are mentioned on a BLOCK

keyword.

The order of the FORMULAS on the BLOCK statement determines the order

in which they are evalued.



Format of SOLVE statement



solve( expression :range i1 i2 :block form1 form2);



The :range key word is required. The :block keyword is only needed if

formulas are used. The order of the formulas on the block keyword

determines how they will be evaluated.



The below example shows a SOLVE statement used without a FORMULA

to make a recursive call.



b34sexec matrix;

/$ Unlike RATS, SOLVE and FORMULA statements can refer

/$ to themselves recursively

n=1000;

v=1.0;

ar1=array(n:)+missing();

ar1(1)=99.+rn(v);

solve(ar1=ar1(t-1)+rn(v):range 2 n);

call graph(ar1);

call tabulate(ar1);

b34srun;



Formulas can substantially speed up calculations. Formulas should

not be used unless a recursive calculation is needed since they are

substantially slower than the usual b34s MATRIX command analytic

statement. The larger the number of cases the relative faster the

SOLVE statement over the DO loop. In simple cases of 3000 observations

the

SOLVE statement is 15 times faster than the DO loop using Lahey LF90.

Warning: The above not withstanding the b34s SOLVE and DO statements are

quite slow and should be avoided where ever possible.



The reason that by design the SOLVE and FORMULA statements are slow is

that

with object oriented programming only one parse is needed. The expression

y=x*a;



where x and a are matrix objects only needs to be parse once. A recursive

expression by construction needs to be resolved an element at a time.



Examples of SOLVE where BLOCK statement is used:



* archvar and resid start out as variables set to zero;

* They are updated by the formula statement ONLY for obs t;

* For t=2, this value of u is used to get archvar;

archvar=array(norows(y):);

resid =array(norows(y):);

formula archvar = a0 + a1 * (resid(t-1)**2.) ;

formula resid = y(t) - b1 - b2*x1(t) - b3*dsqrt(archvar(t));

solve(

archlogl =(-.5)*(dlog(archvar(t))+((resid(t)**2.)/archvar(t))

:range 2 norows(y) :block archvar resid);







Design objective:



The SOLVE and FORMULA commands were developed to allow the

user full control over the calculation of the likelihood function

when running ML problems. The RATS implementation sums the elements

and does not allow the user to fully monitor how the calculation

unfolds. RATS appears to throw out from the SUM observations with

large values. It may be the case that these values are associated with

specific observation outliers. At the cost of reduced SPEED of

execution, the b34s ML implementation gives the user as full control

of the solution process as if a fortran subroutine were called. The

ability to save values in named storage by observation allows

investigation of the pattern of an individual conditional volatility

measure as the solution unfolds. For simple ML models where the solution

proceeds without problems, the greater speed of RATS is surely a

major advantage. For worst case (very difficult) models, b34s allows

as near total control as possible. If the minimizer is questioned,

it could be written directly in the b34s matrix language such as has

been supplied for NLLS models.





Copy commands and formulas:



Assume:



formula test = x**2.;

tt = test;

tt is now a formula but it will not work unless the command



call subrename(tt);



is given to rename test to tt.



Once TEST can been executed with the SOLVE command, it

no longer can be seen as a formula. It will be seen as

a real*8 variable. Hence a formula must be copied BEFORE it

is solved. If a formula has been solved, the local variable

must be erased before any formula is copied. It is unlikely

that a formula needs to be copied. These conventions may change

in future implementations.



Nonlinear Estimation Capability in the Matrix Language



The b34s MATRIX command has a number of powerful

built-in nonlinear estimation commands where the user

model is specified in a MATRIX command program. Using the

full power of the b34s MATRIX programming language,

the user can solve a wide range of models.



Note on recursion: If the user model requires

recursion, DO loops must be used to recursively evaluate

the model. As an alternative FORMULA & SOLVE commands can be

used. In a recursive model running a DO loop for each function

evaluation shows program execution substantially. The

FORMULA / SOLVE approach is from 4 to 10 times faster than

the DO loop. The more complex the model, the closer the

two methods. The more observations in the model, DO loop

speed slows down relatively. Since recursive models are

widely used in ARCH, GARCH and GARCH-M model building,

the built-in GARCH command will recursively solve a range of

the more widely used models and avoid recursion solution

cpu overhead.



In addition to the Nonlinear commands

Current Commands:



NLLSQ => Estimation of Nonlinear Least Squares.



MAXF1 => Maximize function using Quasi-Newton Method

using IMSL ZXMIN. SE given.



MAXF2 => Maximize function using IMSL DUMINF

If gradiant known, uses IMSL DUMING.

SE is given. This routine is very

stable.



MAXF3 => Maximize a function using IMSL DU2POL which

uses simplex method. Useful for starting

values.

CMAXF1 => Maximize constrained function using IMSL

routine ZXMWD. No SE given. Unless CMAXF2

is not avaliable, this routine usually

should not be used. CMAXF2 is a bettter

choice.



CMAXF2 => Maximize constrained function using IMSL

routine DBCONF or DBCONG if gradiant is

known. SE is given. This routine is very

stable.



CMAXF3 => Maximize constrained function using IMSL

routine DB2POL which uses simplex method.

Useful for starting values.



NLEQ => Solve a system of nonlinear equations using

IMSL ZSPOW which is based on MINPACK

HYBRD1 routine. NO SE is given



NLSTART => Generate a matrix of starting values. This

command is useful when testing for global vs

local solutions of models.



If the function is multiplied by -1.* in the

user supplied b34s program, minimization

problems can be solved. In this mode of

operation the output will display the

functional value times -1.



NLPMIN1 => Solve a general nonlinear programming problem

using the successive quadratic programming

algorithm and a finite difference gradient.

This command is the easiest to use.

Uses IMSL DN2CONF.



NLPMIN2 => Solve a general nonlinear programming problem

using the successive quadratic programming

algorithm and a user supplied gradient.

Uses IMSL DN2CONG.



NLPMIN3 => Solve a general nonlinear programming problem

using the successive quadratic programming

algorithm and a user supplied gradient with

reverse communication. Hessian is calculated.

Calling sequence in complex.

Uses IMSL DN0ONF.



A number of commands are supplied to solve a problems of the

form



min f(x)

st g(i)(x) = 0 for i=1,ME

g(j)(x) GE 0 for j=ME+1,m

The test case illustrated is



Min F(x) = (x1-x2)**2. -(x2-1)**2.



st g(1)(x) = x1 - 2.*x2 + 1 =0

g(2)(x) = -1.*((x1**2.)/4. -(x2**2.)+1. GE 0



Note: If just a min is needed, use MAXF2. If the constraints are

linear, use CMAXF2. The commands NLPMIN1, NLPMIN2 and NLPMIN3

are designed to handle really intractable problems. If the

function is linear, then use LPMAX or LPMIN. QPMIN can be used

for special forms of nonlinearity.







Notes on SE calculation: The commands MAXF1, MAXF2, MAXF3, CMAXF1,

CMAXF2 and CMAXF3 calculate the SE of the

model as the square root of the absolute

value of the diagonal elements of INV(HESS)

where HESS is the Hessian matrix produced

by the specific IMSL routine called. Since

the hessian matrix is automatically saved,

users can easily program alternative

"small sample" SE estimators. In

the optimization literature it is well

known that the various approaches to estimation

can give quite different SE estimates in

small samples. The developer



Notes for NLLSQ Estimation of Nonlinear Least Squares.



The MATRIX command can be used to estimate a user nonlinear

model using the MATRIX command routines DUD and MARQ which are

supplied in the file matrix2.mac. This approach has the advantage

of being truly transparent to the user because the command is

completely written in the MATRIX language. The user specifies the

model with a MATRIX SUBROUTINE. The disadvantage of this approach

is that the execution time is relatively slow. A major advantage

is that the user can instrument the solution process at all stages

to allow monitoring of the convergence. By use of the MESSAGE command,

the user can stop the execution, print further intermediate results

and modified parameters to control convergence.



The NLLSQ command represents a hybrid approach. The model is

specified in a user MATRIX PROGRAM and the solution is carried out

using a specially modified version of the time tested GAUSHAUS

program that was developed by Meeter and is discussed in Draper

and Smith (1966) "Applied Regression Analysis." Further

discussion of this program is contained under the NONLIN

section (22) of this manual and in Chapter 11 of Stokes (1997).

Various versions of GAUSHAUS are used in the BJEST and BTEST

commands. During estimation both the right hand side and left

hand side variables can be modified provided that the number

of observations is not changed. A common approach is to

estimate a box-Cox transformation lamda jointly with the

estimated model.



Since the switches to the NLLSQ command are contained

within the estimation space, it is possible to change parameters

as the job is running. This should not be done. If the left

hand variable is changed during the estimation process the

convergence will fail. Thus a Box-Cox model on the right is

possible, but a Box-Cox Transformation on the left is not

possible unless done is a grid search. MAXF2 should be

used if Box-Cox Model is estimated with a transformation

on the left. For furtherv detail, see NLLSQ command.





Maximum Likelihood Estimation





The MATRIX command provides a number of options for maximum

likelihood estimation with both constrained and unconstrained models.

The user specifies the model using a MATRIX command program that produces

a functional value that is maximized. Optionally the user can specify a

program to calculate the jacobian (first derivatives) and the hessian

(second derivatives). A number of estimation methods are supported that

include 9 routines.



MAXF1 - Maximize function using Quasi-Newton Method using IMSL ZXMIN

MAXF2 - Maximize function using IMSL DU2INF / DU2ING

MAXF3 - Maximize function using IMSL DU2POL

CMAXF1 - Maximize constrained function using IMSL routine ZXMWD

CMAXF2 - Maximize constrained function using IMSL DB2ONF / DB2ONG

CMAXF3 - Maximize constrained function using IMSL DB2POL

NLPMIN1 - Nonlinear Programming

NLPMIN2 - Nonlinear Programming - User Gradiant

NLPMIN3 - Nonlinear Programming - User Gradiant calculates Hessian

NLEQ - Solve a system of nonlinear equations using IMSL ZSPOW

NLSTART - Generate a matrix of starting values



For constrained problems, use CMAXF2 on platforms for which it is

available. For unconstrained problems, use MAXF2 or MAXF1 in that order

when MAXF2 is available. MAXF3 cab be used to generate starting values.



As discussed earlier, special coding has to be used if the model is

recursive. Here execution speed slows substantially. While the DO loop

is a possible approach, the FORMULA / SOLVE strategy is from 4 - 10 times

faster BUT still really too slow for large problems. In future releases

it

is hoped that this can be corrected.



The subroutine GARCH is supplied to allow estimation of a fairly general

class of ARCH, ARCH-M and GARCH-M models using one or more series. The

advantage of the GARCH subroutine is that recursive calls are

substantially

faster than would be the case if DO loops were used. While the MAXF2 and

MAXF3 routines can be used, probably a better way to proceed is to use

CMAXF2 and CMAXF3 and constrain the parameters of the ARCH process such

that in the iteration process data points do not become unusable.



The GARCH3, GARCH4 and GARCH5 test cases illustrate this use of CMAXF2.



The subroutine GARCHEST combines GARCH and CMACF2 and for standard GARCH

class models is the fastest way to go since there is no parse overhead

to estimate a model.



Users interested in ML estimation should run the many test cases in the

MATRIX.MAC library.









B34S is pleased to be able to implement variable precision math using

a modification of version 1.2 of the FMLIB and ZMLIB code developed by

David M. Smith. The major reference is from ACM.



FMLIB is Algorithm 693, ACM Transactions on Mathematical Software,

Vol. 17, No. 2, June 1991, pages 273-283.



which documents the code in the library.



Real, integer and complex data types are supported using variable

precision math. The Matrix VPA (Variable Precision Arithmethic) option

allows calculations between real, integer and complex variables where up

to 1786 digits of accuracy are used. As implemented, extended precision

calculations can be mixed into the usual matrix commands to allow the

user to make more precise calculations of key data. Six new kinds of

data are now supported.



kind = 88 => fm or unpacked real data.

kind = 888 => fp or packed real data.

kind = -44 => im or unpacked integer data.

kind = -444 => ip or packed integer data.

kind = 160 => zm or unpacked complex data.

kind = 1600 => zp or packed complex data



Important new commands include subroutine vpaset and function vpa.

When the matrix command is started calls are made to set the number

of digits to be used in the calculation to 60. This can be changed by

the call



call vpaset(:ndigits 70);



to 70. The ndigits refers to the number of real*8 variables used to

store the data. For example ndigits=60 implies that 60 real*8

variables are processed to make any calculation. The number of output

nigits can be substantially more than the number of ndigits needed to

make a calculation. For example, real*8 data would have a ndigits=1

but would allow up to 16 significant nigits.



Output format can be set by the options :jform1 and :jform2.

call vpaset(:jform1 n1);



JFORM1 = 0 => E format ( .314159M+6 )

= 1 => 1PE format ( 3.14159M+5 )

= 2 => F format ( 314159.000 )





call vpaset(:jform2 nn2);





JFORM2 is the number of significant digits to display (if

JFORM1 = 0 or 1). If JFORM2.EQ.0 then a default number

of digits is chosen. The default is roughly the full

precision of the number.



JFORM2 is the number of digits after the decimal point (if

JFORM1 = 2). See the FMOUT documentation for more details.





vp (variable precision) data is saved in the B34S matrix command

workspace using real*8 data but has a different "kind" so the b34s

matrix command parser will know how to handle the series. Assuming



NDIGMX=256

LPACK = (NDIGMX+1)/2+1 +1

LUNPCK = (6*NDIGMX)/5+20 +1

LPACKZ = 2*LPACK+1+1

LUNPKZ = 2*LUNPCK+1+1

LUNPCKI= (6*NDIGMX)/5+20 +1





NDIGMX = sets the maxiumum number of real*8 nigits that can be used to

save a data value. (Developer note: The use of the term

ndigits to refer to the number of real*8 data values NOT the

printed digits might be confusing. However it is what Smith,

the developer of the library user, used and thus has been

retained for the time being in this dciscussion.

LPACK = number of real*8 data points for VPA real/integer packed data.

LUNPCK = number of real*8 data points for VPA real unpacked data.

LPACKZ = number of real*8 data points for VPA complex packed data.

LUNPCK = number of real*8 data points for VPA complex unpacked data.

LUNPCK = number of real*8 data points for integer unpacked data.



for NDIGMX =256

LPACK =130.5 => 131

LUNPCK =328.2 => 329

LPACKZ =263 => 263

LUNPKZ =658.4 => 658

LUNPCKI=328.2 => 328



Arrays, vectors and matrices are supported.



The b34s matrix commands call write( ) and call read( ) can be used

to save data. In addition the command



call vpaset( fm real8dat :saveasr8);



can be used to "save" VPA data as a kind=8 variable. This can be put

back to vpa with



call vpaset(real8dat fm :saveasvpa



The kind of data is saved in the real*8 header. This real*8 variable

should not be used in a calculation. To avoid this possibility the

conversion is in a subroutine call (vpaset) not a VPA function.



The below listed sections document the fortran calls for the

fm_zmlib.f file that can be used independently of b34s provided that the

routines in utility.f are linked into the user program. This section

is not needed by a b34s user.



QUICK start USER'S GUIDE FOR THE VPA Routines



Note: This sections has been taken from the fm_zmlib.f documentation.



The various lists of available multiple precision operations and

routines have been collected here, along with some general advice

on using the package.



CALL ZMSET(N)



in the main program before any multiple precision operations

are done, with N replaced by the number of decimal digits of

accuracy to be used. This will initialize both FMLIB and ZMLIB

packages. If only real arithmetic is to be used, then call



CALL FMSET(N)



Warning: The library uses addresses from 0.



DOUBLE PRECISION A(0:LUNPCK),B(0:LUNPCK),C(0:LUNPCK)



where LUNPCK is defined in the PARAMETER statement included

with the FM common blocks. The numbers are then added by

calling the FMLIB routine where the arguments are assumed to be

arrays, not TYPE (FM) derived types:





Routines:



CALL FMADD(A,B,C)



DOUBLE PRECISION A(0:LPACK),B(0:LPACK),C(0:LPACK)



The routines that work with packed arrays have names where the

second letter has been changed from M to P:

CALL FPADD(A,B,C)



The packed versions are slower.





There are three multiple precision data types:





FM (multiple precision real)

IM (multiple precision integer)

ZM (multiple precision complex)



Some the the interface routines assume that the precision chosen

in the calling program (using FM_SET or ZM_SET) represents more

significant digits than does the machine's double precision.



Assume fm_ and fp_ are real unpacked and packed numbers.

Assume im_ and ip_ are integer unpacked and packed numbers.

Assume zm_ and zp_ are complex unpacked and packed numbers.





The following commands move data in an out of these types.



fm1=vpa(dp);

=vpa('string');

=vpa(int);

=vpa(dp);

=vpa('string');

=vpa(int)

=vpa(fp );

=fm;



im1=vpa(vpa(int) :to_im);

=vpa(fm :to_im);

=vpa(vpa('string') :to_im);



zm1=vpa(z);

=vpa(fm1,fm2);

=vpa(vpa('string1') vpa('string2'));

=vpa(zm);



fp1=vpa(dp :pack);

=vpa(vpa('string') :pack);

=vpa(vpa(int) :pack);

=vpa(fm :pack);



ip1=vpa(vpa(vpa(int) :to_int) :pack);

=vpa(vpa(vpa('string') :to_int) :pack);



zp1=vpa(zm :pack);

=vpa(vpa(fm1,fm2) :pack);

=vpa(vpa(vpa('string1'),vpa('string2')) :pack);



Note: Since the usual use of the VPA facility is with fm and fp

data the system as been designed to make this use of the

program the most easy. For example getting data into

VPA can be done as:



fm=vpa(1.88);

fm=vpa('1.88');

fm=vpa(22);



----- Brief discussion of Subroutines in Smith Library ---------

------------------------------------------------------------------

----- Routines for Real Floating-Point Operations ------







FMABS(MA,MB) MB = ABS(MA)



FMACOS(MA,MB) MB = ACOS(MA)



FMADD(MA,MB,MC) MC = MA + MB



FMASIN(MA,MB) MB = ASIN(MA)



FMATAN(MA,MB) MB = ATAN(MA)



FMATN2(MA,MB,MC) MC = ATAN2(MA,MB)



FMBIG(MA) MA = Biggest FM number less than overflow.



FMCHSH(MA,MB,MC) MB = COSH(MA), MC = SINH(MA). Faster than

making two separate calls.



FMCOMP(MA,LREL,MB) Logical comparison of MA and MB.

LREL is a CHARACTER*2 value identifying

which comparison is made.

Example: IF (FMCOMP(MA,'GE',MB)) ...



FMCONS Set several saved constants that depend

on MBASE, the base being used. FMCONS

should be called immediately after

changing MBASE.



FMCOS(MA,MB) MB = COS(MA)



FMCOSH(MA,MB) MB = COSH(MA)



FMCSSN(MA,MB,MC) MB = COS(MA), MC = SIN(MA). Faster than

making two separate calls.



FMDIG(NSTACK,KST) Find a set of precisions to use during

Newton iteration for finding a simple

root starting with about double

precision accuracy.



FMDIM(MA,MB,MC) MC = DIM(MA,MB)

FMDIV(MA,MB,MC) MC = MA/MB



FMDIVI(MA,IVAL,MB) MB = MA/IVAL IVAL is a one word integer.



FMDP2M(X,MA) MA = X Convert from double precision to FM.



FMDPM(X,MA) MA = X Convert from double precision to FM.

Much faster than FMDP2M, but MA agrees

with X only to D.P. accuracy. See

the comments in the two routines.



FMEQ(MA,MB) MB = MA Both have precision NDIG.

This is the version to use for

standard B = A statements.



FMEQU(MA,MB,NA,NB) MB = MA Version for changing precision.

MA has NA digits (i.e., MA was

computed using NDIG = NA), and MB

will be defined having NB digits.

MB is zero-padded if NB.GT.NA

MB is rounded if NB.LT.NA



FMEXP(MA,MB) MB = EXP(MA)



FMFORM(FORM,MA,STRING) MA is converted to a character string

using format FORM and returned in

STRING. FORM can represent I, F,

E, or 1PE formats. Example:

CALL FMFORM('F60.40',MA,STRING)



FMFPRT(FORM,MA) Print MA on unit KW using FORM format.



FMI2M(IVAL,MA) MA = IVAL Convert from one word integer

to FM.



FMINP(LINE,MA,LA,LB) MA = LINE Input conversion.

Convert LINE(LA) through LINE(LB)

from characters to FM.



FMINT(MA,MB) MB = INT(MA) Integer part of MA.



FMIPWR(MA,IVAL,MB) MB = MA**IVAL Raise an FM number to a one

word integer power.



FMLG10(MA,MB) MB = LOG10(MA)



FMLN(MA,MB) MB = LOG(MA)



FMLNI(IVAL,MA) MA = LOG(IVAL) Natural log of a one word

integer.



FMM2DP(MA,X) X = MA Convert from FM to double precision.

FMM2I(MA,IVAL) IVAL = MA Convert from FM to integer.



FMM2SP(MA,X) X = MA Convert from FM to single precision.



FMMAX(MA,MB,MC) MC = MAX(MA,MB)



FMMIN(MA,MB,MC) MC = MIN(MA,MB)



FMMOD(MA,MB,MC) MC = MA mod MB



FMMPY(MA,MB,MC) MC = MA*MB



FMMPYI(MA,IVAL,MB) MB = MA*IVAL Multiply by a one word integer.



FMNINT(MA,MB) MB = NINT(MA) Nearest FM integer.



FMOUT(MA,LINE,LB) LINE = MA Convert from FM to character.

LINE is a character array of

length LB.



FMPI(MA) MA = pi



FMPRNT(MA) Print MA on unit KW using current format.



FMPWR(MA,MB,MC) MC = MA**MB



FMREAD(KREAD,MA) MA is returned after reading one (possibly

multi-line) FM number on unit KREAD.

This routine reads numbers written by

FMWRIT.



FMRPWR(MA,K,J,MB) MB = MA**(K/J) Rational power. Faster than

FMPWR for functions like the cube root.



FMSET(NPREC) Set default values and machine-dependent

variables to give at least NPREC base 10

digits plus three base 10 guard digits.

Must be called to initialize FM package.



FMSIGN(MA,MB,MC) MC = SIGN(MA,MB) Sign transfer.



FMSIN(MA,MB) MB = SIN(MA)



FMSINH(MA,MB) MB = SINH(MA)



FMSP2M(X,MA) MA = X Convert from single precision to FM.



FMSQR(MA,MB) MB = MA*MA Faster than FMMPY.



FMSQRT(MA,MB) MB = SQRT(MA)



FMST2M(STRING,MA) MA = STRING

Convert from character string to FM.

Often more convenient than FMINP, which

converts an array of CHARACTER*1 values.

Example: CALL FMST2M('123.4',MA).



FMSUB(MA,MB,MC) MC = MA - MB



FMTAN(MA,MB) MB = TAN(MA)



FMTANH(MA,MB) MB = TANH(MA)



FMULP(MA,MB) MB = One Unit in the Last Place of MA.



FMWRIT(KWRITE,MA) Write MA on unit KWRITE.

Multi-line numbers will have '&' as the

last nonblank character on all but the last

line. These numbers can then be read

easily using FMREAD.







---------------------------------------------------------------------

----------------- Routines for Integer Operations ----------------

---------------------------------------------------------------------





These are the integer routines that are designed to be called by

the user. All are subroutines except logical function IMCOMP.

MA, MB, MC refer to IM format numbers. In each case the version

of the routine to handle packed IM numbers has the same name,

with 'IM' replaced by 'IP'.



IMABS(MA,MB) MB = ABS(MA)



IMADD(MA,MB,MC) MC = MA + MB



IMBIG(MA) MA = Biggest IM number less than overflow.



IMCOMP(MA,LREL,MB) Logical comparison of MA and MB.

LREL is a CHARACTER*2 value identifying

which comparison is made.

Example: IF (IMCOMP(MA,'GE',MB)) ...



IMDIM(MA,MB,MC) MC = DIM(MA,MB)



IMDIV(MA,MB,MC) MC = int(MA/MB)

Use IMDIVR if the remainder is also

needed.



IMDIVI(MA,IVAL,MB) MB = int(MA/IVAL)

IVAL is a one word integer. Use IMDVIR

to get the remainder also.



IMDIVR(MA,MB,MC,MD) MC = int(MA/MB), MD = MA mod MB

When both the quotient and remainder are

needed, this routine is twice as fast as

calling both IMDIV and IMMOD.



IMDVIR(MA,IVAL,MB,IREM) MB = int(MA/IVAL), IREM = MA mod IVAL

IVAL and IREM are one word integers.



IMEQ(MA,MB) MB = MA



IMFM2I(MAFM,MB) MB = MAFM Convert from real (FM) format

to integer (IM) format.



IMFORM(FORM,MA,STRING) MA is converted to a character string

using format FORM and returned in

STRING. FORM can represent I, F,

E, or 1PE formats. Example:

CALL IMFORM('I70',MA,STRING)



IMFPRT(FORM,MA) Print MA on unit KW using FORM format.



IMGCD(MA,MB,MC) MC = greatest common divisor of MA and MB.



IMI2FM(MA,MBFM) MBFM = MA Convert from integer (IM) format

to real (FM) format.



IMI2M(IVAL,MA) MA = IVAL Convert from one word integer

to IM.



IMINP(LINE,MA,LA,LB) MA = LINE Input conversion.

Convert LINE(LA) through LINE(LB)

from characters to IM.



IMM2DP(MA,X) X = MA Convert from IM to double

precision.



IMM2I(MA,IVAL) IVAL = MA Convert from IM to one word

integer.



IMMAX(MA,MB,MC) MC = MAX(MA,MB)



IMMIN(MA,MB,MC) MC = MIN(MA,MB)



IMMOD(MA,MB,MC) MC = MA mod MB



IMMPY(MA,MB,MC) MC = MA*MB



IMMPYI(MA,IVAL,MB) MB = MA*IVAL Multiply by a one word integer.



IMMPYM(MA,MB,MC,MD) MD = MA*MB mod MC

Slightly faster than calling IMMPY and

IMMOD separately, and it works for cases

where IMMPY would return OVERFLOW.



IMOUT(MA,LINE,LB) LINE = MA Convert from IM to character.

LINE is a character array of

length LB.

IMPMOD(MA,MB,MC,MD) MD = MA**MB mod MC



IMPRNT(MA) Print MA on unit KW.



IMPWR(MA,MB,MC) MC = MA**MB



IMREAD(KREAD,MA) MA is returned after reading one (possibly

multi-line) IM number on unit KREAD. This

routine reads numbers written by IMWRIT.



IMSIGN(MA,MB,MC) MC = SIGN(MA,MB) Sign transfer.



IMSQR(MA,MB) MB = MA*MA Faster than IMMPY.



IMST2M(STRING,MA) MA = STRING

Convert from character string to IM.

Often more convenient than IMINP, which

converts an array of CHARACTER*1 values.

Example: CALL IMST2M('12345678901',MA).



IMSUB(MA,MB,MC) MC = MA - MB



IMWRIT(KWRITE,MA) Write MA on unit KWRITE.

Multi-line numbers will have '&' as

the last nonblank character on all but

the last line. These numbers can then be

read easily using IMREAD.



Many of the IM routines call FM routines, but none of the FM

routines call IM routines, so the IM routines can be omitted

if none are called explicitly from a program.







---------------------------------------------------------------------

---------- Routines for Complex Floating-Point Operations -------

---------------------------------------------------------------------





These are the routines in ZMLIB that are designed to be called by

the user. All are subroutines, and in each case the version of the

routine to handle packed ZM numbers has the same name, with 'ZM'

replaced by 'ZP'.



MA, MB, MC refer to ZM format complex numbers.

MAFM, MBFM, MCFM refer to FM format real numbers.

INTEG is a Fortran INTEGER variable.

ZVAL is a Fortran COMPLEX variable.



In each case it is permissible to use the same array more than

once in the calling sequence. The statement

MA = MA*MA may be written CALL ZMMPY(MA,MA,MA).

ZMABS(MA,MBFM) MBFM = ABS(MA) Result is real.



ZMACOS(MA,MB) MB = ACOS(MA)



ZMADD(MA,MB,MC) MC = MA + MB



ZMADDI(MA,INTEG) MA = MA + INTEG Increment an ZM number by a

one word integer. Note this

call does not have an "MB"

result like ZMDIVI and

ZMMPYI.



ZMARG(MA,MBFM) MBFM = Argument(MA) Result is real.



ZMASIN(MA,MB) MB = ASIN(MA)



ZMATAN(MA,MB) MB = ATAN(MA)



ZMCHSH(MA,MB,MC) MB = COSH(MA), MC = SINH(MA).

Faster than 2 calls.



ZMCMPX(MAFM,MBFM,MC) MC = CMPLX(MAFM,MBFM)



ZMCONJ(MA,MB) MB = CONJG(MA)



ZMCOS(MA,MB) MB = COS(MA)



ZMCOSH(MA,MB) MB = COSH(MA)



ZMCSSN(MA,MB,MC) MB = COS(MA), MC = SIN(MA).

Faster than 2 calls.



ZMDIV(MA,MB,MC) MC = MA / MBOn the PC the SHNAME(' ',' ','

') comma



ZMDIVI(MA,INTEG,MB) MB = MA / INTEG



ZMEQ(MA,MB) MB = MA



ZMEQU(MA,MB,NDA,NDB) MB = MA Version for changing precision.

(NDA and NDB are as in FMEQU)



ZMEXP(MA,MB) MB = EXP(MA)



ZMFORM(FORM1,FORM2,MA,STRING) STRING = MA

MA is converted to a character string using

format FORM1 for the real part and FORM2 for

the imaginary part. The result is returned

in STRING. FORM1 and FORM2 can represent I,

F, E, or 1PE formats. Example:

CALL ZMFORM('F20.10','F15.10',MA,STRING)



ZMFPRT(FORM1,FORM2,MA) Print MA on unit KW using

formats FORM1 and FORM2.

ZMI2M(INTEG,MA) MA = CMPLX(INTEG,0)



ZM2I2M(INTEG1,INTEG2,MA) MA = CMPLX(INTEG1,INTEG2)



ZMIMAG(MA,MBFM) MBFM = IMAG(MA) Imaginary part.



ZMINP(LINE,MA,LA,LB) MA = LINE Input conversion.

Convert LINE(LA) through LINE(LB)

from characters to ZM. LINE is a

character array of length at least

LB.



ZMINT(MA,MB) MB = INT(MA) Integer part of both Real

and Imaginary parts of MA.



ZMIPWR(MA,INTEG,MB) MB = MA ** INTEG Integer power function.



ZMLG10(MA,MB) MB = LOG10(MA)



ZMLN(MA,MB) MB = LOG(MA)



ZMM2I(MA,INTEG) INTEG = INT(REAL(MA))



ZMM2Z(MA,ZVAL) ZVAL = MA



ZMMPY(MA,MB,MC) MC = MA * MB



ZMMPYI(MA,INTEG,MB) MB = MA * INTEG



ZMNINT(MA,MB) MB = NINT(MA) Nearest integer of both Real

and Imaginary.



ZMOUT(MA,LINE,LB,LAST1,LAST2) LINE = MA

Convert from FM to character.

LINE is the returned character array.

LB is the dimensioned size of LINE.

LAST1 is returned as the position in LINE of

the last character of REAL(MA).

LAST2 is returned as the position in LINE

of the last character of AIMAG(MA).



ZMPRNT(MA) Print MA on unit KW using current format.



ZMPWR(MA,MB,MC) MC = MA ** MB



ZMREAD(KREAD,MA) MA is returned after reading one (possibly

multi-line) ZM number on unit KREAD. This

routine reads numbers written by ZMWRIT.



ZMREAL(MA,MBFM) MBFM = REAL(MA) Real part.



ZMRPWR(MA,IVAL,JVAL,MB) MB = MA ** (IVAL/JVAL)

ZMSET(NPREC) Initialize ZM package. Set precision to the

equivalent of at least NPREC base 10 digits.



ZMSIN(MA,MB) MB = SIN(MA)



ZMSINH(MA,MB) MB = SINH(MA)



ZMSQR(MA,MB) MB = MA*MA Faster than ZMMPY.



ZMSQRT(MA,MB) MB = SQRT(MA)



ZMST2M(STRING,MA) MA = STRING

Convert from character string to ZM.

Often more convenient than ZMINP, which

converts an array of CHARACTER*1 values.

Example: CALL ZMST2M('123.4+5.67i',MA).



ZMSUB(MA,MB,MC) MC = MA - MB



ZMTAN(MA,MB) MB = TAN(MA)



ZMTANH(MA,MB) MB = TANH(MA)



ZMWRIT(KWRITE,MA) Write MA on unit KWRITE. Multi-line numbers

are formatted for automatic reading with

ZMREAD.



ZMZ2M(ZVAL,MA) MA = ZVAL







---------------------------------------------------------------------

-------------------------- FMLIB.f Notes ------------------------

---------------------------------------------------------------------



The FM routines in this package perform floating-point

multiple-precision arithmetic, and the IM routines perform

integer multiple-precision arithmetic.







1. INITIALIZING THE PACKAGE



Before calling any routine in the package, several variables in

the common blocks /FMUSER/, /FM/, /FMBUFF/, and /FMSAVE/ must be

initialized. These four common blocks contain information that

is saved between calls, so they should be declared in the main

program.



Subroutine FMSET initializes these variables to default values and

defines all machine-dependent values in the package. After calling

FMSET once at the start of a program, the user may sometimes want

to reset some of the variables in these common blocks. These

variables are described below.

2. REPRESENTATION OF FM NUMBERS



MBASE is the base in which the arithmetic is done. MBASE must be

bigger than one, and less than or equal to the square root of

the largest representable integer. For best efficiency MBASE

should be large, but no more than about 1/4 of the square

root of the largest representable integer. Input and output

conversions are much faster when MBASE is a power of ten.



NDIG is the number of base MBASE digits that are carried in the

multiple precision numbers. NDIG must be at least two. The

upper limit for NDIG is defined in the PARAMETER statement at

the top of each routine and is restricted only by the amount

of memory available.



Sometimes it is useful to dynamically vary NDIG during the program.

Use FMEQU to round numbers to lower precision or zero-pad them to

higher precision when changing NDIG.



It is rare to need to change MBASE during a program. Use FMCONS to

reset some saved constants that depend on MBASE. FMCONS should be

called immediately after changing MBASE.



There are two representations for a floating multiple precision

number. The unpacked representation used by the routines while

doing the computations is base MBASE and is stored in NDIG+2 words.

A packed representation is available to store the numbers in the

user's program in compressed form. In this format, the NDIG

(base MBASE) digits of the mantissa are packed two per word to

conserve storage. Thus the external, packed form of a number

requires (NDIG+1)/2+2 words.



This version uses double precision arrays to hold the numbers.

Version 1.0 of FM used integer arrays, which are faster on some

machines. The package can easily be changed to use integer

arrays -- see section 11 on EFFICIENCY below.



The unpacked format of a floating multiple precision number is as

follows. A number MA is kept in an array with MA(1) containing

the exponent and MA(2) through MA(NDIG+1) containing one digit of

the mantissa, expressed in base MBASE. The array is dimensioned

to start at MA(0), with the approximate number of bits of precision

stored in MA(0). This precision value is intended to be used by FM

functions that need to monitor cancellation error in addition and

subtraction. The cancellation monitor code is usually disabled for

user calls, and FM functions only check for cancellation when they

must. Tracking cancellation causes most routines to run slower,

with addition and subtraction being affected the most.



The exponent is a power of MBASE and the implied radix point is

immediately before the first digit of the mantissa. Every nonzero

number is normalized so that the second array element (the first

digit of the mantissa) is nonzero.

In both representations the sign of the number is carried on the

second array element only. Elements 3,4,... are always nonnegative.

The exponent is a signed integer and may be as large in magnitude

as MXEXP (defined in FMSET).



For MBASE = 10,000 and NDIG = 4, the number -pi would have these

representations:

Word 1 2 3 4 5



Unpacked: 1 -3 1415 9265 3590

Packed: 1 -31415 92653590



Word 0 would be 42 in both formats, indicating that the mantissa

has about 42 bits of precision.



Because of normalization in a large base, the equivalent number

of base 10 significant digits for an FM number may be as small as

LOG10(MBASE)*(NDIG-1) + 1.



The integer routines use the FMLIB format to represent numbers,

without the number of digits (NDIG) being fixed. Integers in IM

format are essentially variable precision, using the minimum number

of words to represent each value.



For programs using both FM and IM numbers, FM routines should not

be called with IM numbers, and IM routines should not be called

with FM numbers, since the implied value of NDIG used for an IM

number may not match the explicit NDIG expected by an FM routine.

Use the conversion routines IMFM2I and IMI2FM to change between

the FM and IM formats.







3. INPUT/OUTPUT ROUTINES



All versions of the input routines perform free-format conversion

from characters to FM numbers.



a. Conversion to or from a character array



FMINP converts from a character*1 array to an FM number.



FMOUT converts an FM number to base 10 and formats it for output

as an array of type character*1. The output is left

justified in the array, and the format is defined by two

variables in common, so that a separate format definition

does not have to be provided for each output call.



The user sets JFORM1 and JFORM2 to determine the output format.



JFORM1 = 0 E format ( .314159M+6 )

= 1 1PE format ( 3.14159M+5 )

= 2 F format ( 314159.000 )

JFORM2 is the number of significant digits to display (if

JFORM1 = 0 or 1). If JFORM2.EQ.0 then a default number

of digits is chosen. The default is roughly the full

precision of the number.

JFORM2 is the number of digits after the decimal point (if

JFORM1 = 2).See FMOUT documentation for more details.



b. Conversion to or from a character string



FMST2M converts from a character string to an FM number.



FMFORM converts an FM number to a character string according to

a format provided in each call. The format description

is more like that of a Fortran FORMAT statement, and

integer or fixed-point output is right justified.



c. Direct read or write



FMPRNT uses FMOUT to print one FM number.



FMFPRT uses FMFORM to print one FM number.



FMWRIT writes FM numbers for later input using FMREAD.



FMREAD reads FM numbers written by FMWRIT.



The values given to JFORM1 and JFORM2 can be used to define a

default output format when FMOUT or FMPRNT are called. The

explicit format used in a call to FMFORM or FMFPRT overrides

the settings of JFORM1 and JFORM2.



KW is the unit number to be used for standard output from

the package, including error and warning messages, and

trace output.



For multiple precision integers, the corresponding routines

IMINP, IMOUT, IMST2M, IMFORM, IMPRNT, IMFPRT, IMWRIT, and

IMREAD provide similar input and output conversions. For

output of IM numbers, JFORM1 and JFORM2 are ignored and

integer format (JFORM1=2, JFORM2=0) is used.



For further description of these routines, see sections

9 and 10 below.







4. ARITHMETIC TRACING



NTRACE and LVLTRC control trace printout from the package.



NTRACE = 0 No printout except warnings and errors.

= 1 The result of each call to one of the routines

is printed in base 10, using FMOUT.

= -1 The result of each call to one of the routines

is printed in internal base MBASE format.

= 2 The input arguments and result of each call to one

of the routines is printed in base 10, using FMOUT.

= -2 The input arguments and result of each call to one

of the routines is printed in base MBASE format.



LVLTRC defines the call level to which the trace is done.

LVLTRC = 1 means only FM routines called directly by the user are

traced, LVLTRC = 2 also prints traces for FM routines called by

other FM routines called directly by the user, etc.



In the above description, internal MBASE format means the number is

printed as it appears in the array --- an exponent followed by NDIG

base MBASE digits.







5. ERROR CONDITIONS



KFLAG is a condition parameter returned by the package after each

call to one of the routines. Negative values indicate

conditions for which a warning message will be printed

unless KWARN = 0. Positive values indicate conditions

that may be of interest but are not errors.

No warning message is printed if KFLAG is nonnegative.



KFLAG = 0 Normal operation.



= 1 One of the operands in FMADD or FMSUB was

insignificant with respect to the other, so

that the result was equal to the argument of

larger magnitude.

= 2 In converting an FM number to a one word integer

in FMM2I, the FM number was not exactly an

integer. The next integer toward zero was

returned.



= -1 NDIG was less than 2 or more than NDIGMX.

= -2 MBASE was less than 2 or more than MXBASE.

= -3 An exponent was out of range.

= -4 Invalid input argument(s) to an FM routine.

UNKNOWN was returned.

= -5 + or - OVERFLOW was generated as a result from an

FM routine.

= -6 + or - UNDERFLOW was generated as a result from an

FM routine.

= -7 The input string (array) to FMINP was not legal.

= -8 The character array was not large enough in an

input or output routine.

= -9 Precision could not be raised enough to provide all

requested guard digits. Increasing NDIGMX in

all the PARAMETER statements may fix this.

UNKNOWN was returned.

= -10 An FM input argument was too small in magnitude to

convert to the machine's single or double

precision in FMM2SP or FMM2DP. Check that the

definitions of SPMAX and DPMAX in FMSET are

correct for the current machine. Zero was returned.



When a negative KFLAG condition is encountered, the value of KWARN

determines the action to be taken.



KWARN = 0 Execution continues and no message is printed.

= 1 A warning message is printed and execution continues.

= 2 A warning message is printed and execution stops.



The default setting is KWARN = 1.



When an overflow or underflow is generated for an operation in which

an input argument was already an overflow or underflow, no additional

message is printed. When an unknown result is generated and an input

argument was already unknown, no additional message is printed. In

these cases the negative KFLAG value is still returned.



IM routines handle exceptions like OVERFLOW or UNKNOWN in the same

way as FM routines. When using IMMPY, the product of two large

positive integers will return +OVERFLOW. The routine IMMPYM can

be used to obtain a modular result without overflow. The largest

representable IM integer is MBASE**NDIGMX - 1. For example, if

MBASE is 10**7 and NDIGMX is set to 256, integers less than 10**1792

can be used.







6. OTHER PARAMETERS



KRAD = 0 All angles in the trigonometric functions and

inverse functions are measured in degrees.

= 1 All angles are measured in radians. (Default)





KROUND = 0 All final results are chopped (rounded toward

zero). Intermediate results are rounded.

= 1 All results are rounded to the nearest FM

number, or to the value with an even last

digit if the result is halfway between two

FM numbers. (Default)



KSWIDE defines the maximum screen width to be used for all unit KW

output. Default is 80.



KESWCH controls the action taken in FMINP and other input routines

for strings like 'E7' that have no digits before the exponent

field. Default is for 'E7' to translate like '1.0E+7'.



CMCHAR defines the exponent letter to be used for FM variable

output. Default is 'M', as in 1.2345M+678.

KDEBUG = 0 Error checking is not done for valid input arguments

and parameters like NDIG and MBASE upon entry to

each routine. (Default)

= 1 Some error checking is done. (Slower speed)



See FMSET for additional description of these and other variables

defining various FM conditions.







7. ARRAY DIMENSIONS



The dimensions of the arrays in the FM package are defined using

a PARAMETER statement at the top of each routine. The size of

these arrays depends on the values of parameters NDIGMX and NBITS.

NDIGMX is the maximum value the user may set for NDIG.

NBITS is the number of bits used to represent integers for a

given machine. See the EFFICIENCY discussion below.



The standard version of FMLIB sets NDIGMX = 256, so on a 32-bit

machine using MBASE = 10**7 the maximum precision is about

7*255+1 = 1786 significant digits. To change dimensions so that

10,000 significant digit calculation can be done, NDIGMX needs to

be at least 10**4/7 + 5 = 1434. This allows for a few user guard

digits to be defined when the package is initialized using

CALL FMSET(10000). Changing 'NDIGMX=256' to 'NDIGMX=1434'

everywhere in the package and the user's calling program will

define all the new array sizes.



If NDIG much greater than 256 is to be used and elementary functions

will be needed, they will be faster if array MJSUMS is larger. The

parameter defining the size of MJSUMS is set in the standard version

by LJSUMS = 8*(LUNPCK+2). The 8 means that up to eight concurrent

sums can be used by the elementary functions. The approximate number

needed for best speed is given by the formula



0.051*Log(MBASE)*NDIG**(1/3) + 1.85



For example, with MBASE=10**7 and NDIG=1434 this gives 11. Changing

LJSUMS = 8*(LUNPCK+2)' to 'LJSUMS =11*(LUNPCK+2)' everywhere in the

package and the user's calling program will give slightly better

speed.



FM numbers in packed format have dimension 0:LPACK, and those

in unpacked format have dimension 0:LUNPCK.



8. PORTABILITY



In FMSET there is some machine-dependent code that attempts to

approximate the largest representable integer value. The current

code works on all machines tested, but if an FM run fails, check

the MAXINT and INTMAX loops in FMSET. Values for SPMAX and DPMAX

are also defined in FMSET that should be set to values near overflow

for single precision and double precision. Setting KDEBUG = 1 may

also identify some errors if a run fails.



Some compilers object to a function like FMCOMP with side effects

such as changing KFLAG or other common variables. Blocks of code

in FMCOMP and IMCOMP that modify common are identified so they may

be removed or commented out to produce a function without side

effects. This disables trace printing in FMCOMP and IMCOMP, and

error codes are not returned in KFLAG. See FMCOMP and IMCOMP for

further details.



All variables are explicitly declared in each routine. There is

a commented IMPLICIT NONE statement in each routine that can be

enabled to get more compiler diagnostic information in some testing

or debugging situations.





9. NEW FOR VERSION 1.1



Version 1.0 used integer arrays and integer arithmetic internally

to perform the multiple precision operations. Version 1.1 uses

double precision arithmetic and arrays internally. This is usually

faster at higher precisions, and on many machines it is also faster

at lower precisions. Version 1.1 is written so that the arithmetic

used can easily be changed from double precision to integer, or any

other available arithmetic type. This permits the user to make the

best use of a given machine's arithmetic hardware.

See the EFFICIENCY discussion below.



Several routines have undergone minor modification, but only a few

changes should affect programs that used FM 1.0. Many of the

routines are faster in version 1.1, because code has been added to

take advantage of special cases for individual functions instead of

using general formulas that are more compact. For example, there

are separate routines using series for SINH and COSH instead of

just calling EXP.



FMEQU was the only routine that required the user to give the value

of the current precision. This was to allow automatic rounding or

zero-padding when changing precision. Since few user calls change

precision, a new routine has been added for this case.



FMEQ now handles this case and has a simple argument list that does

not include the value of NDIG. FMEQU is used for changing precision.



See the list of FM routines above for details.



All variable names beginning with M in the package are now declared

as double precision, so FM common blocks in the user's program need

D.P. declarations, and FM variables (arrays) used in the calling

program need to be D.P.



/FMUSER/ is a common block holding parameters that define the

arithmetic to be used and other user options. Several

new variables have been added, including screen width to

be used for output. See above for further description.



/FMSAVE/ is a common block for saving constants to avoid

re-computing them. Several new variables have been added.



/FMBUFF/ is a common block containing a character array used to

format FM numbers for output. Two new items have been

added.



New routines:



All the IM routines are new for version 1.1.



FMADDI increments an FM number by a small integer.

It runs in O(1) time, on the average.



FMCHSH returns both SINH(MA) and COSH(MA).

When both are needed, this is almost twice as fast

as making separate calls to FMCOSH and FMSINH.



FMCSSN returns both SIN(MA) and COS(MA).

When both are needed, this is almost twice as fast

as making separate calls to FMCOS and FMSIN.



FMFORM uses a format string to convert an FM number to a

character string.



FMFPRT prints an FM number using a format string.



FMREAD reads an FM number written using FMWRIT.



FMRPWR computes an FM number raised to a rational power. For cube

roots and similar rational powers it is usually much faster

than FMPWR.



FMSQR squares an FM number. It is faster than using FMMPY.



FMST2M converts character strings to FM format. Since FMINP converts

character arrays, this routine can be more convenient for

easily defining an FM number.

For example, CALL FMST2M('123.4',MA).



FMWRIT writes an FM number using a format for multi-line numbers

with '&' at the end of all but the last line of a multi-

line

number. This allows automatic reading of FM numbers without

needing to know the base, precision or format under which they

were written.



One extra word has been added to the dimensions of all FM numbers.

Word zero in each array contains a value used to monitor cancellation

error arising from addition or subtraction. This value approximates

the number of bits of precision for an FM value. It allows higher

level FM functions to detect cases where too much cancellation has

occurred. KACCSW is a switch variable in COMMON /FM/ used internally

to enable cancellation error monitoring.





10. EFFICIENCY



To take advantage of hardware architecture on different machines, the

package has been designed so that the arithmetic used to perform the

multiple precision operations can easily be changed. All variables

that must be changed to get a different arithmetic have names

beginning with 'M' and are declared using DOUBLE PRECISION M....



For example, to change the package to use integer arithmetic

internally, make these two changes everywhere in the package:

change 'DOUBLE PRECISION M' to 'INTEGER M',

change 'DINT(' to 'INT('.

On some systems, changing 'DINT(' to '(' may give better speed.



When changing to a different type of arithmetic, all FM common blocks

and arrays in the user's program must be changed to agree. In a few

places in FM, where a DINT function is not supposed to be changed, it

is spelled 'DINT (' so the global change will not find it.



This version restricts the base used to be also representable in

integer variables, so using precision above double usually does not

save much time unless integers can also be declared at a higher

precision. Using IEEE Extended would allow a base of around 10**9

to be chosen, but the delayed digit-normalization method used for

multiplication and division means that a slightly smaller base like

10**8 would usually run faster. This would usually not be much

faster than using 10**7 with double precision.



The value of NBITS defined as a parameter in most FM routines

refers to the number of bits used to represent integers in an

M-variable word. Typical values for NBITS are: 24 for IEEE single

precision, 32 for integer, 53 for IEEE double precision. NBITS

controls only array size, so setting it too high is ok, but then

the program will use more memory than necessary.



For cases where special compiler directives or minor re-writing

of the code may improve speed, several of the most important

loops in FM are identified by comments containing the string

'(Inner Loop)'.







---------------------------------------------------------------------

-------------------------- ZMLIB.f Notes ------------------------

---------------------------------------------------------------------



The ZM routines perform complex floating-point multiple-precision

arithmetic.

These routines use the FMLIB package (version 1.1) for real

floating-point multiple-precision arithmetic.



FMLIB is Algorithm 693, ACM Transactions on Mathematical Software,

Vol. 17, No. 2, June 1991, pages 273-283.



This package and FMLIB 1.1 use double precision arithmetic and arrays

internally. This is usually faster at higher precision, and on many

machines it is also faster at lower precision. Both packages are

written so that the arithmetic used can easily be changed from double

precision to integer, or another available arithmetic type. See the

EFFICIENCY discussion in the FMLIB.f Notes for details.







1. INITIALIZING THE PACKAGE



Before calling any routine in the package, several variables in the

common blocks /FMUSER/, /FM/, /FMSAVE/, /FMBUFF/, and /ZMUSER/ must

be initialized. These common blocks contain information that is

saved between calls, so they should be declared in the main program.



Subroutine ZMSET initializes these variables to default values and

defines all machine-dependent values in the package. After calling

ZMSET once at the start of a program, the user may sometimes want

to reset some of the variables in common blocks

/FMUSER/ or /ZMUSER/.





2. REPRESENTATION OF ZM NUMBERS



The format for complex FM numbers (called ZM numbers below) is very

similar to that for real FM numbers in FMLIB. Each ZM array holds

two FM numbers to represent the real and imaginary parts of a

complex number. Each ZM array is twice as long as a corresponding

FM array, with the imaginary part starting at the midpoint of the

array. As with FM, there are packed and unpacked formats for the

numbers.





3. INPUT/OUTPUT ROUTINES



All versions of the input routines perform free-format conversion

from characters to ZM numbers.



a. Conversion to or from a character array



ZMINP converts from a character*1 array to an ZM number.



ZMOUT converts an ZM number to base 10 and formats it for output

as an array of type character*1. The output is left

justified in the array, and the format is defined by

variables in common, so that a separate format definition

does not have to be provided for each output call.

For the output format of ZM numbers, JFORM1 and JFORM2 determine

the format for the individual parts of a complex number as

described in the FMLIB documentation.



JFORMZ (in /ZMUSER/) determines the combined output format of

the real and imaginary parts.



JFORMZ = 1 normal setting : 1.23 - 4.56 i

= 2 use capital I : 1.23 - 4.56 I

= 3 parenthesis format ( 1.23 , -4.56 )



JPRNTZ (in /ZMUSER/) controls whether to print real

and imaginary parts on one line whenever possible.



JPRNTZ = 1print both parts as a single string :

1.23456789M+321 - 9.87654321M-123 i

= 2 print on separate lines without the 'i' :

1.23456789M+321

-9.87654321M-123



b. Conversion to or from a character string



ZMST2M converts from a character string to an ZM number.



ZMFORM converts an ZM number to a character string according to

a format provided in each call. The format descriptions

are more like that of a Fortran FORMAT statement, and

integer or fixed-point output is right justified.



c. Direct read or write



ZMPRNT uses ZMOUT to print one ZM number.



ZMFPRT uses ZMFORM to print one ZM number.



ZMWRIT writes ZM numbers for later input using ZMREAD.



ZMREAD reads ZM numbers written by ZMWRIT.



For further description of these routines, see the list of ZM

routines above.





4. ARRAY DIMENSIONS



The parameters LPACKZ and LUNPKZ define the size of the packed and

unpacked ZM arrays. The real part starts at the beginning of the

array, and the imaginary part starts at word KPTIMP for packed format

or at word KPTIMU for unpacked format.



---------------------------------------------------------------------


Share This Document


Related docs
Other docs by TitusYoung
PDQ (050702)
Views: 12  |  Downloads: 0
Prosecution
Views: 24  |  Downloads: 0
October DOC[98]
Views: 5  |  Downloads: 0
Flipchart Transcript
Views: 3  |  Downloads: 0
April DOC[176]
Views: 8  |  Downloads: 0
GENMOD
Views: 16  |  Downloads: 3
Centers for Disease Control and Prevention
Views: 48  |  Downloads: 0
rr
Views: 31  |  Downloads: 0
Privacy Audit form
Views: 2  |  Downloads: 0
Systems Thinking, Part II
Views: 15  |  Downloads: 1
by registering with docstoc.com you agree to our
privacy policy

You are almost ready to download!

You are almost ready to download!