Work on matrix documentation.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 1 Oct 2021 05:54:35 +0000 (22:54 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 1 Oct 2021 05:54:35 +0000 (22:54 -0700)
doc/flow-control.texi
doc/matrices.texi

index 14a4f9b30a14b965ce943e951e61ca624113b9f1..866e8a1054d8b92745520d2486b4c152c78c4a93 100644 (file)
@@ -45,6 +45,7 @@ BREAK.
 @vindex DEFINE
 @cindex macro
 
+@node Macro Overview
 @subsection Overview
 
 @display
@@ -102,6 +103,7 @@ The body may also include the following constructs:
 @t{!LET} @i{!var} @t{=} @i{expression}
 @end display
 
+@node Macro Introduction
 @subsection Introduction
 
 The DEFINE command creates a @dfn{macro}, which is a name for a
index cfbf009b673734916266a95698185605ca5e9892..3dc19af48ab5a6cc7a34d106a2dc19927a319445 100644 (file)
@@ -705,10 +705,12 @@ The following matrix commands provide additional support:
 @subsection Introduction
 
 @code{MATRIX} and @code{END MATRIX} enclose a special @pspp{}
-sub-language, called the matrix language.  With few exceptions, matrix
-language commands are independent of those in the enclosing @pspp{}
-program.  In addition, each @code{MATRIX@dots{}END MATRIX} is an
-independent program in the matrix language
+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}}
@@ -717,17 +719,350 @@ 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 has limited support for matrices that contain
-short strings instead of numbers.  Each entry in a string matrix is 8
-bytes in size, with longer strings truncated and shorter strings
-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 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.
 
+@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:
+
+@itemize @bullet
+@item @t{(@dots{})}  @t{@{@dots{}@}}
+
+@item @t{(}@i{index}[@t{,} @i{index}]@t{)}
+
+@item @t{+  -}
+
+@item @t{:}
+
+@item @t{**  &**}
+
+@item @t{*  /  &*  &/}
+
+@item @t{+  -}
+
+@item @t{< <= = >= > <>}
+
+@item @t{NOT}
+
+@item @t{AND}
+
+@item @t{OR  XOR}
+@end itemize
+
+Each of these operators is described in more detail below.
+
+@node Matrix Construction Operator
+@subsubsection The 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 The 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 The 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 Arithmetic Operators
+@subsubsection Unary Arithmetic Operators
+
+The unary @samp{-} operator inverts the sign of each element in its
+argument.  The unary @samp{+} operator has no effect:
+
+@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@}}
+@end multitable
+
+@node Matrix Elementwise Operators
+@subsubsection Elementwise Operators
+
+The elementwise 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 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 NOT
+True if its single operand is false.
+
+@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
+
+@node Matrix Multiplication Operator
+@subsubsection The 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 The 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.