From: Ben Pfaff Date: Fri, 1 Oct 2021 05:54:35 +0000 (-0700) Subject: Work on matrix documentation. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=062ad53a6cdc841c06443a7d3cccdca91b46f907;p=pspp Work on matrix documentation. --- diff --git a/doc/flow-control.texi b/doc/flow-control.texi index 14a4f9b30a..866e8a1054 100644 --- a/doc/flow-control.texi +++ b/doc/flow-control.texi @@ -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 diff --git a/doc/matrices.texi b/doc/matrices.texi index cfbf009b67..3dc19af48a 100644 --- a/doc/matrices.texi +++ b/doc/matrices.texi @@ -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.