1 USING: arrays generic.single help.markup help.syntax kernel math
2 math.matrices math.matrices.private math.matrices.extras
3 math.order math.ratios math.vectors opengl.gl random sequences
5 IN: math.matrices.extras
7 ABOUT: "math.matrices.extras"
9 ARTICLE: "math.matrices.extras" "Extra matrix operations"
11 "These constructions have special mathematical properties:"
20 "Common transformation matrices:"
31 <random-integer-matrix>
39 linearly-independent-matrix?
42 "Common algorithms on matrices:"
45 gram-schmidt-normalize
56 determinant 1/det m*1/det
58 multiplicative-inverse
61 "Covariance in matrices:"
64 covariance-matrix-ddof
65 sample-covariance-matrix
68 "Errors thrown by this vocabulary:"
69 { $subsections negative-power-matrix non-square-determinant undefined-inverse } ;
71 HELP: invertible-matrix?
72 { $values { "matrix" matrix } { "?" boolean } }
73 { $description "Tests whether the input matrix has a " { $link multiplicative-inverse } ". In order for a matrix to be invertible, it must be a " { $link square-matrix } ", " { $emphasis "or" } ", if it is non-square, it must not be of " { $link +deficient-rank+ } "." }
74 { $examples { $example "USING: math.matrices.extras prettyprint ;" "" } } ;
76 HELP: linearly-independent-matrix?
77 { $values { "matrix" matrix } { "?" boolean } }
78 { $description "Tests whether the input matrix is linearly independent." }
79 { $examples { $example "USING: math.matrices.extras prettyprint ;" "" } } ;
81 ! SINGLETON RANK TYPES
83 { $class-description "The class of matrix rank quantifiers." } ;
86 { $class-description "A " { $link rank-kind } " describing a matrix of full rank." } ;
88 { $class-description "A " { $link rank-kind } " describing a matrix of half rank." } ;
90 { $class-description "A " { $link rank-kind } " describing a matrix of zero rank." } ;
91 HELP: +deficient-rank+
92 { $class-description "A " { $link rank-kind } " describing a matrix of deficient rank." } ;
93 HELP: +uncalculated-rank+
94 { $class-description "A " { $link rank-kind } " describing a matrix whose rank is not (yet) known." } ;
98 HELP: negative-power-matrix
99 { $values { "m" matrix } { "n" integer } }
100 { $description "Throws a " { $link negative-power-matrix } " error." }
101 { $error-description "Given the semantics of " { $link m^n } ", negative exponents are not within the domain of the power matrix function." } ;
103 HELP: non-square-determinant
104 { $values { "m" integer } { "n" integer } }
105 { $description "Throws a " { $link non-square-determinant } " error." }
106 { $error-description { $link determinant } " was used with a non-square matrix whose dimensions are " { $snippet "m x n" } ". It is not generally possible to find the determinant of a non-square matrix." } ;
108 HELP: undefined-inverse
109 { $values { "m" integer } { "n" integer } { "r" rank-kind } }
110 { $description "Throws an " { $link undefined-inverse } " error." }
111 { $error-description { $link multiplicative-inverse } " was used with a non-square matrix of rank " { $snippet "rank" } " whose dimensions are " { $snippet "m x n" } ". It is not generally possible to find the inverse of a " { $link +deficient-rank+ } " non-square " { $link matrix } "." } ;
113 HELP: <random-integer-matrix>
114 { $values { "m" integer } { "n" integer } { "max" integer } { "matrix" matrix } }
115 { $description "Creates a " { $snippet "m x n" } " " { $link matrix } " full of random, possibly signed " { $link integer } "s whose absolute values are less than or equal to " { $snippet "max" } ", as given by " { $link random-integers } "." }
117 { "The signedness of the numbers in the resulting matrix will be randomized. Use " { $link mabs } " with this word to generate a matrix of random positive integers." }
118 { $equiv-word-note "integral" <random-unit-matrix> }
120 { $errors { $link no-method } " if " { $snippet "max" } " is not an " { $link integer } "." }
123 "USING: math.matrices.extras prettyprint ;"
124 "2 4 15 <random-integer-matrix> ."
125 "{ { -9 -9 1 3 } { -14 -8 14 10 } }"
129 HELP: <random-unit-matrix>
130 { $values { "m" integer } { "n" integer } { "max" number } { "matrix" matrix } }
131 { $description "Creates a " { $snippet "m x n" } " " { $link matrix } " full of random, possibly signed " { $link float } "s as a fraction of " { $snippet "max" } "." }
133 { "The signedness of the numbers in the resulting matrix will be randomized. Use " { $link mabs } " with this word to generate a matrix of random positive numbers." }
134 { $equiv-word-note "real" <random-integer-matrix> }
135 { "This word is implemented by generating sub-integral floats through " { $link random-units } " and multiplying by random integers less than or equal to " { $snippet "max" } "." }
139 "USING: math.matrices.extras prettyprint ;"
140 "4 2 15 <random-unit-matrix> ."
142 { -3.713295909201797 3.815787135075961 }
143 { -2.460506890603817 1.535222788710546 }
144 { 3.692213981267878 -1.462963244399762 }
145 { 13.8967592095433 -6.688509969360172 }
152 HELP: <hankel-matrix>
153 { $values { "n" integer } { "matrix" matrix } }
155 "A Hankel matrix is a symmetric, " { $link square-matrix } " in which each ascending skew-diagonal from left to right is constant. See " { $url URL" https://en.wikipedia.org/wiki/Hankel_matrix" "hankel matrix" } "."
157 "The following is true of any Hankel matrix" { $snippet "A" } ": " { $snippet "A[i][j] = A[j][i] = a[i+j-2]" } "."
159 "The " { $link <toeplitz-matrix> } " is an upside-down Hankel matrix."
161 "The " { $link <hilbert-matrix> } " is a special case of the Hankel matrix."
165 "USING: math.matrices.extras prettyprint ;"
166 "4 <hankel-matrix> ."
167 "{ { 1 2 3 4 } { 2 3 4 0 } { 3 4 0 0 } { 4 0 0 0 } }"
171 HELP: <hilbert-matrix>
172 { $values { "m" integer } { "n" integer } { "matrix" matrix } }
174 "A Hilbert matrix is a " { $link square-matrix } " " { $snippet "A" } " in which entries are the unit fractions "
175 { $snippet "A[i][j] = 1/(i+j-1)" }
176 ". See " { $url URL" https://en.wikipedia.org/wiki/Hilbert_matrix" "hilbert matrix" } "."
178 "A Hilbert matrix is a special case of the " { $link <hankel-matrix> } "."
182 "USING: math.matrices.extras prettyprint ;"
183 "1 2 <hilbert-matrix> ."
187 "USING: math.matrices.extras prettyprint ;"
188 "3 6 <hilbert-matrix> ."
190 { 1 1/2 1/3 1/4 1/5 1/6 }
191 { 1/2 1/3 1/4 1/5 1/6 1/7 }
192 { 1/3 1/4 1/5 1/6 1/7 1/8 }
197 HELP: <toeplitz-matrix>
198 { $values { "n" integer } { "matrix" matrix } }
199 { $description "A Toeplitz matrix is an upside-down " { $link <hankel-matrix> } ". Unlike the Hankel matrix, a Toeplitz matrix can be non-square. See " { $url URL" https://en.wikipedia.org/wiki/Hankel_matrix" "hankel matrix" } "."
203 "USING: math.matrices.extras prettyprint ;"
204 "4 <toeplitz-matrix> ."
205 "{ { 1 2 3 4 } { 2 1 2 3 } { 3 2 1 2 } { 4 3 2 1 } }"
210 { $values { "r" integer } { "matrix" matrix } }
211 { $description "Create a box matrix (a " { $link square-matrix } ") with the dimensions of " { $snippet "r x r" } ", filled with ones. The number of elements in the output scales linearly (" { $snippet "(r*2)+1" } ") with " { $snippet "r" } "." }
214 "USING: math.matrices.extras prettyprint ;"
225 "USING: math.matrices.extras prettyprint ;"
240 HELP: <scale-matrix3>
241 { $values { "factors" sequence } { "matrix" matrix } }
242 { $description "Make a " { $snippet "3 x 3" } " scaling matrix, used to scale an object in 3 dimensions. See " { $url URL" https://en.wikipedia.org/wiki/Scaling_(geometry)#Matrix_representation" "scaling matrix on Wikipedia" } "." }
244 { $finite-input-note "three" "factors" }
245 { $equiv-word-note "3-matrix" <scale-matrix4> }
249 "USING: math.matrices.extras prettyprint ;"
250 "{ 22 33 -44 } <scale-matrix4> ."
260 HELP: <scale-matrix4>
261 { $values { "factors" sequence } { "matrix" matrix } }
262 { $description "Make a " { $snippet "4 x 4" } " scaling matrix, used to scale an object in 3 or more dimensions. See " { $url URL" https://en.wikipedia.org/wiki/Scaling_(geometry)#Matrix_representation" "scaling matrix on Wikipedia" } "." }
264 { $finite-input-note "three" "factors" }
265 { $equiv-word-note "4-matrix" <scale-matrix3> }
269 "USING: math.matrices.extras prettyprint ;"
270 "{ 22 33 -44 } <scale-matrix4> ."
280 HELP: <ortho-matrix4>
281 { $values { "factors" sequence } { "matrix" matrix } }
282 { $description "Create a " { $link <scale-matrix4> } ", with the scale factors inverted." }
284 { $finite-input-note "three" "factors" }
285 { $equiv-word-note "inverse" <scale-matrix4> }
289 "USING: math.matrices.extras prettyprint ;"
290 "{ -9.3 100 1/2 } <ortho-matrix4> ."
292 { -0.1075268817204301 0.0 0.0 0.0 }
293 { 0.0 1/100 0.0 0.0 }
300 HELP: <frustum-matrix4>
301 { $values { "xy-dim" pair } { "near" number } { "far" number } { "matrix" matrix } }
302 { $description "Make a " { $snippet "4 x 4" } " matrix suitable for representing an occlusion frustum. A viewing or occlusion frustum is the three-dimensional region of a three-dimensional object which is visible on the screen. See " { $url URL" https://en.wikipedia.org/wiki/Frustum" "frustum on Wikipedia" } "." }
303 { $notes { $finite-input-note "two" "xy-dim" } }
306 "USING: math.matrices.extras prettyprint ;"
307 "{ 5 4 } 5 6 <frustum-matrix4> ."
311 { 0.0 0.0 -11.0 -60.0 }
316 { <frustum-matrix4> glFrustum } related-words
318 HELP: cartesian-matrix-map
319 { $values { "matrix" matrix } { "quot" { $quotation ( ... pair matrix -- ... matrix' ) } } { "matrix-seq" { $sequence matrix } } }
320 { $description "Calls the quotation with the matrix and the coordinate pair of the current element on the stack, with the matrix on the top of the stack." }
323 "USING: arrays math.matrices.extras prettyprint ;"
324 "{ { 21 22 } { 23 24 } } [ 2array ] cartesian-matrix-map ."
327 { { 0 0 } { { 21 22 } { 23 24 } } }
328 { { 0 1 } { { 21 22 } { 23 24 } } }
331 { { 1 0 } { { 21 22 } { 23 24 } } }
332 { { 1 1 } { { 21 22 } { 23 24 } } }
338 { $equiv-word-note "orthogonal" cartesian-column-map }
339 { $equiv-word-note "two-dimensional" map-index }
343 HELP: cartesian-column-map
344 { $values { "matrix" matrix } { "quot" { $quotation ( ... pair matrix -- ... matrix' ) } } { "matrix-seq" { $sequence matrix } } }
346 { $equiv-word-note "orthogonal" cartesian-matrix-map }
351 { $values { "matrix" matrix } { "orthogonal" matrix } }
352 { $description "Apply a Gram-Schmidt transform on the matrix." }
355 "USING: math.matrices.extras prettyprint ;"
356 "{ { 1 2 } { 3 4 } { 5 6 } } gram-schmidt ."
357 "{ { 1 2 } { 4/5 -2/5 } { 0 0 } }"
361 HELP: gram-schmidt-normalize
362 { $values { "matrix" matrix } { "orthonormal" matrix } }
363 { $description "Apply a Gram-Schmidt transform on the matrix, and " { $link normalize } " each row of the result, resulting in an orthogonal and normalized matrix (orthonormal)." }
366 "USING: math.matrices.extras prettyprint ;"
367 "{ { 1 2 } { 3 4 } { 5 6 } } gram-schmidt-normalize ."
369 { 0.4472135954999579 0.8944271909999159 }
370 { 0.894427190999916 -0.447213595499958 }
371 { NAN: 8000000000000 NAN: 8000000000000 }
377 { $values { "m" matrix } { "n" object } }
378 { $description "Compute the " { $snippet "nth" } " power of the input matrix. If " { $snippet "n" } " is " { $snippet "-1" } ", the inverse of the matrix is calculated (but see " { $link multiplicative-inverse } " for pitfalls)." }
380 { $link negative-power-matrix } " if " { $snippet "n" } " is a negative number other than " { $snippet "-1" } "."
382 { $link undefined-inverse } " if " { $snippet "n" } " is " { $snippet "-1" } " and the " { $link multiplicative-inverse } " of " { $snippet "m" } " is undefined."
385 { $equiv-word-note "swapped" n^m }
387 { $matrix-scalar-note max abs / }
391 "USING: math.matrices.extras prettyprint ;"
392 "{ { 1 2 } { 3 4 } } 2 m^n ."
393 "{ { 7 10 } { 15 22 } }"
398 { $values { "n" object } { "m" matrix } }
399 { $description "Because it is nonsensical to raise a number to the power of a matrix, this word exists to save typing " { $snippet "swap m^n" } ". See " { $link m^n } " for more information." }
401 { $link negative-power-matrix } " if " { $snippet "n" } " is a negative number other than " { $snippet "-1" } "."
403 { $link undefined-inverse } " if " { $snippet "n" } " is " { $snippet "-1" } " and the " { $link multiplicative-inverse } " of " { $snippet "m" } " is undefined."
406 { $equiv-word-note "swapped" m^n }
408 { $matrix-scalar-note max abs / }
412 "USING: math.matrices.extras prettyprint ;"
413 "2 { { 1 2 } { 3 4 } } n^m ."
414 "{ { 7 10 } { 15 22 } }"
418 HELP: kronecker-product
419 { $values { "m1" matrix } { "m2" matrix } { "m" matrix } }
420 { $description "Calculates the " { $url URL" http://enwp.org/Kronecker_product" "Kronecker product" } " of two matrices. This product can be described as a generalization of the vector-based " { $link outer-product } " to matrices. The Kronecker product gives the matrix of the tensor product with respect to a standard choice of basis." }
422 { $equiv-word-note "matrix" outer-product }
424 { $matrix-scalar-note * }
428 "USING: math.matrices.extras prettyprint ;"
435 } kronecker-product ."
445 { $values { "u" sequence } { "v" sequence } { "matrix" matrix } }
446 { $description "Computes the " { $url URL" http:// enwp.org/Outer_product" "outer-product product" } " of " { $snippet "u" } " and " { $snippet "v" } "." }
449 "USING: math.matrices.extras prettyprint ;"
450 "{ 5 6 7 } { 1 2 3 } outer-product ."
451 "{ { 5 10 15 } { 6 12 18 } { 7 14 21 } }" }
455 { $values { "matrix" matrix } { "rank" rank-kind } }
456 { $contract "The " { $emphasis "rank" } " of a " { $link matrix } " is how its number of linearly independent columns compare to the maximal number of linearly independent columns for a matrix with the same dimension." }
457 { $notes "See " { $url "https://en.wikipedia.org/wiki/Rank_(linear_algebra)" } " for more information." } ;
460 { $values { "matrix" matrix } { "nullity" rank-kind } }
464 { $values { "matrix" square-matrix } { "determinant" number } }
465 { $contract "Compute the determinant of the input matrix. Generally, the determinant of a matrix is a scaling factor of the transformation described by the matrix." }
468 { $matrix-scalar-note max - * }
470 { $errors { $link non-square-determinant } " if the input matrix is not a " { $link square-matrix } "." }
473 "USING: math.matrices.extras prettyprint ;"
482 "USING: math.matrices.extras prettyprint ;"
484 { -8 -8 13 11 10 -5 -14 }
485 { 3 -11 -8 3 -7 -3 4 }
486 { 10 4 -5 3 0 -6 -12 }
487 { -14 0 -3 -8 10 0 10 }
488 { 3 -6 1 -10 -9 10 0 }
489 { 5 -12 -14 6 5 -1 -7 }
490 { -9 -14 -8 5 2 2 -2 }
497 { $values { "matrix" square-matrix } { "1/det" number } }
498 { $description "Find the inverse (" { $link recip } ") of the " { $link determinant } " of the input matrix." }
501 { $matrix-scalar-note determinant recip }
504 { $link non-square-determinant } " if the input matrix is not a " { $link square-matrix } "."
506 { $link division-by-zero } " if the " { $link determinant } " of the input matrix is " { $snippet "0" } "."
510 "USING: math.matrices.extras prettyprint ;"
522 { $values { "matrix" square-matrix } { "matrix'" square-matrix } }
523 { $description "Multiply the input matrix by the inverse (" { $link recip } ") of its " { $link determinant } "." }
525 { "This word is used to implement " { $link recip } " for " { $link square-matrix } "." }
527 { $matrix-scalar-note determinant recip }
531 "USING: math.matrices.extras prettyprint ;"
539 { 7/6855 0 13/13710 -7/13710 }
540 { 2/6855 -11/13710 -7/13710 2/2285 }
541 { 1/4570 -1/6855 -3/4570 7/6855 }
542 { -1/4570 1/2742 -1/1371 1/6855 }
549 { $values { "matrix" square-matrix } { "matrix'" square-matrix } }
550 { $description "Calculate the " { $emphasis "matrix of minors" } " of the input matrix. See " { $url URL" https://en.wikipedia.org/wiki/Minor_(linear_algebra)" "minor on Wikipedia" } "." }
554 { $matrix-scalar-note determinant }
556 { $errors { $link non-square-determinant } " if the input matrix is not a " { $link square-matrix } "." }
559 "USING: math.matrices.extras prettyprint ;"
567 { 1710 -130 2555 -1635 }
568 { -690 -286 -2965 1385 }
569 { 1650 -754 3795 -1215 }
570 { 1100 416 2530 -810 }
576 { $values { "matrix" matrix } { "matrix'" matrix } }
577 { $description "Calculate the " { $emphasis "matrix of cofactors" } " of the input matrix. See " { $url URL" https://en.wikipedia.org/wiki/Minor_(linear_algebra)#Inverse_of_a_matrix" "matrix of cofactors on Wikipedia" } ". Alternating elements of the input matrix have their signs inverted." $nl "On odd rows, the even elements have their signs inverted. On even rows, odd elements have their signs inverted." }
581 { $matrix-scalar-note neg }
585 "USING: math.matrices.extras prettyprint ;"
600 "USING: math.matrices.extras prettyprint ;"
616 HELP: multiplicative-inverse
617 { $values { "x" matrix } { "y" matrix } }
618 { $description "Calculate the multiplicative inverse of the input." $nl "If the input is a " { $link square-matrix } ", this is done by multiplying the " { $link transpose } " of the " { $link2 >cofactors "cofactors" } " of the " { $link2 >minors "minors" } " of the input matrix by the " { $link2 1/det "inverse of the determinant" } " of the input matrix." }
622 { $matrix-scalar-note determinant >cofactors 1/det }
624 { $errors { $link non-square-determinant } " if the input matrix is not a " { $link square-matrix } "." } ;
627 HELP: covariance-matrix-ddof
628 { $values { "matrix" matrix } { "ddof" object } { "cov" matrix } }
630 HELP: covariance-matrix
631 { $values { "matrix" matrix } { "cov" matrix } }
633 HELP: sample-covariance-matrix
634 { $values { "matrix" matrix } { "cov" matrix } }
636 HELP: population-covariance-matrix
637 { $values { "matrix" matrix } { "cov" matrix } }