X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=doc%2Fmatrices.texi;h=58dea2f31b5aa655c5f9f047e43d7000c756dd87;hb=ff7ae14592cbdbebc4e4322424db95663ea7e166;hp=85d38fa54b2875982dd62b868efc027cf0db7a39;hpb=510cc9dd9baf3108ba55cfb7893384517c9930b4;p=pspp diff --git a/doc/matrices.texi b/doc/matrices.texi index 85d38fa54b..58dea2f31b 100644 --- a/doc/matrices.texi +++ b/doc/matrices.texi @@ -607,3 +607,2083 @@ explicitly request removing the existing data. The @cmd{MCONVERT} command requires its input to be a matrix file. Use @cmd{MATRIX DATA} to convert text input into matrix file format. @xref{MATRIX DATA}, for details. + +@node MATRIX +@section MATRIX +@vindex MATRIX +@vindex END MATRIX + +@display +@t{MATRIX.} +@dots{}@i{matrix commands}@dots{} +@t{END MATRIX.} +@end display + +@noindent +The following basic matrix commands are supported: + +@display +@t{COMPUTE} @i{variable}[@t{(}@i{index}[@t{,}@i{index}]@t{)}]@t{=}@i{expression}@t{.} +@t{CALL} @i{procedure}@t{(}@i{argument}@t{,} @dots{}). +@t{PRINT} [@i{expression}] + [@t{/FORMAT}@t{=}@i{format}] + [@t{/TITLE}@t{=}@i{title}] + [@t{/SPACE}@t{=}@{@t{NEWPAGE} @math{|} @i{n}@}] + [@{@t{/RLABELS}@t{=}@i{string}@dots{} @math{|} @t{/RNAMES}@t{=}@i{expression}@}] + [@{@t{/CLABELS}@t{=}@i{string}@dots{} @math{|} @t{/CNAMES}@t{=}@i{expression}@}]@t{.} +@end display + +@noindent +The following matrix commands offer support for flow control: + +@display +@t{DO IF} @i{expression}@t{.} + @dots{}@i{matrix commands}@dots{} +[@t{ELSE IF} @i{expression}@t{.} + @dots{}@i{matrix commands}@dots{}]@dots{} +[@t{ELSE} + @dots{}@i{matrix commands}@dots{}] +@t{END IF}@t{.} + +@t{LOOP} [@i{var}@t{=}@i{first} @t{TO} @i{last} [@t{BY} @i{step}]] [@t{IF} @i{expression}]@t{.} + @dots{}@i{matrix commands}@dots{} +@t{END LOOP} [@t{IF} @i{expression}]@t{.} + +@t{BREAK}@t{.} +@end display + +@noindent +The following matrix commands support matrix input and output: + +@display +@t{READ} @i{variable}[@t{(}@i{index}[@t{,}@i{index}]@t{)}] + [@t{/FILE}@t{=}@i{file}] + @t{/FIELD}@t{=}@i{first} @t{TO} @i{last} [@t{BY} @i{width}] + [@t{/FORMAT}@t{=}@i{format}] + [@t{/SIZE}@t{=}@i{expression}] + [@t{/MODE}@t{=}@{@t{RECTANGULAR} @math{|} @t{SYMMETRIC}@}] + [@t{/REREAD}]@t{.} +@t{WRITE} @i{expression} + [@t{/OUTFILE}@t{=}@i{file}] + @t{/FIELD}@t{=}@i{first} @t{TO} @i{last} [@t{BY} @i{width}] + [@t{/MODE}@t{=}@{@t{RECTANGULAR} @math{|} @t{TRIANGULAR}@}] + [@t{/HOLD}] + [@t{/FORMAT}@t{=}@i{format}]@t{.} +@t{GET} @i{variable}[@t{(}@i{index}[@t{,}@i{index}]@t{)}] + [@t{/FILE}@t{=}@{@i{file} @math{|} @t{*}@}] + [@t{/VARIABLES}@t{=}@i{variable}@dots{}] + [@t{/NAMES}@t{=}@i{expression}] + [@t{/MISSING}@t{=}@{@t{ACCEPT} @math{|} @t{OMIT} @math{|} @i{number}@}] + [@t{/SYSMIS}@t{=}@{@t{OMIT} @math{|} @i{number}@}]@t{.} +@t{SAVE} @i{expression} + [@t{/OUTFILE}@t{=}@{@i{file} @math{|} @t{*}@}] + [@t{/VARIABLES}@t{=}@i{variable}@dots{}] + [@t{/NAMES}@t{=}@i{expression}] + [@t{/STRINGS}@t{=}@i{variable}@dots{}]@t{.} +@t{MGET} [@t{/FILE}@t{=}@i{file}] + [@t{/TYPE}@t{=}@{@t{COV} @math{|} @t{CORR} @math{|} @t{MEAN} @math{|} @t{STDDEV} @math{|} @t{N} @math{|} @t{COUNT}@}]@t{.} +@t{MSAVE} @i{expression} + @t{/TYPE}@t{=}@{@t{COV} @math{|} @t{CORR} @math{|} @t{MEAN} @math{|} @t{STDDEV} @math{|} @t{N} @math{|} @t{COUNT}@} + [@t{/OUTFILE}@t{=}@i{file}] + [@t{/VARIABLES}@t{=}@i{variable}@dots{}] + [@t{/SNAMES}@t{=}@i{variable}@dots{}] + [@t{/SPLIT}@t{=}@i{expression}] + [@t{/FNAMES}@t{=}@i{variable}@dots{}] + [@t{/FACTOR}@t{=}@i{expression}]@t{.} +@end display + +@noindent +The following matrix commands provide additional support: + +@display +@t{DISPLAY} [@{@t{DICTIONARY} @math{|} @t{STATUS}@}]@t{.} +@t{RELEASE} @i{variable}@dots{}@t{.} +@end display + +@code{MATRIX} and @code{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 @code{MATRIX}@dots{}@code{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 @dfn{matrix} is a +rectangular array of real numbers. An @math{@var{n}@times{}@var{m}} +matrix has @var{n} rows and @var{m} columns. Some special cases are +important: a @math{@var{n}@times{}1} matrix is a @dfn{column vector}, +a @math{1@times{}@var{n}} is a @dfn{row vector}, and a +@math{1@times{}1} matrix is a @dfn{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 @code{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. + +@code{MATRIX} is a procedure, so it cannot be enclosed inside @code{DO +IF}, @code{LOOP}, etc. + +Macros may be used within a matrix program, and macros may expand to +include entire matrix programs. The @code{DEFINE} command may not +appear within a matrix program. @xref{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 @code{COMMENT} command (@pxref{COMMENT}) is also +supported. + +@node Matrix Expressions +@subsection 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. + +@itemize @bullet +@item +Function call @t{()} and matrix construction @t{@{@}} + +@item +Indexing @t{()} + +@item +Unary @t{+} and @t{-} + +@item +Integer sequence @t{:} + +@item +Exponentiation @t{**} and @t{&**} + +@item +Multiplication @t{*} and @t{&*}, and division @t{/} and @t{&/} + +@item +Addition @t{+} and subtraction @t{-} + +@item +Relational @t{< <= = >= > <>} + +@item +Logical @t{NOT} + +@item +Logical @t{AND} + +@item +Logical @t{OR} and @t{XOR} +@end itemize + +@xref{Matrix Functions}, for the available matrix functions. The +remaining operators are described in more detail below. + +@cindex restricted expressions +Expressions appear in the matrix language in some contexts where there +would be ambiguity whether @samp{/} is an operator or a separator +between subcommands. In these contexts, only the operators with +higher precedence than @samp{/} are allowed outside parentheses. +Later sections call these @dfn{restricted expressions}. + +@node Matrix Construction Operator +@subsubsection Matrix Construction Operator @t{@{@}} + +Use the @t{@{}@t{@}} operator to construct matrices. Within +the curly braces, commas separate elements within a row and semicolons +separate rows. The following examples show a @math{2@times{}3} +matrix, a @math{1@times{}4} row vector, a @math{3@times{}1} column +vector, and a scalar. + +@multitable @columnfractions .4 .05 .4 +@item @t{@{1, 2, 3; 4, 5, 6@}} +@tab @result{} +@tab +@ifnottex +@t{[1 2 3] @* [4 5 6]} +@end ifnottex +@iftex +@math{\left(\matrix{1 & 2 & 3 \cr 4 & 5 & 6}\right)} +@end iftex +@ +@item @t{@{3.14, 6.28, 9.24, 12.57@}} +@tab @result{} +@tab +@ifnottex +[3.14 6.28 9.42 12.57] +@end ifnottex +@iftex +@math{(\matrix{3.14 & 6.28 & 9.42 & 12.57})} +@end iftex +@ +@item @t{@{1.41; 1.73; 2@}} +@tab @result{} +@tab +@ifnottex +@t{[1.41] @* [1.73] @* [2.00]} +@end ifnottex +@iftex +@math{(\matrix{1.41 & 1.73 & 2.00})} +@end iftex +@ +@item @t{@{5@}} +@tab @result{} +@tab 5 +@end multitable + +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 +@samp{m} is matrix @code{@{1, 2; 3, 4@}}, @samp{r} is row vector +@code{@{5, 6@}}, and @samp{c} is column vector @code{@{7, 8@}}, then +curly braces can be used as follows: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{m, c; r, 10@}} +@tab @result{} +@tab +@ifnottex +@t{[1 2 7] @* [3 4 8] @* [5 6 10]} +@end ifnottex +@iftex +@math{\left(\matrix{1 & 2 & 7 \cr 3 & 4 & 8 \cr 5 & 6 & 10}\right)} +@end iftex +@ +@item @t{@{c, 2 * c, T(r)@}} +@tab @result{} +@tab +@ifnottex +@t{[7 14 5] @* [8 16 6]} +@end ifnottex +@iftex +@math{\left(\matrix{7 & 14 & 5 \cr 8 & 16 & 6}\right)} +@end iftex +@end multitable + +The final example above uses the transposition function @code{T}. + +@node Matrix Sequence Operator +@subsubsection Integer Sequence Operator @samp{:} + +The syntax @code{@var{first}:@var{last}:@var{step}} yields a row +vector of consecutive integers from @var{first} to @var{last} counting +by @var{step}. The final @code{:@var{step}} is optional and +defaults to 1 when omitted. + +Each of @var{first}, @var{last}, and @var{step} must be a scalar and +should be an integer (any fractional part is discarded). Because +@samp{:} has a high precedence, operands other than numeric literals +must usually be parenthesized. + +When @var{step} is positive (or omitted) and @math{@var{end} < +@var{start}}, or if @var{step} is negative and @math{@var{end} > +@var{start}}, then the result is an empty matrix. If @var{step} is 0, +then @pspp{} reports an error. + +Here are some examples: + +@multitable @columnfractions .4 .05 .4 +@item @t{1:6} @tab @result{} @tab @t{@{1, 2, 3, 4, 5, 6@}} +@item @t{1:6:2} @tab @result{} @tab @t{@{1, 3, 5@}} +@item @t{-1:-5:-1} @tab @result{} @tab @t{@{-1, -2, -3, -4, -5@}} +@item @t{-1:-5} @tab @result{} @tab @t{@{@}} +@item @t{2:1:0} @tab @result{} @tab (error) +@end multitable + +@node Matrix Index Operator +@subsubsection Index Operator @code{()} + +The result of the submatrix or indexing operator, written +@code{@var{m}(@var{rindex}, @var{cindex})}, contains the rows of +@var{m} whose indexes are given in vector @var{rindex} and the columns +whose indexes are given in vector @var{cindex}. + +In the simplest case, if @var{rindex} and @var{cindex} are both +scalars, the result is also a scalar: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{10, 20; 30, 40@}(1, 1)} @tab @result{} @tab @t{10} +@item @t{@{10, 20; 30, 40@}(1, 2)} @tab @result{} @tab @t{20} +@item @t{@{10, 20; 30, 40@}(2, 1)} @tab @result{} @tab @t{30} +@item @t{@{10, 20; 30, 40@}(2, 2)} @tab @result{} @tab @t{40} +@end multitable + +If the index arguments have multiple elements, then the result +includes multiple rows or columns: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{10, 20; 30, 40@}(1:2, 1)} @tab @result{} @tab @t{@{10; 30@}} +@item @t{@{10, 20; 30, 40@}(2, 1:2)} @tab @result{} @tab @t{@{30, 40@}} +@item @t{@{10, 20; 30, 40@}(1:2, 1:2)} @tab @result{} @tab @t{@{10, 20; 30, 40@}} +@end multitable + +The special argument @samp{:} may stand in for all the rows or columns +in the matrix being indexed, like this: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{10, 20; 30, 40@}(:, 1)} @tab @result{} @tab @t{@{10; 30@}} +@item @t{@{10, 20; 30, 40@}(2, :)} @tab @result{} @tab @t{@{30, 40@}} +@item @t{@{10, 20; 30, 40@}(:, :)} @tab @result{} @tab @t{@{10, 20; 30, 40@}} +@end multitable + +The index arguments do not have to be in order, and they may contain +repeated values, like this: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{10, 20; 30, 40@}(@{2, 1@}, 1)} @tab @result{} @tab @t{@{30; 10@}} +@item @t{@{10, 20; 30, 40@}(2, @{2; 2; 1@})} @tab @result{} @tab @t{@{40, 40, 30@}} +@item @t{@{10, 20; 30, 40@}(2:1:-1, :)} @tab @result{} @tab @t{@{30, 40; 10, 20@}} +@end multitable + +When the matrix being indexed is a row or column vector, only a single +index argument is needed, like this: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{11, 12, 13, 14, 15@}(2:4)} @tab @result{} @tab @t{@{12, 13, 14@}} +@item @t{@{11; 12; 13; 14; 15@}(2:4)} @tab @result{} @tab @t{@{12; 13; 14@}} +@end multitable + +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: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{11, 12, 13, 14@}(@{2.5, 4.6@})} @tab @result{} @tab @t{@{12, 14@}} +@item @t{@{11; 12; 13; 14@}(0)} @tab @result{} @tab (error) +@end multitable + +@node Matrix Unary Operators +@subsubsection Unary Operators + +The unary operators take a single operand of any dimensions and +operate on each of its elements independently. The unary operators +are: + +@table @code +@item - +Inverts the sign of each element. + +@item + +No change. + +@item NOT +Logical inversion: each positive value becomes 0 and each zero or +negative value becomes 1. +@end table + +Examples: + +@multitable @columnfractions .4 .05 .4 +@item @t{-@{1, -2; 3, -4@}} @tab @result{} @tab @t{@{-1, 2; -3, 4@}} +@item @t{+@{1, -2; 3, -4@}} @tab @result{} @tab @t{@{1, -2; 3, -4@}} +@item @t{NOT @{1, 0; -1, 1@}} @tab @result{} @tab @t{@{0, 1; 1, 0@}} +@end multitable + +@node Matrix Elementwise Binary Operators +@subsubsection 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. + +@itemize @bullet +@item +The arithmetic operators, for familiar arithmetic operations: + +@table @asis +@item @code{+} +Addition. + +@item @code{-} +Subtraction. + +@item @code{*} +Multiplication, if one operand is a scalar. (Otherwise this is matrix +multiplication, described below.) + +@item @code{/} or @code{&/} +Division. + +@item @code{&*} +Multiplication. + +@item @code{&**} +Exponentiation. +@end table + +@item +The relational operators, whose results are 1 when a comparison is +true and 0 when it is false: + +@table @asis +@item @code{<} or @code{LT} +Less than. + +@item @code{<=} or @code{LE} +Less than or equal. + +@item @code{=} or @code{EQ} +Equal. + +@item @code{>} or @code{GT} +Greater than. + +@item @code{>=} or @code{GE} +Greater than or equal. + +@item @code{<>} or @code{~=} or @code{NE} +Not equal. +@end table + +@item +The logical operators, which treat positive operands as true and +nonpositive operands as false. They yield 0 for false and 1 for true: + +@table @code +@item AND +True if both operands are true. + +@item OR +True if at least one operand is true. + +@item XOR +True if exactly one operand is true. +@end table +@end itemize + +Examples: + +@multitable @columnfractions .4 .05 .4 +@item @t{1 + 2} @tab @result{} @tab @t{3} +@item @t{1 + @{3; 4@}} @tab @result{} @tab @t{@{4; 5@}} +@item @t{@{66, 77; 88, 99@} + 5} @tab @result{} @tab @t{@{71, 82; 93, 104@}} +@item @t{@{4, 8; 3, 7@} + @{1, 0; 5, 2@}} @tab @result{} @tab @t{@{5, 8; 8, 9@}} +@item @t{@{1, 2; 3, 4@} < @{4, 3; 2, 1@}} @tab @result{} @tab @t{@{1, 1; 0, 0@}} +@item @t{@{1, 3; 2, 4@} >= 3} @tab @result{} @tab @t{@{0, 1; 0, 1@}} +@item @t{@{0, 0; 1, 1@} AND @{0, 1; 0, 1@}} @tab @result{} @tab @t{@{0, 0; 0, 1@}} +@end multitable + +@node Matrix Multiplication Operator +@subsubsection Matrix Multiplication Operator @samp{*} + +If @code{A} is an @math{@var{m}@times{}@var{n}} matrix and @code{B} is +an @math{@var{n}@times{}@var{p}} matrix, then @code{A*B} is the +@math{@var{m}@times{}@var{p}} matrix multiplication product @code{C}. +@pspp{} reports an error if the number of columns in @code{A} differs +from the number of rows in @code{B}. + +The @code{*} 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 @code{INV} or @code{GINV}. + +Some examples: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{1, 2, 3@} * @{4; 5; 6@}} @tab @result{} @tab @t{32} +@item @t{@{4; 5; 6@} * @{1, 2, 3@}} @tab @result{} @tab @t{@{4,@w{ } 8, 12; @*@w{ }5, 10, 15; @*@w{ }6, 12, 18@}} +@end multitable + +@node Matrix Exponentiation Operator +@subsubsection Matrix Exponentiation Operator @code{**} + +The result of @code{A**B} is defined as follows when @code{A} is a +square matrix and @code{B} is an integer scalar: + +@itemize @bullet +@item +For @code{B > 0}, @code{A**B} is @code{A*@dots{}*A}, where there are +@code{B} @samp{A}s. (@pspp{} implements this efficiently for large +@code{B}, using exponentiation by squaring.) + +@item +For @code{B < 0}, @code{A**B} is @code{INV(A**(-B))}. + +@item +For @code{B = 0}, @code{A**B} is the identity matrix. +@end itemize + +@noindent +@pspp{} reports an error if @code{A} is not square or @code{B} is not +an integer. + +Examples: + +@multitable @columnfractions .4 .05 .4 +@item @t{@{2, 5; 1, 4@}**3} @tab @result{} @tab @t{@{48, 165; 33, 114@}} +@item @t{@{2, 5; 1, 4@}**0} @tab @result{} @tab @t{@{1, 0; 0, 1@}} +@item @t{10*@{4, 7; 2, 6@}**-1} @tab @result{} @tab @t{@{6, -7; -2, 4@}} +@end multitable + +@node Matrix Functions +@subsection 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: + +@table @var +@item s +A scalar. + +@item n +A nonnegative integer scalar. (Non-integers are accepted and silently +rounded down to the nearest integer.) + +@item V +A row or column vector. + +@item M +A matrix. +@end table + +@node Matrix Elementwise Functions +@subsubsection Elementwise Functions + +These functions act on each element of their argument independently, +like the elementwise operators (@pxref{Matrix Elementwise Binary +Operators}). + +@deffn {Matrix Function} ABS (@var{M}) +Takes the absolute value of each element of @var{M}. + +@t{ABS(@{-1, 2; -3, 0@}) @result{} @{1, 2; 3, 0@}} +@end deffn + +@deffn {Matrix Function} ARSIN (@var{M}) +@deffnx {Matrix Function} ARTAN (@var{M}) +Computes the inverse sine or tangent, respectively, of each element in +@var{M}. The results are in radians, between @math{-\pi/2} and +@math{+\pi/2}, inclusive. + +The value of @math{\pi} can be computed as @code{4*ARTAN(1)}. + +@t{ARSIN(@{-1, 0, 1@}) @result{} @{-1.57, 0, 1.57@}} (approximately) + +@t{ARTAN(@{-5, -1, 1, 5@}) @result{} @{-1.37, -.79, .79, 1.37@}} (approximately) +@end deffn + +@deffn {Matrix Function} COS (@var{M}) +@deffnx {Matrix Function} SIN (@var{M}) +Computes the cosine or sine, respectively, of each element in @var{M}, +which must be in radians. + +@t{COS(@{0.785, 1.57; 3.14, 1.57 + 3.14@}) @result{} @{.71, 0; -1, 0@}} (approximately) +@end deffn + +@deffn {Matrix Function} EXP (@var{M}) +Computes @math{e^x} for each element @var{x} in @var{M}. + +@t{EXP(@{2, 3; 4, 5@}) @result{} @{7.39, 20.09; 54.6, 148.4@}} (approximately) +@end deffn + +@deffn {Matrix Function} LG10 (@var{M}) +@deffnx {Matrix Function} LN (@var{M}) +Takes the logarithm with base 10 or base @math{e}, respectively, of +each element in @var{M}. + +@t{LG10(@{1, 10, 100, 1000@}) @result{} @{0, 1, 2, 3@}} @* +@t{LG10(0) @result{}} (error) + +@t{LN(@{EXP(1), 1, 2, 3, 4@}) @result{} @{1, 0, .69, 1.1, 1.39@}} (approximately) @* +@t{LN(0) @result{}} (error) +@end deffn + +@deffn {Matrix Function} MOD (@var{M}, @var{s}) +Takes each element in @var{M} modulo nonzero scalar value @var{s}, +that is, the remainder of division by @var{s}. The sign of the result +is the same as the sign of the dividend. + +@t{MOD(@{5, 4, 3, 2, 1, 0@}, 3) @result{} @{2, 1, 0, 2, 1, 0@}} @* +@t{MOD(@{5, 4, 3, 2, 1, 0@}, -3) @result{} @{2, 1, 0, 2, 1, 0@}} @* +@t{MOD(@{-5, -4, -3, -2, -1, 0@}, 3) @result{} @{-2, -1, 0, -2, -1, 0@}} @* +@t{MOD(@{-5, -4, -3, -2, -1, 0@}, -3) @result{} @{-2, -1, 0, -2, -1, 0@}} @* +@t{MOD(@{5, 4, 3, 2, 1, 0@}, 1.5) @result{} @{.5, 1.0, .0, .5, 1.0, .0@}} @* +@t{MOD(@{5, 4, 3, 2, 1, 0@}, 0) @result{}} (error) +@end deffn + +@deffn {Matrix Function} RND (@var{M}) +@deffnx {Matrix Function} TRUNC (@var{M}) +Rounds each element of @var{M} to an integer. @code{RND} rounds to +the nearest integer, with halves rounded to even integers, and +@code{TRUNC} rounds toward zero. + +@t{RND(@{-1.6, -1.5, -1.4@}) @result{} @{-2, -2, -1@}} @* +@t{RND(@{-.6, -.5, -.4@}) @result{} @{-1, 0, 0@}} @* +@t{RND(@{.4, .5, .6@} @result{} @{0, 0, 1@}} @* +@t{RND(@{1.4, 1.5, 1.6@}) @result{} @{1, 2, 2@}} + +@t{TRUNC(@{-1.6, -1.5, -1.4@}) @result{} @{-1, -1, -1@}} @* +@t{TRUNC(@{-.6, -.5, -.4@}) @result{} @{0, 0, 0@}} @* +@t{TRUNC(@{.4, .5, .6@} @result{} @{0, 0, 0@}} @* +@t{TRUNC(@{1.4, 1.5, 1.6@}) @result{} @{1, 1, 1@}} +@end deffn + +@deffn {Matrix Function} SQRT (@var{M}) +Takes the square root of each element of @var{M}, which must not be +negative. + +@t{SQRT(@{0, 1, 2, 4, 9, 81@}) @result{} @{0, 1, 1.41, 2, 3, 9@}} (approximately) @* +@t{SQRT(-1) @result{}} (error) +@end deffn + +@node Matrix Logical Functions +@subsubsection Logical Functions + +@deffn {Matrix Function} ALL (@var{M}) +Returns a scalar with value 1 if all of the elements in @var{M} are +nonzero, or 0 if at least one element is zero. + +@t{ALL(@{1, 2, 3@} < @{2, 3, 4@}) @result{} 1} @* +@t{ALL(@{2, 2, 3@} < @{2, 3, 4@}) @result{} 0} @* +@t{ALL(@{2, 3, 3@} < @{2, 3, 4@}) @result{} 0} @* +@t{ALL(@{2, 3, 4@} < @{2, 3, 4@}) @result{} 0} +@end deffn + +@deffn {Matrix Function} ANY (@var{M}) +Returns a scalar with value 1 if any of the elements in @var{M} is +nonzero, or 0 if all of them are zero. + +@t{ANY(@{1, 2, 3@} < @{2, 3, 4@}) @result{} 1} @* +@t{ANY(@{2, 2, 3@} < @{2, 3, 4@}) @result{} 1} @* +@t{ANY(@{2, 3, 3@} < @{2, 3, 4@}) @result{} 1} @* +@t{ANY(@{2, 3, 4@} < @{2, 3, 4@}) @result{} 0} +@end deffn + +@node Matrix Construction Functions +@subsubsection Matrix Construction Functions + +@deffn {Matrix Function} BLOCK (@var{M1}, @dots{}, @var{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. + +@format +@t{BLOCK(@{1, 2; 3, 4@}, 5, @{7; 8; 9@}, @{10, 11@}) @result{} + 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} +@end format +@end deffn + +@deffn {Matrix Function} IDENT (@var{n}) +@deffnx {Matrix Function} IDENT (@var{nr}, @var{nc}) +Returns an identity matrix, whose main diagonal elements are one and +whose other elements are zero. The returned matrix has @var{n} rows +and columns or @var{nr} rows and @var{nc} columns, respectively. + +@format +@t{IDENT(1) @result{} 1 +IDENT(2) @result{} + 1 0 + 0 1 +IDENT(3, 5) @result{} + 1 0 0 0 0 + 0 1 0 0 0 + 0 0 1 0 0 +IDENT(5, 3) @result{} + 1 0 0 + 0 1 0 + 0 0 1 + 0 0 0 + 0 0 0} +@end format +@end deffn + +@deffn {Matrix Function} MAGIC (@var{n}) +Returns an @math{@var{n}@times{}@var{n}} matrix that contains each of +the integers @math{1@dots{}@var{n}} once, in which each column, each +row, and each diagonal sums to @math{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 @var{n}. + +@t{MAGIC(3) @result{} @{8, 1, 6; 3, 5, 7; 4, 9, 2@}} @* +@t{MAGIC(4) @result{} @{1, 5, 12, 16; 15, 11, 6, 2; 14, 8, 9, 3; 4, 10, 7, 13@}} +@end deffn + +@deffn {Matrix Function} MAKE (@var{nr}, @var{nc}, @var{s}) +Returns an @math{@var{nr}@times{}@var{nc}} matrix whose elements are +all @var{s}. + +@t{MAKE(1, 2, 3) @result{} @{3, 3@}} @* +@t{MAKE(2, 1, 4) @result{} @{4; 4@}} @* +@t{MAKE(2, 3, 5) @result{} @{5, 5, 5; 5, 5, 5@}} +@end deffn + +@deffn {Matrix Function} MDIAG (@var{V}) +@anchor{MDIAG} Given @var{n}-element vector @var{V}, returns a +@math{@var{n}@times{}@var{n}} matrix whose main diagonal is copied +from @var{V}. The other elements in the returned vector are zero. + +Use @code{CALL SETDIAG} (@pxref{CALL SETDIAG}) to replace the main +diagonal of a matrix in-place. + +@format +@t{MDIAG(@{1, 2, 3, 4@}) @result{} + 1 0 0 0 + 0 2 0 0 + 0 0 3 0 + 0 0 0 4} +@end format +@end deffn + +@deffn {Matrix Function} RESHAPE (@var{M}, @var{nr}, @var{nc}) +Returns an @math{@var{nr}@times{}@var{nc}} matrix whose elements come +from @var{M}, which must have the same number of elements as the new +matrix, copying elements from @var{M} to the new matrix row by row. + +@format +@t{RESHAPE(1:12, 1, 12) @result{} + 1 2 3 4 5 6 7 8 9 10 11 12 +RESHAPE(1:12, 2, 6) @result{} + 1 2 3 4 5 6 + 7 8 9 10 11 12 +RESHAPE(1:12, 3, 4) @result{} + 1 2 3 4 + 5 6 7 8 + 9 10 11 12 +RESHAPE(1:12, 4, 3) @result{} + 1 2 3 + 4 5 6 + 7 8 9 + 10 11 12} +@end format +@end deffn + +@deffn {Matrix Function} T (@var{M}) +@deffnx {Matrix Function} TRANSPOS (@var{M}) +Returns @var{M} with rows exchanged for columns. + +@t{T(@{1, 2, 3@}) @result{} @{1; 2; 3@}} @* +@t{T(@{1; 2; 3@}) @result{} @{1, 2, 3@}} +@end deffn + +@deffn {Matrix Function} UNIFORM (@var{nr}, @var{nc}) +Returns a @math{@var{nr}@times{}@var{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 +(@pxref{SET SEED}). + +The following example shows one possible output, but of course every +result will be different (given different seeds): + +@format +@t{UNIFORM(4, 5)*10 @result{} + 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} +@end format +@end deffn + +@node Matrix Minimum and Maximum and Sum Functions +@subsubsection Minimum, Maximum, and Sum Functions + +@deffn {Matrix Function} CMIN (@var{M}) +@deffnx {Matrix Function} CMAX (@var{M}) +@deffnx {Matrix Function} CSUM (@var{M}) +@deffnx {Matrix Function} CSSQ (@var{M}) +Returns a row vector with the same number of columns as @var{M}, in +which each element is the minimum, maximum, sum, or sum of squares, +respectively, of the elements in the same column of @var{M}. + +@t{CMIN(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} @{1, 2, 3@}} @* +@t{CMAX(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} @{7, 8, 9@}} @* +@t{CSUM(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} @{12, 15, 18@}} @* +@t{CSSQ(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} @{66, 93, 126@}} +@end deffn + +@deffn {Matrix Function} MMIN (@var{M}) +@deffnx {Matrix Function} MMAX (@var{M}) +@deffnx {Matrix Function} MSUM (@var{M}) +@deffnx {Matrix Function} MSSQ (@var{M}) +Returns the minimum, maximum, sum, or sum of squares, respectively, of +the elements of @var{M}. + +@t{MMIN(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} 1} @* +@t{MMAX(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} 9} @* +@t{MSUM(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} 45} @* +@t{MSSQ(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} 285} +@end deffn + +@deffn {Matrix Function} RMIN (@var{M}) +@deffnx {Matrix Function} RMAX (@var{M}) +@deffnx {Matrix Function} RSUM (@var{M}) +@deffnx {Matrix Function} RSSQ (@var{M}) +Returns a column vector with the same number of rows as @var{M}, in +which each element is the minimum, maximum, sum, or sum of squares, +respectively, of the elements in the same row of @var{M}. + +@t{RMIN(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} @{1; 4; 7@}} @* +@t{RMAX(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} @{3; 6; 9@}} @* +@t{RSUM(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} @{6; 15; 24@}} @* +@t{RSSQ(@{1, 2, 3; 4, 5, 6; 7, 8, 9@} @result{} @{14; 77; 194@}} +@end deffn + +@deffn {Matrix Function} SSCP (@var{M}) +Returns @math{@var{M}^T @times{} @var{M}}. + +@t{SSCP(@{1, 2, 3; 4, 5, 6@}) @result{} @{17, 22, 27; 22, 29, 36; 27, 36, 45@}} +@end deffn + +@deffn {Matrix Function} TRACE (@var{M}) +Returns the sum of the elements along @var{M}'s main diagonal, +equivalent to @code{MSUM(DIAG(@var{M}))}. + +@t{TRACE(MDIAG(1:5)) @result{} 15} +@end deffn + +@node Matrix Property Functions +@subsubsection Matrix Property Functions + +@deffn {Matrix Function} NROW (@var{M}) +@deffnx {Matrix Function} NCOL (@var{M}) +Returns the number of row or columns, respectively, in @var{M}. + +@format +@t{NROW(@{1, 0; -2, -3; 3, 3@}) @result{} 3 +NROW(1:5) @result{} 1 + +NCOL(@{1, 0; -2, -3; 3, 3@}) @result{} 2 +NCOL(1:5) @result{} 5} +@end format +@end deffn + +@deffn {Matrix Function} DIAG (@var{M}) +Returns a column vector containing a copy of @var{M}'s main diagonal. +The vector's length is the lesser of @code{NCOL(@var{M})} and +@code{NROW(@var{M})}. + +@t{DIAG(@{1, 0; -2, -3; 3, 3@}) @result{} @{1; -3@}} +@end deffn + +@node Matrix Rank Ordering Functions +@subsubsection Matrix Rank Ordering Functions + +The @code{GRADE} and @code{RANK} functions each take a matrix @var{M} +and return a matrix @var{r} with the same dimensions. Each element in +@var{r} ranges between 1 and the number of elements @var{n} in +@var{M}, inclusive. When the elements in @var{M} all have unique +values, both of these functions yield the same results: the smallest +element in @var{M} corresponds to value 1 in @var{r}, the next +smallest to 2, and so on, up to the largest to @var{n}. When multiple +elements in @var{M} have the same value, these functions use different +rules for handling the ties. + +@deffn {Matrix Function} GRADE (@var{M}) +Returns a ranking of @var{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. + +@t{GRADE(@{1, 0, 3; 3, 1, 2; 3, 0, 5@})} @result{} @t{@{3, 1, 6; 7, 4, 5; 8, 2, 9@}} +@end deffn + +@deffn {Matrix Function} RNKORDER (@var{M}) +Returns a ranking of @var{M}, turning duplicate values into the mean +of their sequential ranks. + +@t{RNKORDER(@{1, 0, 3; 3, 1, 2; 3, 0, 5@})} @*@w{ }@result{} @t{@{3.5, 1.5, 7; 7, 3.5, 5; 7, 1.5, 9@}} +@end deffn + +@noindent +One may use @code{GRADE} to sort a vector: + +@example +COMPUTE v(GRADE(v))=v. /* Sort v in ascending order. +COMPUTE v(GRADE(-v))=v. /* Sort v in descending order. +@end example + +@node Matrix Algebra Functions +@subsubsection Matrix Algebra Functions + +@deffn {Matrix Function} CHOL (@var{M}) +Matrix @var{M} must be an @math{@var{n}@times{}@var{n}} symmetric +positive-definite matrix. Returns an @math{@var{n}@times{}@var{n}} +matrix @var{B} such that @math{@var{B}^T@times{}@var{B}=@var{M}}. + +@format +@t{CHOL(@{4, 12, -16; 12, 37, -43; -16, -43, 98@}) @result{} + 2 6 -8 + 0 1 5 + 0 0 3} +@end format +@end deffn + +@deffn {Matrix Function} DESIGN (@var{M}) +Returns a design matrix for @var{M}. The design matrix has the same +number of rows as @var{M}. Each column @var{c} in @var{M}, from left +to right, yields a group of columns in the output. For each unique +value @var{v} in @var{c}, from top to bottom, add a column to the +output in which @var{v} becomes 1 and other values become 0. + +@pspp{} issues a warning if a column only contains a single unique value. + +@format +@t{DESIGN(@{1; 2; 3@}) @result{} @{1, 0, 0; 0, 1, 0; 0, 0, 1@}} +@t{DESIGN(@{5; 8; 5@}) @result{} @{1, 0; 0, 1; 1, 0@}} +@t{DESIGN(@{1, 5; 2, 8; 3, 5@})} + @result{} @t{@{1, 0, 0, 1, 0; 0, 1, 0, 0, 1; 0, 0, 1, 1, 0@}} +@t{DESIGN(@{5; 5; 5@})} @result{} (warning) +@end format +@end deffn + +@deffn {Matrix Function} DET (@var{M}) +Returns the determinant of square matrix @var{M}. + +@t{DET(@{3, 7; 1, -4@}) @result{} -19} +@end deffn + +@deffn {Matrix Function} EVAL (@var{M}) +@anchor{EVAL} +Returns a column vector containing the eigenvalues of symmetric matrix +@var{M}, sorted in ascending order. + +Use @code{CALL EIGEN} (@pxref{CALL EIGEN}) to compute eigenvalues and +eigenvectors of a matrix. + +@t{EVAL(@{2, 0, 0; 0, 3, 4; 0, 4, 9@}) @result{} @{11; 2; 1@}} +@end deffn + +@deffn {Matrix Function} GINV (@var{M}) +Returns the @math{@var{k}@times{}@var{n}} matrix @var{A} that is the +@dfn{generalized inverse} of @math{@var{n}@times{}@var{k}} matrix +@var{M}, defined such that +@math{@var{M}@times{}@var{A}@times{}@var{M}=@var{M}} and +@math{@var{A}@times{}@var{M}@times{}@var{A}=@var{A}}. + +@t{GINV(@{1, 2@}) @result{} @{.2; .4@}} (approximately) @* +@t{@{1:9@} * GINV(1:9) * @{1:9@} @result{} @{1:9@}} (approximately) +@end deffn + +@deffn {Matrix Function} GSCH (@var{M}) +@var{M} must be a @math{@var{n}@times{}@var{m}} matrix, @math{@var{m} +@geq{} @var{n}}, with rank @var{n}. Returns an +@math{@var{n}@times{}@var{n}} orthonormal basis for @var{M}, obtained +using the Gram-Schmidt process. + +@t{GSCH(@{3, 2; 1, 2@}) * SQRT(10) @result{} @{3, -1; 1, 3@}} (approximately) +@end deffn + +@deffn {Matrix Function} INV (@var{M}) +Returns the @math{@var{n}@times{}@var{n}} matrix @var{A} that is the +inverse of @math{@var{n}@times{}@var{n}} matrix @var{M}, defined such +that @math{@var{M}@times{}@var{A} = @var{A}@times{}@var{M} = I}, where +@var{I} is the identity matrix. @var{M} must not be singular, that +is, @math{\det(@var{M}) @ne{} 0}. + +@t{INV(@{4, 7; 2, 6@}) @result{} @{.6, -.7; -.2, .4@}} (approximately) +@end deffn + +@deffn {Matrix Function} KRONEKER (@var{Ma}, @var{Mb}) +Returns the @math{@var{pm}@times{}@var{qn}} matrix @var{P} that is the +@dfn{Kroneker product} of @math{@var{m}@times{}@var{n}} matrix +@var{Ma} and @math{@var{p}@times{}@var{q}} matrix @var{Mb}. One may +view @var{P} as the concatenation of multiple +@math{@var{p}@times{}@var{q}} blocks, each of which is the scalar +product of @var{Mb} by a different element of @var{Ma}. For example, +when @code{A} is a @math{2@times{}2} matrix, @code{KRONEKER(A, B)} is +equivalent to @code{@{A(1,1)*B, A(1,2)*B; A(2,1)*B, A(2,2)*B@}}. + +@format +@t{KRONEKER(@{1, 2; 3, 4@}, @{0, 5; 6, 7@}) @result{} + 0 5 0 10 + 6 7 12 14 + 0 15 0 20 + 18 21 24 28} +@end format +@end deffn + +@deffn {Matrix Function} RANK (@var{M}) +Returns the rank of matrix @var{M}, a integer scalar whose value is +the dimension of the vector space spanned by its columns or, +equivalently, by its rows. + +@format +@t{RANK(@{1, 0, 1; -2, -3, 1; 3, 3, 0@}) @result{} 2 +RANK(@{1, 1, 0, 2; -1, -1, 0, -2@}) @result{} 1 +RANK(@{1, -1; 1, -1; 0, 0; 2, -2@}) @result{} 1 +RANK(@{1, 2, 1; -2, -3, 1; 3, 5, 0@}) @result{} 2 +RANK(@{1, 0, 2; 2, 1, 0; 3, 2, 1@}) @result{} 3} +@end format +@end deffn + +@deffn {Matrix Function} SOLVE (@var{Ma}, @var{Mb}) +@var{Ma} must be an @math{@var{n}@times{}@var{n}} matrix, with +@math{\det(@var{Ma}) @ne{} 0}, and @var{Mb} an +@math{@var{n}@times{}@var{k}} matrix. Returns an +@math{@var{n}@times{}@var{k}} matrix @var{X} such that @math{@var{Ma} +@times{} @var{X} = @var{Mb}}. + +All of the following examples show approximate results: + +@format +@t{SOLVE(@{2, 3; 4, 9@}, @{6, 2; 15, 5@}) @result{} + 1.50 .50 + 1.00 .33 +SOLVE(@{1, 3, -2; 3, 5, 6; 2, 4, 3@}, @{5; 7; 8@}) @result{} + -15.00 + 8.00 + 2.00 +SOLVE(@{2, 1, -1; -3, -1, 2; -2, 1, 2@}, @{8; -11; -3@}) @result{} + 2.00 + 3.00 + -1.00} +@end format +@end deffn + +@deffn {Matrix Function} SVAL (@var{M}) +@anchor{SVAL} + +Given @math{@var{n}@times{}@var{k}} matrix @var{M}, returns a +@math{\min(@var{n},@var{k})}-element column vector containing the +singular values of @var{M} in descending order. + +Use @code{CALL SVD} (@pxref{CALL SVD}) to compute the full singular +value decomposition of a matrix. + +@format +@t{SVAL(@{1, 1; 0, 0@}) @result{} @{1.41; .00@} +SVAL(@{1, 0, 1; 0, 1, 1; 0, 0, 0@}) @result{} @{1.73; 1.00; .00@} +SVAL(@{2, 4; 1, 3; 0, 0; 0, 0@}) @result{} @{5.46; .37@}} +@end format +@end deffn + +@deffn {Matrix Function} SWEEP (@var{M}, @var{nk}) +Given @math{@var{r}@times{}@var{c}} matrix @var{M} and integer scalar +@math{k = @var{nk}} such that @math{1 @leq{} k @leq{} +\min(@var{r},@var{c})}, returns the @math{@var{r}@times{}@var{c}} +sweep matrix @var{A}. + +If @math{@var{M}_{kk} @ne{} 0}, then: + +@display +@math{@var{A}_{kk} = 1/@var{M}_{kk}}, +@math{@var{A}_{ik} = -@var{M}_{ik}/@var{M}_{kk} @r{for} i @ne{} k}, +@math{@var{A}_{kj} = @var{M}_{kj}/@var{M}_{kk} @r{for} j @ne{} k, @r{and}} +@math{@var{A}_{ij} = @var{M}_{ij} - @var{M}_{ik}@var{M}_{kj}/@var{M}_{kk} @r{for} i @ne{} k @r{and} j @ne{} k}. +@end display + +If @math{@var{M}_{kk} = 0}, then: + +@display +@math{@var{A}_{ik} = @var{A}_{ki} = 0 @r{and}} +@math{@var{A}_{ij} = @var{M}_{ij}, @r{for} i @ne{} k @r{and} j @ne{} k}. +@end display + +Given @t{M = @{0, 1, 2; 3, 4, 5; 6, 7, 8@}}, then (approximately): + +@format +@t{SWEEP(M, 1) @result{} + .00 .00 .00 + .00 4.00 5.00 + .00 7.00 8.00 +SWEEP(M, 2) @result{} + -.75 -.25 .75 + .75 .25 1.25 + .75 -1.75 -.75 +SWEEP(M, 3) @result{} + -1.50 -.75 -.25 + -.75 -.38 -.63 + .75 .88 .13} +@end format +@end deffn + +@node Matrix Statistical Distribution Functions +@subsubsection 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. @xref{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, +@code{CDF.BVNOR} and @code{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. + +@node Matrix EOF Function +@subsubsection EOF Function + +This function works with files being used on the @code{READ} statement. + +@deffn {Matrix Function} EOF (@var{file}) +@anchor{EOF Matrix Function} + +Given a file handle or file name @var{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 @code{REREAD} on the next @code{READ} command +following @code{EOF} on the same file will be ineffective. +@end deffn + +The @code{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 @file{data.txt}, each consisting of three numbers, as rows +in matrix @code{data}: + +@verbatim +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. + +@end verbatim + +@node Matrix COMPUTE Command +@subsection The @code{COMPUTE} Command + +@display +@t{COMPUTE} @i{variable}[@t{(}@i{index}[@t{,}@i{index}]@t{)}]@t{=}@i{expression}@t{.} +@end display + +The @code{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 (@pxref{Matrix +Index Operator}). + +@node Matrix CALL command +@subsection The @code{CALL} Command + +A matrix function returns a single result. The @code{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 @code{CALL} procedure must be a single variable +name. + +The following procedures are implemented via @code{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: + +@table @asis +@item @t{CALL EIGEN(@var{M}, @var{evec}, @var{eval})} +@anchor{CALL EIGEN} + +Computes the eigenvalues and eigenvector of symmetric +@math{@var{n}@times{}@var{n}} matrix @var{M}. Assigns the +eigenvectors of @var{M} to the columns of +@math{@var{n}@times{}@var{n}} matrix @var{evec} and the eigenvalues in +descending order to @var{n}-element column vector @var{eval}. + +Use the @code{EVAL} function (@pxref{EVAL}) to compute just the +eigenvalues of a symmetric matrix. + +For example, the following matrix language commands: +@example +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. +@end example + +@noindent +yield this output: + +@example +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 +@end example + +@item @t{CALL SVD(@var{M}, @var{U}, @var{S}, @var{V})} +@anchor{CALL SVD} + +Computes the singular value decomposition of +@math{@var{n}@times{}@var{k}} matrix @var{M}, assigning @var{S} a +@math{@var{n}@times{}@var{k}} diagonal matrix and to @var{U} and +@var{V} unitary @math{@var{k}@times{}@var{k}} matrices such that +@math{@var{M} = @var{U}@times{}@var{S}@times{}@var{V}^T}. The main +diagonal of @var{Q} contains the singular values of @var{M}. + +Use the @code{SVAL} function (@pxref{SVAL}) to compute just the +singular values of a matrix. + +For example, the following matrix program: + +@example +CALL SVD(@{3, 2, 2; 2, 3, -2@}, u, s, v). +PRINT (u * s * T(v))/FORMAT F5.1. +@end example + +@noindent +yields this output: + +@example +(u * s * T(v)) + 3.0 2.0 2.0 + 2.0 3.0 -2.0 +@end example +@end table + +The final procedure is implemented via @code{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. + +@table @asis +@item @t{CALL SETDIAG(@var{M}, @var{V})} +@anchor{CALL SETDIAG} + +Replaces the main diagonal of @math{@var{n}@times{}@var{p}} matrix +@var{M} by the contents of @var{k}-element vector @var{V}. If +@math{@var{k} = 1}, so that @var{V} is a scalar, replaces all of the +diagonal elements of @var{M} by @var{V}. If @math{@var{k} < +\min(@var{n},@var{p})}, only the upper @var{k} diagonal elements are +replaced; if @math{@var{k} > \min(@var{n},@var{p})}, then the +extra elements of @var{V} are ignored. + +Use the @code{MDIAG} function (@pxref{MDIAG}) to construct a new +matrix with a specified main diagonal. + +For example, this matrix program: + +@example +COMPUTE x=@{1, 2, 3; 4, 5, 6; 7, 8, 9@}. +CALL SETDIAG(x, 10). +PRINT x. +@end example + +@noindent +outputs the following: + +@example +x + 10 2 3 + 4 10 6 + 7 8 10 +@end example +@end table + +@node Matrix PRINT Command +@subsection The @code{PRINT} Command + +@display +@t{PRINT} [@i{expression}] + [@t{/FORMAT}@t{=}@i{format}] + [@t{/TITLE}@t{=}@i{title}] + [@t{/SPACE}@t{=}@{@t{NEWPAGE} @math{|} @i{n}@}] + [@{@t{/RLABELS}@t{=}@i{string}@dots{} @math{|} @t{/RNAMES}@t{=}@i{expression}@}] + [@{@t{/CLABELS}@t{=}@i{string}@dots{} @math{|} @t{/CNAMES}@t{=}@i{expression}@}]@t{.} +@end display + +The @code{PRINT} command is commonly used to display a matrix. It +evaluates the restricted @var{expression}, if present, and outputs it +either as text or a pivot table, depending on the setting of +@code{MDISPLAY} (@pxref{SET MDISPLAY}). + +Use the @code{FORMAT} subcommand to specify a format, such as +@code{F8.2}, for displaying the matrix elements. @code{FORMAT} is +optional for numerical matrices. When it is omitted, @pspp{} chooses +how to format entries automatically using @var{m}, the magnitude of +the largest-magnitude element in the matrix to be displayed: + +@enumerate +@item +If @math{@var{m} < 10^{11}} and the matrix's elements are all +integers, @pspp{} chooses the narrowest @code{F} format that fits +@var{m} plus a sign. For example, if the matrix is @t{@{1:10@}}, then +@math{m = 10}, which fits in 3 columns with room for a sign, the +format is @code{F3.0}. + +@item +Otherwise, if @math{@var{m} @geq{} 10^9} or @math{@var{m} @leq{} +10^{-4}}, @pspp{} scales all of the numbers in the matrix by +@math{10^x}, where @var{x} is the exponent that would be used to +display @var{m} in scientific notation. For example, for +@math{@var{m} = 5.123@times{}10^{20}}, the scale factor is +@math{10^{20}}. @pspp{} displays the scaled values in format +@code{F13.10} and notes the scale factor in the output. + +@item +Otherwise, @pspp{} displays the matrix values, without scaling, in +format @code{F13.10}. +@end enumerate + +The optional @code{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 @code{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 @code{NEWPAGE} +as an argument, it prints the matrix at the top of a new page. The +@code{SPACE} subcommand has no effect when a matrix is output as a +pivot table. + +The @code{RLABELS} and @code{RNAMES} subcommands, which are mutually +exclusive, can supply a label to accompany each row in the output. +With @code{RLABELS}, specify the labels as comma-separated strings or +other tokens. With @code{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 @code{RLABELS}, the labels can be any length; otherwise, +the labels are truncated to 8 bytes. + +The @code{CLABELS} and @code{CNAMES} subcommands work for labeling +columns as @code{RLABELS} and @code{RNAMES} do for labeling rows. + +When the @var{expression} is omitted, @code{PRINT} does not output a +matrix. Instead, it outputs only the text specified on @code{TITLE}, +if any, preceded by any space specified on the @code{SPACE} +subcommand, if any. Any other subcommands are ignored, and the +command acts as if @code{MDISPLAY} is set to @code{TEXT} regardless of +its actual setting. + +The following syntax demonstrates two different ways to label the rows +and columns of a matrix with @code{PRINT}: + +@example +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. +@end example + +@noindent +With @code{MDISPLAY=TEXT} (the default), this program outputs the +following (twice): + +@example +m + x y z +a 1 2 3 +b 4 5 6 +c 7 8 9 +@end example + +@noindent +With @samp{SET MDISPLAY=TABLES.} added above @samp{MATRIX.}, the +output becomes the following (twice): + +@psppoutput {matrix-print} + +@node Matrix DO IF Command +@subsection The @code{DO IF} Command + +@display +@t{DO IF} @i{expression}@t{.} + @dots{}@i{matrix commands}@dots{} +[@t{ELSE IF} @i{expression}@t{.} + @dots{}@i{matrix commands}@dots{}]@dots{} +[@t{ELSE} + @dots{}@i{matrix commands}@dots{}] +@t{END IF}@t{.} +@end display + +A @code{DO IF} command evaluates its expression argument. If the +@code{DO IF} expression evaluates to true, then @pspp{} executes the +associated commands. Otherwise, @pspp{} evaluates the expression on +each @code{ELSE IF} clause (if any) in order, and executes the +commands associated with the first one that yields a true value. +Finally, if the @code{DO IF} and all the @code{ELSE IF} expressions +all evaluate to false, @pspp{} executes the commands following the +@code{ELSE} clause (if any). + +Each expression on @code{DO IF} and @code{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 @samp{b} to the term +following @samp{a} in the +@url{https://en.wikipedia.org/wiki/Juggler_sequence, Juggler +sequence}: + +@example +DO IF MOD(a, 2) = 0. + COMPUTE b = TRUNC(a &** (1/2)). +ELSE. + COMPUTE b = TRUNC(a &** (3/2)). +END IF. +@end example + +@node Matrix LOOP and BREAK Commands +@subsection The @code{LOOP} and @code{BREAK} Commands + +@display +@t{LOOP} [@i{var}@t{=}@i{first} @t{TO} @i{last} [@t{BY} @i{step}]] [@t{IF} @i{expression}]@t{.} + @dots{}@i{matrix commands}@dots{} +@t{END LOOP} [@t{IF} @i{expression}]@t{.} + +@t{BREAK}@t{.} +@end display + +The @code{LOOP} command executes a nested group of matrix commands, +called the loop's @dfn{body}, repeatedly. It has three optional +clauses that control how many times the loop body executes. +Regardless of these clauses, the global @code{MXLOOPS} setting, which +defaults to 40, also limits the number of iterations of a loop. To +iterate more times, raise the maximum with @code{SET MXLOOPS} outside +of the @code{MATRIX} command (@pxref{SET MXLOOPS}). + +The optional index clause causes @var{var} to be assigned successive +values on each trip through the loop: first @var{first}, then +@math{@var{first} + @var{step}}, then @math{@var{first} + 2 @times{} +@var{step}}, and so on. The loop ends when @math{@var{var} > +@var{last}}, for positive @var{step}, or @math{@var{var} < +@var{last}}, for negative @var{step}. If @var{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 @var{step} +evaluates as zero (or rounds to zero), then the loop body never +executes. + +The optional @code{IF} on @code{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 @code{IF} on @code{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 @math{l(n)}, whose value is the +number of steps in the +@url{https://en.wikipedia.org/wiki/Juggler_sequence, Juggler sequence} +for @math{n}, for @math{n} from 2 to 10 inclusive: + +@example +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. +@end example + +@menu +* Matrix BREAK Command:: +@end menu + +@node Matrix BREAK Command +@subsubsection The @code{BREAK} Command + +The @code{BREAK} command may be used inside a loop body, ordinarily +within a @code{DO IF} command. If it is executed, then the loop +terminates immediately, jumping to the command just following +@code{END LOOP}. When multiple @code{LOOP} commands nest, +@code{BREAK} terminates the innermost loop. + +The following example is a revision of the one above that shows how +@code{BREAK} could substitute for the index and @code{IF} clauses on +@code{LOOP} and @code{END LOOP}: + +@example +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. +@end example + +@node Matrix READ and WRITE Commands +@subsection The @code{READ} and @code{WRITE} Commands + +The @code{READ} and @code{WRITE} commands perform matrix input and +output with text files. They share the following syntax for +specifying how data is divided among input lines: + +@display +@t{/FIELD}@t{=}@i{first} @t{TO} @i{last} [@t{BY} @i{width}] +[@t{/FORMAT}@t{=}@i{format}] +@end display + +Both commands require the @code{FIELD} subcommand. It specifies the +range of columns, from @var{first} to @var{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 @code{1 TO 100000}. + +The @code{FORMAT} subcommand is optional for numerical matrices. For +string matrix input and output, specify an @code{A} format. In +addition to @code{FORMAT}, the optional @code{BY} specification on +@code{FIELD} determine the meaning of each text line: + +@itemize @bullet +@item +With neither @code{BY} nor @code{FORMAT}, the numbers in the text file +are in @code{F} format separated by spaces or commas. For +@code{WRITE}, @pspp{} uses as many digits of precision as needed to +accurately represent the numbers in the matrix. + +@item +@code{BY @i{width}} divides the input area into fixed-width fields +with the given @i{width}. The input area must be a multiple of +@i{width} columns wide. Numbers are read or written as +@code{F@i{width}.0} format. + +@item +@code{FORMAT=@i{count}F} divides the input area into @i{count} +equal-width fields per line. The input area must be a multiple of +@i{count} columns wide. Another format type may be substituted for +@code{F}. + +@item +@code{FORMAT=F@i{w}}[@code{.@i{d}}] divides the input area into fixed-width +fields with width @i{w}. The input area must be a multiple of @i{w} +columns wide. Another format type may be substituted for @code{F}. +The @code{READ} command disregards @i{d}. + +@item +@code{FORMAT=F} specifies format @code{F} without indicating a field +width. Another format type may be substituted for @code{F}. The +@code{WRITE} command accepts this form, but it has no effect unless +@code{BY} is also used to specify a field width. +@end itemize + +If @code{BY} and @code{FORMAT} both specify or imply a field width, +then they must indicate the same field width. + +@node Matrix READ Command +@subsubsection The @code{READ} Command + +@display +@t{READ} @i{variable}[@t{(}@i{index}[@t{,}@i{index}]@t{)}] + [@t{/FILE}@t{=}@i{file}] + @t{/FIELD}@t{=}@i{first} @t{TO} @i{last} [@t{BY} @i{width}] + [@t{/FORMAT}@t{=}@i{format}] + [@t{/SIZE}@t{=}@i{expression}] + [@t{/MODE}@t{=}@{@t{RECTANGULAR} @math{|} @t{SYMMETRIC}@}] + [@t{/REREAD}]@t{.} +@end display + +The @code{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 @code{FILE} subcommand is required in the first @code{READ} +command that appears within @code{MATRIX}. It specifies the text file +to be read, either as a file name in quotes or a file handle +previously declared on @code{FILE HANDLE} (@pxref{FILE HANDLE}). +Later @code{READ} commands (in syntax order) use the previous +referenced file if @code{FILE} is omitted. + +The @code{FIELD} and @code{FORMAT} subcommands specify how input lines +are interpreted. @code{FIELD} is required, but @code{FORMAT} is +optional. @xref{Matrix READ and WRITE Commands}, for details. + +The @code{SIZE} subcommand is required for reading into an entire +variable. Its restricted expression argument should evaluate to a +2-element vector @code{@{@var{n},@w{ }@var{m}@}} or +@code{@{@var{n};@w{ }@var{m}@}}, which indicates a +@math{@var{n}@times{}@var{m}} matrix destination. A scalar @var{n} is +also allowed and indicates a @math{@var{n}@times{}1} column vector +destination. When the destination is a submatrix, @code{SIZE} is +optional, and if it is present then it must match the size of the +submatrix. + +By default, or with @code{MODE=RECTANGULAR}, the command reads an +entry for every row and column. With @code{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 @code{MODE=SYMMETRIC}. + +Ordinarily, each @code{READ} command starts from a new line in the +text file. Specify the @code{REREAD} subcommand to instead start from +the last line read by the previous @code{READ} command. This has no +effect for the first @code{READ} command to read from a particular +file. It is also ineffective just after a command that uses the +@code{EOF} matrix function (@pxref{EOF Matrix Function}) on a +particular file, because @code{EOF} has to try to read the next line +from the file to determine whether the file contains more input. + +@subsubheading Example 1: Basic Use + +The following matrix program reads the same matrix @code{@{1, 2, 4; 2, +3, 5; 4, 5, 6@}} into matrix variables @code{v}, @code{w}, and +@code{x}: + +@example +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. +@end example + +@noindent +given that @file{input.txt} contains the following: + +@example +1, 2, 4 +2, 3, 5 +4, 5, 6 +1 +2 3 +4 5 6 +1 +23 +456 +@end example + +The @code{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 @code{1, 2, 4} +could be written with a line break following either or both commas. + +@subsubheading Example 2: Reading into a Submatrix + +The following reads a @math{5@times{}5} matrix from @file{input2.txt}, +reversing the order of the rows: + +@example +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. +@end example + +@subsubheading Example 3: Using @code{REREAD} + +Suppose each of the 5 lines in a file @file{input3.txt} starts with an +integer @var{count} followed by @var{count} numbers, e.g.: + +@example +1 5 +3 1 2 3 +5 6 -1 2 5 1 +2 8 9 +3 1 3 2 +@end example + +@noindent +Then, the following reads this file into a matrix @code{m}: + +@example +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. +@end example + +@node Matrix WRITE Command +@subsubsection The @code{WRITE} Command + +@display +@t{WRITE} @i{expression} + [@t{/OUTFILE}@t{=}@i{file}] + @t{/FIELD}@t{=}@i{first} @t{TO} @i{last} [@t{BY} @i{width}] + [@t{/FORMAT}@t{=}@i{format}] + [@t{/MODE}@t{=}@{@t{RECTANGULAR} @math{|} @t{TRIANGULAR}@}] + [@t{/HOLD}]@t{.} +@end display + +The @code{WRITE} command evaluates @i{expression} and writes its value +to a text file in a specified format. Write the expression to +evaluate just after the command name. + +The @code{OUTFILE} subcommand is required in the first @code{WRITE} +command that appears within @code{MATRIX}. It specifies the text file +to be written, either as a file name in quotes or a file handle +previously declared on @code{FILE HANDLE} (@pxref{FILE HANDLE}). +Later @code{WRITE} commands (in syntax order) use the previous +referenced file if @code{FILE} is omitted. + +The @code{FIELD} and @code{FORMAT} subcommands specify how output +lines are formed. @code{FIELD} is required, but @code{FORMAT} is +optional. @xref{Matrix READ and WRITE Commands}, for details. + +By default, or with @code{MODE=RECTANGULAR}, the command writes an +entry for every row and column. With @code{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 @code{MODE=TRIANGULAR}. + +Ordinarily, each @code{WRITE} command writes complete lines to the +output file. With @code{HOLD}, the final line written by @code{WRITE} +will be held back for the next @code{WRITE} command to augment. This +can be useful to write more than one matrix on a single output line. + +@subsubheading Example 1: Basic Usage + +This matrix program: + +@example +WRITE @{1, 2; 3, 4@} /OUTFILE='matrix.txt' /FIELD=1 TO 80. +@end example + +@noindent +writes the following to @file{matrix.txt}: + +@example + 1 2 + 3 4 +@end example + +@subsubheading Example 2: Triangular Matrix + +This matrix program: + +@example +WRITE MAGIC(5) /OUTFILE='matrix.txt' /FIELD=1 TO 80 BY 5 /MODE=TRIANGULAR. +@end example + +@noindent +writes the following to @file{matrix.txt}: + +@example + 17 + 23 5 + 4 6 13 + 10 12 19 21 + 11 18 25 2 9 +@end example + +@node Matrix GET Command +@subsection The @code{GET} Command + +@display +@t{GET} @i{variable}[@t{(}@i{index}[@t{,}@i{index}]@t{)}] + [@t{/FILE}@t{=}@{@i{file} @math{|} @t{*}@}] + [@t{/VARIABLES}@t{=}@i{variable}@dots{}] + [@t{/NAMES}@t{=}@i{variable}] + [@t{/MISSING}@t{=}@{@t{ACCEPT} @math{|} @t{OMIT} @math{|} @i{number}@}] + [@t{/SYSMIS}@t{=}@{@t{OMIT} @math{|} @i{number}@}]@t{.} +@end display + +The @code{READ} command reads numeric data from an SPSS system file, +SPSS/PC+ system file, or SPSS portable file into a matrix variable or +submatrix: + +@itemize @bullet +@item +To read data into a variable, specify just its name following +@code{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 @code{VARIABLES} subcommand and as many +rows as there are cases in the input file. + +@item +To read data into a submatrix, specify the name of an existing +variable, followed by an indexing expression, just after @code{GET}. +The submatrix must have as many columns as variables specified on +@code{VARIABLES} and as many rows as cases in the input file. +@end itemize + +Specify the name or handle of the file to be read on @code{FILE}. Use +@samp{*}, or simply omit the @code{FILE} subcommand, to read from the +active file. Reading from the active file is only permitted if it was +already defined outside @code{MATRIX}. + +List the variables to be read as columns in the matrix on the +@code{VARIABLES} subcommand. The list can use @code{TO} for +collections of variables or @code{ALL} for all variables. If +@code{VARIABLES} is omitted, all variables are read. Only numeric +variables may be read. + +If a variable is named on @code{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 @code{MISSING} and @code{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 @code{GET} from executing. To accept missing +values, specify one of the following settings on @code{MISSING}: + +@table @asis +@item @code{ACCEPT} +Accept user-missing values with no change. + +By default, system-missing values still yield an error. Use the +@code{SYSMIS} subcommand to change this treatment: + +@table @asis +@item @code{OMIT} +Skip any case that contains a system-missing value. + +@item @i{number} +Recode the system-missing value to @i{number}. +@end table + +@item @code{OMIT} +Skip any case that contains any user- or system-missing value. + +@item @i{number} +Recode all user- and system-missing values to @i{number}. +@end table + +The @code{SYSMIS} subcommand has an effect only with +@code{MISSING=ACCEPT}. + +@node Matrix SAVE Command +@subsection The @code{SAVE} Command + +@display +@t{SAVE} @i{expression} + [@t{/OUTFILE}@t{=}@{@i{file} @math{|} @t{*}@}] + [@t{/VARIABLES}@t{=}@i{variable}@dots{}] + [@t{/NAMES}@t{=}@i{expression}] + [@t{/STRINGS}@t{=}@i{variable}@dots{}]@t{.} +@end display + +The @code{SAVE} matrix command evaluates @i{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 +@code{OUTFILE} subcommand, or @samp{*} to write the output as the new +active file. The @code{OUTFILE} subcommand is required on the first +@code{SAVE} command, in syntax order, within @code{MATRIX}. For +@code{SAVE} commands after the first, the default output file is the +same as the previous. + +When multiple @code{SAVE} commands write to one destination within a +single @code{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 @code{VARIABLES}, @code{NAMES}, and @code{STRINGS} +subcommands are honored only for the first @code{SAVE} command that +writes to a given file. + +By default, @code{SAVE} names the variables in the output file +@code{COL1} through @code{COL@i{n}}. Use @code{VARIABLES} or +@code{NAMES} to give the variables meaningful names. The +@code{VARIABLES} subcommand accepts a comma-separated list of variable +names. Its alternative, @code{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, @code{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 @code{STRINGS}. + +@node Matrix MGET Command +@subsection The @code{MGET} Command + +@display +@t{MGET} [@t{/FILE}@t{=}@i{file}] + [@t{/TYPE}@t{=}@{@t{COV} @math{|} @t{CORR} @math{|} @t{MEAN} @math{|} @t{STDDEV} @math{|} @t{N} @math{|} @t{COUNT}@}]@t{.} +@end display + +The @code{MGET} command reads the data from a matrix file +(@pxref{Matrix Files}) into matrix variables. + +All of @code{MGET}'s subcommands are optional. Specify the name or +handle of the matrix file to be read on the @code{FILE} subcommand; if +it is omitted, then the command reads the active file. + +By default, @code{MGET} reads all of the data from the matrix file. +Specify a space-delimited list of matrix types on @code{TYPE} to limit +the kinds of data to the one specified: + +@table @code +@item COV +Covariance matrix. + +@item CORR +Correlation coefficient matrix. + +@item MEAN +Vector of means. + +@item STDDEV +Vector of standard deviations. + +@item N +Vector of case counts. + +@item COUNT +Vector of counts. +@end table + +@code{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: + +@itemize @bullet +@item +A 2-character prefix that identifies the type of the matrix: + +@table @code +@item CV +Covariance matrix. + +@item CR +Correlation coefficient matrix. + +@item MN +Vector of means. + +@item SD +Vector of standard deviations. + +@item NC +Vector of case counts. + +@item CN +Vector of counts. +@end table + +@item +If the matrix file has factor variables, @code{F@i{n}}, where @i{n} is +a number identifying a group of factors: @code{F1} for the first +group, @code{F2} for the second, and so on. This part is omitted for +pooled data (where the factors all have the system-missing value). + +@item +If the matrix file has split file variables, @code{S@i{n}}, where +@i{n} is a number identifying a split group: @code{S1} for the first +group, @code{S2} for the second, and so on. +@end itemize + +If @code{MGET} chooses the name of an existing variable, it issues a +warning and does not change the variable. + +@node Matrix MSAVE Command +@subsection The @code{MSAVE} Command + +@display +@t{MSAVE} @i{expression} + @t{/TYPE}@t{=}@{@t{COV} @math{|} @t{CORR} @math{|} @t{MEAN} @math{|} @t{STDDEV} @math{|} @t{N} @math{|} @t{COUNT}@} + [@t{/FACTOR}@t{=}@i{expression}] + [@t{/SPLIT}@t{=}@i{expression}] + [@t{/OUTFILE}@t{=}@i{file}] + [@t{/VARIABLES}@t{=}@i{variable}@dots{}] + [@t{/SNAMES}@t{=}@i{variable}@dots{}] + [@t{/FNAMES}@t{=}@i{variable}@dots{}]@t{.} +@end display + +The @code{MSAVE} command evaluates the @i{expression} specified just +after the command name, and writes the resulting matrix to a matrix +file (@pxref{Matrix Files}). + +The @code{TYPE} subcommand is required. It specifies the +@code{ROWTYPE_} to write along with this matrix. + +The @code{FACTOR} and @code{SPLIT} subcommands are required on the +first @code{MSAVE} if and only if the matrix file has factor or split +variables, respectively. After that, their values are carried along +from one @code{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 @code{MSAVE} only writes data for a single +combination of factor and split variables, so many @code{MSAVE} +commands (or one inside a loop) may be needed to write a complete set. + +The remaining @code{MSAVE} subcommands define the format of the matrix +file. All of the @code{MSAVE} commands within a given matrix program +write to the same matrix file, so these subcommands are only +meaningful on the first @code{MSAVE} command within a matrix program. +(If they are given again on later @code{MSAVE} commands, then they +must have the same values as on the first.) + +The @code{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 @code{VARIABLES} subcommand specifies a comma-separated list of +the names of the continuous variables to be written to the matrix +file. The @code{TO} keyword can be used to define variables named +with consecutive integer suffixes. These names become column names +and names that appear in @code{VARNAME_} in the matrix file. +@code{ROWTYPE_} and @code{VARNAME_} are not allowed on +@code{VARIABLES}. If @code{VARIABLES} is omitted, then @pspp{} uses +the names @code{COL1}, @code{COL2}, and so on. + +The @code{FNAMES} subcommand may be used to supply a comma-separated +list of factor variable names. The default names are @code{FAC1}, +@code{FAC2}, and so on. + +The @code{SNAMES} subcommand can supply a comma-separated list of +split variable names. The default names are @code{SPL1}, @code{SPL2}, +and so on. + +@node Matrix DISPLAY Command +@subsection The @code{DISPLAY} Command + +@display +@t{DISPLAY} [@{@t{DICTIONARY} @math{|} @t{STATUS}@}]@t{.} +@end display + +The @code{DISPLAY} command makes @pspp{} display a table with the name +and dimensions of each matrix variable. The @code{DICTIONARY} and +@code{STATUS} keywords are accepted but have no effect. + +@node Matrix RELEASE Command +@subsection The @code{RELEASE} Command + +@display +@t{RELEASE} @i{variable}@dots{}@t{.} +@end display + +The @code{RELEASE} command accepts a comma-separated list of matrix +variable names. It deletes each variable and releases the memory +associated with it. + +The @code{END MATRIX} command releases all matrix variables.