@@ -39,7 +39,7 @@ an SVD), while the pivots are used to extract a spanning set of independent colu
3939
4040The rank-revealing Businger–Golub QR algorithm is used for the pivoting strategy, appending
4141the "most independent" column with respect to the current set of pivots at each step via
42- Householder transformations [BG65; pp. 269--70](@cite) .
42+ Householder transformations [BG65; pp. 269--70].
4343
4444# Arguments
4545- `A::AbstractMatrix{T<:Integer}`: the matrix whose independent columns to extract.
@@ -75,9 +75,9 @@ julia> SDiagonalizability._extract_independent_cols(A)
7575Since we already need a pivoted QR decomposition to identify independent columns of `A` (or,
7676rather, to order the columns in such a way that the first `rank(A)` ones are guaranteed to
7777be independent), it makes sense to use data from the resulting factorization object to
78- compute the rank of `A` rather than compute a separate SVD. We thus count the nonzero scaling
79- coefficients—that is, the diagonal entries of the `R` matrix in `A = QR`—to determine the
80- rank, similarly to how we count the nonzero singular values in an SVD.
78+ compute the rank of `A` rather than compute a separate SVD. We thus count the nonzero
79+ scaling coefficients—that is, the diagonal entries of the `R` matrix in `A = QR`—to
80+ determine the rank, similarly to how we count the nonzero singular values in an SVD.
8181
8282It is worth noting that we manually specify a higher relative tolerance for this rank
8383computation. Further discussion can be found in the [`_rank_rtol`](@ref) documentation, but
@@ -87,7 +87,18 @@ tall-and-skinny and short-and-fat matrices (precisely the type we expect to enco
8787dealing with all ``\\ {-1, 0, 1\\ }``-eigenvectors of a Laplacian matrix, which is the
8888intended use case of this helper function in this package). Our replacement tolerance, on
8989the other hand, is a widely accepted standard in numerical analysis which uses the maximum
90- dimension instead [PTVF07; p. 795](@cite).
90+ dimension instead [PTVF07; p. 795].
91+
92+ # References
93+
94+ - [BG65](@cite): P. Businger and G. H. Golub. *Linear Least Squares Solutions by Householder
95+ Transformations*. *Numerische Mathematik* **7**, 269–76 (1965).
96+ https://doi.org/10.1007/BF01436084.
97+
98+ - [PTVF07](@cite): W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery.
99+ *Numerical Recipes: The Art of Scientific Computing*. 3rd Edition (Cambridge University
100+ Press, Cambridge, UK, 2007). ISBN: 978-0-521-88068-8.
101+ https://dl.acm.org/doi/10.5555/1403886.
91102"""
92103function _extract_independent_cols (A:: AbstractMatrix{<:Integer} )
93104 F = qr (A, ColumnNorm ())
@@ -156,7 +167,7 @@ Matrix has nonzero row sums; cannot be an (undirected) Laplacian
156167
157168Both the in-degree and out-degree Laplacian matrices of this random tournament digraph have
158169zero row sums but are not symmetric, so they fail the check. (These are the two standard
159- ways of extending the concept of the Laplacian to directed graphs [VL20; p. 196](@cite) .)
170+ ways of extending the concept of the Laplacian to directed graphs [VL20; p. 196].)
160171```jldoctest
161172julia> using Graphs
162173
@@ -204,6 +215,12 @@ At first blush, it may seem as though the choice of `DomainError` over something
204215this is informed by the simple *ad hoc* use of this function to validate inputs for other
205216functions requiring Laplacian matrices. Certainly, this function is never meant to be
206217publicly exposed on its own.
218+
219+ # References
220+
221+ - [VL20](@cite): J. J. Veerman and R. Lyons. *A Primer on Laplacian Dynamics in Directed
222+ Graphs*. *Nonlinear Phenomena in Complex Systems* **23**, 196–206 (2020).
223+ https://doi.org/10.33581/1561-4085-2020-23-2-196-206.
207224"""
208225function _assert_matrix_is_undirected_laplacian (L:: AbstractMatrix{<:Integer} )
209226 if ! issymmetric (L)
@@ -266,11 +283,26 @@ type of `A` when `eltype(A)` is not an `AbstractFloat`.
266283`LinearAlgebra.rank`'s default `rtol` of `min(m,n) * ϵ` for computing the rank of an
267284``m×n`` matrix may result in overestimating rank when ``|m - n| ≫ 0``, since condition
268285number (which determines how numerically stable SVD and QRD are) grows with both dimensions
269- [CD05; p. 603](@cite) . Given that we often deal with short-and-fat matrices in this package
286+ [CD05; p. 603]. Given that we often deal with short-and-fat matrices in this package
270287(particularly when processing all ``\\ {-1, 0, 1\\ }``-eigenvectors of a Laplacian matrix), we
271288turn instead to the same relative tolerance used by NumPy's and MATLAB's rank
272- functions—`max(m,n) * ϵ` [Num25, MAT25](@cite). (Indeed, this is a widely adopted standard
273- across the field of numerical analysis [PTVF07; p. 795](@cite).)
289+ functions—`max(m,n) * ϵ` [Num25, MAT25]. (Indeed, this is a widely adopted standard across
290+ the field of numerical analysis [PTVF07; p. 795].)
291+
292+ # References
293+
294+ - [CD05](@cite): Z. Chen and J. Dongarra. *Condition Numbers of Gaussian Random Matrices*.
295+ *SIAM Journal on Matrix Analysis and Applications* **27**, 603–20 (2005).
296+ https://doi.org/10.1137/040616413.
297+ - [MAT25](@cite): MATLAB Developers, *rank*. MATLAB reference documentation – R2025a (2025).
298+ Accessed: 2025-05-29. https://www.mathworks.com/help/matlab/ref/rank.html.
299+ - [Num25](@cite): NumPy Developers, *numpy.linalg.matrix_rank*. NumPy reference
300+ documentation – v2.2 (2025). Accessed: 2025-05-22.
301+ https://numpy.org/doc/stable/reference/generated/numpy.linalg.matrix_rank.html.
302+ - [PTVF07](@cite): W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery.
303+ *Numerical Recipes: The Art of Scientific Computing*. 3rd Edition (Cambridge University
304+ Press, Cambridge, UK, 2007). ISBN: 978-0-521-88068-8.
305+ https://dl.acm.org/doi/10.5555/1403886.
274306"""
275307function _rank_rtol (A:: AbstractMatrix{T} ) where {T}
276308 return maximum (size (A)) * eps (LinearAlgebra. eigtype (T))
0 commit comments