]> gitweb.factorcode.org Git - factor.git/blob - basis/math/matrices/matrices-docs.factor
factor: trim using lists
[factor.git] / basis / math / matrices / matrices-docs.factor
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 ;
5 IN: math.matrices
6
7 <PRIVATE
8 ! like $subsections but skip the extra blank line
9 : $subs-nobl ( children -- )
10     [ $subsection* ] each ;
11
12 ! swapped and n-matrix variants
13 : $equiv-word-note ( children -- )
14     [ "This word is the " ] dip
15     first2
16     " variant of " swap
17     [ { $link } ] dip suffix
18     "."
19     5 narray print-element ;
20
21 ! words like <scale-matrix3> which have an array of inputs
22 : $finite-input-note ( children -- )
23     [ "Only the first " ] dip
24     first2
25     " values in " swap
26     [ { $snippet } ] dip suffix
27     " are used."
28     5 narray print-element ;
29
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."
34     }
35     print-element ;
36
37 ! a note for numeric-specific operations
38 : $matrix-scalar-note ( children -- )
39     \ $subs-nobl prefix
40     "This word assumes that elements of the input matrix are compatible with the following words:"
41     swap 2array
42     print-element ;
43
44 : $keep-shape-note ( children -- )
45     drop { "The shape of the input matrix is preserved in the output." } print-element ;
46
47 : $link2 ( children -- )
48     first2 swap [ write-link ] topic-span ;
49
50 ! so that we don't end up with multiple $notes calls leading to multiple Notes sections
51 : $notelist ( children -- )
52     \ $list prefix $notes ;
53 PRIVATE>
54
55 ABOUT: "math.matrices"
56
57 ARTICLE: "math.matrices" "Matrix operations"
58
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."
60 $nl
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."
62 $nl
63 "The " { $vocab-link "math.matrices.extras" } " vocabulary implements extensions to this one."
64 $nl
65 "Matrices are classified their mathematical properties, and by predicate words:"
66 $nl
67 ! split up intentionally
68 { $subsections
69     matrix
70     irregular-matrix
71     square-matrix
72     zero-matrix
73     zero-square-matrix
74     null-matrix
75
76 } { $subsections
77     matrix?
78     irregular-matrix?
79     square-matrix?
80     zero-matrix?
81     zero-square-matrix?
82     null-matrix?
83 }
84
85 "There are many ways to create 2-dimensional matrices:"
86 { $subsections
87     <matrix>
88     <matrix-by>
89     <matrix-by-indices>
90
91 } { $subsections
92     <zero-matrix>
93     <zero-square-matrix>
94     <diagonal-matrix>
95     <anti-diagonal-matrix>
96     <identity-matrix>
97     <simple-eye>
98     <eye>
99
100 } { $subsections
101     <coordinate-matrix>
102     <square-rows>
103     <square-cols>
104     <upper-matrix>
105     <lower-matrix>
106     <cartesian-square-indices>
107 }
108
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 }
111
112 "By-element mathematical operations of two matrices:"
113 { $subsections m+ m- m* m/ m~ }
114
115 "Dot product (multiplication) of vectors and matrices:"
116 { $subsections vdotm mdotv mdot }
117
118 "Transformations and elements of matrices:"
119 { $subsections
120     dimension
121     transpose anti-transpose
122     matrix-nth matrix-nths
123     matrix-set-nth matrix-set-nths
124
125 } { $subsections
126     row rows rows-except
127     col cols cols-except
128
129 } { $subsections
130     matrix-except matrix-except-all
131
132 } { $subsections
133     matrix-map column-map stitch
134
135 } { $subsections
136     main-diagonal
137     anti-diagonal
138 }
139
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:"
141 { $subsections
142     matrix-l1-norm
143     matrix-l2-norm
144     matrix-l-infinity-norm
145     matrix-p-norm
146     matrix-p-q-norm
147 }
148 "For readability, user code should prefer the available generic versions of the above, from " { $vocab-link "math.vectors" } ", which are optimized the same:"
149 { $subsections
150   l1-norm l2-norm l-infinity-norm p-norm
151 } ;
152
153 ! PREDICATE CLASSES
154
155 HELP: matrix
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 } "." ;
160
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." } ;
163
164 HELP: square-matrix
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." } ;
166
167 HELP: zero-matrix
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." } ;
170
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 } "." } ;
173
174 HELP: null-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 } "." } ;
177
178 { matrix irregular-matrix square-matrix zero-matrix null-matrix zero-square-matrix null-matrix } related-words
179
180 ! NON-PREDICATE TESTS
181
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." }
186 { $examples
187     "The example is an irregular matrix, because the rows have an unequal number of elements."
188     { $example
189         "USING: math.matrices prettyprint ;"
190         "{ { 1 } { } } regular-matrix? ."
191         "f"
192     }
193     "The example is a regular matrix, because the rows have an equal number of elements."
194     { $example
195         "USING: math.matrices prettyprint ;"
196         "{ { 1 } { 2 } } regular-matrix? ."
197         "t"
198     }
199 } ;
200
201 ! BUILDERS
202 HELP: <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" } "." }
205 { $examples
206     { $example
207         "USING: math.matrices prettyprint ;"
208         "3 2 10 <matrix> ."
209         "{ { 10 10 } { 10 10 } { 10 10 } }"
210     }
211     { $example
212         "USING: math.matrices prettyprint ;"
213         "4 1 \"¢\" <matrix> ."
214         "{ { \"¢\" } { \"¢\" } { \"¢\" } { \"¢\" } }"
215     }
216 } ;
217
218 HELP: <matrix-by>
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>" }
224 }
225 { $examples
226     { $example
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 } }"
230     }
231 } ;
232
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>" }
239 }
240 { $examples
241     { $example
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 } }"
245     }
246 } ;
247
248 HELP: <zero-matrix>
249 { $values { "m" integer } { "n" integer } { "matrix" matrix } }
250 { $description "Creates a matrix of size " { $snippet "m x n" } ", filled with zeroes." }
251 { $examples
252     { $example
253         "USING: math.matrices prettyprint ;"
254         "2 3 <zero-matrix> ."
255         "{ { 0 0 0 } { 0 0 0 } }"
256     }
257 } ;
258
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>" } "." }
262 { $examples
263     { $example
264         "USING: math.matrices prettyprint ;"
265         "2 <zero-square-matrix> ."
266         "{ { 0 0 } { 0 0 } }"
267     }
268 } ;
269
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." }
274 { $examples
275     { $example
276         "USING: math.matrices prettyprint ;"
277         "{ 1 2 3 } <diagonal-matrix> ."
278         "{ { 1 0 0 } { 0 2 0 } { 0 0 3 } }"
279     }
280 } ;
281
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." }
286 { $examples
287     { $example
288         "USING: math.matrices prettyprint ;"
289         "{ 1 2 3 } <anti-diagonal-matrix> ."
290         "{ { 0 0 1 } { 0 2 0 } { 3 0 0 } }"
291     }
292 } ;
293
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." }
297 { $examples
298     { $example
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 } }"
302     }
303 } ;
304
305 HELP: <eye>
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." }
308 { $examples
309     { $example
310         "USING: math.matrices prettyprint ;"
311         "5 6 0 4 <eye> ."
312         "{
313     { 4 0 0 0 0 0 }
314     { 0 4 0 0 0 0 }
315     { 0 0 4 0 0 0 }
316     { 0 0 0 4 0 0 }
317     { 0 0 0 0 4 0 }
318 }"
319     }
320     { $example
321         "USING: math.matrices prettyprint ;"
322         "5 5 2 2 <eye> ."
323         "{
324     { 0 0 2 0 0 }
325     { 0 0 0 2 0 }
326     { 0 0 0 0 2 }
327     { 0 0 0 0 0 }
328     { 0 0 0 0 0 }
329 }"
330     }
331 } ;
332
333 HELP: <simple-eye>
334 { $values { "m" integer } { "n" integer } { "k" integer } { "matrix" matrix } }
335 { $description
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>" }
338     $nl
339     "Specify a different diagonal value with " { $link <eye> } "."
340 }
341 { $examples
342     { $example
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 } }"
346     }
347 } ;
348
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 } "." }
352 { $notelist
353     { $equiv-word-note "non-square" <cartesian-square-indices> }
354     { $finite-input-note "two" "dim" }
355 }
356 { $examples
357     { $example
358         "USING: math.matrices prettyprint ;"
359         "{ 2 4 } <coordinate-matrix> ."
360 "{
361     { { 0 0 } { 0 1 } { 0 2 } { 0 3 } }
362     { { 1 0 } { 1 1 } { 1 2 } { 1 3 } }
363 }"
364     }
365 } ;
366
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> } "." }
370 { $examples
371     { $example
372         "USING: math.matrices prettyprint ;"
373         "{ 2 4 } <cartesian-indices> ."
374 "{
375     { { 0 0 } { 0 1 } { 0 2 } { 0 3 } }
376     { { 1 0 } { 1 1 } { 1 2 } { 1 3 } }
377 }"
378     }
379 } ;
380
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" } "." }
384 { $notes
385     { $equiv-word-note "square" <cartesian-indices> }
386 }
387 { $examples
388     { $example
389         "USING: math.matrices prettyprint ;"
390         "1 <cartesian-square-indices> ."
391         "{ { { 0 0 } } }"
392     }
393     { $example
394         "USING: math.matrices prettyprint ;"
395         "3 <cartesian-square-indices> ."
396 "{
397     { { 0 0 } { 0 1 } { 0 2 } }
398     { { 1 0 } { 1 1 } { 1 2 } }
399     { { 2 0 } { 2 1 } { 2 2 } }
400 }"
401     }
402 } ;
403
404 HELP: <square-rows>
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." }
408 { $examples
409     { $example
410         "USING: math.matrices prettyprint ;"
411         "3 <square-rows> ."
412         "{ { 0 1 2 } { 0 1 2 } { 0 1 2 } }"
413     }
414     { $example
415         "USING: math.matrices prettyprint ;"
416         "{ 2 3 5 } <square-rows> ."
417         "{ { 2 3 5 } { 2 3 5 } { 2 3 5 } }"
418     }
419 } ;
420
421 HELP: <square-cols>
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." }
425 { $examples
426     { $example
427         "USING: math.matrices prettyprint ;"
428         "3 <square-cols> ."
429         "{ { 0 0 0 } { 1 1 1 } { 2 2 2 } }"
430     }
431     { $example
432         "USING: math.matrices prettyprint ;"
433         "{ 2 3 5 } <square-cols> ."
434         "{ { 2 2 2 } { 3 3 3 } { 5 5 5 } }"
435     }
436 } ;
437
438 HELP: <lower-matrix>
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" } "." }
441 { $examples
442     { $example
443         "USING: math.matrices prettyprint ;"
444         "1 5 5 <lower-matrix> ."
445 "{
446     { 1 0 0 0 0 }
447     { 1 1 0 0 0 }
448     { 1 1 1 0 0 }
449     { 1 1 1 1 0 }
450     { 1 1 1 1 1 }
451 }"
452     }
453 } ;
454
455 HELP: <upper-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" } "." }
458 { $examples
459     { $example
460         "USING: math.matrices prettyprint ;"
461         "1 5 5 <upper-matrix> ."
462 "{
463     { 1 1 1 1 1 }
464     { 0 1 1 1 1 }
465     { 0 0 1 1 1 }
466     { 0 0 0 1 1 }
467     { 0 0 0 0 1 }
468 }"
469     }
470 } ;
471
472 HELP: stitch
473 { $values { "m" matrix } { "m'" matrix } }
474 { $description "Folds an " { $snippet "n>2" } "-dimensional matrix onto itself." }
475 { $examples
476     { $unchecked-example
477         "USING: math.matrices prettyprint ;"
478 "{
479     { { 0 5 } { 6 7 } { 0 15 } { 18 21 } }
480     { { 0 10 } { 12 14 } { 0 20 } { 24 28 } }
481 } stitch ."
482 "{
483     { 0 5 0 10 }
484     { 6 7 12 14 }
485     { 0 15 0 20 }
486     { 18 21 24 28 }
487 }"
488     }
489 } ;
490
491 HELP: row
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" } "." }
495 { $examples
496     { $example
497         "USING: kernel math.matrices prettyprint ;"
498         "{ { 1 2 } { 3 4 } } 1 swap row ."
499         "{ 3 4 }"
500     }
501 } ;
502
503 HELP: rows
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 } }
507 { $examples
508     { $example
509         "USING: math.matrices prettyprint ;"
510         "{ 0 1 } { { 1 2 } { 3 4 } } rows ."
511         "{ { 1 2 } { 3 4 } }"
512     }
513 } ;
514
515 HELP: col
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" } "." }
519 { $examples
520     { $example
521         "USING: kernel math.matrices prettyprint ;"
522         "{ { 1 2 } { 3 4 } } 1 swap col ."
523         "{ 2 4 }"
524     }
525 } ;
526
527 HELP: cols
528 { $values { "seq" sequence } { "matrix" matrix } { "cols" sequence } }
529 { $description "Get the columns from " { $snippet "matrix" } " listed by " { $snippet "seq" } "." }
530 { $examples
531     { $example
532         "USING: math.matrices prettyprint ;"
533         "{ 0 1 } { { 1 2 } { 3 4 } } cols ."
534         "{ { 1 3 } { 2 4 } }"
535     }
536 } ;
537
538 HELP: >square-matrix
539 { $values { "m" matrix } { "subset" square-matrix } }
540 { $description "Find only the " { $link2 square-matrix "square" } " subset of the input matrix." }
541 { $examples
542     { $example
543         "USING: math.matrices prettyprint ;"
544         "{ { 0 2 4 6 } { 1 3 5 7 } } >square-matrix ."
545         "{ { 0 2 } { 1 3 } }"
546     }
547 } ;
548
549 HELP: matrix-map
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 }
553 { $examples
554     { $example
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 } }"
558     }
559 } ;
560
561 HELP: column-map
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 } }
565 { $examples
566     { $example
567         "USING: sequences math.matrices prettyprint ;"
568         "3 <identity-matrix> [ reverse ] column-map ."
569         "{ { 0 0 1 } { 0 1 0 } { 1 0 0 } }"
570     }
571 } ;
572
573 HELP: matrix-nth
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 }
577 { $errors { $list
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" } }
580 } }
581 { $examples
582     "Get the entry at row 1, column 0."
583     { $example
584         "USING: math.matrices prettyprint ;"
585         "{ 1 0 } { { 0 1 } { 2 3 } } matrix-nth ."
586         "2"
587     }
588 } ;
589
590 HELP: matrix-nths
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 }
594 { $errors { $list
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" } }
597 } }
598 { $examples
599     { $example
600         "USING: math.matrices prettyprint ;"
601         "{ { 1 0 } { 1 1 } } { { 0 1 } { 2 3 } } matrix-nths ."
602         "{ 2 3 }"
603     }
604 } ;
605
606 HELP: matrix-set-nth
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  }
611 { $errors { $list
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."
615 } }
616 { $examples
617     "Change the entry at row 1, column 0."
618     { $example
619         "USING: math.matrices kernel prettyprint ;"
620         "{ { 0 1 } { 2 3 } } \"a\" { 1 0 } pick matrix-set-nth ."
621         "{ { 0 1 } { \"a\" 3 } }"
622     }
623 } ;
624
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 }
630 { $errors { $list
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."
634 } }
635 { $examples
636     "Change both entries on row 0."
637     { $example
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\" } }"
641     }
642 } ;
643
644
645 HELP: mneg
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." }
648 { $notelist
649     { $equiv-word-note "companion" mabs }
650     $2d-only-note
651     { $matrix-scalar-note neg }
652 }
653 { $examples
654     { $example
655         "USING: math.matrices prettyprint ;"
656         "{ { 5 9 } { 15 -17 } } mneg ."
657         "{ { -5 -9 } { -15 17 } }"
658     }
659 } ;
660
661 HELP: mabs
662 { $values { "m" matrix } { "m'" matrix } }
663 { $description "Compute the absolute value (" { $link abs } ") of each element in the matrix." }
664 { $notelist
665     { $equiv-word-note "companion" mneg }
666     $2d-only-note
667     { $matrix-scalar-note abs }
668 }
669 { $examples
670     { $example
671         "USING: math.matrices prettyprint ;"
672         "{ { -5 -9 } { -15 17 } } mabs ."
673         "{ { 5 9 } { 15 17 } }"
674     }
675 } ;
676
677 HELP: n+m
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" } "." }
680 { $notelist
681     { $equiv-word-note "swapped" m+n }
682     $2d-only-note
683     { $matrix-scalar-note + }
684 }
685 { $examples
686     { $example
687         "USING: kernel math.matrices prettyprint ;"
688         "1 3 <identity-matrix> n+m ."
689         "{ { 2 1 1 } { 1 2 1 } { 1 1 2 } }"
690     }
691 } ;
692
693 HELP: m+n
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" } "." }
696 { $notelist
697     { $equiv-word-note "swapped" n+m }
698     $2d-only-note
699     { $matrix-scalar-note + }
700 }
701 { $examples
702     { $example
703         "USING: kernel math.matrices prettyprint ;"
704         "3 <identity-matrix> 1 m+n ."
705         "{ { 2 1 1 } { 1 2 1 } { 1 1 2 } }"
706     }
707 } ;
708
709 HELP: n-m
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" } "." }
712 { $notelist
713     { $equiv-word-note "swapped" m-n }
714     $2d-only-note
715     { $matrix-scalar-note - }
716 }
717 { $examples
718     { $example
719         "USING: kernel math.matrices prettyprint ;"
720         "1 3 <identity-matrix> n-m ."
721         "{ { 0 1 1 } { 1 0 1 } { 1 1 0 } }"
722     }
723 } ;
724
725 HELP: m-n
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" } "." }
728 { $notelist
729     { $equiv-word-note "swapped" n-m }
730     $2d-only-note
731     { $matrix-scalar-note - }
732 }
733 { $examples
734     { $example
735         "USING: kernel math.matrices prettyprint ;"
736         "3 <identity-matrix> 1 m-n ."
737         "{ { 0 -1 -1 } { -1 0 -1 } { -1 -1 0 } }"
738     }
739 } ;
740
741 HELP: n*m
742 { $values { "n" object } { "m" matrix }  }
743 { $description "Every element in the input matrix " { $snippet "m" } " is multiplied by the scalar " { $snippet "n" } "." }
744 { $notelist
745     $keep-shape-note
746     { $equiv-word-note "swapped" m*n }
747     $2d-only-note
748     { $matrix-scalar-note * }
749 }
750 { $examples
751     { $example
752         "USING: kernel math.matrices prettyprint ;"
753         "3 3 <identity-matrix> n*m ."
754         "{ { 3 0 0 } { 0 3 0 } { 0 0 3 } }"
755     }
756 } ;
757
758 HELP: m*n
759 { $values { "m" matrix } { "n" object } }
760 { $description "Every element in the input matrix " { $snippet "m" } " is multiplied by the scalar " { $snippet "n" } "." }
761 { $notelist
762     $keep-shape-note
763     { $equiv-word-note "swapped" n*m }
764     $2d-only-note
765     { $matrix-scalar-note * }
766 }
767
768 { $examples
769     { $example
770         "USING: kernel math.matrices prettyprint ;"
771         "3 <identity-matrix> 3 m*n ."
772         "{ { 3 0 0 } { 0 3 0 } { 0 0 3 } }"
773     }
774 } ;
775
776 HELP: n/m
777 { $values { "n" object } { "m" matrix }  }
778 { $description "Every element in the input matrix " { $snippet "m" } " is divided by the scalar " { $snippet "n" } "." }
779 { $notelist
780     $keep-shape-note
781     { $equiv-word-note "swapped" m/n }
782     $2d-only-note
783     { $matrix-scalar-note / }
784 }
785 { $examples
786     { $example
787         "USING: kernel math.matrices prettyprint ;"
788         "2 { { 4 5 } { 2 1 } } n/m ."
789         "{ { 1/2 2/5 } { 1 2 } }"
790     }
791 } ;
792
793 HELP: m/n
794 { $values { "m" matrix } { "n" object } }
795 { $description "Every element in the input matrix " { $snippet "m" } " is divided by the scalar " { $snippet "n" } "." }
796 { $notelist
797     $keep-shape-note
798     { $equiv-word-note "swapped" n/m }
799     $2d-only-note
800     { $matrix-scalar-note / }
801 }
802 { $examples
803     { $example
804         "USING: kernel math.matrices prettyprint ;"
805         "{ { 4 5 } { 2 1 } } 2 m/n ."
806         "{ { 2 2+1/2 } { 1 1/2 } }"
807     }
808 } ;
809
810 HELP: m+
811 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
812 { $description "Adds two matrices element-wise." }
813 { $notelist
814     $2d-only-note
815     { $matrix-scalar-note + }
816 }
817 { $examples
818     { $example
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 } }"
822     }
823 } ;
824
825 HELP: m-
826 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
827 { $description "Subtracts two matrices element-wise." }
828 { $notelist
829     $2d-only-note
830     { $matrix-scalar-note - }
831 }
832 { $examples
833     { $example
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 } }"
837     }
838 } ;
839
840 HELP: m*
841 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
842 { $description "Multiplies two matrices element-wise." }
843 { $notelist
844     $2d-only-note
845     { $matrix-scalar-note * }
846 }
847 { $examples
848     { $example
849         "USING: math.matrices prettyprint ;"
850         "{ { 5 9 } { 15 17 } } { { 3 2 } { 4 9 } } m* ."
851         "{ { 15 18 } { 60 153 } }"
852     }
853 } ;
854
855 HELP: m/
856 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
857 { $description "Divides two matrices element-wise." }
858 { $notelist
859     $2d-only-note
860     { $matrix-scalar-note / }
861 }
862 { $examples
863     { $example
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 } }"
867     }
868 } ;
869
870 HELP: mdotv
871 { $values { "m" matrix } { "v" sequence } { "p" matrix } }
872 { $description "Computes the dot product of a matrix and a vector." }
873 { $notelist
874     { $equiv-word-note "swapped" vdotm }
875     $2d-only-note
876     { $matrix-scalar-note * + }
877 }
878 { $examples
879     { $example
880         "USING: math.matrices prettyprint ;"
881         "{ { 1 -1 2 } { 0 -3 1 } } { 2 1 0 } mdotv ."
882         "{ 1 -3 }"
883     }
884 } ;
885
886 HELP: vdotm
887 { $values { "v" sequence } { "m" matrix } { "p" matrix } }
888 { $description "Computes the dot product of a vector and a matrix." }
889 { $notelist
890     { $equiv-word-note "swapped" mdotv }
891     $2d-only-note
892     { $matrix-scalar-note * + }
893 }
894 { $examples
895     { $example
896         "USING: math.matrices prettyprint ;"
897         "{ 2 1 0 } { { 1 -1 2 } { 0 -3 1 } } vdotm ."
898         "{ 2 -5 5 }"
899     }
900 } ;
901
902 HELP: mdot
903 { $values { "m" matrix } }
904 { $description "Computes the dot product of two matrices, i.e multiplies them." }
905 { $notelist
906     $2d-only-note
907     { $matrix-scalar-note * + }
908 }
909 { $examples
910     { $example
911         "USING: math.matrices prettyprint ;"
912         "{ { 1 -1 2 } { 0 -3 1 } } { { 3 7 } { 9 12 } } mdot ."
913         "{ { -6 -5 } { -27 -36 } }"
914     }
915 } ;
916
917 HELP: m~
918 { $values { "m1" matrix } { "m2" matrix } { "epsilon" number } { "?" boolean } }
919 { $description "Compares the matrices like " { $link ~ } ", using the " { $snippet "epsilon" } "." }
920 { $notelist
921     $2d-only-note
922     { $matrix-scalar-note ~ }
923 }
924 { $examples
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." }
926     { $example
927         "USING: kernel math math.matrices prettyprint ;"
928         "{ { 5 9 } { 15 17 } } dup [ .01 + ] matrix-map .1 m~ ."
929         "t"
930     }
931 } ;
932
933 HELP: mmin
934 { $values { "m" matrix } { "n" object } }
935 { $description "Determine the minimum value of the matrix." }
936 { $notelist
937     $2d-only-note
938     { $matrix-scalar-note min }
939 }
940 { $examples
941     { $example
942         "USING: math.matrices prettyprint ;"
943         "{ { 5 9 } { 15 17 } } mmin ."
944         "5"
945     }
946 } ;
947
948 HELP: mmax
949 { $values { "m" matrix } { "n" object } }
950 { $description "Determine the maximum value of the matrix." }
951 { $notelist
952     $2d-only-note
953     { $matrix-scalar-note max }
954 }
955 { $examples
956     { $example
957         "USING: math.matrices prettyprint ;"
958         "{ { 5 9 } { 15 17 } } mmax ."
959         "17"
960     }
961 } ;
962
963 { l2-norm frobenius-norm hilbert-schmidt-norm } related-words
964
965 HELP: matrix-l1-norm
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." }
969 { $notelist
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 }
974     $2d-only-note
975 }
976 { $examples
977     { $example
978         "USING: math.matrices prettyprint ;"
979         "{ { 2 -2 1 } { 1 3 -1 } { 2 -4 2 } } matrix-l1-norm ."
980         "9"
981     }
982 } ;
983
984 HELP: matrix-l2-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." }
988 { $notelist
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 }
994     $2d-only-note
995 }
996 { $examples
997     { $example
998         "USING: math.matrices prettyprint ;"
999         "{ { 1 1 } { 1 1 } } matrix-l2-norm ."
1000         "2.0"
1001     }
1002 } ;
1003
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." }
1008 { $notelist
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 }
1013     $2d-only-note
1014 }
1015 { $examples
1016     { $example
1017         "USING: math.matrices prettyprint ;"
1018         "{ { 2 -2 1 } { 1 3 -1 } { 2 -4 2 } } matrix-l-infinity-norm ."
1019         "8"
1020     }
1021 } ;
1022
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." }
1027 { $examples
1028     "Equivalent to " { $link l2-norm } " for " { $snippet "p = q = 2 " } ":"
1029     { $example
1030         "USING: math.matrices prettyprint ;"
1031         "{ { 1 1 } { 1 1 } } 2 2 matrix-p-q-norm ."
1032         "2.0"
1033     }
1034 } ;
1035
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 } "." }
1040 { $examples
1041    { $example
1042        "USING: math.matrices prettyprint ;"
1043        "4 4 1 <matrix> 2 matrix-p-norm-entrywise ."
1044        "4.0"
1045    }
1046 } ;
1047
1048 HELP: matrix-p-norm
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." }
1051 { $notelist
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 }
1055     $2d-only-note
1056 }
1057 { $examples
1058    "Calls " { $link l1-norm } ":"
1059    { $example
1060        "USING: math.matrices prettyprint ;"
1061        "4 4 1 <matrix> 1 matrix-p-norm ."
1062        "4"
1063    }
1064    "Falls back to " { $link matrix-p-norm-entrywise } ":"
1065    { $example
1066        "USING: math.functions math.matrices prettyprint ;"
1067        "2 2 3 <matrix> 1.5 matrix-p-norm 7.559 10e-4 ~ ."
1068        "t"
1069    }
1070 } ;
1071
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
1074
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" } "." }
1078 { $notelist
1079    $2d-only-note
1080    { $matrix-scalar-note max abs / }
1081 }
1082 { $examples
1083    { $example
1084        "USING: math.matrices prettyprint ;"
1085        "{ { 5 9 } { 15 17 } } matrix-normalize ."
1086        "{ { 5/17 9/17 } { 15/17 1 } }"
1087    }
1088 } ;
1089
1090 HELP: main-diagonal
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> } ")." }
1093 { $notelist
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 }
1097 }
1098 { $examples
1099     { "The operation is simple on a " { $link square-matrix } ":" }
1100     { $example
1101         "USING: math.matrices prettyprint ;"
1102 "{
1103     { 7 2 11 }
1104     { 9 7 7 }
1105     { 1 8 0 }
1106 } main-diagonal ."
1107         "{ 7 7 0 }"
1108     }
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."
1110     { $example
1111         "USING: math.matrices prettyprint ;"
1112 "{
1113     { 6 5 0 }
1114     { 7 2 6 }
1115     { 4 3 9 }
1116     { 3 3 3 }
1117 } main-diagonal ."
1118         "{ 6 2 9 }"
1119     }
1120 } ;
1121
1122 HELP: anti-diagonal
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> } ")." }
1125 { $notelist
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 }
1129 }
1130 { $examples
1131     { "The operation is simple on a " { $link square-matrix } ":" }
1132     { $example
1133         "USING: math.matrices prettyprint ;"
1134 "{
1135     { 7 2 11 }
1136     { 9 7 7 }
1137     { 1 8 0 }
1138 } anti-diagonal ."
1139         "{ 11 7 1 }"
1140     }
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."
1142     { $example
1143         "USING: math.matrices prettyprint ;"
1144 "{
1145     { 6 5 0 }
1146     { 7 2 6 }
1147     { 4 3 9 }
1148     { 3 3 3 }
1149 } anti-diagonal ."
1150         "{ 0 2 4 }"
1151     }
1152 } ;
1153
1154
1155 HELP: transpose
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." }
1158 { $notelist
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 }
1161 }
1162 { $examples
1163     { $example
1164         "USING: math.matrices sequences prettyprint ;"
1165         "5 <iota> <anti-diagonal-matrix> transpose ."
1166 "{
1167     { 0 0 0 0 4 }
1168     { 0 0 0 3 0 }
1169     { 0 0 2 0 0 }
1170     { 0 1 0 0 0 }
1171     { 0 0 0 0 0 }
1172 }"
1173     }
1174 } ;
1175
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 } }
1180 { $examples
1181     { $example
1182         "USING: math.matrices sequences prettyprint ;"
1183         "5 <iota> <diagonal-matrix> anti-transpose ."
1184 "{
1185     { 4 0 0 0 0 }
1186     { 0 3 0 0 0 }
1187     { 0 0 2 0 0 }
1188     { 0 0 0 1 0 }
1189     { 0 0 0 0 0 }
1190 }"
1191     }
1192 } ;
1193
1194 HELP: rows-except
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" } "." }
1197 { $examples
1198     { $example
1199         "USING: math.matrices prettyprint ;"
1200 "{
1201     { 2 7 12 2 }
1202     { 8 9 10 0 }
1203     { 1 3 3 5 }
1204     { 8 13 7 12 }
1205 } { 1 3 } rows-except ."
1206         "{ { 2 7 12 2 } { 1 3 3 5 } }"
1207     }
1208 } ;
1209
1210 HELP: cols-except
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" } "." }
1213 { $examples
1214     { $example
1215         "USING: math.matrices prettyprint ;"
1216 "{
1217     { 2 7 12 2 }
1218     { 8 9 10 0 }
1219     { 1 3 3 5 }
1220     { 8 13 7 12 }
1221 } { 1 3 } cols-except . "
1222         "{ { 2 12 } { 8 10 } { 1 3 } { 8 7 } }"
1223     }
1224 } ;
1225 HELP: matrix-except
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." }
1228 { $examples
1229     { $example
1230         "USING: math.matrices prettyprint ;"
1231         "{ { 0 1 } { 2 3 } } { 0 1 } matrix-except ."
1232         "{ { 2 } }"
1233     }
1234 } ;
1235
1236 HELP: submatrix-excluding
1237 { $values { "matrix" matrix } { "exclude-pair" pair } { "submatrix" matrix } }
1238 { $description "A possibly more obvious word for " { $link matrix-except } "." } ;
1239
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." }
1243 { $examples
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."
1245     { $example
1246         "USING: math.matrices prettyprint ;"
1247         "{ { 0 1 2 } { 3 4 5 } { 6 7 8 } } matrix-except-all ."
1248         "{
1249     {
1250         { { 4 5 } { 7 8 } }
1251         { { 3 5 } { 6 8 } }
1252         { { 3 4 } { 6 7 } }
1253     }
1254     {
1255         { { 1 2 } { 7 8 } }
1256         { { 0 2 } { 6 8 } }
1257         { { 0 1 } { 6 7 } }
1258     }
1259     {
1260         { { 1 2 } { 4 5 } }
1261         { { 0 2 } { 3 5 } }
1262         { { 0 1 } { 3 4 } }
1263     }
1264 }"
1265     }
1266 } ;
1267
1268 HELP: all-submatrices
1269 { $values { "matrix" matrix } { "submatrices" { $sequence matrix } } }
1270 { $description "A possibly more obvious name for " { $link matrix-except-all } "." } ;
1271
1272 HELP: dimension
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." }
1276 { $examples
1277     { $example
1278         "USING: math.matrices prettyprint ;"
1279         "4 30 1 <matrix> dimension ."
1280         "{ 4 30 }"
1281     }
1282     { $example
1283         "USING: math.matrices prettyprint ;"
1284         "{ } dimension ."
1285         "{ 0 0 }"
1286     }
1287 } ;