1 ! Copyright (C) 2005, 2010, 2018, 2020 Slava Pestov, Joe Groff, and Cat Stevens.
2 USING: arrays assocs help.markup help.markup.private help.syntax
3 kernel math math.functions math.order math.vectors sequences
4 sequences.generalizations ;
8 ! like $subsections but skip the extra blank line
9 : $subs-nobl ( children -- )
10 [ $subsection* ] each ;
12 ! swapped and n-matrix variants
13 : $equiv-word-note ( children -- )
14 [ "This word is the " ] dip
17 [ { $link } ] dip suffix
19 5 narray print-element ;
21 ! words like <scale-matrix3> which have an array of inputs
22 : $finite-input-note ( children -- )
23 [ "Only the first " ] dip
26 [ { $snippet } ] dip suffix
28 5 narray print-element ;
30 ! a note for when a word assumes a 2d matrix
31 : $2d-only-note ( children -- )
32 drop { "This word is intended for use with \"flat\" (2-dimensional) matrices. "
33 ! "Using it with matrices of 3 or more dimensions may lead to unexpected results."
37 ! a note for numeric-specific operations
38 : $matrix-scalar-note ( children -- )
40 "This word assumes that elements of the input matrix are compatible with the following words:"
44 : $keep-shape-note ( children -- )
45 drop { "The shape of the input matrix is preserved in the output." } print-element ;
47 : $link2 ( children -- )
48 first2 swap [ write-link ] topic-span ;
50 ! so that we don't end up with multiple $notes calls leading to multiple Notes sections
51 : $notelist ( children -- )
52 \ $list prefix $notes ;
55 ABOUT: "math.matrices"
57 ARTICLE: "math.matrices" "Matrix operations"
59 "The " { $vocab-link "math.matrices" } " vocabulary implements many ways of working with " { $emphasis "matrices" } " — sequences which have a minimum of 2 dimensions. Operations on 1-dimensional numeric vectors are implemented in " { $vocab-link "math.vectors" } ", upon which this vocabulary relies."
61 "In this vocabulary's documentation, " { $snippet "m" } " and " { $snippet "matrix" } " are the conventional names used for a given matrix object. " { $snippet "m" } " may also refer to a number."
63 "The " { $vocab-link "math.matrices.extras" } " vocabulary implements extensions to this one."
65 "Matrices are classified their mathematical properties, and by predicate words:"
67 ! split up intentionally
85 "There are many ways to create 2-dimensional matrices:"
95 <anti-diagonal-matrix>
106 <cartesian-square-indices>
109 "By-element mathematical operations on a matrix:"
110 { $subsections matrix-normalize mneg m+n m-n m*n m/n n+m n-m n*m n/m }
112 "By-element mathematical operations of two matrices:"
113 { $subsections m+ m- m* m/ m~ }
115 "Dot product (multiplication) of vectors and matrices:"
116 { $subsections vdotm mdotv mdot }
118 "Transformations and elements of matrices:"
121 transpose anti-transpose
122 matrix-nth matrix-nths
123 matrix-set-nth matrix-set-nths
130 matrix-except matrix-except-all
133 matrix-map column-map stitch
140 "The following matrix norms are provided in the 𝑙ₚ and " { $snippet "L^p,q" } " vector spaces; these words are equivalent to ∥・∥ₚ and ∥・∥^p,q for " { $snippet "p = 1, 2, ∞, ℝ" } ", and " { $snippet "p, q ∈ ℝ" } ", respectively:"
144 matrix-l-infinity-norm
148 "For readability, user code should prefer the available generic versions of the above, from " { $vocab-link "math.vectors" } ", which are optimized the same:"
150 l1-norm l2-norm l-infinity-norm p-norm
156 { $class-description "The class of regular, rectangular matrices. In mathematics and linear algebra, a matrix is a rectangular collection of scalar elements for the purpose of the uniform application of algorithms." }
157 { $notes "In Factor, any sequence with two or more dimensions (one or more layers of subsequences) can be a " { $link matrix } ", and the elements may be any " { $link object } "."
158 $nl "A regular matrix is a sequence with two or more dimensions, whose subsequences are all of equal length. See " { $link regular-matrix? } "." }
159 $nl "Irregular matrices are classified by " { $link irregular-matrix } "." ;
161 HELP: irregular-matrix
162 { $class-description "The most common matrix, and most easily manipulated by this vocabulary, is rectangular. This predicate classifies irregular (non-rectangular) matrices." } ;
165 { $class-description "The class of square matrices. A square matrix is a " { $link matrix } " which has the same number of rows and columns. In other words, its outermost two dimensions are of equal size." } ;
168 { $class-description "The class of zero matrices. A zero matrix is a matrix whose only elements are the scalar " { $snippet "0" } "." }
169 { $notes "In mathematics, a zero-filled matrix is called a null matrix. In Factor, a " { $link null-matrix } " is an empty matrix." } ;
171 HELP: zero-square-matrix
172 { $class-description "The class of square zero matrices. This predicate is a composition of " { $link zero-matrix } " and " { $link square-matrix } "." } ;
175 { $class-description "The class of null matrices. A null matrix is an empty sequence, or a sequence which consists only of empty sequences." }
176 { $notes "In mathematics, a null matrix is a matrix full of zeroes. In Factor, such a matrix is called a " { $link zero-matrix } "." } ;
178 { matrix irregular-matrix square-matrix zero-matrix null-matrix zero-square-matrix null-matrix } related-words
180 ! NON-PREDICATE TESTS
182 HELP: regular-matrix?
183 { $values { "object" object } { "?" boolean } }
184 { $description "Tests if the object is a regular (well-formed, rectangular, etc) " { $link matrix } ". A regular matrix is a sequence with an equal number of elements in every row, and an equal number of elements in every column, such that there are no empty slots." }
185 { $notes "The " { $link null-matrix } " is considered regular, because of semantic requirements of the matrix implementation." }
187 "The example is an irregular matrix, because the rows have an unequal number of elements."
189 "USING: math.matrices prettyprint ;"
190 "{ { 1 } { } } regular-matrix? ."
193 "The example is a regular matrix, because the rows have an equal number of elements."
195 "USING: math.matrices prettyprint ;"
196 "{ { 1 } { 2 } } regular-matrix? ."
203 { $values { "m" integer } { "n" integer } { "element" object } { "matrix" matrix } }
204 { $description "Creates a matrix of size " { $snippet "m x n" } ", filled with " { $snippet "element" } "." }
207 "USING: math.matrices prettyprint ;"
209 "{ { 10 10 } { 10 10 } { 10 10 } }"
212 "USING: math.matrices prettyprint ;"
213 "4 1 \"¢\" <matrix> ."
214 "{ { \"¢\" } { \"¢\" } { \"¢\" } { \"¢\" } }"
219 { $values { "m" integer } { "n" integer } { "quot" { $quotation ( ... -- elt ) } } { "matrix" matrix } }
220 { $description "Creates a matrix of size " { $snippet "m x n" } " using elements given by " { $snippet "quot" } ", a quotation called to create each element." }
221 { $notes "The following are equivalent:"
222 { $code "m n [ 2drop foo ] <matrix-by-indices>" }
223 { $code "m n [ foo ] <matrix-by>" }
227 "USING: math.matrices prettyprint ;"
228 "4 5 [ 5 ] <matrix-by> ."
229 "{ { 5 5 5 5 5 } { 5 5 5 5 5 } { 5 5 5 5 5 } { 5 5 5 5 5 } }"
233 HELP: <matrix-by-indices>
234 { $values { "m" integer } { "n" integer } { "quot" { $quotation ( ... m' n' -- ... elt ) } } { "matrix" matrix } }
235 { $description "Creates an " { $snippet "m x n" } " " { $link matrix } " using elements given by " { $snippet "quot" } " . This word differs from " { $link <matrix-by> } " in that the indices are placed on the stack (in the same order) before " { $snippet "quot" } " runs. The output of the quotation will be the element at the given position in the matrix." }
236 { $notes "The following are equivalent:"
237 { $code "m n [ 2drop foo ] <matrix-by-indices>" }
238 { $code "m n [ foo ] <matrix-by>" }
242 "USING: math math.matrices prettyprint ;"
243 "3 4 [ * ] <matrix-by-indices> ."
244 "{ { 0 0 0 0 } { 0 1 2 3 } { 0 2 4 6 } }"
249 { $values { "m" integer } { "n" integer } { "matrix" matrix } }
250 { $description "Creates a matrix of size " { $snippet "m x n" } ", filled with zeroes." }
253 "USING: math.matrices prettyprint ;"
254 "2 3 <zero-matrix> ."
255 "{ { 0 0 0 } { 0 0 0 } }"
259 HELP: <zero-square-matrix>
260 { $values { "n" integer } { "matrix" matrix } }
261 { $description "Creates a matrix of size " { $snippet "n x n" } ", filled with zeroes. Shorthand for " { $code "n n <zero-matrix>" } "." }
264 "USING: math.matrices prettyprint ;"
265 "2 <zero-square-matrix> ."
266 "{ { 0 0 } { 0 0 } }"
270 HELP: <diagonal-matrix>
271 { $values { "diagonal-seq" sequence } { "matrix" matrix } }
272 { $description "Creates a matrix with the specified main diagonal. This word has the opposite effect of " { $link main-diagonal } "." }
273 { $notes "To use a diagonal starting in the lower right, reverse the input sequence before calling this word." }
276 "USING: math.matrices prettyprint ;"
277 "{ 1 2 3 } <diagonal-matrix> ."
278 "{ { 1 0 0 } { 0 2 0 } { 0 0 3 } }"
282 HELP: <anti-diagonal-matrix>
283 { $values { "diagonal-seq" sequence } { "matrix" matrix } }
284 { $description "Creates a matrix with the specified anti-diagonal. This word has the opposite effect of " { $link anti-diagonal } "." }
285 { $notes "To use a diagonal starting in the lower left, reverse the input sequence before calling this word." }
288 "USING: math.matrices prettyprint ;"
289 "{ 1 2 3 } <anti-diagonal-matrix> ."
290 "{ { 0 0 1 } { 0 2 0 } { 3 0 0 } }"
294 HELP: <identity-matrix>
295 { $values { "n" integer } { "matrix" matrix } }
296 { $description "Creates an " { $url URL" http://enwp.org/Identity_matrix" "identity matrix" } " of size " { $snippet "n x n" } ", where the diagonal values are all ones." }
299 "USING: math.matrices prettyprint ;"
300 "4 <identity-matrix> ."
301 "{ { 1 0 0 0 } { 0 1 0 0 } { 0 0 1 0 } { 0 0 0 1 } }"
306 { $values { "m" integer } { "n" integer } { "k" integer } { "z" object } { "matrix" matrix } }
307 { $description "Creates an " { $snippet "m x n" } " matrix with a diagonal of " { $snippet "z" } " offset by " { $snippet "k" } " from the main diagonal. A positive value of " { $snippet "k" } " gives a diagonal above the main diagonal, whereas a negative value of " { $snippet "k" } " gives a diagonal below the main diagonal." }
310 "USING: math.matrices prettyprint ;"
321 "USING: math.matrices prettyprint ;"
334 { $values { "m" integer } { "n" integer } { "k" integer } { "matrix" matrix } }
336 "Creates an " { $snippet "m x n" } " matrix with a diagonal of ones offset by " { $snippet "k" } " from the main diagonal."
337 "The following are equivalent for any " { $snippet "m n k" } ":" { $code "m n k 1 <eye>" } { $code "m n k <simple-eye>" }
339 "Specify a different diagonal value with " { $link <eye> } "."
343 "USING: math.matrices prettyprint ;"
344 "4 5 2 <simple-eye> ."
345 "{ { 0 0 1 0 0 } { 0 0 0 1 0 } { 0 0 0 0 1 } { 0 0 0 0 0 } }"
349 HELP: <coordinate-matrix>
350 { $values { "dim" pair } { "coordinates" matrix } }
351 { $description "Create a matrix in which each element is its own coordinate pair, also called a " { $link cartesian-product } "." }
353 { $equiv-word-note "non-square" <cartesian-square-indices> }
354 { $finite-input-note "two" "dim" }
358 "USING: math.matrices prettyprint ;"
359 "{ 2 4 } <coordinate-matrix> ."
361 { { 0 0 } { 0 1 } { 0 2 } { 0 3 } }
362 { { 1 0 } { 1 1 } { 1 2 } { 1 3 } }
367 HELP: <cartesian-indices>
368 { $values { "dim" pair } { "coordinates" matrix } }
369 { $description "An alias for " { $link <coordinate-matrix> } " which serves as the logical non-square companion to " { $link <cartesian-square-indices> } "." }
372 "USING: math.matrices prettyprint ;"
373 "{ 2 4 } <cartesian-indices> ."
375 { { 0 0 } { 0 1 } { 0 2 } { 0 3 } }
376 { { 1 0 } { 1 1 } { 1 2 } { 1 3 } }
381 HELP: <cartesian-square-indices>
382 { $values { "n" integer } { "matrix" square-matrix } }
383 { $description "Create a " { $link square-matrix } " full of " { $link cartesian-product } "s. See " { $url URL" https://en.wikipedia.org/wiki/Cartesian_product" "cartesian product" } "." }
385 { $equiv-word-note "square" <cartesian-indices> }
389 "USING: math.matrices prettyprint ;"
390 "1 <cartesian-square-indices> ."
394 "USING: math.matrices prettyprint ;"
395 "3 <cartesian-square-indices> ."
397 { { 0 0 } { 0 1 } { 0 2 } }
398 { { 1 0 } { 1 1 } { 1 2 } }
399 { { 2 0 } { 2 1 } { 2 2 } }
405 { $values { "desc" { $or sequence integer matrix } } { "matrix" matrix } }
406 { $contract "Generate a " { $link square-matrix } " from a descriptor." }
407 { $description "If the descriptor is an " { $link integer } ", it is used to generate square rows within that range." $nl "If it is a 1-dimensional sequence, it is " { $link replicate } "d to create each row." $nl "If it is a " { $link matrix } ", it is cropped into a " { $link square-matrix } "." $nl "If it is a " { $link square-matrix } ", it is returned unchanged." }
410 "USING: math.matrices prettyprint ;"
412 "{ { 0 1 2 } { 0 1 2 } { 0 1 2 } }"
415 "USING: math.matrices prettyprint ;"
416 "{ 2 3 5 } <square-rows> ."
417 "{ { 2 3 5 } { 2 3 5 } { 2 3 5 } }"
422 { $values { "desc" { $or sequence integer matrix } } { "matrix" matrix } }
423 { $contract "Generate a " { $link square-matrix } " from a descriptor." }
424 { $description "If the descriptor is an " { $link integer } ", it is used to generate square columns within that range." $nl "If it is a 1-dimensional sequence, it is " { $link replicate } "d to create each column." $nl "If it is a " { $link matrix } ", it is cropped into a " { $link square-matrix } "." $nl "If it is a " { $link square-matrix } ", it is returned unchanged." }
427 "USING: math.matrices prettyprint ;"
429 "{ { 0 0 0 } { 1 1 1 } { 2 2 2 } }"
432 "USING: math.matrices prettyprint ;"
433 "{ 2 3 5 } <square-cols> ."
434 "{ { 2 2 2 } { 3 3 3 } { 5 5 5 } }"
439 { $values { "object" object } { "m" integer } { "n" integer } { "matrix" matrix } }
440 { $description "Make a lower triangular matrix, where all the values above the main diagonal are " { $snippet "0" } ". " { $snippet "object" } " will be used as the value for the nonzero part of the matrix, while " { $snippet "m" } " and " { $snippet "n" } " are used as the dimensions. The inverse of this word is " { $link <upper-matrix> } ". See " { $url URL" https://en.wikipedia.org/wiki/Triangular_matrix" "triangular matrix" } "." }
443 "USING: math.matrices prettyprint ;"
444 "1 5 5 <lower-matrix> ."
456 { $values { "object" object } { "m" integer } { "n" integer } { "matrix" matrix } }
457 { $description "Make an upper triangular matrix, where all the values below the main diagonal are " { $snippet "0" } ". " { $snippet "object" } " will be used as the value for the nonzero part of the matrix, while " { $snippet "m" } " and " { $snippet "n" } " are used as the dimensions. The inverse of this word is " { $link <lower-matrix> } ". See " { $url URL" https://en.wikipedia.org/wiki/Triangular_matrix" "triangular matrix" } "." }
460 "USING: math.matrices prettyprint ;"
461 "1 5 5 <upper-matrix> ."
473 { $values { "m" matrix } { "m'" matrix } }
474 { $description "Folds an " { $snippet "n>2" } "-dimensional matrix onto itself." }
477 "USING: math.matrices prettyprint ;"
479 { { 0 5 } { 6 7 } { 0 15 } { 18 21 } }
480 { { 0 10 } { 12 14 } { 0 20 } { 24 28 } }
492 { $values { "n" integer } { "matrix" matrix } { "row" sequence } }
493 { $description "Get the nth row of the matrix." }
494 { $notes "Like most Factor sequences, indexing is 0-based. The first row is given by " { $snippet "m 0 row" } "." }
497 "USING: kernel math.matrices prettyprint ;"
498 "{ { 1 2 } { 3 4 } } 1 swap row ."
504 { $values { "seq" sequence } { "matrix" matrix } { "rows" sequence } }
505 { $description "Get the rows from " { $snippet "matrix" } " listed by " { $snippet "seq" } "." }
506 { $notelist { $equiv-word-note "multiplexing" row } }
509 "USING: math.matrices prettyprint ;"
510 "{ 0 1 } { { 1 2 } { 3 4 } } rows ."
511 "{ { 1 2 } { 3 4 } }"
516 { $values { "n" integer } { "matrix" matrix } { "col" sequence } }
517 { $description "Get the " { $snippet "n" } "th column of the matrix." }
518 { $notes "Like most Factor sequences, indexing is 0-based. The first column is given by " { $snippet "m 0 col" } "." }
521 "USING: kernel math.matrices prettyprint ;"
522 "{ { 1 2 } { 3 4 } } 1 swap col ."
528 { $values { "seq" sequence } { "matrix" matrix } { "cols" sequence } }
529 { $description "Get the columns from " { $snippet "matrix" } " listed by " { $snippet "seq" } "." }
532 "USING: math.matrices prettyprint ;"
533 "{ 0 1 } { { 1 2 } { 3 4 } } cols ."
534 "{ { 1 3 } { 2 4 } }"
539 { $values { "m" matrix } { "subset" square-matrix } }
540 { $description "Find only the " { $link2 square-matrix "square" } " subset of the input matrix." }
543 "USING: math.matrices prettyprint ;"
544 "{ { 0 2 4 6 } { 1 3 5 7 } } >square-matrix ."
545 "{ { 0 2 } { 1 3 } }"
550 { $values { "matrix" matrix } { "quot" { $quotation ( ... elt -- ... elt' ) } } { "matrix'" matrix } }
551 { $description "Apply the quotation to every element of the matrix." }
552 { $notelist $2d-only-note }
555 "USING: math.matrices kernel math prettyprint ;"
556 "3 <identity-matrix> [ zero? 15 -8 ? ] matrix-map ."
557 "{ { -8 15 15 } { 15 -8 15 } { 15 15 -8 } }"
562 { $values { "matrix" matrix } { "quot" { $quotation ( ... col -- ... col' ) } } { "matrix'" { $maybe sequence matrix } } }
563 { $description "Apply the quotation to every column of the matrix. The output of the quotation must be a sequence." }
564 { $notelist $2d-only-note { $equiv-word-note "transpose" map } }
567 "USING: sequences math.matrices prettyprint ;"
568 "3 <identity-matrix> [ reverse ] column-map ."
569 "{ { 0 0 1 } { 0 1 0 } { 1 0 0 } }"
574 { $values { "pair" pair } { "matrix" matrix } { "elt" object } }
575 { $description "Retrieve the element in the matrix at the zero-indexed " { $snippet "row, column" } " pair." }
576 { $notelist { $equiv-word-note "two-dimensional" nth } $2d-only-note }
578 { { $link bounds-error } " if the first element in " { $snippet "pair" } " is greater than the maximum row index in " { $snippet "matrix" } }
579 { { $link bounds-error } " if the second element in " { $snippet "pair" } " is greater than the maximum column index in " { $snippet "matrix" } }
582 "Get the entry at row 1, column 0."
584 "USING: math.matrices prettyprint ;"
585 "{ 1 0 } { { 0 1 } { 2 3 } } matrix-nth ."
591 { $values { "pairs" assoc } { "matrix" matrix } { "elts" sequence } }
592 { $description "Retrieve all the elements in the matrix at each of the zero-indexed " { $snippet "row, column" } " pairs in " { $snippet "pairs" } "." }
593 { $notelist { $equiv-word-note "two-dimensional" nths } $2d-only-note }
595 { { $link bounds-error } " if the first element of a pair in " { $snippet "pairs" } " is greater than the maximum row index in " { $snippet "matrix" } }
596 { { $link bounds-error } " if the second element of a pair in " { $snippet "pairs" } " is greater than the maximum column index in " { $snippet "matrix" } }
600 "USING: math.matrices prettyprint ;"
601 "{ { 1 0 } { 1 1 } } { { 0 1 } { 2 3 } } matrix-nths ."
607 { $values { "obj" object } { "pair" pair } { "matrix" matrix } }
608 { $description "Set the element in the matrix at the 2D index given by " { $snippet "pair" } " to " { $snippet "obj" } ". This operation is destructive." }
609 { $side-effects "matrix" }
610 { $notelist { $equiv-word-note "two-dimensional" set-nth } $2d-only-note }
612 { { $link bounds-error } " if the first element of a pair in " { $snippet "pairs" } " is greater than the maximum row index in " { $snippet "matrix" } }
613 { { $link bounds-error } " if the second element of a pair in " { $snippet "pairs" } " is greater than the maximum column index in " { $snippet "matrix" } }
614 "Throws an error if the sequence cannot hold elements of the given type."
617 "Change the entry at row 1, column 0."
619 "USING: math.matrices kernel prettyprint ;"
620 "{ { 0 1 } { 2 3 } } \"a\" { 1 0 } pick matrix-set-nth ."
621 "{ { 0 1 } { \"a\" 3 } }"
625 HELP: matrix-set-nths
626 { $values { "obj" object } { "pairs" assoc } { "matrix" matrix } }
627 { $description "Applies " { $link matrix-set-nth } " to " { $snippet "matrix" } " for each " { $snippet "row, column" } " pair in " { $snippet "pairs" } ", setting the elements to " { $snippet "obj" } "." }
628 { $side-effects "matrix" }
629 { $notelist { $equiv-word-note "multiplexing" matrix-set-nth } $2d-only-note }
631 { { $link bounds-error } " if the first element of a pair in " { $snippet "pairs" } " is greater than the maximum row index in " { $snippet "matrix" } }
632 { { $link bounds-error } " if the second element of a pair in " { $snippet "pairs" } " is greater than the maximum column index in " { $snippet "matrix" } }
633 "Throws an error if the sequence cannot hold elements of the given type."
636 "Change both entries on row 1."
638 "USING: math.matrices kernel prettyprint ;"
639 "{ { 0 1 } { 2 3 } } \"a\" { { 1 0 } { 1 1 } } pick matrix-set-nths ."
640 "{ { 0 1 } { \"a\" \"a\" } }"
646 { $values { "m" matrix } { "m'" matrix } }
647 { $description "Negate (invert the sign) of every element in the matrix. The resulting matrix is called the " { $emphasis "additive inverse" } " of the input matrix." }
649 { $equiv-word-note "companion" mabs }
651 { $matrix-scalar-note neg }
655 "USING: math.matrices prettyprint ;"
656 "{ { 5 9 } { 15 -17 } } mneg ."
657 "{ { -5 -9 } { -15 17 } }"
662 { $values { "m" matrix } { "m'" matrix } }
663 { $description "Compute the absolute value (" { $link abs } ") of each element in the matrix." }
665 { $equiv-word-note "companion" mneg }
667 { $matrix-scalar-note abs }
671 "USING: math.matrices prettyprint ;"
672 "{ { -5 -9 } { -15 17 } } mabs ."
673 "{ { 5 9 } { 15 17 } }"
678 { $values { "n" object } { "m" matrix } }
679 { $description { $snippet "n" } " is treated as a scalar and added to each element of the matrix " { $snippet "m" } "." }
681 { $equiv-word-note "swapped" m+n }
683 { $matrix-scalar-note + }
687 "USING: kernel math.matrices prettyprint ;"
688 "1 3 <identity-matrix> n+m ."
689 "{ { 2 1 1 } { 1 2 1 } { 1 1 2 } }"
694 { $values { "m" matrix } { "n" object } }
695 { $description { $snippet "n" } " is treated as a scalar and added to each element of the matrix " { $snippet "m" } "." }
697 { $equiv-word-note "swapped" n+m }
699 { $matrix-scalar-note + }
703 "USING: kernel math.matrices prettyprint ;"
704 "3 <identity-matrix> 1 m+n ."
705 "{ { 2 1 1 } { 1 2 1 } { 1 1 2 } }"
710 { $values { "n" object } { "m" matrix } }
711 { $description { $snippet "n" } " is treated as a scalar and subtracted from each element of the matrix " { $snippet "m" } "." }
713 { $equiv-word-note "swapped" m-n }
715 { $matrix-scalar-note - }
719 "USING: kernel math.matrices prettyprint ;"
720 "1 3 <identity-matrix> n-m ."
721 "{ { 0 1 1 } { 1 0 1 } { 1 1 0 } }"
726 { $values { "m" matrix } { "n" object } }
727 { $description { $snippet "n" } " is treated as a scalar and subtracted from each element of the matrix " { $snippet "m" } "." }
729 { $equiv-word-note "swapped" n-m }
731 { $matrix-scalar-note - }
735 "USING: kernel math.matrices prettyprint ;"
736 "3 <identity-matrix> 1 m-n ."
737 "{ { 0 -1 -1 } { -1 0 -1 } { -1 -1 0 } }"
742 { $values { "n" object } { "m" matrix } }
743 { $description "Every element in the input matrix " { $snippet "m" } " is multiplied by the scalar " { $snippet "n" } "." }
746 { $equiv-word-note "swapped" m*n }
748 { $matrix-scalar-note * }
752 "USING: kernel math.matrices prettyprint ;"
753 "3 3 <identity-matrix> n*m ."
754 "{ { 3 0 0 } { 0 3 0 } { 0 0 3 } }"
759 { $values { "m" matrix } { "n" object } }
760 { $description "Every element in the input matrix " { $snippet "m" } " is multiplied by the scalar " { $snippet "n" } "." }
763 { $equiv-word-note "swapped" n*m }
765 { $matrix-scalar-note * }
770 "USING: kernel math.matrices prettyprint ;"
771 "3 <identity-matrix> 3 m*n ."
772 "{ { 3 0 0 } { 0 3 0 } { 0 0 3 } }"
777 { $values { "n" object } { "m" matrix } }
778 { $description "Every element in the input matrix " { $snippet "m" } " is divided by the scalar " { $snippet "n" } "." }
781 { $equiv-word-note "swapped" m/n }
783 { $matrix-scalar-note / }
787 "USING: kernel math.matrices prettyprint ;"
788 "2 { { 4 5 } { 2 1 } } n/m ."
789 "{ { 1/2 2/5 } { 1 2 } }"
794 { $values { "m" matrix } { "n" object } }
795 { $description "Every element in the input matrix " { $snippet "m" } " is divided by the scalar " { $snippet "n" } "." }
798 { $equiv-word-note "swapped" n/m }
800 { $matrix-scalar-note / }
804 "USING: kernel math.matrices prettyprint ;"
805 "{ { 4 5 } { 2 1 } } 2 m/n ."
806 "{ { 2 2+1/2 } { 1 1/2 } }"
811 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
812 { $description "Adds two matrices element-wise." }
815 { $matrix-scalar-note + }
819 "USING: math.matrices prettyprint ;"
820 "{ { 1 2 3 } { 3 2 1 } } { { 4 5 6 } { 6 5 4 } } m+ ."
821 "{ { 5 7 9 } { 9 7 5 } }"
826 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
827 { $description "Subtracts two matrices element-wise." }
830 { $matrix-scalar-note - }
834 "USING: math.matrices prettyprint ;"
835 "{ { 4 5 6 } { 6 5 4 } } { { 1 2 3 } { 3 2 1 } } m- ."
836 "{ { 3 3 3 } { 3 3 3 } }"
841 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
842 { $description "Multiplies two matrices element-wise." }
845 { $matrix-scalar-note * }
849 "USING: math.matrices prettyprint ;"
850 "{ { 5 9 } { 15 17 } } { { 3 2 } { 4 9 } } m* ."
851 "{ { 15 18 } { 60 153 } }"
856 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
857 { $description "Divides two matrices element-wise." }
860 { $matrix-scalar-note / }
864 "USING: math.matrices prettyprint ;"
865 "{ { 5 9 } { 15 17 } } { { 3 2 } { 4 9 } } m/ ."
866 "{ { 1+2/3 4+1/2 } { 3+3/4 1+8/9 } }"
871 { $values { "m" matrix } { "v" sequence } { "p" matrix } }
872 { $description "Computes the dot product of a matrix and a vector." }
874 { $equiv-word-note "swapped" vdotm }
876 { $matrix-scalar-note * + }
880 "USING: math.matrices prettyprint ;"
881 "{ { 1 -1 2 } { 0 -3 1 } } { 2 1 0 } mdotv ."
887 { $values { "v" sequence } { "m" matrix } { "p" matrix } }
888 { $description "Computes the dot product of a vector and a matrix." }
890 { $equiv-word-note "swapped" mdotv }
892 { $matrix-scalar-note * + }
896 "USING: math.matrices prettyprint ;"
897 "{ 2 1 0 } { { 1 -1 2 } { 0 -3 1 } } vdotm ."
903 { $values { "m" matrix } }
904 { $description "Computes the dot product of two matrices, i.e multiplies them." }
907 { $matrix-scalar-note * + }
911 "USING: math.matrices prettyprint ;"
912 "{ { 1 -1 2 } { 0 -3 1 } } { { 3 7 } { 9 12 } } mdot ."
913 "{ { -6 -5 } { -27 -36 } }"
918 { $values { "m1" matrix } { "m2" matrix } { "epsilon" number } { "?" boolean } }
919 { $description "Compares the matrices like " { $link ~ } ", using the " { $snippet "epsilon" } "." }
922 { $matrix-scalar-note ~ }
925 { "In the example, only " { $snippet ".01" } " was added to each element, so the new matrix is within the epsilon " { $snippet ".1" } "of the original." }
927 "USING: kernel math math.matrices prettyprint ;"
928 "{ { 5 9 } { 15 17 } } dup [ .01 + ] matrix-map .1 m~ ."
934 { $values { "m" matrix } { "n" object } }
935 { $description "Determine the minimum value of the matrix." }
938 { $matrix-scalar-note min }
942 "USING: math.matrices prettyprint ;"
943 "{ { 5 9 } { 15 17 } } mmin ."
949 { $values { "m" matrix } { "n" object } }
950 { $description "Determine the maximum value of the matrix." }
953 { $matrix-scalar-note max }
957 "USING: math.matrices prettyprint ;"
958 "{ { 5 9 } { 15 17 } } mmax ."
963 { l2-norm frobenius-norm hilbert-schmidt-norm } related-words
966 { $values { "m" matrix } { "n" number } }
967 { $description "Find the norm (size) of a matrix in 𝑙₁ (" { $snippet "L^₁" } ") vector space, usually written ∥・∥₁."
968 $nl "This is the matrix norm when " { $snippet "p=1" } ", and is the overall maximum of the sums of the columns." }
970 { "User code should call the generic " { $link l1-norm } " instead." }
971 { $equiv-word-note "matrix-specific" l1-norm }
972 { $equiv-word-note { $snippet "p = 1" } matrix-p-norm }
973 { $equiv-word-note "transpose" matrix-l-infinity-norm }
978 "USING: math.matrices prettyprint ;"
979 "{ { 2 -2 1 } { 1 3 -1 } { 2 -4 2 } } matrix-l1-norm ."
985 { $values { "m" matrix } { "n" number } }
986 { $description "Find the norm (size) of a matrix in 𝑙₂ (" { $snippet "L^2" } ") vector space, usually written ∥・∥₂."
987 $nl "This is the matrix norm when " { $snippet "p=2" } ", and is the square root of the sums of the squares of all the elements of the matrix." }
989 { "This norm is sometimes called the Hilbert-Schmidt norm." }
990 { "User code should call the generic " { $link p-norm } " instead." }
991 { $equiv-word-note "matrix-specific" l2-norm }
992 { $equiv-word-note { $snippet "p = 2" } matrix-p-norm }
993 { $equiv-word-note "transpose" l1-norm }
998 "USING: math.matrices prettyprint ;"
999 "{ { 1 1 } { 1 1 } } matrix-l2-norm ."
1004 HELP: matrix-l-infinity-norm
1005 { $values { "m" matrix } { "n" number } }
1006 { $description "Find the norm (size) of a matrix, in 𝑙∞ (" { $snippet "L^∞" } ") vector space, usually written ∥・∥∞."
1007 $nl "This is the matrix norm when " { $snippet "p=∞" } ", and is the overall maximum of the sums of the rows." }
1009 { "User code should call the generic " { $link l1-norm } " instead." }
1010 { $equiv-word-note "matrix-specific" l-infinity-norm }
1011 { $equiv-word-note { $snippet "p = ∞" } matrix-p-norm }
1012 { $equiv-word-note "transpose" matrix-l1-norm }
1017 "USING: math.matrices prettyprint ;"
1018 "{ { 2 -2 1 } { 1 3 -1 } { 2 -4 2 } } matrix-l-infinity-norm ."
1023 HELP: matrix-p-q-norm
1024 { $values { "m" matrix } { "p" "a positive real number" } { "q" "a positive real number" } { "n" "a non-negative real number" } }
1025 { $description "Find the norm (size) of a matrix in " { $snippet "L^p,q" } " vector space."
1026 $nl "This is the matrix norm for any " { $snippet "p, q ∈ ℝ" } ". It is still an entry-wise norm, like " { $link matrix-p-norm-entrywise } ", and is not an induced or Schatten norm." }
1028 "Equivalent to " { $link l2-norm } " for " { $snippet "p = q = 2 " } ":"
1030 "USING: math.matrices prettyprint ;"
1031 "{ { 1 1 } { 1 1 } } 2 2 matrix-p-q-norm ."
1036 HELP: matrix-p-norm-entrywise
1037 { $values { "m" matrix } { "p" "a positive real number" } { "n" "a non-negative real number" } }
1038 { $description "Find the entry-wise norm of a matrix, in 𝑙ₚ (" { $snippet "L^p" } ") vector space." }
1039 { $notes "This word is not an induced or Schatten norm, and it is distinct from all of " { $links matrix-l1-norm matrix-l2-norm matrix-l-infinity-norm } "." }
1042 "USING: math.matrices prettyprint ;"
1043 "4 4 1 <matrix> 2 matrix-p-norm-entrywise ."
1049 { $values { "m" matrix } { "p" "a positive real number" } { "n" "a non-negative real number" } }
1050 { $description "Find the norm (size) of a matrix in 𝑙ₚ (" { $snippet "L^p" } ") vector space, usually written ∥・∥ₚ. For " { $snippet "p ≠ 1, 2, ∞" } ", this is an \"entry-wise\" norm." }
1052 { "User code should call the generic " { $link p-norm } " instead." }
1053 { $equiv-word-note "matrix-specific" p-norm }
1054 { $equiv-word-note { $snippet "p = q" } matrix-p-q-norm }
1058 "Calls " { $link l1-norm } ":"
1060 "USING: math.matrices prettyprint ;"
1061 "4 4 1 <matrix> 1 matrix-p-norm ."
1064 "Falls back to " { $link matrix-p-norm-entrywise } ":"
1066 "USING: math.functions math.matrices prettyprint ;"
1067 "2 2 3 <matrix> 1.5 matrix-p-norm 7.559 10e-4 ~ ."
1072 { matrix-p-norm matrix-p-norm-entrywise } related-words
1073 { matrix-l1-norm matrix-l2-norm matrix-l-infinity-norm matrix-p-norm matrix-p-q-norm } related-words
1075 HELP: matrix-normalize
1076 { $values { "m" "a matrix with at least 1 non-zero number" } { "m'" matrix } }
1077 { $description "Normalize a matrix containing at least 1 non-zero element. Each element from the input matrix is computed as a fraction of the maximum element. The maximum element becomes " { $snippet "1/1" } "." }
1080 { $matrix-scalar-note max abs / }
1084 "USING: math.matrices prettyprint ;"
1085 "{ { 5 9 } { 15 17 } } matrix-normalize ."
1086 "{ { 5/17 9/17 } { 15/17 1 } }"
1091 { $values { "matrix" matrix } { "seq" sequence } }
1092 { $description "Find the main diagonal of a matrix." $nl "This diagonal begins in the upper left of the matrix at index " { $snippet "{ 0 0 }" } ", continuing downward and rightward for all indices " { $snippet "{ n n }" } " in the " { $link square-matrix } " subset of the input (see " { $link <square-rows> } ")." }
1094 { "If the number of rows in the square subset of the input is even, then this diagonal will not contain elements found in the " { $link anti-diagonal } ". However, if the size of the square subset is odd, then this diagonal will share at most one element with " { $link anti-diagonal } "." }
1095 { "This diagonal is sometimes called the " { $emphasis "first diagonal" } "." }
1096 { $equiv-word-note "opposite" anti-diagonal }
1099 { "The operation is simple on a " { $link square-matrix } ":" }
1101 "USING: math.matrices prettyprint ;"
1109 "The square subset of the following input matrix consists of all rows but the last. The main diagonal does not include the last row because it has no fourth element."
1111 "USING: math.matrices prettyprint ;"
1123 { $values { "matrix" matrix } { "seq" sequence } }
1124 { $description "Find the anti-diagonal of a matrix." $nl "This diagonal begins in the upper right of the matrix, continuing downward and leftward for all indices in the " { $link square-matrix } " subset of the input (see " { $link <square-rows> } ")." }
1126 { "If the number of rows in the square subset of the input is even, then this diagonal will not contain elements found in the " { $link main-diagonal } ". However, if the size of the square subset is odd, then this diagonal will share at most one element with " { $link main-diagonal } "." }
1127 { "This diagonal is sometimes called the " { $emphasis "second diagonal" } "." }
1128 { $equiv-word-note "opposite" main-diagonal }
1131 { "The operation is simple on a " { $link square-matrix } ":" }
1133 "USING: math.matrices prettyprint ;"
1141 "The square subset of the following input matrix consists of all rows but the last. The anti-diagonal does not include the last row because it has no fourth element."
1143 "USING: math.matrices prettyprint ;"
1156 { $values { "matrix" matrix } { "newmatrix" matrix } }
1157 { $description "Transpose the input matrix over its " { $link main-diagonal } ". The main diagonal itself is preserved, whereas the anti-diagonal is reversed." }
1159 { "This word is an alias for " { $link flip } ", so that it may be recognised as the common mathematical operation." }
1160 { $equiv-word-note "opposite" anti-transpose }
1164 "USING: math.matrices sequences prettyprint ;"
1165 "5 <iota> <anti-diagonal-matrix> transpose ."
1176 HELP: anti-transpose
1177 { $values { "matrix" matrix } { "newmatrix" matrix } }
1178 { $description "Like " { $link transpose } " except that the matrix is transposed over the " { $link anti-diagonal } ", so that the anti-diagonal itself is preserved and the " { $link main-diagonal } " is reversed." }
1179 { $notes { $equiv-word-note "opposite" transpose } }
1182 "USING: math.matrices sequences prettyprint ;"
1183 "5 <iota> <diagonal-matrix> anti-transpose ."
1195 { $values { "matrix" matrix } { "desc" { $or integer sequence } } { "others" matrix } }
1196 { $contract "Get all the rows from " { $snippet "matrix" } " " { $emphasis "not" } " described by " { $snippet "desc" } "." }
1199 "USING: math.matrices prettyprint ;"
1205 } { 1 3 } rows-except ."
1206 "{ { 2 7 12 2 } { 1 3 3 5 } }"
1211 { $values { "matrix" matrix } { "desc" { $or integer sequence } } { "others" matrix } }
1212 { $contract "Get all the columns from " { $snippet "matrix" } " " { $emphasis "not" } " described by " { $snippet "desc" } "." }
1215 "USING: math.matrices prettyprint ;"
1221 } { 1 3 } cols-except . "
1222 "{ { 2 12 } { 8 10 } { 1 3 } { 8 7 } }"
1226 { $values { "matrix" matrix } { "exclude-pair" pair } { "submatrix" matrix } }
1227 { $description "Get all the rows and columns from " { $snippet "matrix" } " except the row and column given in " { $snippet "exclude-pair" } ". The result is the " { $snippet "submatrix" } " containing no values from the given row and column." }
1230 "USING: math.matrices prettyprint ;"
1231 "{ { 0 1 } { 2 3 } } { 0 1 } matrix-except ."
1236 HELP: submatrix-excluding
1237 { $values { "matrix" matrix } { "exclude-pair" pair } { "submatrix" matrix } }
1238 { $description "A possibly more obvious word for " { $link matrix-except } "." } ;
1240 HELP: matrix-except-all
1241 { $values { "matrix" matrix } { "submatrices" { $sequence matrix } } }
1242 { $description "Find every possible submatrix of " { $snippet "matrix" } " by using " { $link matrix-except } " for every value's row-column pair." }
1244 "There are 9 possible 2x2 submatrices of a 3x3 matrix with 9 indices, because there are 9 indices to exclude creating a new submatrix."
1246 "USING: math.matrices prettyprint ;"
1247 "{ { 0 1 2 } { 3 4 5 } { 6 7 8 } } matrix-except-all ."
1268 HELP: all-submatrices
1269 { $values { "matrix" matrix } { "submatrices" { $sequence matrix } } }
1270 { $description "A possibly more obvious name for " { $link matrix-except-all } "." } ;
1273 { $values { "matrix" matrix } { "dimension" pair } }
1274 { $description "Find the dimension of the input matrix, in the order of " { $snippet "{ rows cols }" } "." }
1275 { $notelist $2d-only-note "Not to be confused with dimensionality, or the number of dimension scalars needed to describe a matrix." }
1278 "USING: math.matrices prettyprint ;"
1279 "4 30 1 <matrix> dimension ."
1283 "USING: math.matrices prettyprint ;"