Matrices
********

Some pspp procedures work with matrices by producing numeric matrices that report results of data analysis, or by consuming matrices as a basis for further analysis.  This chapter documents the format of data files that store these matrices and commands for working with them, as well as pspp's general-purpose facility for matrix operations.

Matrix Files
============

A matrix file is an SPSS system file that conforms to the dictionary and case structure described in this section.  Procedures that read matrices from files expect them to be in the matrix file format. Procedures that write matrices also use this format.

Text files that contain matrices can be converted to matrix file format.  See MATRIX DATA, for a command to read a text file as a matrix file.

A matrix file's dictionary must have the following variables in the specified order:

 1. Zero or more numeric split variables.  These are included by procedures when SPLIT FILE is active.  MATRIX DATA assigns split variables format F4.0.

 2. ROWTYPE_, a string variable with width 8.  This variable indicates the kind of matrix or vector that a given case represents. The supported row types are listed below.

 3. Zero or more numeric factor variables.  These are included by procedures that divide data into cells.  For within-cell data, factor variables are filled with non-missing values; for pooled data, they are missing.  MATRIX DATA assigns factor variables format F4.0.

 4. VARNAME_, a string variable.  Matrix data includes one row per continuous variable (see below), naming each continuous variable in order.  This column is blank for vector data.  MATRIX DATA makes VARNAME_ wide enough for the name of any of the continuous variables, but at least 8 bytes.

 5. One or more numeric continuous variables.  These are the variables whose data was analyzed to produce the matrices.  MATRIX DATA assigns continuous variables format F10.4.

Case weights are ignored in matrix files.

Row Types
---------

Matrix files support a fixed set of types of matrix and vector data. The ROWTYPE_ variable in each case of a matrix file indicates its row type.

The supported matrix row types are listed below.  Each type is listed with the keyword that identifies it in ROWTYPE_.  All supported types of matrices are square, meaning that each matrix must include one row per continuous variable, with the VARNAME_ variable indicating each continuous variable in turn in the same order as the dictionary.

CORR
     Correlation coefficients.

COV
     Covariance coefficients.

MAT
     General-purpose matrix.

N_MATRIX
     Counts.

PROX
     Proximities matrix.

The supported vector row types are listed below, along with their associated keyword.  Vector row types only require a single row, whose VARNAME_ is blank:

COUNT
     Unweighted counts.

DFE
     Degrees of freedom.

MEAN
     Means.

MSE
     Mean squared errors.

N
     Counts.

STDDEV
     Standard deviations.

Only the row types listed above may appear in matrix files.  The MATRIX DATA command, however, accepts the additional row types listed below, which it changes into matrix file row types as part of its conversion process:

N_VECTOR
     Synonym for N.

SD
     Synonym for STDDEV.

N_SCALAR
     Accepts a single number from the MATRIX DATA input and writes it as an N row with the number replicated across all the continuous variables.

MATRIX DATA
===========

     MATRIX DATA
             VARIABLES=VARIABLES
             [FILE={'FILE_NAME' | INLINE}
             [/FORMAT=[{LIST | FREE}]
                      [{UPPER | LOWER | FULL}]
                      [{DIAGONAL | NODIAGONAL}]]
             [/SPLIT=SPLIT_VARS]
             [/FACTORS=FACTOR_VARS]
             [/N=N]

     The following subcommands are only needed when ROWTYPE_ is not
     specified on the VARIABLES subcommand:
             [/CONTENTS={CORR,COUNT,COV,DFE,MAT,MEAN,MSE,
                         N_MATRIX,N|N_VECTOR,N_SCALAR,PROX,SD|STDDEV}]
             [/CELLS=N_CELLS]

The MATRIX DATA command convert matrices and vectors from text format into the matrix file format (see Matrix Files) for use by procedures that read matrices.  It reads a text file or inline data and outputs to the active file, replacing any data already in the active dataset.  The matrix file may then be used by other commands directly from the active file, or it may be written to a .sav file using the SAVE command.

The text data read by MATRIX DATA can be delimited by spaces or commas.  A plus or minus sign, except immediately following a d or e, also begins a new value.  Optionally, values may be enclosed in single or double quotes.

MATRIX DATA can read the types of matrix and vector data supported in matrix files (see Matrix File Row Types).

The FILE subcommand specifies the source of the command's input.  To read input from a text file, specify its name in quotes. To supply input inline, omit FILE or specify INLINE. Inline data must directly follow MATRIX DATA, inside BEGIN DATA (see BEGIN DATA).

VARIABLES is the only required subcommand.  It names the variables present in each input record in the order that they appear. (MATRIX DATA reorders the variables in the matrix file it produces, if needed to fit the matrix file format.)  The variable list must include split variables and factor variables, if they are present in the data, in addition to the continuous variables that form matrix rows and columns.  It may also include a special variable named ROWTYPE_.

Matrix data may include split variables or factor variables or both. List split variables, if any, on the SPLIT subcommand and factor variables, if any, on the FACTORS subcommand.  Split and factor variables must be numeric.  Split and factor variables must also be listed on VARIABLES, with one exception: if VARIABLES does not include ROWTYPE_, then SPLIT may name a single variable that is not in VARIABLES (see MATRIX DATA Example 8).

The FORMAT subcommand accepts settings to describe the format of the input data:

LIST (default)
FREE
     LIST requires each row to begin at the start of a new input line. FREE allows rows to begin in the middle of a line.  Either setting allows a single row to continue across multiple input lines.

LOWER (default)
UPPER
FULL
     With LOWER, only the lower triangle is read from the input data and the upper triangle is mirrored across the main diagonal.  UPPER behaves similarly for the upper triangle.  FULL reads the entire matrix.

DIAGONAL (default)
NODIAGONAL
     With DIAGONAL, the main diagonal is read from the input data.  With NODIAGONAL, which is incompatible with FULL, the main diagonal is not read from the input data but instead set to 1 for correlation matrices and system-missing for others.

The N subcommand is a way to specify the size of the population.  It is equivalent to specifying an N vector with the specified value for each split file.

MATRIX DATA supports two different ways to indicate the kinds of matrices and vectors present in the data, depending on whether a variable with the special name ROWTYPE_ is present in VARIABLES.  The following subsections explain MATRIX DATA syntax and behavior in each case.

With ROWTYPE_
-------------

If VARIABLES includes ROWTYPE_, each case's ROWTYPE_ indicates the type of data contained in the row. See Matrix File Row Types, for a list of supported row types.

Example 1: Defaults with ROWTYPE_
.................................

This example shows a simple use of MATRIX DATA with ROWTYPE_ plus 8 variables named var01 through var08.

Because ROWTYPE_ is the first variable in VARIABLES, it appears first on each line. The first three lines in the example data have ROWTYPE_ values of MEAN, SD, and N.  These indicate that these lines contain vectors of means, standard deviations, and counts, respectively, for var01 through var08 in order.

The remaining 8 lines have a ROWTYPE_ of CORR which indicates that the values are correlation coefficients.  Each of the lines corresponds to a row in the correlation matrix: the first line is for var01, the next line for var02, and so on.  The input only contains values for the lower triangle, including the diagonal, since FORMAT=LOWER DIAGONAL is the default.

With ROWTYPE_, the CONTENTS subcommand is optional and the CELLS subcommand may not be used.

     MATRIX DATA
         VARIABLES=ROWTYPE_ var01 TO var08.
     BEGIN DATA.
     MEAN  24.3   5.4  69.7  20.1  13.4   2.7  27.9   3.7
     SD     5.7   1.5  23.5   5.8   2.8   4.5   5.4   1.5
     N       92    92    92    92    92    92    92    92
     CORR  1.00
     CORR   .18  1.00
     CORR  -.22  -.17  1.00
     CORR   .36   .31  -.14  1.00
     CORR   .27   .16  -.12   .22  1.00
     CORR   .33   .15  -.17   .24   .21  1.00
     CORR   .50   .29  -.20   .32   .12   .38  1.00
     CORR   .17   .29  -.05   .20   .27   .20   .04  1.00
     END DATA.

Example 2: FORMAT=UPPER NODIAGONAL
..................................

This syntax produces the same matrix file as example 1, but it uses FORMAT=UPPER NODIAGONAL to specify the upper triangle and omit the diagonal.  Because the matrix's ROWTYPE_ is CORR, pspp automatically fills in the diagonal with 1.

     MATRIX DATA
         VARIABLES=ROWTYPE_ var01 TO var08
         /FORMAT=UPPER NODIAGONAL.
     BEGIN DATA.
     MEAN  24.3   5.4  69.7  20.1  13.4   2.7  27.9   3.7
     SD     5.7   1.5  23.5   5.8   2.8   4.5   5.4   1.5
     N       92    92    92    92    92    92    92    92
     CORR         .17   .50  -.33   .27   .36  -.22   .18
     CORR               .29   .29  -.20   .32   .12   .38
     CORR                     .05   .20  -.15   .16   .21
     CORR                           .20   .32  -.17   .12
     CORR                                 .27   .12  -.24
     CORR                                      -.20  -.38
     CORR                                             .04
     END DATA.

Example 3: N subcommand
.......................

This syntax uses the N subcommand in place of an N vector.  It produces the same matrix file as examples 1 and 2.

     MATRIX DATA
         VARIABLES=ROWTYPE_ var01 TO var08
         /FORMAT=UPPER NODIAGONAL
         /N 92.
     BEGIN DATA.
     MEAN  24.3   5.4  69.7  20.1  13.4   2.7  27.9   3.7
     SD     5.7   1.5  23.5   5.8   2.8   4.5   5.4   1.5
     CORR         .17   .50  -.33   .27   .36  -.22   .18
     CORR               .29   .29  -.20   .32   .12   .38
     CORR                     .05   .20  -.15   .16   .21
     CORR                           .20   .32  -.17   .12
     CORR                                 .27   .12  -.24
     CORR                                      -.20  -.38
     CORR                                             .04
     END DATA.

Example 4: Split variables
..........................

This syntax defines two matrices, using the variable s1 to distinguish between them.  Notice how the order of variables in the input matches their order on VARIABLES.  This example also uses FORMAT=FULL.

     MATRIX DATA
         VARIABLES=s1 ROWTYPE_  var01 TO var04
         /SPLIT=s1
         /FORMAT=FULL.
     BEGIN DATA.
     0 MEAN 34 35 36 37
     0 SD   22 11 55 66
     0 N    99 98 99 92
     0 CORR  1 .9 .8 .7
     0 CORR .9  1 .6 .5
     0 CORR .8 .6  1 .4
     0 CORR .7 .5 .4  1
     1 MEAN 44 45 34 39
     1 SD   23 15 51 46
     1 N    98 34 87 23
     1 CORR  1 .2 .3 .4
     1 CORR .2  1 .5 .6
     1 CORR .3 .5  1 .7
     1 CORR .4 .6 .7  1
     END DATA.

Example 5: Factor variables
...........................

This syntax defines a matrix file that includes a factor variable f1.  The data includes mean, standard deviation, and count vectors for two values of the factor variable, plus a correlation matrix for pooled data.

     MATRIX DATA
         VARIABLES=ROWTYPE_ f1 var01 TO var04
         /FACTOR=f1.
     BEGIN DATA.
     MEAN 0 34 35 36 37
     SD   0 22 11 55 66
     N    0 99 98 99 92
     MEAN 1 44 45 34 39
     SD   1 23 15 51 46
     N    1 98 34 87 23
     CORR .  1
     CORR . .9  1
     CORR . .8 .6  1
     CORR . .7 .5 .4  1
     END DATA.

Without ROWTYPE_
----------------

If VARIABLES does not contain ROWTYPE_, the CONTENTS subcommand defines the row types that appear in the file and their order.  If CONTENTS is omitted, CONTENTS=CORR is assumed.

Factor variables without ROWTYPE_ introduce special requirements, illustrated below in Examples 8 and 9.

Example 6: Defaults without ROWTYPE_
....................................

This example shows a simple use of MATRIX DATA with 8 variables named var01 through var08, without ROWTYPE_. This yields the same matrix file as Example 1 (see MATRIX DATA Example 1).

     MATRIX DATA
         VARIABLES=var01 TO var08
        /CONTENTS=MEAN SD N CORR.
     BEGIN DATA.
     24.3   5.4  69.7  20.1  13.4   2.7  27.9   3.7
      5.7   1.5  23.5   5.8   2.8   4.5   5.4   1.5
       92    92    92    92    92    92    92    92
     1.00
      .18  1.00
     -.22  -.17  1.00
      .36   .31  -.14  1.00
      .27   .16  -.12   .22  1.00
      .33   .15  -.17   .24   .21  1.00
      .50   .29  -.20   .32   .12   .38  1.00
      .17   .29  -.05   .20   .27   .20   .04  1.00
     END DATA.

Example 7: Split variables with explicit values
...............................................

This syntax defines two matrices, using the variable s1 to distinguish between them.  Each line of data begins with s1. This yields the same matrix file as Example 4 (see MATRIX DATA Example 4).

     MATRIX DATA
         VARIABLES=s1 var01 TO var04
         /SPLIT=s1
         /FORMAT=FULL
         /CONTENTS=MEAN SD N CORR.
     BEGIN DATA.
     0 34 35 36 37
     0 22 11 55 66
     0 99 98 99 92
     0  1 .9 .8 .7
     0 .9  1 .6 .5
     0 .8 .6  1 .4
     0 .7 .5 .4  1
     1 44 45 34 39
     1 23 15 51 46
     1 98 34 87 23
     1  1 .2 .3 .4
     1 .2  1 .5 .6
     1 .3 .5  1 .7
     1 .4 .6 .7  1
     END DATA.

Example 8: Split variable with sequential values
................................................

Like this previous example, this syntax defines two matrices with split variable s1.  In this case, though, s1 is not listed in VARIABLES, which means that its value does not appear in the data.  Instead, MATRIX DATA reads matrix data until the input is exhausted, supplying 1 for the first split, 2 for the second, and so on.

     MATRIX DATA
         VARIABLES=var01 TO var04
         /SPLIT=s1
         /FORMAT=FULL
         /CONTENTS=MEAN SD N CORR.
     BEGIN DATA.
     34 35 36 37
     22 11 55 66
     99 98 99 92
      1 .9 .8 .7
     .9  1 .6 .5
     .8 .6  1 .4
     .7 .5 .4  1
     44 45 34 39
     23 15 51 46
     98 34 87 23
      1 .2 .3 .4
     .2  1 .5 .6
     .3 .5  1 .7
     .4 .6 .7  1
     END DATA.

Factor variables without ROWTYPE_
.................................

Without ROWTYPE_, factor variables introduce two new wrinkles to MATRIX DATA syntax.  First, the CELLS subcommand must declare the number of combinations of factor variables present in the data.  If there is, for example, one factor variable for which the data contains three values, one would write CELLS=3; if there are two (or more) factor variables for which the data contains five combinations, one would use CELLS=5; and so on.

Second, the CONTENTS subcommand must distinguish within-cell data from pooled data by enclosing within-cell row types in parentheses.  When different within-cell row types for a single factor appear in subsequent lines, enclose the row types in a single set of parentheses; when different factors' values for a given within-cell row type appear in subsequent lines, enclose each row type in individual parentheses.

Without ROWTYPE_, input lines for pooled data do not include factor values, not even as missing values, but input lines for within-cell data do.

The following examples aim to clarify this syntax.

Example 9: Factor variables, grouping within-cell records by factor
...................................................................

This syntax defines the same matrix file as Example 5 (see MATRIX DATA Example 5), without using ROWTYPE_.  It declares CELLS=2 because the data contains two values (0 and 1) for factor variable f1.  Within-cell vector row types MEAN, SD, and N are in a single set of parentheses on CONTENTS because they are grouped together in subsequent lines for a single factor value.  The data lines with the pooled correlation matrix do not have any factor values.

     MATRIX DATA
         VARIABLES=f1 var01 TO var04
         /FACTOR=f1
         /CELLS=2
         /CONTENTS=(MEAN SD N) CORR.
     BEGIN DATA.
     0 34 35 36 37
     0 22 11 55 66
     0 99 98 99 92
     1 44 45 34 39
     1 23 15 51 46
     1 98 34 87 23
        1
       .9  1
       .8 .6  1
       .7 .5 .4  1
     END DATA.

Example 10: Factor variables, grouping within-cell records by row type
......................................................................

This syntax defines the same matrix file as the previous example.  The only difference is that the within-cell vector rows are grouped differently: two rows of means (one for each factor), followed by two rows of standard deviations, followed by two rows of counts.

     MATRIX DATA
         VARIABLES=f1 var01 TO var04
         /FACTOR=f1
         /CELLS=2
         /CONTENTS=(MEAN) (SD) (N) CORR.
     BEGIN DATA.
     0 34 35 36 37
     1 44 45 34 39
     0 22 11 55 66
     1 23 15 51 46
     0 99 98 99 92
     1 98 34 87 23
        1
       .9  1
       .8 .6  1
       .7 .5 .4  1
     END DATA.

MCONVERT
========

     MCONVERT
         [[MATRIX=]
          [IN({*|'FILE'})]
          [OUT({*|'FILE'})]]
         [/{REPLACE,APPEND}].

The MCONVERT command converts matrix data from a correlation matrix and a vector of standard deviations into a covariance matrix, or vice versa.

By default, MCONVERT both reads and writes the active file.  Use the MATRIX subcommand to specify other files.  To read a matrix file, specify its name inside parentheses following IN.  To write a matrix file, specify its name inside parentheses following OUT.  Use * to explicitly specify the active file for input or output.

When MCONVERT reads the input, by default it substitutes a correlation matrix and a vector of standard deviations each time it encounters a covariance matrix, and vice versa.  Specify /APPEND to instead have MCONVERT add the other form of data without removing the existing data.  Use /REPLACE to explicitly request removing the existing data.

The MCONVERT command requires its input to be a matrix file. Use MATRIX DATA to convert text input into matrix file format. See MATRIX DATA, for details.

MATRIX
======

     MATRIX.
     ...matrix commands...
     END MATRIX.

The following basic matrix commands are supported:

     COMPUTE variable[(index[,index])]=expression.
     CALL procedure(argument, ...).
     PRINT [expression]
           [/FORMAT=format]
           [/TITLE=title]
           [/SPACE={NEWPAGE | n}]
           [{/RLABELS=string... | /RNAMES=expression}]
           [{/CLABELS=string... | /CNAMES=expression}].

The following matrix commands offer support for flow control:

     DO IF expression.
       ...matrix commands...
     [ELSE IF expression.
       ...matrix commands...]...
     [ELSE
       ...matrix commands...]
     END IF.

     LOOP [var=first TO last [BY step]] [IF expression].
       ...matrix commands...
     END LOOP [IF expression].

     BREAK.

The following matrix commands support matrix input and output:

     READ variable[(index[,index])]
          [/FILE=file]
          /FIELD=first TO last [BY width]
          [/FORMAT=format]
          [/SIZE=expression]
          [/MODE={RECTANGULAR | SYMMETRIC}]
          [/REREAD].
     WRITE expression
           [/OUTFILE=file]
           /FIELD=first TO last [BY width]
           [/MODE={RECTANGULAR | TRIANGULAR}]
           [/HOLD]
           [/FORMAT=format].
     GET variable[(index[,index])]
         [/FILE={file | *}]
         [/VARIABLES=variable...]
         [/NAMES=expression]
         [/MISSING={ACCEPT | OMIT | number}]
         [/SYSMIS={OMIT | number}].
     SAVE expression
          [/OUTFILE={file | *}]
          [/VARIABLES=variable...]
          [/NAMES=expression]
          [/STRINGS=variable...].
     MGET [/FILE=file]
          [/TYPE={COV | CORR | MEAN | STDDEV | N | COUNT}].
     MSAVE expression
           /TYPE={COV | CORR | MEAN | STDDEV | N | COUNT}
           [/OUTFILE=file]
           [/VARIABLES=variable...]
           [/SNAMES=variable...]
           [/SPLIT=expression]
           [/FNAMES=variable...]
           [/FACTOR=expression].

The following matrix commands provide additional support:

     DISPLAY [{DICTIONARY | STATUS}].
     RELEASE variable....

MATRIX and END MATRIX enclose a special pspp sub-language, called the matrix language.  The matrix language does not require an active dataset to be defined and only a few of the matrix language commands work with any datasets that are defined. Each instance of MATRIX...END MATRIX is a separate program whose state is independent of any instance, so that variables declared within a matrix program are forgotten at its end.

The matrix language works with matrices, where a matrix is a rectangular array of real numbers.  An N times M matrix has N rows and M columns.  Some special cases are important: a N times1 matrix is a column vector, a 1 times N is a row vector, and a 1 times1 matrix is a scalar.

The matrix language also has limited support for matrices that contain 8-byte strings instead of numbers.  Strings longer than 8 bytes are truncated, and shorter strings are padded with spaces.  String matrices are mainly useful for labeling rows and columns when printing numerical matrices with the MATRIX PRINT command.  Arithmetic operations on string matrices will not produce useful results.  The user should not mix strings and numbers within a matrix.

The matrix language does not work with cases.  A variable in the matrix language represents a single matrix.

The matrix language does not support missing values.

MATRIX is a procedure, so it cannot be enclosed inside DO IF, LOOP, etc.

Macros may be used within a matrix program, and macros may expand to include entire matrix programs.  The DEFINE command may not appear within a matrix program.  See DEFINE, for more information about macros.

The following sections describe the details of the matrix language: first, the syntax of matrix expressions, then each of the supported commands.  The COMMENT command (see COMMENT) is also supported.

Matrix Expressions
------------------

Many matrix commands use expressions.  A matrix expression may use the following operators, listed in descending order of operator precedence.  Within a single level, operators associate from left to right.

  * Function call () and matrix construction {}

  * Indexing ()

  * Unary + and -

  * Integer sequence :

  * Exponentiation ** and &**

  * Multiplication * and &*, and division / and &/

  * Addition + and subtraction -

  * Relational < <= = >= > <>

  * Logical NOT

  * Logical AND

  * Logical OR and XOR

See Matrix Functions, for the available matrix functions.  The remaining operators are described in more detail below.

Expressions appear in the matrix language in some contexts where there would be ambiguity whether / is an operator or a separator between subcommands.  In these contexts, only the operators with higher precedence than / are allowed outside parentheses. Later sections call these restricted expressions.

Matrix Construction Operator {}
...............................

Use the {} operator to construct matrices.  Within the curly braces, commas separate elements within a row and semicolons separate rows.  The following examples show a 2 times3 matrix, a 1 times4 row vector, a 3 times1 column vector, and a scalar.

{1, 2, 3; 4, 5, 6}
=>

[1  2  3]
 [4  5  6]
{3.14, 6.28, 9.24, 12.57}
=>

[3.14  6.28  9.42  12.57]
{1.41; 1.73; 2}
=>

[1.41]
 [1.73]
 [2.00]
{5}
=>
5

Curly braces are not limited to holding numeric literals.  They can contain calculations, and they can paste together matrices and vectors in any way as long as the result is rectangular.  For example, if m is matrix {1, 2; 3, 4}, r is row vector {5, 6}, and c is column vector {7, 8}, then curly braces can be used as follows:

{m, c; r, 10}
=>

[1 2  7]
 [3 4  8]
 [5 6 10]
{c, 2 * c, T(r)}
=>

[7 14 5]
 [8 16 6]

The final example above uses the transposition function T.

Integer Sequence Operator :
...........................

The syntax FIRST:LAST:STEP yields a row vector of consecutive integers from FIRST to LAST counting by STEP.  The final :STEP is optional and defaults to 1 when omitted.

Each of FIRST, LAST, and STEP must be a scalar and should be an integer (any fractional part is discarded).  Because : has a high precedence, operands other than numeric literals must usually be parenthesized.

When STEP is positive (or omitted) and END < START, or if STEP is negative and END > START, then the result is an empty matrix.  If STEP is 0, then pspp reports an error.

Here are some examples:

1:6        =>   {1, 2, 3, 4, 5, 6}
1:6:2      =>   {1, 3, 5}
-1:-5:-1   =>   {-1, -2, -3, -4, -5}
-1:-5      =>   {}
2:1:0      =>   (error)

Index Operator ()
.................

The result of the submatrix or indexing operator, written M(RINDEX, CINDEX), contains the rows of M whose indexes are given in vector RINDEX and the columns whose indexes are given in vector CINDEX.

In the simplest case, if RINDEX and CINDEX are both scalars, the result is also a scalar:

{10, 20; 30, 40}(1, 1)   =>   10
{10, 20; 30, 40}(1, 2)   =>   20
{10, 20; 30, 40}(2, 1)   =>   30
{10, 20; 30, 40}(2, 2)   =>   40

If the index arguments have multiple elements, then the result includes multiple rows or columns:

{10, 20; 30, 40}(1:2, 1)   =>   {10; 30}
{10, 20; 30, 40}(2, 1:2)   =>   {30, 40}
{10, 20; 30, 40}(1:2, 1:2)   =>   {10, 20; 30, 40}

The special argument : may stand in for all the rows or columns in the matrix being indexed, like this:

{10, 20; 30, 40}(:, 1)   =>   {10; 30}
{10, 20; 30, 40}(2, :)   =>   {30, 40}
{10, 20; 30, 40}(:, :)   =>   {10, 20; 30, 40}

The index arguments do not have to be in order, and they may contain repeated values, like this:

{10, 20; 30, 40}({2, 1}, 1)   =>   {30; 10}
{10, 20; 30, 40}(2, {2; 2; 1})   =>   {40, 40, 30}
{10, 20; 30, 40}(2:1:-1, :)   =>   {30, 40; 10, 20}

When the matrix being indexed is a row or column vector, only a single index argument is needed, like this:

{11, 12, 13, 14, 15}(2:4)   =>   {12, 13, 14}
{11; 12; 13; 14; 15}(2:4)   =>   {12; 13; 14}

When an index is not an integer, pspp discards the fractional part. It is an error for an index to be less than 1 or greater than the number of rows or columns:

{11, 12, 13, 14}({2.5, 4.6})   =>   {12, 14}
{11; 12; 13; 14}(0)   =>   (error)

Unary Operators
...............

The unary operators take a single operand of any dimensions and operate on each of its elements independently.  The unary operators are:

-
     Inverts the sign of each element.

+
     No change.

NOT
     Logical inversion: each positive value becomes 0 and each zero or negative value becomes 1.

Examples:

-{1, -2; 3, -4}   =>   {-1, 2; -3, 4}
+{1, -2; 3, -4}   =>   {1, -2; 3, -4}
NOT {1, 0; -1, 1}   =>   {0, 1; 1, 0}

Elementwise Binary Operators
............................

The elementwise binary operators require their operands to be matrices with the same dimensions.  Alternatively, if one operand is a scalar, then its value is treated as if it were duplicated to the dimensions of the other operand.  The result is a matrix of the same size as the operands, in which each element is the result of the applying the operator to the corresponding elements of the operands.

The elementwise binary operators are listed below.

  * The arithmetic operators, for familiar arithmetic operations:

     +
          Addition.

     -
          Subtraction.

     *
          Multiplication, if one operand is a scalar.  (Otherwise this is matrix multiplication, described below.)

     / or &/
          Division.

     &*
          Multiplication.

     &**
          Exponentiation.

  * The relational operators, whose results are 1 when a comparison is true and 0 when it is false:

     < or LT
          Less than.

     <= or LE
          Less than or equal.

     = or EQ
          Equal.

     > or GT
          Greater than.

     >= or GE
          Greater than or equal.

     <> or ~= or NE
          Not equal.

  * The logical operators, which treat positive operands as true and nonpositive operands as false.  They yield 0 for false and 1 for true:

     AND
          True if both operands are true.

     OR
          True if at least one operand is true.

     XOR
          True if exactly one operand is true.

Examples:

1 + 2   =>   3
1 + {3; 4}   =>   {4; 5}
{66, 77; 88, 99} + 5   =>   {71, 82; 93, 104}
{4, 8; 3, 7} + {1, 0; 5, 2}   =>   {5, 8; 8, 9}
{1, 2; 3, 4} < {4, 3; 2, 1}   =>   {1, 1; 0, 0}
{1, 3; 2, 4} >= 3   =>   {0, 1; 0, 1}
{0, 0; 1, 1} AND {0, 1; 0, 1}   =>   {0, 0; 0, 1}

Matrix Multiplication Operator *
................................

If A is an M times N matrix and B is an N times P matrix, then A*B is the M times P matrix multiplication product C. pspp reports an error if the number of columns in A differs from the number of rows in B.

The * operator performs elementwise multiplication (see above) if one of its operands is a scalar.

No built-in operator yields the inverse of matrix multiplication. Instead, multiply by the result of INV or GINV.

Some examples:

{1, 2, 3} * {4; 5; 6}   =>   32
{4; 5; 6} * {1, 2, 3}   =>   {4,  8, 12;
 5, 10, 15;
 6, 12, 18}

Matrix Exponentiation Operator **
.................................

The result of A**B is defined as follows when A is a square matrix and B is an integer scalar:

  * For B > 0, A**B is A*...*A, where there are B As.  (pspp implements this efficiently for large B, using exponentiation by squaring.)

  * For B < 0, A**B is INV(A**(-B)).

  * For B = 0, A**B is the identity matrix.

pspp reports an error if A is not square or B is not an integer.

Examples:

{2, 5; 1, 4}**3   =>   {48, 165; 33, 114}
{2, 5; 1, 4}**0   =>   {1, 0; 0, 1}
10*{4, 7; 2, 6}**-1   =>   {6, -7; -2, 4}

Matrix Functions
----------------

The matrix language support numerous functions in multiple categories. The following subsections document each of the currently supported functions.  The first letter of each parameter's name indicate the required argument type:

s
     A scalar.

n
     A nonnegative integer scalar.  (Non-integers are accepted and silently rounded down to the nearest integer.)

V
     A row or column vector.

M
     A matrix.

Elementwise Functions
.....................

These functions act on each element of their argument independently, like the elementwise operators (see Matrix Elementwise Binary Operators).

 -- Matrix Function: ABS (M)
     Takes the absolute value of each element of M.

     ABS({-1, 2; -3, 0}) => {1, 2; 3, 0}

 -- Matrix Function: ARSIN (M)
 -- Matrix Function: ARTAN (M)
     Computes the inverse sine or tangent, respectively, of each element in M.  The results are in radians, between -\pi/2 and +\pi/2, inclusive.

     The value of \pi can be computed as 4*ARTAN(1).

     ARSIN({-1, 0, 1}) => {-1.57, 0, 1.57} (approximately)

     ARTAN({-5, -1, 1, 5}) => {-1.37, -.79, .79, 1.37} (approximately)

 -- Matrix Function: COS (M)
 -- Matrix Function: SIN (M)
     Computes the cosine or sine, respectively, of each element in M, which must be in radians.

     COS({0.785, 1.57; 3.14, 1.57 + 3.14}) => {.71, 0; -1, 0} (approximately)

 -- Matrix Function: EXP (M)
     Computes e^x for each element X in M.

     EXP({2, 3; 4, 5}) => {7.39, 20.09; 54.6, 148.4} (approximately)

 -- Matrix Function: LG10 (M)
 -- Matrix Function: LN (M)
     Takes the logarithm with base 10 or base e, respectively, of each element in M.

     LG10({1, 10, 100, 1000}) => {0, 1, 2, 3}

     LG10(0) => (error)

     LN({EXP(1), 1, 2, 3, 4}) => {1, 0, .69, 1.1, 1.39} (approximately)

     LN(0) => (error)

 -- Matrix Function: MOD (M, S)
     Takes each element in M modulo nonzero scalar value S, that is, the remainder of division by S.  The sign of the result is the same as the sign of the dividend.

     MOD({5, 4, 3, 2, 1, 0}, 3) => {2, 1, 0, 2, 1, 0}

     MOD({5, 4, 3, 2, 1, 0}, -3) => {2, 1, 0, 2, 1, 0}

     MOD({-5, -4, -3, -2, -1, 0}, 3) => {-2, -1, 0, -2, -1, 0}

     MOD({-5, -4, -3, -2, -1, 0}, -3) => {-2, -1, 0, -2, -1, 0}

     MOD({5, 4, 3, 2, 1, 0}, 1.5) => {.5, 1.0, .0, .5, 1.0, .0}

     MOD({5, 4, 3, 2, 1, 0}, 0) => (error)

 -- Matrix Function: RND (M)
 -- Matrix Function: TRUNC (M)
     Rounds each element of M to an integer.  RND rounds to the nearest integer, with halves rounded to even integers, and TRUNC rounds toward zero.

     RND({-1.6, -1.5, -1.4}) => {-2, -2, -1}

     RND({-.6, -.5, -.4}) => {-1, 0, 0}

     RND({.4, .5, .6} => {0, 0, 1}

     RND({1.4, 1.5, 1.6}) => {1, 2, 2}

     TRUNC({-1.6, -1.5, -1.4}) => {-1, -1, -1}

     TRUNC({-.6, -.5, -.4}) => {0, 0, 0}

     TRUNC({.4, .5, .6} => {0, 0, 0}

     TRUNC({1.4, 1.5, 1.6}) => {1, 1, 1}

 -- Matrix Function: SQRT (M)
     Takes the square root of each element of M, which must not be negative.

     SQRT({0, 1, 2, 4, 9, 81}) => {0, 1, 1.41, 2, 3, 9} (approximately)

     SQRT(-1) => (error)

Logical Functions
.................

 -- Matrix Function: ALL (M)
     Returns a scalar with value 1 if all of the elements in M are nonzero, or 0 if at least one element is zero.

     ALL({1, 2, 3} < {2, 3, 4}) => 1

     ALL({2, 2, 3} < {2, 3, 4}) => 0

     ALL({2, 3, 3} < {2, 3, 4}) => 0

     ALL({2, 3, 4} < {2, 3, 4}) => 0

 -- Matrix Function: ANY (M)
     Returns a scalar with value 1 if any of the elements in M is nonzero, or 0 if all of them are zero.

     ANY({1, 2, 3} < {2, 3, 4}) => 1

     ANY({2, 2, 3} < {2, 3, 4}) => 1

     ANY({2, 3, 3} < {2, 3, 4}) => 1

     ANY({2, 3, 4} < {2, 3, 4}) => 0

Matrix Construction Functions
.............................

 -- Matrix Function: BLOCK (M1, ..., MN)
     Returns a block diagonal matrix with as many rows as the sum of its arguments' row counts and as many columns as the sum of their columns. Each argument matrix is placed along the main diagonal of the result, and all other elements are zero.

          BLOCK({1, 2; 3, 4}, 5, {7; 8; 9}, {10, 11}) =>
             1   2   0   0   0   0
             3   4   0   0   0   0
             0   0   5   0   0   0
             0   0   0   7   0   0
             0   0   0   8   0   0
             0   0   0   9   0   0
             0   0   0   0  10  11

 -- Matrix Function: IDENT (N)
 -- Matrix Function: IDENT (NR, NC)
     Returns an identity matrix, whose main diagonal elements are one and whose other elements are zero.  The returned matrix has N rows and columns or NR rows and NC columns, respectively.

          IDENT(1) => 1
          IDENT(2) =>
            1  0
            0  1
          IDENT(3, 5) =>
            1  0  0  0  0
            0  1  0  0  0
            0  0  1  0  0
          IDENT(5, 3) =>
            1  0  0
            0  1  0
            0  0  1
            0  0  0
            0  0  0

 -- Matrix Function: MAGIC (N)
     Returns an N times N matrix that contains each of the integers 1...N once, in which each column, each row, and each diagonal sums to n(n^2+1)/2.  There are many magic squares with given dimensions, but this function always returns the same one for a given value of N.

     MAGIC(3) => {8, 1, 6; 3, 5, 7; 4, 9, 2}

     MAGIC(4) => {1, 5, 12, 16; 15, 11, 6, 2; 14, 8, 9, 3; 4, 10, 7, 13}

 -- Matrix Function: MAKE (NR, NC, S)
     Returns an NR times NC matrix whose elements are all S.

     MAKE(1, 2, 3) => {3, 3}

     MAKE(2, 1, 4) => {4; 4}

     MAKE(2, 3, 5) => {5, 5, 5; 5, 5, 5}

 -- Matrix Function: MDIAG (V)
      Given N-element vector V, returns a N times N matrix whose main diagonal is copied from V.  The other elements in the returned vector are zero.

     Use CALL SETDIAG (see CALL SETDIAG) to replace the main diagonal of a matrix in-place.

          MDIAG({1, 2, 3, 4}) =>
            1  0  0  0
            0  2  0  0
            0  0  3  0
            0  0  0  4

 -- Matrix Function: RESHAPE (M, NR, NC)
     Returns an NR times NC matrix whose elements come from M, which must have the same number of elements as the new matrix, copying elements from M to the new matrix row by row.

          RESHAPE(1:12, 1, 12) =>
             1   2   3   4   5   6   7   8   9  10  11  12
          RESHAPE(1:12, 2, 6) =>
             1   2   3   4   5   6
             7   8   9  10  11  12
          RESHAPE(1:12, 3, 4) =>
             1   2   3   4
             5   6   7   8
             9  10  11  12
          RESHAPE(1:12, 4, 3) =>
             1   2   3
             4   5   6
             7   8   9
            10  11  12

 -- Matrix Function: T (M)
 -- Matrix Function: TRANSPOS (M)
     Returns M with rows exchanged for columns.

     T({1, 2, 3}) => {1; 2; 3}

     T({1; 2; 3}) => {1, 2, 3}

 -- Matrix Function: UNIFORM (NR, NC)
     Returns a NR times NC matrix in which each element is randomly chosen from a uniform distribution of real numbers between 0 and 1.  Random number generation honors the current seed setting (see SET SEED).

     The following example shows one possible output, but of course every result will be different (given different seeds):

          UNIFORM(4, 5)*10 =>
            7.71  2.99   .21  4.95  6.34
            4.43  7.49  8.32  4.99  5.83
            2.25   .25  1.98  7.09  7.61
            2.66  1.69  2.64   .88  1.50

Minimum, Maximum, and Sum Functions
...................................

 -- Matrix Function: CMIN (M)
 -- Matrix Function: CMAX (M)
 -- Matrix Function: CSUM (M)
 -- Matrix Function: CSSQ (M)
     Returns a row vector with the same number of columns as M, in which each element is the minimum, maximum, sum, or sum of squares, respectively, of the elements in the same column of M.

     CMIN({1, 2, 3; 4, 5, 6; 7, 8, 9} => {1, 2, 3}

     CMAX({1, 2, 3; 4, 5, 6; 7, 8, 9} => {7, 8, 9}

     CSUM({1, 2, 3; 4, 5, 6; 7, 8, 9} => {12, 15, 18}

     CSSQ({1, 2, 3; 4, 5, 6; 7, 8, 9} => {66, 93, 126}

 -- Matrix Function: MMIN (M)
 -- Matrix Function: MMAX (M)
 -- Matrix Function: MSUM (M)
 -- Matrix Function: MSSQ (M)
     Returns the minimum, maximum, sum, or sum of squares, respectively, of the elements of M.

     MMIN({1, 2, 3; 4, 5, 6; 7, 8, 9} => 1

     MMAX({1, 2, 3; 4, 5, 6; 7, 8, 9} => 9

     MSUM({1, 2, 3; 4, 5, 6; 7, 8, 9} => 45

     MSSQ({1, 2, 3; 4, 5, 6; 7, 8, 9} => 285

 -- Matrix Function: RMIN (M)
 -- Matrix Function: RMAX (M)
 -- Matrix Function: RSUM (M)
 -- Matrix Function: RSSQ (M)
     Returns a column vector with the same number of rows as M, in which each element is the minimum, maximum, sum, or sum of squares, respectively, of the elements in the same row of M.

     RMIN({1, 2, 3; 4, 5, 6; 7, 8, 9} => {1; 4; 7}

     RMAX({1, 2, 3; 4, 5, 6; 7, 8, 9} => {3; 6; 9}

     RSUM({1, 2, 3; 4, 5, 6; 7, 8, 9} => {6; 15; 24}

     RSSQ({1, 2, 3; 4, 5, 6; 7, 8, 9} => {14; 77; 194}

 -- Matrix Function: SSCP (M)
     Returns M^T times M.

     SSCP({1, 2, 3; 4, 5, 6}) => {17, 22, 27; 22, 29, 36; 27, 36, 45}

 -- Matrix Function: TRACE (M)
     Returns the sum of the elements along M's main diagonal, equivalent to MSUM(DIAG(M)).

     TRACE(MDIAG(1:5)) => 15

Matrix Property Functions
.........................

 -- Matrix Function: NROW (M)
 -- Matrix Function: NCOL (M)
     Returns the number of row or columns, respectively, in M.

          NROW({1, 0; -2, -3; 3, 3}) => 3
          NROW(1:5) => 1

          NCOL({1, 0; -2, -3; 3, 3}) => 2
          NCOL(1:5) => 5

 -- Matrix Function: DIAG (M)
     Returns a column vector containing a copy of M's main diagonal. The vector's length is the lesser of NCOL(M) and NROW(M).

     DIAG({1, 0; -2, -3; 3, 3}) => {1; -3}

Matrix Rank Ordering Functions
..............................

The GRADE and RANK functions each take a matrix M and return a matrix R with the same dimensions.  Each element in R ranges between 1 and the number of elements N in M, inclusive.  When the elements in M all have unique values, both of these functions yield the same results: the smallest element in M corresponds to value 1 in R, the next smallest to 2, and so on, up to the largest to N.  When multiple elements in M have the same value, these functions use different rules for handling the ties.

 -- Matrix Function: GRADE (M)
     Returns a ranking of M, turning duplicate values into sequential ranks.  The returned matrix always contains each of the integers 1 through the number of elements in the matrix exactly once.

     GRADE({1, 0, 3; 3, 1, 2; 3, 0, 5}) => {3, 1, 6; 7, 4, 5; 8, 2, 9}

 -- Matrix Function: RNKORDER (M)
     Returns a ranking of M, turning duplicate values into the mean of their sequential ranks.

     RNKORDER({1, 0, 3; 3, 1, 2; 3, 0, 5})
      => {3.5, 1.5, 7; 7, 3.5, 5; 7, 1.5, 9}

One may use GRADE to sort a vector:

     COMPUTE v(GRADE(v))=v.   /* Sort v in ascending order.
     COMPUTE v(GRADE(-v))=v.  /* Sort v in descending order.

Matrix Algebra Functions
........................

 -- Matrix Function: CHOL (M)
     Matrix M must be an N times N symmetric positive-definite matrix.  Returns an N times N matrix B such that B^T times B=M.

          CHOL({4, 12, -16; 12, 37, -43; -16, -43, 98}) =>
            2  6 -8
            0  1  5
            0  0  3

 -- Matrix Function: DESIGN (M)
     Returns a design matrix for M.  The design matrix has the same number of rows as M.  Each column C in M, from left to right, yields a group of columns in the output.  For each unique value V in C, from top to bottom, add a column to the output in which V becomes 1 and other values become 0.

     pspp issues a warning if a column only contains a single unique value.

          DESIGN({1; 2; 3}) => {1, 0, 0; 0, 1, 0; 0, 0, 1}
          DESIGN({5; 8; 5}) => {1, 0; 0, 1; 1, 0}
          DESIGN({1, 5; 2, 8; 3, 5})
           => {1, 0, 0, 1, 0; 0, 1, 0, 0, 1; 0, 0, 1, 1, 0}
          DESIGN({5; 5; 5}) => (warning)

 -- Matrix Function: DET (M)
     Returns the determinant of square matrix M.

     DET({3, 7; 1, -4}) => -19

 -- Matrix Function: EVAL (M)
     Returns a column vector containing the eigenvalues of symmetric matrix M, sorted in ascending order.

     Use CALL EIGEN (see CALL EIGEN) to compute eigenvalues and eigenvectors of a matrix.

     EVAL({2, 0, 0; 0, 3, 4; 0, 4, 9}) => {11; 2; 1}

 -- Matrix Function: GINV (M)
     Returns the K times N matrix A that is the generalized inverse of N times K matrix M, defined such that M times A times M=M and A times M times A=A.

     GINV({1, 2}) => {.2; .4} (approximately)

     {1:9} * GINV(1:9) * {1:9} => {1:9} (approximately)

 -- Matrix Function: GSCH (M)
     M must be a N times M matrix, M ≥ N, with rank N.  Returns an N times N orthonormal basis for M, obtained using the Gram-Schmidt process.

     GSCH({3, 2; 1, 2}) * SQRT(10) => {3, -1; 1, 3} (approximately)

 -- Matrix Function: INV (M)
     Returns the N times N matrix A that is the inverse of N times N matrix M, defined such that M times A = A times M = I, where I is the identity matrix.  M must not be singular, that is, \det(M) ne 0.

     INV({4, 7; 2, 6}) => {.6, -.7; -.2, .4} (approximately)

 -- Matrix Function: KRONEKER (MA, MB)
     Returns the PM times QN matrix P that is the Kroneker product of M times N matrix MA and P times Q matrix MB.  One may view P as the concatenation of multiple P times Q blocks, each of which is the scalar product of MB by a different element of MA.  For example, when A is a 2 times2 matrix, KRONEKER(A, B) is equivalent to {A(1,1)*B, A(1,2)*B; A(2,1)*B, A(2,2)*B}.

          KRONEKER({1, 2; 3, 4}, {0, 5; 6, 7}) =>
             0   5   0  10
             6   7  12  14
             0  15   0  20
            18  21  24  28

 -- Matrix Function: RANK (M)
     Returns the rank of matrix M, a integer scalar whose value is the dimension of the vector space spanned by its columns or, equivalently, by its rows.

          RANK({1, 0, 1; -2, -3, 1; 3, 3, 0}) => 2
          RANK({1, 1, 0, 2; -1, -1, 0, -2}) => 1
          RANK({1, -1; 1, -1; 0, 0; 2, -2}) => 1
          RANK({1, 2, 1; -2, -3, 1; 3, 5, 0}) => 2
          RANK({1, 0, 2; 2, 1, 0; 3, 2, 1}) => 3

 -- Matrix Function: SOLVE (MA, MB)
     MA must be an N times N matrix, with \det(MA) ne 0, and MB an N times K matrix.  Returns an N times K matrix X such that MA times X = MB.

     All of the following examples show approximate results:

          SOLVE({2, 3; 4, 9}, {6, 2; 15, 5}) =>
             1.50    .50
             1.00    .33
          SOLVE({1, 3, -2; 3, 5, 6; 2, 4, 3}, {5; 7; 8}) =>
           -15.00
             8.00
             2.00
          SOLVE({2, 1, -1; -3, -1, 2; -2, 1, 2}, {8; -11; -3}) =>
             2.00
             3.00
            -1.00

 -- Matrix Function: SVAL (M)

     Given N times K matrix M, returns a \min(N,K)-element column vector containing the singular values of M in descending order.

     Use CALL SVD (see CALL SVD) to compute the full singular value decomposition of a matrix.

          SVAL({1, 1; 0, 0}) => {1.41; .00}
          SVAL({1, 0, 1; 0, 1, 1; 0, 0, 0}) => {1.73; 1.00; .00}
          SVAL({2, 4; 1, 3; 0, 0; 0, 0}) => {5.46; .37}

 -- Matrix Function: SWEEP (M, NK)
     Given R times C matrix M and integer scalar k = NK such that 1 ≤ k ≤ \min(R,C), returns the R times C sweep matrix A.

     If M_kk ne 0, then:

          A_{kk} = 1/M_{kk},
          A_{ik} = -M_{ik}/M_{kk} for i ne k,
          A_{kj} = M_{kj}/M_{kk} for j ne k, and
          A_{ij} = M_{ij} - M_{ik}M_{kj}/M_{kk} for i ne k and j ne k.

     If M_kk = 0, then:

          A_{ik} = A_{ki} = 0 and
          A_{ij} = M_{ij}, for i ne k and j ne k.

     Given M = {0, 1, 2; 3, 4, 5; 6, 7, 8}, then (approximately):

          SWEEP(M, 1) =>
             .00   .00   .00
             .00  4.00  5.00
             .00  7.00  8.00
          SWEEP(M, 2) =>
            -.75  -.25   .75
             .75   .25  1.25
             .75 -1.75  -.75
          SWEEP(M, 3) =>
           -1.50  -.75  -.25
            -.75  -.38  -.63
             .75   .88   .13

Matrix Statistical Distribution Functions
.........................................

The matrix language can calculate several functions of standard statistical distributions using the same syntax and semantics as in pspp transformation expressions.  See Statistical Distribution Functions, for details.

The matrix language extends the PDF, CDF, SIG, IDF, NPDF, and NCDF functions by allowing the first parameters to each of these functions to be a vector or matrix with any dimensions.  In addition, CDF.BVNOR and PDF.BVNOR allow either or both of their first two parameters to be vectors or matrices; if both are non-scalar then they must have the same dimensions.  In each case, the result is a matrix or vector with the same dimensions as the input populated with elementwise calculations.

EOF Function
............

This function works with files being used on the READ statement.

 -- Matrix Function: EOF (FILE)

     Given a file handle or file name FILE, returns an integer scalar 1 if the last line in the file has been read or 0 if more lines are available.  Determining this requires attempting to read another line, which means that REREAD on the next READ command following EOF on the same file will be ineffective.

The EOF function gives a matrix program the flexibility to read a file with text data without knowing the length of the file in advance.  For example, the following program will read all the lines of data in data.txt, each consisting of three numbers, as rows in matrix data:

MATRIX.
COMPUTE data={}.
LOOP IF NOT EOF('data.txt').
  READ row/FILE='data.txt'/FIELD=1 TO 1000/SIZE={1,3}.
  COMPUTE data={data; row}.
END LOOP.
PRINT data.
END MATRIX.

The COMPUTE Command
-------------------

     COMPUTE variable[(index[,index])]=expression.

The COMPUTE command evaluates an expression and assigns the result to a variable or a submatrix of a variable.  Assigning to a submatrix uses the same syntax as the index operator (see Matrix Index Operator).

The CALL Command
----------------

A matrix function returns a single result.  The CALL command implements procedures, which take a similar syntactic form to functions but yield results by modifying their arguments rather than returning a value.

Output arguments to a CALL procedure must be a single variable name.

The following procedures are implemented via CALL to allow them to return multiple results.  For these procedures, the output arguments need not name existing variables; if they do, then their previous values are replaced:

CALL EIGEN(M, EVEC, EVAL)

     Computes the eigenvalues and eigenvector of symmetric N times N matrix M.  Assigns the eigenvectors of M to the columns of N times N matrix EVEC and the eigenvalues in descending order to N-element column vector EVAL.

     Use the EVAL function (see EVAL) to compute just the eigenvalues of a symmetric matrix.

     For example, the following matrix language commands:

          CALL EIGEN({1, 0; 0, 1}, evec, eval).
          PRINT evec.
          PRINT eval.

          CALL EIGEN({3, 2, 4; 2, 0, 2; 4, 2, 3}, evec2, eval2).
          PRINT evec2.
          PRINT eval2.

     yield this output:

          evec
            1  0
            0  1

          eval
            1
            1

          evec2
            -.6666666667   .0000000000   .7453559925
            -.3333333333  -.8944271910  -.2981423970
            -.6666666667   .4472135955  -.5962847940

          eval2
            8.0000000000
           -1.0000000000
           -1.0000000000

CALL SVD(M, U, S, V)

     Computes the singular value decomposition of N times K matrix M, assigning S a N times K diagonal matrix and to U and V unitary K times K matrices such that M = U times S times V^T.  The main diagonal of Q contains the singular values of M.

     Use the SVAL function (see SVAL) to compute just the singular values of a matrix.

     For example, the following matrix program:

          CALL SVD({3, 2, 2; 2, 3, -2}, u, s, v).
          PRINT (u * s * T(v))/FORMAT F5.1.

     yields this output:

          (u * s * T(v))
             3.0   2.0   2.0
             2.0   3.0  -2.0

The final procedure is implemented via CALL to allow it to modify a matrix instead of returning a modified version.  For this procedure, the output argument must name an existing variable.

CALL SETDIAG(M, V)

     Replaces the main diagonal of N times P matrix M by the contents of K-element vector V.  If K = 1, so that V is a scalar, replaces all of the diagonal elements of M by V.  If K < \min(N,P), only the upper K diagonal elements are replaced; if K > \min(N,P), then the extra elements of V are ignored.

     Use the MDIAG function (see MDIAG) to construct a new matrix with a specified main diagonal.

     For example, this matrix program:

          COMPUTE x={1, 2, 3; 4, 5, 6; 7, 8, 9}.
          CALL SETDIAG(x, 10).
          PRINT x.

     outputs the following:

          x
            10   2   3
             4  10   6
             7   8  10

The PRINT Command
-----------------

     PRINT [expression]
           [/FORMAT=format]
           [/TITLE=title]
           [/SPACE={NEWPAGE | n}]
           [{/RLABELS=string... | /RNAMES=expression}]
           [{/CLABELS=string... | /CNAMES=expression}].

The PRINT command is commonly used to display a matrix.  It evaluates the restricted EXPRESSION, if present, and outputs it either as text or a pivot table, depending on the setting of MDISPLAY (see SET MDISPLAY).

Use the FORMAT subcommand to specify a format, such as F8.2, for displaying the matrix elements.  FORMAT is optional for numerical matrices.  When it is omitted, pspp chooses how to format entries automatically using M, the magnitude of the largest-magnitude element in the matrix to be displayed:

 1. If M < 10^11 and the matrix's elements are all integers, pspp chooses the narrowest F format that fits M plus a sign.  For example, if the matrix is {1:10}, then m = 10, which fits in 3 columns with room for a sign, the format is F3.0.

 2. Otherwise, if M ≥ 10^9 or M ≤ 10^-4, pspp scales all of the numbers in the matrix by 10^x, where X is the exponent that would be used to display M in scientific notation.  For example, for M = 5.123 times10^20, the scale factor is 10^20.  pspp displays the scaled values in format F13.10 and notes the scale factor in the output.

 3. Otherwise, pspp displays the matrix values, without scaling, in format F13.10.

The optional TITLE subcommand specifies a title for the output text or table, as a quoted string.  When it is omitted, the syntax of the matrix expression is used as the title.

Use the SPACE subcommand to request extra space above the matrix output.  With a numerical argument, it adds the specified number of lines of blank space above the matrix.  With NEWPAGE as an argument, it prints the matrix at the top of a new page.  The SPACE subcommand has no effect when a matrix is output as a pivot table.

The RLABELS and RNAMES subcommands, which are mutually exclusive, can supply a label to accompany each row in the output. With RLABELS, specify the labels as comma-separated strings or other tokens.  With RNAMES, specify a single expression that evaluates to a vector of strings.  Either way, if there are more labels than rows, the extra labels are ignored, and if there are more rows than labels, the extra rows are unlabeled.  For output to a pivot table with RLABELS, the labels can be any length; otherwise, the labels are truncated to 8 bytes.

The CLABELS and CNAMES subcommands work for labeling columns as RLABELS and RNAMES do for labeling rows.

When the EXPRESSION is omitted, PRINT does not output a matrix.  Instead, it outputs only the text specified on TITLE, if any, preceded by any space specified on the SPACE subcommand, if any.  Any other subcommands are ignored, and the command acts as if MDISPLAY is set to TEXT regardless of its actual setting.

The following syntax demonstrates two different ways to label the rows and columns of a matrix with PRINT:

     MATRIX.
     COMPUTE m={1, 2, 3; 4, 5, 6; 7, 8, 9}.
     PRINT m/RLABELS=a, b, c/CLABELS=x, y, z.

     COMPUTE rlabels={"a", "b", "c"}.
     COMPUTE clabels={"x", "y", "z"}.
     PRINT m/RNAMES=rlabels/CNAMES=clabels.
     END MATRIX.

With MDISPLAY=TEXT (the default), this program outputs the following (twice):

     m
                     x        y        z
     a               1        2        3
     b               4        5        6
     c               7        8        9

With SET MDISPLAY=TABLES. added above MATRIX., the output becomes the following (twice):

matrix-print

The DO IF Command
-----------------

     DO IF expression.
       ...matrix commands...
     [ELSE IF expression.
       ...matrix commands...]...
     [ELSE
       ...matrix commands...]
     END IF.

A DO IF command evaluates its expression argument.  If the DO IF expression evaluates to true, then pspp executes the associated commands.  Otherwise, pspp evaluates the expression on each ELSE IF clause (if any) in order, and executes the commands associated with the first one that yields a true value. Finally, if the DO IF and all the ELSE IF expressions all evaluate to false, pspp executes the commands following the ELSE clause (if any).

Each expression on DO IF and ELSE IF must evaluate to a scalar.  Positive scalars are considered to be true, and scalars that are zero or negative are considered to be false.

The following matrix language fragment sets b to the term following a in the Juggler sequence (https://en.wikipedia.org/wiki/Juggler_sequence):

     DO IF MOD(a, 2) = 0.
       COMPUTE b = TRUNC(a &** (1/2)).
     ELSE.
       COMPUTE b = TRUNC(a &** (3/2)).
     END IF.

The LOOP and BREAK Commands
---------------------------

     LOOP [var=first TO last [BY step]] [IF expression].
       ...matrix commands...
     END LOOP [IF expression].

     BREAK.

The LOOP command executes a nested group of matrix commands, called the loop's body, repeatedly.  It has three optional clauses that control how many times the loop body executes. Regardless of these clauses, the global MXLOOPS setting, which defaults to 40, also limits the number of iterations of a loop.  To iterate more times, raise the maximum with SET MXLOOPS outside of the MATRIX command (see SET MXLOOPS).

The optional index clause causes VAR to be assigned successive values on each trip through the loop: first FIRST, then FIRST + STEP, then FIRST + 2 times STEP, and so on.  The loop ends when VAR > LAST, for positive STEP, or VAR < LAST, for negative STEP.  If STEP is not specified, it defaults to 1.  All the index clause expressions must evaluate to scalars, and non-integers are rounded toward zero.  If STEP evaluates as zero (or rounds to zero), then the loop body never executes.

The optional IF on LOOP is evaluated before each iteration through the loop body.  If its expression, which must evaluate to a scalar, is zero or negative, then the loop terminates without executing the loop body.

The optional IF on END LOOP is evaluated after each iteration through the loop body.  If its expression, which must evaluate to a scalar, is zero or negative, then the loop terminates.

The following computes and prints l(n), whose value is the number of steps in the Juggler sequence (https://en.wikipedia.org/wiki/Juggler_sequence) for n, for n from 2 to 10 inclusive:

     COMPUTE l = {}.
     LOOP n = 2 TO 10.
       COMPUTE a = n.
       LOOP i = 1 TO 100.
         DO IF MOD(a, 2) = 0.
           COMPUTE a = TRUNC(a &** (1/2)).
         ELSE.
           COMPUTE a = TRUNC(a &** (3/2)).
         END IF.
       END LOOP IF a = 1.
       COMPUTE l = {l; i}.
     END LOOP.
     PRINT l.

The BREAK Command
.................

The BREAK command may be used inside a loop body, ordinarily within a DO IF command.  If it is executed, then the loop terminates immediately, jumping to the command just following END LOOP.  When multiple LOOP commands nest, BREAK terminates the innermost loop.

The following example is a revision of the one above that shows how BREAK could substitute for the index and IF clauses on LOOP and END LOOP:

     COMPUTE l = {}.
     LOOP n = 2 TO 10.
       COMPUTE a = n.
       COMPUTE i = 1.
       LOOP.
         DO IF MOD(a, 2) = 0.
           COMPUTE a = TRUNC(a &** (1/2)).
         ELSE.
           COMPUTE a = TRUNC(a &** (3/2)).
         END IF.
         DO IF a = 1.
           BREAK.
         END IF.
         COMPUTE i = i + 1.
       END LOOP.
       COMPUTE l = {l; i}.
     END LOOP.
     PRINT l.

The READ and WRITE Commands
---------------------------

The READ and WRITE commands perform matrix input and output with text files.  They share the following syntax for specifying how data is divided among input lines:

     /FIELD=first TO last [BY width]
     [/FORMAT=format]

Both commands require the FIELD subcommand.  It specifies the range of columns, from FIRST to LAST, inclusive, that the data occupies on each line of the file.  The leftmost column is column 1.  The columns must be literal numbers, not expressions.  To use entire lines, even if they might be very long, specify a column range such as 1 TO 100000.

The FORMAT subcommand is optional for numerical matrices.  For string matrix input and output, specify an A format.  In addition to FORMAT, the optional BY specification on FIELD determine the meaning of each text line:

  * With neither BY nor FORMAT, the numbers in the text file are in F format separated by spaces or commas.  For WRITE, pspp uses as many digits of precision as needed to accurately represent the numbers in the matrix.

  * BY width divides the input area into fixed-width fields with the given width.  The input area must be a multiple of width columns wide.  Numbers are read or written as Fwidth.0 format.

  * FORMAT=countF divides the input area into count equal-width fields per line.  The input area must be a multiple of count columns wide.  Another format type may be substituted for F.

  * FORMAT=Fw[.d] divides the input area into fixed-width fields with width w.  The input area must be a multiple of w columns wide.  Another format type may be substituted for F. The READ command disregards d.

  * FORMAT=F specifies format F without indicating a field width.  Another format type may be substituted for F.  The WRITE command accepts this form, but it has no effect unless BY is also used to specify a field width.

If BY and FORMAT both specify or imply a field width, then they must indicate the same field width.

The READ Command
................

     READ variable[(index[,index])]
          [/FILE=file]
          /FIELD=first TO last [BY width]
          [/FORMAT=format]
          [/SIZE=expression]
          [/MODE={RECTANGULAR | SYMMETRIC}]
          [/REREAD].

The READ command reads from a text file into a matrix variable. Specify the target variable just after the command name, either just a variable name to create or replace an entire variable, or a variable name followed by an indexing expression to replace a submatrix of an existing variable.

The FILE subcommand is required in the first READ command that appears within MATRIX.  It specifies the text file to be read, either as a file name in quotes or a file handle previously declared on FILE HANDLE (see FILE HANDLE). Later READ commands (in syntax order) use the previous referenced file if FILE is omitted.

The FIELD and FORMAT subcommands specify how input lines are interpreted.  FIELD is required, but FORMAT is optional.  See Matrix READ and WRITE Commands, for details.

The SIZE subcommand is required for reading into an entire variable.  Its restricted expression argument should evaluate to a 2-element vector {N, M} or {N; M}, which indicates a N times M matrix destination.  A scalar N is also allowed and indicates a N times1 column vector destination.  When the destination is a submatrix, SIZE is optional, and if it is present then it must match the size of the submatrix.

By default, or with MODE=RECTANGULAR, the command reads an entry for every row and column.  With MODE=SYMMETRIC, the command reads only the entries on and below the matrix's main diagonal, and copies the entries above the main diagonal from the corresponding symmetric entries below it.  Only square matrices may use MODE=SYMMETRIC.

Ordinarily, each READ command starts from a new line in the text file.  Specify the REREAD subcommand to instead start from the last line read by the previous READ command.  This has no effect for the first READ command to read from a particular file.  It is also ineffective just after a command that uses the EOF matrix function (see EOF Matrix Function) on a particular file, because EOF has to try to read the next line from the file to determine whether the file contains more input.

Example 1: Basic Use
....................

The following matrix program reads the same matrix {1, 2, 4; 2, 3, 5; 4, 5, 6} into matrix variables v, w, and x:

     READ v /FILE='input.txt' /FIELD=1 TO 100 /SIZE={3, 3}.
     READ w /FIELD=1 TO 100 /SIZE={3; 3} /MODE=SYMMETRIC.
     READ x /FIELD=1 TO 100 BY 1/SIZE={3, 3} /MODE=SYMMETRIC.

given that input.txt contains the following:

     1, 2, 4
     2, 3, 5
     4, 5, 6
     1
     2 3
     4 5 6
     1
     23
     456

The READ command will read as many lines of input as needed for a particular row, so it's also acceptable to break any of the lines above into multiple lines.  For example, the first line 1, 2, 4 could be written with a line break following either or both commas.

Example 2: Reading into a Submatrix
...................................

The following reads a 5 times5 matrix from input2.txt, reversing the order of the rows:

     COMPUTE m = MAKE(5, 5, 0).
     LOOP r = 5 TO 1 BY -1.
       READ m(r, :) /FILE='input2.txt' /FIELD=1 TO 100.
     END LOOP.

Example 3: Using REREAD
.......................

Suppose each of the 5 lines in a file input3.txt starts with an integer COUNT followed by COUNT numbers, e.g.:

     1 5
     3 1 2 3
     5 6 -1 2 5 1
     2 8 9
     3 1 3 2

Then, the following reads this file into a matrix m:

     COMPUTE m = MAKE(5, 5, 0).
     LOOP i = 1 TO 5.
       READ count /FILE='input3.txt' /FIELD=1 TO 1 /SIZE=1.
       READ m(i, 1:count) /FIELD=3 TO 100 /REREAD.
     END LOOP.

The WRITE Command
.................

     WRITE expression
           [/OUTFILE=file]
           /FIELD=first TO last [BY width]
           [/FORMAT=format]
           [/MODE={RECTANGULAR | TRIANGULAR}]
           [/HOLD].

The WRITE command evaluates expression and writes its value to a text file in a specified format.  Write the expression to evaluate just after the command name.

The OUTFILE subcommand is required in the first WRITE command that appears within MATRIX.  It specifies the text file to be written, either as a file name in quotes or a file handle previously declared on FILE HANDLE (see FILE HANDLE). Later WRITE commands (in syntax order) use the previous referenced file if FILE is omitted.

The FIELD and FORMAT subcommands specify how output lines are formed.  FIELD is required, but FORMAT is optional.  See Matrix READ and WRITE Commands, for details.

By default, or with MODE=RECTANGULAR, the command writes an entry for every row and column.  With MODE=TRIANGULAR, the command writes only the entries on and below the matrix's main diagonal.  Entries above the diagonal are not written.  Only square matrices may be written with MODE=TRIANGULAR.

Ordinarily, each WRITE command writes complete lines to the output file.  With HOLD, the final line written by WRITE will be held back for the next WRITE command to augment.  This can be useful to write more than one matrix on a single output line.

Example 1: Basic Usage
......................

This matrix program:

     WRITE {1, 2; 3, 4} /OUTFILE='matrix.txt' /FIELD=1 TO 80.

writes the following to matrix.txt:

      1 2
      3 4

Example 2: Triangular Matrix
............................

This matrix program:

     WRITE MAGIC(5) /OUTFILE='matrix.txt' /FIELD=1 TO 80 BY 5 /MODE=TRIANGULAR.

writes the following to matrix.txt:

         17
         23    5
          4    6   13
         10   12   19   21
         11   18   25    2    9

The GET Command
---------------

     GET variable[(index[,index])]
         [/FILE={file | *}]
         [/VARIABLES=variable...]
         [/NAMES=variable]
         [/MISSING={ACCEPT | OMIT | number}]
         [/SYSMIS={OMIT | number}].

The READ command reads numeric data from an SPSS system file, SPSS/PC+ system file, or SPSS portable file into a matrix variable or submatrix:

  * To read data into a variable, specify just its name following GET.  The variable need not already exist; if it does, it is replaced.  The variable will have as many columns as there are variables specified on the VARIABLES subcommand and as many rows as there are cases in the input file.

  * To read data into a submatrix, specify the name of an existing variable, followed by an indexing expression, just after GET. The submatrix must have as many columns as variables specified on VARIABLES and as many rows as cases in the input file.

Specify the name or handle of the file to be read on FILE.  Use *, or simply omit the FILE subcommand, to read from the active file.  Reading from the active file is only permitted if it was already defined outside MATRIX.

List the variables to be read as columns in the matrix on the VARIABLES subcommand.  The list can use TO for collections of variables or ALL for all variables.  If VARIABLES is omitted, all variables are read.  Only numeric variables may be read.

If a variable is named on NAMES, then the names of the variables read as data columns are stored in a string vector within the given name, replacing any existing matrix variable with that name. Variable names are truncated to 8 bytes.

The MISSING and SYSMIS subcommands control the treatment of missing values in the input file.  By default, any user- or system-missing data in the variables being read from the input causes an error that prevents GET from executing.  To accept missing values, specify one of the following settings on MISSING:

ACCEPT
     Accept user-missing values with no change.

     By default, system-missing values still yield an error.  Use the SYSMIS subcommand to change this treatment:

     OMIT
          Skip any case that contains a system-missing value.

     number
          Recode the system-missing value to number.

OMIT
     Skip any case that contains any user- or system-missing value.

number
     Recode all user- and system-missing values to number.

The SYSMIS subcommand has an effect only with MISSING=ACCEPT.

The SAVE Command
----------------

     SAVE expression
          [/OUTFILE={file | *}]
          [/VARIABLES=variable...]
          [/NAMES=expression]
          [/STRINGS=variable...].

The SAVE matrix command evaluates expression and writes the resulting matrix to an SPSS system file.  In the system file, each matrix row becomes a case and each column becomes a variable.

Specify the name or handle of the SPSS system file on the OUTFILE subcommand, or * to write the output as the new active file.  The OUTFILE subcommand is required on the first SAVE command, in syntax order, within MATRIX.  For SAVE commands after the first, the default output file is the same as the previous.

When multiple SAVE commands write to one destination within a single MATRIX, the later commands append to the same output file.  All the matrices written to the file must have the same number of columns.  The VARIABLES, NAMES, and STRINGS subcommands are honored only for the first SAVE command that writes to a given file.

By default, SAVE names the variables in the output file COL1 through COLn.  Use VARIABLES or NAMES to give the variables meaningful names.  The VARIABLES subcommand accepts a comma-separated list of variable names.  Its alternative, NAMES, instead accepts an expression that must evaluate to a row or column string vector of names.  The number of names need not exactly match the number of columns in the matrix to be written: extra names are ignored; extra columns use default names.

By default, SAVE assumes that the matrix to be written is all numeric.  To write string columns, specify a comma-separated list of the string columns' variable names on STRINGS.

The MGET Command
----------------

     MGET [/FILE=file]
          [/TYPE={COV | CORR | MEAN | STDDEV | N | COUNT}].

The MGET command reads the data from a matrix file (see Matrix Files) into matrix variables.

All of MGET's subcommands are optional.  Specify the name or handle of the matrix file to be read on the FILE subcommand; if it is omitted, then the command reads the active file.

By default, MGET reads all of the data from the matrix file. Specify a space-delimited list of matrix types on TYPE to limit the kinds of data to the one specified:

COV
     Covariance matrix.

CORR
     Correlation coefficient matrix.

MEAN
     Vector of means.

STDDEV
     Vector of standard deviations.

N
     Vector of case counts.

COUNT
     Vector of counts.

MGET reads the entire matrix file and automatically names, creates, and populates matrix variables using its contents.  It constructs the name of each variable by concatenating the following:

  * A 2-character prefix that identifies the type of the matrix:

     CV
          Covariance matrix.

     CR
          Correlation coefficient matrix.

     MN
          Vector of means.

     SD
          Vector of standard deviations.

     NC
          Vector of case counts.

     CN
          Vector of counts.

  * If the matrix file has factor variables, Fn, where n is a number identifying a group of factors: F1 for the first group, F2 for the second, and so on.  This part is omitted for pooled data (where the factors all have the system-missing value).

  * If the matrix file has split file variables, Sn, where n is a number identifying a split group: S1 for the first group, S2 for the second, and so on.

If MGET chooses the name of an existing variable, it issues a warning and does not change the variable.

The MSAVE Command
-----------------

     MSAVE expression
           /TYPE={COV | CORR | MEAN | STDDEV | N | COUNT}
           [/FACTOR=expression]
           [/SPLIT=expression]
           [/OUTFILE=file]
           [/VARIABLES=variable...]
           [/SNAMES=variable...]
           [/FNAMES=variable...].

The MSAVE command evaluates the expression specified just after the command name, and writes the resulting matrix to a matrix file (see Matrix Files).

The TYPE subcommand is required.  It specifies the ROWTYPE_ to write along with this matrix.

The FACTOR and SPLIT subcommands are required on the first MSAVE if and only if the matrix file has factor or split variables, respectively.  After that, their values are carried along from one MSAVE command to the next in syntax order as defaults. Each one takes an expression that must evaluate to a vector with the same number of entries as the matrix has factor or split variables, respectively.  Each MSAVE only writes data for a single combination of factor and split variables, so many MSAVE commands (or one inside a loop) may be needed to write a complete set.

The remaining MSAVE subcommands define the format of the matrix file.  All of the MSAVE commands within a given matrix program write to the same matrix file, so these subcommands are only meaningful on the first MSAVE command within a matrix program. (If they are given again on later MSAVE commands, then they must have the same values as on the first.)

The OUTFILE subcommand specifies the name or handle of the matrix file to be written.  Output must go to an external file, not a data set or the active file.

The VARIABLES subcommand specifies a comma-separated list of the names of the continuous variables to be written to the matrix file.  The TO keyword can be used to define variables named with consecutive integer suffixes.  These names become column names and names that appear in VARNAME_ in the matrix file. ROWTYPE_ and VARNAME_ are not allowed on VARIABLES.  If VARIABLES is omitted, then pspp uses the names COL1, COL2, and so on.

The FNAMES subcommand may be used to supply a comma-separated list of factor variable names.  The default names are FAC1, FAC2, and so on.

The SNAMES subcommand can supply a comma-separated list of split variable names.  The default names are SPL1, SPL2, and so on.

The DISPLAY Command
-------------------

     DISPLAY [{DICTIONARY | STATUS}].

The DISPLAY command makes pspp display a table with the name and dimensions of each matrix variable.  The DICTIONARY and STATUS keywords are accepted but have no effect.

The RELEASE Command
-------------------

     RELEASE variable....

The RELEASE command accepts a comma-separated list of matrix variable names.  It deletes each variable and releases the memory associated with it.

The END MATRIX command releases all matrix variables.