Sparse Arrays
Julia tiene soporte para vectores dispersos y sparse matrices en el módulo estándar SparseArrays. Los arreglos dispersos son arreglos que contienen suficientes ceros como para que almacenarlos en una estructura de datos especial conlleve ahorros en espacio y tiempo de ejecución, en comparación con los arreglos densos.
Se pueden encontrar paquetes externos que implementan diferentes tipos de almacenamiento disperso, arreglos dispersos multidimensionales y más en Noteworthy External Sparse Packages
Compressed Sparse Column (CSC) Sparse Matrix Storage
En Julia, las matrices dispersas se almacenan en el Compressed Sparse Column (CSC) format. Las matrices dispersas de Julia tienen el tipo SparseMatrixCSC{Tv,Ti}, donde Tv es el tipo de los valores almacenados, y Ti es el tipo entero para almacenar punteros de columna e índices de fila. La representación interna de SparseMatrixCSC es la siguiente:
struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
m::Int # Number of rows
n::Int # Number of columns
colptr::Vector{Ti} # Column j is in colptr[j]:(colptr[j+1]-1)
rowval::Vector{Ti} # Row indices of stored values
nzval::Vector{Tv} # Stored values, typically nonzeros
endEl almacenamiento en columnas dispersas comprimidas facilita y acelera el acceso a los elementos en la columna de una matriz dispersa, mientras que el acceso a la matriz dispersa por filas es considerablemente más lento. Operaciones como la inserción de entradas previamente no almacenadas una a la vez en la estructura CSC tienden a ser lentas. Esto se debe a que todos los elementos de la matriz dispersa que están más allá del punto de inserción deben ser movidos un lugar hacia adelante.
Todas las operaciones en matrices dispersas están cuidadosamente implementadas para aprovechar la estructura de datos CSC para el rendimiento y evitar operaciones costosas.
Si tienes datos en formato CSC de una aplicación o biblioteca diferente, y deseas importarlos en Julia, asegúrate de usar indexación basada en 1. Los índices de fila en cada columna deben estar ordenados, y si no lo están, la matriz se mostrará incorrectamente. Si tu objeto SparseMatrixCSC contiene índices de fila desordenados, una forma rápida de ordenarlos es haciendo una doble transposición. Dado que la operación de transposición es perezosa, haz una copia para materializar cada transposición.
En algunas aplicaciones, es conveniente almacenar valores cero explícitos en un SparseMatrixCSC. Estos son aceptados por funciones en Base (pero no hay garantía de que se conserven en operaciones mutantes). Tales ceros almacenados explícitamente se tratan como no ceros estructurales por muchas rutinas. La función nnz devuelve el número de elementos almacenados explícitamente en la estructura de datos dispersa, incluidos los ceros no estructurales. Para contar el número exacto de no ceros numéricos, utiliza count(!iszero, x), que inspecciona cada elemento almacenado de una matriz dispersa. dropzeros, y el dropzeros! en su lugar, se pueden usar para eliminar ceros almacenados de la matriz dispersa.
julia> A = sparse([1, 1, 2, 3], [1, 3, 2, 3], [0, 1, 2, 0])
3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
0 ⋅ 1
⋅ 2 ⋅
⋅ ⋅ 0
julia> dropzeros(A)
3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:
⋅ ⋅ 1
⋅ 2 ⋅
⋅ ⋅ ⋅Sparse Vector Storage
Los vectores dispersos se almacenan en un análogo cercano al formato de columna dispersa comprimida para matrices dispersas. En Julia, los vectores dispersos tienen el tipo SparseVector{Tv,Ti} donde Tv es el tipo de los valores almacenados y Ti el tipo entero para los índices. La representación interna es la siguiente:
struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}
n::Int # Length of the sparse vector
nzind::Vector{Ti} # Indices of stored values
nzval::Vector{Tv} # Stored values, typically nonzeros
endEn cuanto a SparseMatrixCSC, el tipo SparseVector también puede contener ceros almacenados explícitamente. (Ver Sparse Matrix Storage.)
Sparse Vector and Matrix Constructors
La forma más sencilla de crear un arreglo disperso es usar una función equivalente a la función zeros que Julia proporciona para trabajar con arreglos densos. Para producir un arreglo disperso en su lugar, puedes usar el mismo nombre con un prefijo sp:
julia> spzeros(3)
3-element SparseVector{Float64, Int64} with 0 stored entriesLa función sparse es a menudo una forma útil de construir arreglos dispersos. Por ejemplo, para construir una matriz dispersa podemos ingresar un vector I de índices de fila, un vector J de índices de columna y un vector V de valores almacenados (esto también se conoce como COO (coordinate) format). sparse(I,J,V) construye entonces una matriz dispersa tal que S[I[k], J[k]] = V[k]. El constructor de vector disperso equivalente es sparsevec, que toma el vector de índices (de fila) I y el vector V con los valores almacenados y construye un vector disperso R tal que R[I[k]] = V[k].
julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3];
julia> S = sparse(I,J,V)
5×18 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
⎡⠀⠈⠀⠀⠀⠀⠀⠀⢀⎤
⎣⠀⠀⠀⠂⡀⠀⠀⠀⠀⎦
julia> R = sparsevec(I,V)
5-element SparseVector{Int64, Int64} with 4 stored entries:
[1] = 1
[3] = -5
[4] = 2
[5] = 3La inversa de las funciones sparse y sparsevec es findnz, que recupera las entradas utilizadas para crear el arreglo disperso (incluyendo entradas almacenadas iguales a cero). findall(!iszero, x) devuelve los índices cartesianos de las entradas no nulas en x (sin incluir entradas almacenadas iguales a cero).
julia> findnz(S)
([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5])
julia> findall(!iszero, S)
4-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 4)
CartesianIndex(4, 7)
CartesianIndex(5, 9)
CartesianIndex(3, 18)
julia> findnz(R)
([1, 3, 4, 5], [1, -5, 2, 3])
julia> findall(!iszero, R)
4-element Vector{Int64}:
1
3
4
5Otra forma de crear un arreglo disperso es convertir un arreglo denso en un arreglo disperso utilizando la función sparse:
julia> sparse(Matrix(1.0I, 5, 5))
5×5 SparseMatrixCSC{Float64, Int64} with 5 stored entries:
1.0 ⋅ ⋅ ⋅ ⋅
⋅ 1.0 ⋅ ⋅ ⋅
⋅ ⋅ 1.0 ⋅ ⋅
⋅ ⋅ ⋅ 1.0 ⋅
⋅ ⋅ ⋅ ⋅ 1.0
julia> sparse([1.0, 0.0, 1.0])
3-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 1.0
[3] = 1.0Puedes ir en la otra dirección utilizando el constructor Array. La función issparse se puede usar para consultar si una matriz es dispersa.
julia> issparse(spzeros(5))
trueSparse matrix operations
Las operaciones aritméticas en matrices dispersas también funcionan como lo hacen en matrices densas. La indexación, la asignación y la concatenación de matrices dispersas funcionan de la misma manera que las matrices densas. Las operaciones de indexación, especialmente la asignación, son costosas cuando se realizan un elemento a la vez. En muchos casos, puede ser mejor convertir la matriz dispersa en formato (I,J,V) utilizando findnz, manipular los valores o la estructura en los vectores densos (I,J,V), y luego reconstruir la matriz dispersa.
Correspondence of dense and sparse methods
La siguiente tabla proporciona una correspondencia entre los métodos incorporados en matrices dispersas y sus métodos correspondientes en tipos de matrices densas. En general, los métodos que generan matrices dispersas difieren de sus contrapartes densas en que la matriz resultante sigue el mismo patrón de dispersión que una matriz dispersa dada S, o que la matriz dispersa resultante tiene una densidad d, es decir, cada elemento de la matriz tiene una probabilidad d de ser diferente de cero.
Los detalles se pueden encontrar en la sección Sparse Vectors and Matrices de la referencia de la biblioteca estándar.
| Sparse | Dense | Description |
|---|---|---|
spzeros(m,n) | zeros(m,n) | Creates a m-by-n matrix of zeros. (spzeros(m,n) is empty.) |
sparse(I,n,n) | Matrix(I,n,n) | Creates a n-by-n identity matrix. |
sparse(A) | Array(S) | Interconverts between dense and sparse formats. |
sprand(m,n,d) | rand(m,n) | Creates a m-by-n random matrix (of density d) with iid non-zero elements distributed uniformly on the half-open interval $[0, 1)$. |
sprandn(m,n,d) | randn(m,n) | Creates a m-by-n random matrix (of density d) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution. |
sprandn(rng,m,n,d) | randn(rng,m,n) | Creates a m-by-n random matrix (of density d) with iid non-zero elements generated with the rng random number generator |
Sparse Linear Algebra
Los solucionadores de matrices dispersas llaman a funciones de SuiteSparse. Las siguientes factorizaciones están disponibles:
| Type | Description |
|---|---|
CHOLMOD.Factor | Cholesky and LDLt factorizations |
UMFPACK.UmfpackLU | LU factorization |
SPQR.QRSparse | QR factorization |
Estas factorizaciones se describen con más detalle en el Sparse Linear Algebra API section:
SparseArrays API
SparseArrays.AbstractSparseArray — TypeAbstractSparseArray{Tv,Ti,N}Supertipo para arreglos dispersos de N dimensiones (o tipos similares a arreglos) con elementos de tipo Tv y tipo de índice Ti. SparseMatrixCSC, SparseVector y SuiteSparse.CHOLMOD.Sparse son subtipos de esto.
SparseArrays.AbstractSparseVector — TypeAbstractSparseVector{Tv,Ti}Supertipo para arreglos dispersos unidimensionales (o tipos similares a arreglos) con elementos de tipo Tv y tipo de índice Ti. Alias para AbstractSparseArray{Tv,Ti,1}.
SparseArrays.AbstractSparseMatrix — TypeAbstractSparseMatrix{Tv,Ti}Supertipo para arreglos dispersos bidimensionales (o tipos similares a arreglos) con elementos de tipo Tv y tipo de índice Ti. Alias para AbstractSparseArray{Tv,Ti,2}.
SparseArrays.SparseVector — TypeSparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}Tipo de vector para almacenar vectores dispersos. Se puede crear pasando la longitud del vector, un vector ordenado de índices no cero y un vector de valores no cero.
Por ejemplo, el vector [5, 6, 0, 7] se puede representar como
SparseVector(4, [1, 2, 4], [5, 6, 7])Esto indica que el elemento en el índice 1 es 5, en el índice 2 es 6, en el índice 3 es zero(Int), y en el índice 4 es 7.
Puede ser más conveniente crear vectores dispersos directamente a partir de vectores densos usando sparse como
sparse([5, 6, 0, 7])produce el mismo vector disperso.
SparseArrays.SparseMatrixCSC — TypeSparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}Tipo de matriz para almacenar matrices dispersas en el formato de Columna Dispersa Comprimida. La forma estándar de construir SparseMatrixCSC es a través de la función sparse. Ver también spzeros, spdiagm y sprand.
SparseArrays.sparse — Functionsparse(A)Convierte una AbstractMatrix A en una matriz dispersa.
Ejemplos
julia> A = Matrix(1.0I, 3, 3)
3×3 Matrix{Float64}:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
julia> sparse(A)
3×3 SparseMatrixCSC{Float64, Int64} con 3 entradas almacenadas:
1.0 ⋅ ⋅
⋅ 1.0 ⋅
⋅ ⋅ 1.0sparse(I, J, V,[ m, n, combine])Crea una matriz dispersa S de dimensiones m x n tal que S[I[k], J[k]] = V[k]. La función combine se utiliza para combinar duplicados. Si m y n no se especifican, se establecen en maximum(I) y maximum(J) respectivamente. Si la función combine no se proporciona, combine por defecto es + a menos que los elementos de V sean Booleanos, en cuyo caso combine por defecto es |. Todos los elementos de I deben satisfacer 1 <= I[k] <= m, y todos los elementos de J deben satisfacer 1 <= J[k] <= n. Los ceros numéricos en (I, J, V) se retienen como no ceros estructurales; para eliminar ceros numéricos, utiliza dropzeros!.
Para documentación adicional y un controlador experto, consulta SparseArrays.sparse!.
Ejemplos
julia> Is = [1; 2; 3];
julia> Js = [1; 2; 3];
julia> Vs = [1; 2; 3];
julia> sparse(Is, Js, Vs)
3×3 SparseMatrixCSC{Int64, Int64} con 3 entradas almacenadas:
1 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 3SparseArrays.sparse! — Functionsparse!(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{Tv},
m::Integer, n::Integer, combine, klasttouch::Vector{Ti},
csrrowptr::Vector{Ti}, csrcolval::Vector{Ti}, csrnzval::Vector{Tv},
[csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}] ) where {Tv,Ti<:Integer}Padre y controlador experto para sparse; consulte sparse para un uso básico. Este método permite al usuario proporcionar almacenamiento preasignado para los objetos intermedios y el resultado de sparse como se describe a continuación. Esta capacidad permite una construcción sucesiva más eficiente de SparseMatrixCSCs a partir de representaciones de coordenadas, y también permite la extracción de una representación de columna no ordenada de la transposición del resultado sin costo adicional.
Este método consta de tres pasos principales: (1) Ordenar por conteo la representación de coordenadas proporcionada en una forma CSR de fila no ordenada que incluye entradas repetidas. (2) Barrer a través de la forma CSR, calculando simultáneamente el arreglo de punteros de columna de la forma CSC deseada, detectando entradas repetidas y reempaquetando la forma CSR con entradas repetidas combinadas; esta etapa produce una forma CSR de fila no ordenada sin entradas repetidas. (3) Ordenar por conteo la forma CSR anterior en una forma CSC completamente ordenada sin entradas repetidas.
Los arreglos de entrada csrrowptr, csrcolval y csrnzval constituyen almacenamiento para las formas CSR intermedias y requieren length(csrrowptr) >= m + 1, length(csrcolval) >= length(I), y length(csrnzval >= length(I)). El arreglo de entrada klasttouch, espacio de trabajo para la segunda etapa, requiere length(klasttouch) >= n. Los arreglos de entrada opcionales csccolptr, cscrowval y cscnzval constituyen almacenamiento para la forma CSC devuelta S. Si es necesario, estos se redimensionan automáticamente para satisfacer length(csccolptr) = n + 1, length(cscrowval) = nnz(S) y length(cscnzval) = nnz(S); por lo tanto, si nnz(S) es desconocido desde el principio, pasar vectores vacíos del tipo apropiado (Vector{Ti}() y Vector{Tv}() respectivamente) es suficiente, o llamar al método sparse! descuidando cscrowval y cscnzval.
Al regresar, csrrowptr, csrcolval y csrnzval contienen una representación de columna no ordenada de la transposición del resultado.
Puede reutilizar el almacenamiento de los arreglos de entrada (I, J, V) para los arreglos de salida (csccolptr, cscrowval, cscnzval). Por ejemplo, puede llamar a sparse!(I, J, V, csrrowptr, csrcolval, csrnzval, I, J, V). Tenga en cuenta que se redimensionarán para satisfacer las condiciones anteriores.
Por razones de eficiencia, este método no realiza comprobaciones de argumentos más allá de 1 <= I[k] <= m y 1 <= J[k] <= n. Úselo con cuidado. Es recomendable probar con --check-bounds=yes.
Este método se ejecuta en tiempo O(m, n, length(I)). El algoritmo HALFPERM descrito en F. Gustavson, "Dos algoritmos rápidos para matrices dispersas: multiplicación y transposición permutada," ACM TOMS 4(3), 250-269 (1978) inspiró el uso de un par de ordenamientos por conteo en este método.
SparseArrays.sparse!(I, J, V, [m, n, combine]) -> SparseMatrixCSCVariante de sparse! que reutiliza los vectores de entrada (I, J, V) para el almacenamiento de la matriz final. Después de la construcción, los vectores de entrada harán alias a los búferes de la matriz; S.colptr === I, S.rowval === J, y S.nzval === V se cumple, y se redimensionarán según sea necesario.
Tenga en cuenta que algunos búferes de trabajo aún se asignarán. Específicamente, este método es un envoltorio de conveniencia alrededor de sparse!(I, J, V, m, n, combine, klasttouch, csrrowptr, csrcolval, csrnzval, csccolptr, cscrowval, cscnzval) donde este método asigna klasttouch, csrrowptr, csrcolval, y csrnzval de tamaño apropiado, pero reutiliza I, J, y V para csccolptr, cscrowval, y cscnzval.
Los argumentos m, n, y combine tienen como valores predeterminados maximum(I), maximum(J), y +, respectivamente.
Este método requiere Julia versión 1.10 o posterior.
SparseArrays.sparsevec — Functionsparsevec(I, V, [m, combine])Crea un vector disperso S de longitud m tal que S[I[k]] = V[k]. Los duplicados se combinan utilizando la función combine, que por defecto es + si no se proporciona un argumento combine, a menos que los elementos de V sean Booleanos, en cuyo caso combine por defecto es |.
Ejemplos
julia> II = [1, 3, 3, 5]; V = [0.1, 0.2, 0.3, 0.2];
julia> sparsevec(II, V)
5-element SparseVector{Float64, Int64} with 3 stored entries:
[1] = 0.1
[3] = 0.5
[5] = 0.2
julia> sparsevec(II, V, 8, -)
8-element SparseVector{Float64, Int64} with 3 stored entries:
[1] = 0.1
[3] = -0.1
[5] = 0.2
julia> sparsevec([1, 3, 1, 2, 2], [true, true, false, false, false])
3-element SparseVector{Bool, Int64} with 3 stored entries:
[1] = 1
[2] = 0
[3] = 1sparsevec(d::Dict, [m])Crea un vector disperso de longitud m donde los índices no nulos son claves del diccionario, y los valores no nulos son los valores del diccionario.
Ejemplos
julia> sparsevec(Dict(1 => 3, 2 => 2))
2-element SparseVector{Int64, Int64} with 2 stored entries:
[1] = 3
[2] = 2sparsevec(A)Convierte un vector A en un vector disperso de longitud m.
Ejemplos
julia> sparsevec([1.0, 2.0, 0.0, 0.0, 3.0, 0.0])
6-element SparseVector{Float64, Int64} with 3 stored entries:
[1] = 1.0
[2] = 2.0
[5] = 3.0Base.similar — Methodsimilar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}Crea un arreglo mutable no inicializado con el tipo de elemento, tipo de índice y tamaño dados, basado en la fuente SparseMatrixCSC dada. La nueva matriz dispersa mantiene la estructura de la matriz dispersa original, excepto en el caso en que las dimensiones de la matriz de salida son diferentes de la salida.
La matriz de salida tiene ceros en las mismas ubicaciones que la entrada, pero valores no inicializados para las ubicaciones no nulas.
SparseArrays.issparse — Functionissparse(S)Devuelve true si S es disperso, y false en caso contrario.
Ejemplos
julia> sv = sparsevec([1, 4], [2.3, 2.2], 10)
10-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 2.3
[4] = 2.2
julia> issparse(sv)
true
julia> issparse(Array(sv))
falseSparseArrays.nnz — Functionnnz(A)Devuelve el número de elementos almacenados (rellenos) en un arreglo disperso.
Ejemplos
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} con 3 entradas almacenadas:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nnz(A)
3SparseArrays.findnz — Functionfindnz(A::SparseMatrixCSC)Devuelve una tupla (I, J, V) donde I y J son los índices de fila y columna de los valores almacenados ("estructuralmente no cero") en la matriz dispersa A, y V es un vector de los valores.
Ejemplos
julia> A = sparse([1 2 0; 0 0 3; 0 4 0])
3×3 SparseMatrixCSC{Int64, Int64} con 4 entradas almacenadas:
1 2 ⋅
⋅ ⋅ 3
⋅ 4 ⋅
julia> findnz(A)
([1, 1, 3, 2], [1, 2, 2, 3], [1, 2, 4, 3])SparseArrays.spzeros — Functionspzeros([tipo,]m[,n])Crea un vector disperso de longitud m o una matriz dispersa de tamaño m x n. Este arreglo disperso no contendrá ningún valor distinto de cero. No se asignará almacenamiento para valores distintos de cero durante la construcción. El tipo predeterminado es Float64 si no se especifica.
Ejemplos
julia> spzeros(3, 3)
3×3 SparseMatrixCSC{Float64, Int64} con 0 entradas almacenadas:
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ ⋅
julia> spzeros(Float32, 4)
4-element SparseVector{Float32, Int64} con 0 entradas almacenadasspzeros([tipo], I::AbstractVector, J::AbstractVector, [m, n])Crea una matriz dispersa S de dimensiones m x n con ceros estructurales en S[I[k], J[k]].
Este método se puede utilizar para construir el patrón de dispersidad de la matriz, y es más eficiente que usar, por ejemplo, sparse(I, J, zeros(length(I))).
Para documentación adicional y un controlador experto, consulta SparseArrays.spzeros!.
Este método requiere la versión 1.10 de Julia o posterior.
SparseArrays.spzeros! — Functionspzeros!(::Type{Tv}, I::AbstractVector{Ti}, J::AbstractVector{Ti}, m::Integer, n::Integer,
klasttouch::Vector{Ti}, csrrowptr::Vector{Ti}, csrcolval::Vector{Ti},
[csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}]) where {Tv,Ti<:Integer}Padre y controlador experto para spzeros(I, J) que permite al usuario proporcionar almacenamiento preasignado para objetos intermedios. Este método es a spzeros lo que SparseArrays.sparse! es a sparse. Consulte la documentación de SparseArrays.sparse! para obtener detalles y longitudes de búfer requeridas.
Este método requiere Julia versión 1.10 o posterior.
SparseArrays.spzeros!(::Type{Tv}, I, J, [m, n]) -> SparseMatrixCSC{Tv}Variante de spzeros! que reutiliza los vectores de entrada I y J para el almacenamiento de la matriz final. Después de la construcción, los vectores de entrada harán alias a los búferes de la matriz; S.colptr === I y S.rowval === J se cumple, y se redimensionarán según sea necesario.
Tenga en cuenta que algunos búferes de trabajo aún se asignarán. Específicamente, este método es un envoltorio de conveniencia alrededor de spzeros!(Tv, I, J, m, n, klasttouch, csrrowptr, csrcolval, csccolptr, cscrowval) donde este método asigna klasttouch, csrrowptr y csrcolval del tamaño apropiado, pero reutiliza I y J para csccolptr y cscrowval.
Los argumentos m y n tienen como valores predeterminados maximum(I) y maximum(J).
Este método requiere la versión 1.10 de Julia o posterior.
SparseArrays.spdiagm — Functionspdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
spdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)
Construye una matriz diagonal dispersa a partir de `Pair`s de vectores y diagonales. Cada vector `kv.second` se colocará en la diagonal `kv.first`. Por defecto, la matriz es cuadrada y su tamaño se infiere de `kv`, pero se puede especificar un tamaño no cuadrado `m`×`n` (rellenado con ceros según sea necesario) pasando `m,n` como los primeros argumentos.
# Ejemplos
jldoctest julia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1]) 5×5 SparseMatrixCSC{Int64, Int64} con 8 entradas almacenadas: ⋅ 4 ⋅ ⋅ ⋅ 1 ⋅ 3 ⋅ ⋅ ⋅ 2 ⋅ 2 ⋅ ⋅ ⋅ 3 ⋅ 1 ⋅ ⋅ ⋅ 4 ⋅
spdiagm(v::AbstractVector)
spdiagm(m::Integer, n::Integer, v::AbstractVector)Construye una matriz dispersa con los elementos del vector como elementos diagonales. Por defecto (sin m y n dados), la matriz es cuadrada y su tamaño está dado por length(v), pero se puede especificar un tamaño no cuadrado m×n pasando m y n como los primeros argumentos.
Estas funciones requieren al menos Julia 1.6.
Ejemplos
julia> spdiagm([1,2,3])
3×3 SparseMatrixCSC{Int64, Int64} con 3 entradas almacenadas:
1 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 3
julia> spdiagm(sparse([1,0,3]))
3×3 SparseMatrixCSC{Int64, Int64} con 2 entradas almacenadas:
1 ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ 3SparseArrays.sparse_hcat — Functionsparse_hcat(A...)Concatena a lo largo de la dimensión 2. Devuelve un objeto SparseMatrixCSC.
Este método se agregó en Julia 1.8. Imita el comportamiento de concatenación anterior, donde la concatenación con tipos de matriz "sparse" especializados de LinearAlgebra.jl producía automáticamente una salida dispersa incluso en ausencia de cualquier argumento SparseArray.
SparseArrays.sparse_vcat — Functionsparse_vcat(A...)Concatena a lo largo de la dimensión 1. Devuelve un objeto SparseMatrixCSC.
Este método se agregó en Julia 1.8. Imita el comportamiento de concatenación anterior, donde la concatenación con tipos de matriz "sparse" especializados de LinearAlgebra.jl producía automáticamente una salida dispersa incluso en ausencia de cualquier argumento SparseArray.
SparseArrays.sparse_hvcat — Functionsparse_hvcat(rows::Tuple{Vararg{Int}}, values...)Concatenación horizontal y vertical dispersa en una sola llamada. Esta función se llama para la sintaxis de matrices en bloques. El primer argumento especifica el número de argumentos a concatenar en cada fila de bloque.
Este método se agregó en Julia 1.8. Imita el comportamiento de concatenación anterior, donde la concatenación con tipos de matrices "dispersas" especializados de LinearAlgebra.jl producía automáticamente una salida dispersa incluso en ausencia de cualquier argumento SparseArray.
SparseArrays.blockdiag — Functionblockdiag(A...)Concatena matrices de forma bloque-diagonal. Actualmente solo implementado para matrices dispersas.
Ejemplos
julia> blockdiag(sparse(2I, 3, 3), sparse(4I, 2, 2))
5×5 SparseMatrixCSC{Int64, Int64} con 5 entradas almacenadas:
2 ⋅ ⋅ ⋅ ⋅
⋅ 2 ⋅ ⋅ ⋅
⋅ ⋅ 2 ⋅ ⋅
⋅ ⋅ ⋅ 4 ⋅
⋅ ⋅ ⋅ ⋅ 4SparseArrays.sprand — Functionsprand([rng],[T::Type],m,[n],p::AbstractFloat)
sprand([rng],m,[n],p::AbstractFloat,[rfn=rand])Crea un vector disperso de longitud m o una matriz dispersa de m por n, en la que la probabilidad de que cualquier elemento sea diferente de cero se da de manera independiente por p (y, por lo tanto, la densidad media de elementos diferentes de cero también es exactamente p). El argumento opcional rng especifica un generador de números aleatorios, consulta Números Aleatorios. El argumento opcional T especifica el tipo de elemento, que por defecto es Float64.
Por defecto, los valores diferentes de cero se muestrean de una distribución uniforme utilizando la función rand, es decir, mediante rand(T), o rand(rng, T) si se proporciona rng; para el T=Float64 por defecto, esto corresponde a valores diferentes de cero muestreados uniformemente en [0,1).
Puedes muestrear valores diferentes de cero de una distribución diferente pasando una función rfn personalizada en lugar de rand. Esta debe ser una función rfn(k) que devuelva un arreglo de k números aleatorios muestreados de la distribución deseada; alternativamente, si se proporciona rng, debería ser en su lugar una función rfn(rng, k).
Ejemplos
julia> sprand(Bool, 2, 2, 0.5)
2×2 SparseMatrixCSC{Bool, Int64} con 2 entradas almacenadas:
1 1
⋅ ⋅
julia> sprand(Float64, 3, 0.75)
Vector disperso de 3 elementos{Float64, Int64} con 2 entradas almacenadas:
[1] = 0.795547
[2] = 0.49425SparseArrays.sprandn — Functionsprandn([rng][,Type],m[,n],p::AbstractFloat)Crea un vector disperso aleatorio de longitud m o una matriz dispersa de tamaño m por n con la probabilidad (independiente) especificada p de que cualquier entrada sea diferente de cero, donde los valores diferentes de cero se muestrean de la distribución normal. El argumento opcional rng especifica un generador de números aleatorios, consulta Random Numbers.
Especificar el tipo de elemento de salida Type requiere al menos Julia 1.1.
Ejemplos
julia> sprandn(2, 2, 0.75)
2×2 SparseMatrixCSC{Float64, Int64} con 3 entradas almacenadas:
-1.20577 ⋅
0.311817 -0.234641SparseArrays.nonzeros — Functionnonzeros(A)Devuelve un vector de los valores no nulos estructurales en la matriz dispersa A. Esto incluye ceros que están almacenados explícitamente en la matriz dispersa. El vector devuelto apunta directamente al almacenamiento interno de no nulos de A, y cualquier modificación al vector devuelto también mutará A. Consulta rowvals y nzrange.
Ejemplos
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} con 3 entradas almacenadas:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> nonzeros(A)
3-element Vector{Int64}:
2
2
2SparseArrays.rowvals — Functionrowvals(A::AbstractSparseMatrixCSC)Devuelve un vector de los índices de fila de A. Cualquier modificación al vector devuelto también mutará A. Proporcionar acceso a cómo se almacenan internamente los índices de fila puede ser útil en conjunto con la iteración sobre valores no cero estructurales. Ver también nonzeros y nzrange.
Ejemplos
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} con 3 entradas almacenadas:
2 ⋅ ⋅
⋅ 2 ⋅
⋅ ⋅ 2
julia> rowvals(A)
Vector{Int64} de 3 elementos:
1
2
3SparseArrays.nzrange — Functionnzrange(A::AbstractSparseMatrixCSC, col::Integer)Devuelve el rango de índices a los valores no nulos estructurales de una columna de matriz dispersa. En conjunto con nonzeros y rowvals, esto permite iterar de manera conveniente sobre una matriz dispersa:
A = sparse(I,J,V)
rows = rowvals(A)
vals = nonzeros(A)
m, n = size(A)
for j = 1:n
for i in nzrange(A, j)
row = rows[i]
val = vals[i]
# realizar magia dispersa...
end
endAgregar o eliminar elementos no nulos de la matriz puede invalidar el nzrange, no se debe mutar la matriz mientras se itera.
nzrange(x::SparseVectorUnion, col)Devuelve el rango de índices de los valores no nulos estructurales de un vector disperso. El índice de columna col se ignora (se asume que es 1).
SparseArrays.droptol! — Functiondroptol!(A::AbstractSparseMatrixCSC, tol)Elimina los valores almacenados en A cuyo valor absoluto es menor o igual a tol.
droptol!(x::AbstractCompressedVector, tol)Elimina los valores almacenados en x cuyo valor absoluto es menor o igual a tol.
SparseArrays.dropzeros! — Functiondropzeros!(x::AbstractCompressedVector)Elimina los ceros numéricos almacenados de x.
Para una versión fuera de lugar, consulta dropzeros. Para información algorítmica, consulta fkeep!.
SparseArrays.dropzeros — Functiondropzeros(A::AbstractSparseMatrixCSC;)Genera una copia de A y elimina los ceros numéricos almacenados de esa copia.
Para una versión en su lugar e información algorítmica, consulta dropzeros!.
Ejemplos
julia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0])
3×3 SparseMatrixCSC{Float64, Int64} con 3 entradas almacenadas:
1.0 ⋅ ⋅
⋅ 0.0 ⋅
⋅ ⋅ 1.0
julia> dropzeros(A)
3×3 SparseMatrixCSC{Float64, Int64} con 2 entradas almacenadas:
1.0 ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ 1.0dropzeros(x::AbstractCompressedVector)Genera una copia de x y elimina ceros numéricos de esa copia.
Para una versión en su lugar e información algorítmica, consulta dropzeros!.
Ejemplos
julia> A = sparsevec([1, 2, 3], [1.0, 0.0, 1.0])
3-element SparseVector{Float64, Int64} with 3 stored entries:
[1] = 1.0
[2] = 0.0
[3] = 1.0
julia> dropzeros(A)
3-element SparseVector{Float64, Int64} with 2 stored entries:
[1] = 1.0
[3] = 1.0SparseArrays.permute — Functionpermute(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
q::AbstractVector{<:Integer}) where {Tv,Ti}Permutar bilateralmente A, devolviendo PAQ (A[p,q]). La longitud de la permutación de columnas q debe coincidir con el conteo de columnas de A (length(q) == size(A, 2)). La longitud de la permutación de filas p debe coincidir con el conteo de filas de A (length(p) == size(A, 1)).
Para controladores expertos e información adicional, consulte permute!.
Ejemplos
julia> A = spdiagm(0 => [1, 2, 3, 4], 1 => [5, 6, 7])
4×4 SparseMatrixCSC{Int64, Int64} con 7 entradas almacenadas:
1 5 ⋅ ⋅
⋅ 2 6 ⋅
⋅ ⋅ 3 7
⋅ ⋅ ⋅ 4
julia> permute(A, [4, 3, 2, 1], [1, 2, 3, 4])
4×4 SparseMatrixCSC{Int64, Int64} con 7 entradas almacenadas:
⋅ ⋅ ⋅ 4
⋅ ⋅ 3 7
⋅ 2 6 ⋅
1 5 ⋅ ⋅
julia> permute(A, [1, 2, 3, 4], [4, 3, 2, 1])
4×4 SparseMatrixCSC{Int64, Int64} con 7 entradas almacenadas:
⋅ ⋅ 5 1
⋅ 6 2 ⋅
7 3 ⋅ ⋅
4 ⋅ ⋅ ⋅Base.permute! — Methodpermute!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti},
p::AbstractVector{<:Integer}, q::AbstractVector{<:Integer},
[C::AbstractSparseMatrixCSC{Tv,Ti}]) where {Tv,Ti}Permuta bilateralmente A, almacenando el resultado PAQ (A[p,q]) en X. Almacena el resultado intermedio (AQ)^T (transpose(A[:,q])) en el argumento opcional C si está presente. Requiere que ninguno de X, A, y, si está presente, C se alias entre sí; para almacenar el resultado PAQ de vuelta en A, utiliza el siguiente método que no incluye X:
permute!(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
q::AbstractVector{<:Integer}[, C::AbstractSparseMatrixCSC{Tv,Ti},
[workcolptr::Vector{Ti}]]) where {Tv,Ti}Las dimensiones de X deben coincidir con las de A (size(X, 1) == size(A, 1) y size(X, 2) == size(A, 2)), y X debe tener suficiente almacenamiento para acomodar todas las entradas asignadas en A (length(rowvals(X)) >= nnz(A) y length(nonzeros(X)) >= nnz(A)). La longitud de la permutación de columnas q debe coincidir con el conteo de columnas de A (length(q) == size(A, 2)). La longitud de la permutación de filas p debe coincidir con el conteo de filas de A (length(p) == size(A, 1)).
Las dimensiones de C deben coincidir con las de transpose(A) (size(C, 1) == size(A, 2) y size(C, 2) == size(A, 1)), y C debe tener suficiente almacenamiento para acomodar todas las entradas asignadas en A (length(rowvals(C)) >= nnz(A) y length(nonzeros(C)) >= nnz(A)).
Para información adicional (algorítmica), y para versiones de estos métodos que prescinden de la verificación de argumentos, consulta los métodos padres (no exportados) unchecked_noalias_permute! y unchecked_aliasing_permute!.
Consulta también permute.
SparseArrays.halfperm! — Functionhalfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},
q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}Permuta y transpone A, aplicando simultáneamente f a cada entrada de A, almacenando el resultado (f(A)Q)^T (map(f, transpose(A[:,q]))) en X.
El tipo de elemento Tv de X debe coincidir con f(::TvA), donde TvA es el tipo de elemento de A. Las dimensiones de X deben coincidir con las de transpose(A) (size(X, 1) == size(A, 2) y size(X, 2) == size(A, 1)), y X debe tener suficiente almacenamiento para acomodar todas las entradas asignadas en A (length(rowvals(X)) >= nnz(A) y length(nonzeros(X)) >= nnz(A)). La longitud de la permutación de columna q debe coincidir con el conteo de columnas de A (length(q) == size(A, 2)).
Este método es el padre de varios métodos que realizan operaciones de transposición y permutación en SparseMatrixCSCs. Dado que este método no realiza ninguna verificación de argumentos, se prefiere el uso de los métodos hijos más seguros ([c]transpose[!], permute[!]) en lugar de su uso directo.
Este método implementa el algoritmo HALFPERM descrito en F. Gustavson, "Dos algoritmos rápidos para matrices dispersas: multiplicación y transposición permutada," ACM TOMS 4(3), 250-269 (1978). El algoritmo se ejecuta en tiempo O(size(A, 1), size(A, 2), nnz(A)) y no requiere espacio más allá del que se pasa.
SparseArrays.ftranspose! — Functionftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}Transponer A y almacenarlo en X mientras se aplica la función f a los elementos no nulos. No elimina los ceros creados por f. size(X) debe ser igual a size(transpose(A)). No se asigna memoria adicional más allá de redimensionar rowval y nzval de X, si es necesario.
Ver halfperm!
Sparse Linear Algebra API
LinearAlgebra.cholesky — Functioncholesky(A, NoPivot(); check = true) -> CholeskyCalcula la factorización de Cholesky de una matriz densa simétrica definida positiva A y devuelve una Cholesky factorización. La matriz A puede ser una Symmetric o Hermitian AbstractMatrix o una AbstractMatrix perfectamente simétrica o hermítica.
El factor triangular de Cholesky se puede obtener de la factorización F a través de F.L y F.U, donde A ≈ F.U' * F.U ≈ F.L * F.L'.
Las siguientes funciones están disponibles para los objetos Cholesky: size, \, inv, det, logdet y isposdef.
Si tienes una matriz A que es ligeramente no hermítica debido a errores de redondeo en su construcción, envuélvela en Hermitian(A) antes de pasarla a cholesky para tratarla como perfectamente hermítica.
Cuando check = true, se lanza un error si la descomposición falla. Cuando check = false, la responsabilidad de verificar la validez de la descomposición (a través de issuccess) recae en el usuario.
Ejemplos
julia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.]
3×3 Matrix{Float64}:
4.0 12.0 -16.0
12.0 37.0 -43.0
-16.0 -43.0 98.0
julia> C = cholesky(A)
Cholesky{Float64, Matrix{Float64}}
U factor:
3×3 UpperTriangular{Float64, Matrix{Float64}}:
2.0 6.0 -8.0
⋅ 1.0 5.0
⋅ ⋅ 3.0
julia> C.U
3×3 UpperTriangular{Float64, Matrix{Float64}}:
2.0 6.0 -8.0
⋅ 1.0 5.0
⋅ ⋅ 3.0
julia> C.L
3×3 LowerTriangular{Float64, Matrix{Float64}}:
2.0 ⋅ ⋅
6.0 1.0 ⋅
-8.0 5.0 3.0
julia> C.L * C.U == A
truecholesky(A, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivotedCalcula la factorización de Cholesky pivotada de una matriz densa simétrica positiva semidefinida A y devuelve una factorización CholeskyPivoted. La matriz A puede ser una Symmetric o Hermitian AbstractMatrix o una AbstractMatrix perfectamente simétrica o hermítica.
El factor triangular de Cholesky se puede obtener de la factorización F a través de F.L y F.U, y la permutación a través de F.p, donde A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr' con Ur = F.U[1:F.rank, :] y Lr = F.L[:, 1:F.rank], o alternativamente A ≈ Up' * Up ≈ Lp * Lp' con Up = F.U[1:F.rank, invperm(F.p)] y Lp = F.L[invperm(F.p), 1:F.rank].
Las siguientes funciones están disponibles para objetos CholeskyPivoted: size, \, inv, det, y rank.
El argumento tol determina la tolerancia para determinar el rango. Para valores negativos, la tolerancia es la precisión de la máquina.
Si tienes una matriz A que es ligeramente no hermítica debido a errores de redondeo en su construcción, envuélvela en Hermitian(A) antes de pasarla a cholesky para tratarla como perfectamente hermítica.
Cuando check = true, se lanza un error si la descomposición falla. Cuando check = false, la responsabilidad de verificar la validez de la descomposición (a través de issuccess) recae en el usuario.
Ejemplos
julia> X = [1.0, 2.0, 3.0, 4.0];
julia> A = X * X';
julia> C = cholesky(A, RowMaximum(), check = false)
CholeskyPivoted{Float64, Matrix{Float64}, Vector{Int64}}
U factor with rank 1:
4×4 UpperTriangular{Float64, Matrix{Float64}}:
4.0 2.0 3.0 1.0
⋅ 0.0 6.0 2.0
⋅ ⋅ 9.0 3.0
⋅ ⋅ ⋅ 1.0
permutation:
4-element Vector{Int64}:
4
2
3
1
julia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p]
true
julia> l, u = C; # destructuring via iteration
julia> l == C.L && u == C.U
truecholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.FactorCalcula la factorización de Cholesky de una matriz dispersa definida positiva A. A debe ser una SparseMatrixCSC o una vista Symmetric/Hermitian de una SparseMatrixCSC. Ten en cuenta que incluso si A no tiene la etiqueta de tipo, aún debe ser simétrica o hermítica. Si no se proporciona perm, se utiliza una permutación que reduce el llenado. F = cholesky(A) se usa con mayor frecuencia para resolver sistemas de ecuaciones con F\b, pero también se definen los métodos diag, det y logdet para F. También puedes extraer factores individuales de F, usando F.L. Sin embargo, dado que el pivoteo está activado por defecto, la factorización se representa internamente como A == P'*L*L'*P con una matriz de permutación P; usar solo L sin tener en cuenta P dará respuestas incorrectas. Para incluir los efectos de la permutación, es preferible extraer factores "combinados" como PtL = F.PtL (el equivalente de P'*L) y LtP = F.UP (el equivalente de L'*P).
Cuando check = true, se lanza un error si la descomposición falla. Cuando check = false, la responsabilidad de verificar la validez de la descomposición (a través de issuccess) recae en el usuario.
Establecer el argumento de palabra clave opcional shift calcula la factorización de A+shift*I en lugar de A. Si se proporciona el argumento perm, debe ser una permutación de 1:size(A,1) que da el orden a utilizar (en lugar del orden AMD predeterminado de CHOLMOD).
Ejemplos
En el siguiente ejemplo, la permutación que reduce el llenado utilizada es [3, 2, 1]. Si perm se establece en 1:3 para forzar ninguna permutación, el número de elementos no nulos en el factor es 6.
julia> A = [2 1 1; 1 2 0; 1 0 2]
3×3 Matrix{Int64}:
2 1 1
1 2 0
1 0 2
julia> C = cholesky(sparse(A))
SparseArrays.CHOLMOD.Factor{Float64, Int64}
type: LLt
method: simplicial
maxnnz: 5
nnz: 5
success: true
julia> C.p
3-element Vector{Int64}:
3
2
1
julia> L = sparse(C.L);
julia> Matrix(L)
3×3 Matrix{Float64}:
1.41421 0.0 0.0
0.0 1.41421 0.0
0.707107 0.707107 1.0
julia> L * L' ≈ A[C.p, C.p]
true
julia> P = sparse(1:3, C.p, ones(3))
3×3 SparseMatrixCSC{Float64, Int64} con 3 entradas almacenadas:
⋅ ⋅ 1.0
⋅ 1.0 ⋅
1.0 ⋅ ⋅
julia> P' * L * L' * P ≈ A
true
julia> C = cholesky(sparse(A), perm=1:3)
SparseArrays.CHOLMOD.Factor{Float64, Int64}
type: LLt
method: simplicial
maxnnz: 6
nnz: 6
success: true
julia> L = sparse(C.L);
julia> Matrix(L)
3×3 Matrix{Float64}:
1.41421 0.0 0.0
0.707107 1.22474 0.0
0.707107 -0.408248 1.1547
julia> L * L' ≈ A
trueEste método utiliza la biblioteca CHOLMOD[ACM887][DavisHager2009] de SuiteSparse. CHOLMOD solo admite tipos reales o complejos en precisión simple o doble. Las matrices de entrada que no son de esos tipos de elementos se convertirán a estos tipos según sea apropiado.
Muchas otras funciones de CHOLMOD están envueltas pero no exportadas del módulo Base.SparseArrays.CHOLMOD.
LinearAlgebra.cholesky! — Functioncholesky!(A::AbstractMatrix, NoPivot(); check = true) -> CholeskyLo mismo que cholesky, pero ahorra espacio al sobrescribir la entrada A, en lugar de crear una copia. Se lanza una excepción InexactError si la factorización produce un número que no se puede representar con el tipo de elemento de A, por ejemplo, para tipos enteros.
Ejemplos
julia> A = [1 2; 2 50]
2×2 Matrix{Int64}:
1 2
2 50
julia> cholesky!(A)
ERROR: InexactError: Int64(6.782329983125268)
Stacktrace:
[...]cholesky!(A::AbstractMatrix, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivotedLo mismo que cholesky, pero ahorra espacio al sobrescribir la entrada A, en lugar de crear una copia. Se lanza una excepción InexactError si la factorización produce un número que no es representable por el tipo de elemento de A, por ejemplo, para tipos enteros.
cholesky!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.FactorCalcula la factorización de Cholesky ($LL'$) de A, reutilizando la factorización simbólica F. A debe ser una SparseMatrixCSC o una vista Symmetric/ Hermitian de una SparseMatrixCSC. Ten en cuenta que, incluso si A no tiene la etiqueta de tipo, debe seguir siendo simétrica o hermitiana.
Consulta también cholesky.
Este método utiliza la biblioteca CHOLMOD de SuiteSparse, que solo admite tipos reales o complejos en precisión simple o doble. Las matrices de entrada que no sean de esos tipos de elemento se convertirán a estos tipos según sea apropiado.
LinearAlgebra.lowrankupdate — Functionlowrankupdate(C::Cholesky, v::AbstractVector) -> CC::CholeskyActualiza una factorización de Cholesky C con el vector v. Si A = C.U'C.U entonces CC = cholesky(C.U'C.U + v*v') pero el cálculo de CC solo utiliza O(n^2) operaciones.
lowrankupdate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.FactorObtiene una factorización LDLt de A + C*C' dada una factorización LDLt o LLt F de A.
El factor devuelto es siempre una factorización LDLt.
Véase también lowrankupdate!, lowrankdowndate, lowrankdowndate!.
LinearAlgebra.lowrankupdate! — Functionlowrankupdate!(C::Cholesky, v::AbstractVector) -> CC::CholeskyActualiza una factorización de Cholesky C con el vector v. Si A = C.U'C.U entonces CC = cholesky(C.U'C.U + v*v') pero el cálculo de CC solo utiliza O(n^2) operaciones. La factorización de entrada C se actualiza en su lugar de modo que al salir C == CC. El vector v se destruye durante el cálculo.
lowrankupdate!(F::CHOLMOD.Factor, C::AbstractArray)Actualiza una factorización LDLt o LLt F de A a una factorización de A + C*C'.
Las factorizaciones LLt se convierten en LDLt.
Véase también lowrankupdate, lowrankdowndate, lowrankdowndate!.
LinearAlgebra.lowrankdowndate — Functionlowrankdowndate(C::Cholesky, v::AbstractVector) -> CC::CholeskyActualiza hacia abajo una factorización de Cholesky C con el vector v. Si A = C.U'C.U entonces CC = cholesky(C.U'C.U - v*v') pero el cálculo de CC solo utiliza O(n^2) operaciones.
lowrankdowndate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.FactorObtiene una factorización LDLt de A + C*C' dada una factorización LDLt o LLt F de A.
El factor devuelto es siempre una factorización LDLt.
Véase también lowrankdowndate!, lowrankupdate, lowrankupdate!.
LinearAlgebra.lowrankdowndate! — Functionlowrankdowndate!(C::Cholesky, v::AbstractVector) -> CC::CholeskyRealiza una actualización descendente de una factorización de Cholesky C con el vector v. Si A = C.U'C.U entonces CC = cholesky(C.U'C.U - v*v') pero el cálculo de CC solo utiliza O(n^2) operaciones. La factorización de entrada C se actualiza en su lugar de tal manera que al salir C == CC. El vector v se destruye durante el cálculo.
lowrankdowndate!(F::CHOLMOD.Factor, C::AbstractArray)Actualiza una factorización LDLt o LLt F de A a una factorización de A - C*C'.
Las factorizaciones LLt se convierten en LDLt.
Véase también lowrankdowndate, lowrankupdate, lowrankupdate!.
SparseArrays.CHOLMOD.lowrankupdowndate! — Functionlowrankupdowndate!(F::CHOLMOD.Factor, C::Sparse, update::Cint)Actualiza una factorización LDLt o LLt F de A a una factorización de A ± C*C'.
Si se utiliza una factorización que preserva la esparsidad, es decir, L*L' == P*A*P', entonces el nuevo factor será L*L' == P*A*P' + C'*C
update: Cint(1) para A + CC', Cint(0) para A - CC'
LinearAlgebra.ldlt — Functionldlt(S::SymTridiagonal) -> LDLtCalcula una factorización LDLt (es decir, $LDL^T$) de la matriz tridiagonal simétrica real S tal que S = L*Diagonal(d)*L' donde L es una matriz triangular inferior unitaria y d es un vector. El uso principal de una factorización LDLt F = ldlt(S) es resolver el sistema de ecuaciones lineales Sx = b con F\b.
Véase también bunchkaufman para una factorización similar, pero con pivoteo, de matrices simétricas o hermitianas arbitrarias.
Ejemplos
julia> S = SymTridiagonal([3., 4., 5.], [1., 2.])
3×3 SymTridiagonal{Float64, Vector{Float64}}:
3.0 1.0 ⋅
1.0 4.0 2.0
⋅ 2.0 5.0
julia> ldltS = ldlt(S);
julia> b = [6., 7., 8.];
julia> ldltS \ b
3-element Vector{Float64}:
1.7906976744186047
0.627906976744186
1.3488372093023255
julia> S \ b
3-element Vector{Float64}:
1.7906976744186047
0.627906976744186
1.3488372093023255ldlt(A::SparseMatrixCSC; shift = 0.0, check = true, perm=nothing) -> CHOLMOD.FactorCalcula la factorización $LDL'$ de una matriz dispersa A. A debe ser una SparseMatrixCSC o una vista Symmetric/Hermitian de una SparseMatrixCSC. Ten en cuenta que, incluso si A no tiene la etiqueta de tipo, aún debe ser simétrica o hermítica. Se utiliza una permutación que reduce el llenado. F = ldlt(A) se usa con mayor frecuencia para resolver sistemas de ecuaciones A*x = b con F\b. El objeto de factorización devuelto F también admite los métodos diag, det, logdet y inv. Puedes extraer factores individuales de F usando F.L. Sin embargo, dado que el pivoteo está activado por defecto, la factorización se representa internamente como A == P'*L*D*L'*P con una matriz de permutación P; usar solo L sin tener en cuenta P dará respuestas incorrectas. Para incluir los efectos de la permutación, generalmente es preferible extraer factores "combinados" como PtL = F.PtL (el equivalente de P'*L) y LtP = F.UP (el equivalente de L'*P). La lista completa de factores admitidos es :L, :PtL, :D, :UP, :U, :LD, :DU, :PtLD, :DUP.
Cuando check = true, se lanza un error si la descomposición falla. Cuando check = false, la responsabilidad de verificar la validez de la descomposición (a través de issuccess) recae en el usuario.
Establecer el argumento de palabra clave opcional shift calcula la factorización de A+shift*I en lugar de A. Si se proporciona el argumento perm, debe ser una permutación de 1:size(A,1) que da el orden a utilizar (en lugar del orden predeterminado AMD de CHOLMOD).
Este método utiliza la biblioteca CHOLMOD[ACM887][DavisHager2009] de SuiteSparse. CHOLMOD solo admite tipos reales o complejos en precisión simple o doble. Las matrices de entrada que no son de esos tipos de elementos se convertirán a estos tipos según sea apropiado.
Muchas otras funciones de CHOLMOD están envueltas pero no exportadas del módulo Base.SparseArrays.CHOLMOD.
LinearAlgebra.lu — Functionlu(A::AbstractSparseMatrixCSC; check = true, q = nothing, control = get_umfpack_control()) -> F::UmfpackLUCalcula la factorización LU de una matriz dispersa A.
Para A dispersa con tipo de elemento real o complejo, el tipo de retorno de F es UmfpackLU{Tv, Ti}, donde Tv = Float64 o ComplexF64 respectivamente y Ti es un tipo entero (Int32 o Int64).
Cuando check = true, se lanza un error si la descomposición falla. Cuando check = false, la responsabilidad de verificar la validez de la descomposición (a través de issuccess) recae en el usuario.
El vector de permutación q puede ser un vector de permutación o nothing. Si no se proporciona un vector de permutación o q es nothing, se utiliza el predeterminado de UMFPACK. Si la permutación no es basada en cero, se realiza una copia basada en cero.
El vector control tiene como configuración predeterminada la configuración predeterminada del paquete SparseArrays de Julia para UMFPACK (NB: esto se modifica de los predeterminados de UMFPACK para deshabilitar el refinamiento iterativo), pero se puede cambiar pasando un vector de longitud UMFPACK_CONTROL, consulta el manual de UMFPACK para posibles configuraciones. Por ejemplo, para reactivar el refinamiento iterativo:
umfpack_control = SparseArrays.UMFPACK.get_umfpack_control(Float64, Int64) # leer la configuración predeterminada de Julia para una matriz dispersa Float64
SparseArrays.UMFPACK.show_umf_ctrl(umfpack_control) # opcional - mostrar valores
umfpack_control[SparseArrays.UMFPACK.JL_UMFPACK_IRSTEP] = 2.0 # reactivar el refinamiento iterativo (2 es el máximo de pasos de refinamiento iterativo predeterminado de UMFPACK)
Alu = lu(A; control = umfpack_control)
x = Alu \ b # resolver Ax = b, incluyendo el refinamiento iterativo de UMFPACKLos componentes individuales de la factorización F se pueden acceder mediante indexación:
| Componente | Descripción |
|---|---|
L | parte L (triangular inferior) de LU |
U | parte U (triangular superior) de LU |
p | permutación derecha Vector |
q | permutación izquierda Vector |
Rs | Vector de factores de escalado |
: | componentes (L,U,p,q,Rs) |
La relación entre F y A es
F.L*F.U == (F.Rs .* A)[F.p, F.q]
F además soporta las siguientes funciones:
Consulta también lu!
lu(A::AbstractSparseMatrixCSC) utiliza la biblioteca UMFPACK[ACM832] que es parte de SuiteSparse. Como esta biblioteca solo admite matrices dispersas con elementos Float64 o ComplexF64, lu convierte A en una copia que es de tipo SparseMatrixCSC{Float64} o SparseMatrixCSC{ComplexF64} según corresponda.
lu(A, pivot = RowMaximum(); check = true, allowsingular = false) -> F::LUCalcula la factorización LU de A.
Cuando check = true, se lanza un error si la descomposición falla. Cuando check = false, la responsabilidad de verificar la validez de la descomposición (a través de issuccess) recae en el usuario.
Por defecto, con check = true, también se lanza un error cuando la descomposición produce factores válidos, pero el factor triangular superior U es deficiente en rango. Esto se puede cambiar pasando allowsingular = true.
En la mayoría de los casos, si A es un subtipo S de AbstractMatrix{T} con un tipo de elemento T que soporta +, -, * y /, el tipo de retorno es LU{T,S{T}}.
En general, la factorización LU implica una permutación de las filas de la matriz (correspondiente a la salida F.p descrita a continuación), conocida como "pivoting" (porque corresponde a elegir qué fila contiene el "pivot", la entrada diagonal de F.U). Una de las siguientes estrategias de pivoting se puede seleccionar a través del argumento opcional pivot:
RowMaximum()(por defecto): la estrategia de pivoting estándar; el pivot corresponde al elemento de valor absoluto máximo entre las filas restantes a factorizar. Esta estrategia de pivoting requiere que el tipo de elemento también soporteabsy<. (Esta es generalmente la única opción numéricamente estable para matrices de punto flotante.)RowNonZero(): el pivot corresponde al primer elemento no cero entre las filas restantes a factorizar. (Esto corresponde a la elección típica en cálculos manuales, y también es útil para tipos de números algebraicos más generales que soportaniszeropero noabso<.)NoPivot(): pivoting desactivado (fallará si se encuentra una entrada cero en una posición de pivot, incluso cuandoallowsingular = true).
Los componentes individuales de la factorización F se pueden acceder a través de getproperty:
| Componente | Descripción |
|---|---|
F.L | L (parte triangular inferior) de LU |
F.U | U (parte triangular superior) de LU |
F.p | Permutación Vector (derecha) |
F.P | Permutación Matrix (derecha) |
Iterar sobre la factorización produce los componentes F.L, F.U y F.p.
La relación entre F y A es
F.L*F.U == A[F.p, :]
F además soporta las siguientes funciones:
| Función soportada | LU | LU{T,Tridiagonal{T}} |
|---|---|---|
/ | ✓ | |
\ | ✓ | ✓ |
inv | ✓ | ✓ |
det | ✓ | ✓ |
logdet | ✓ | ✓ |
logabsdet | ✓ | ✓ |
size | ✓ | ✓ |
El argumento de palabra clave allowsingular se agregó en Julia 1.11.
Ejemplos
julia> A = [4 3; 6 3]
2×2 Matrix{Int64}:
4 3
6 3
julia> F = lu(A)
LU{Float64, Matrix{Float64}, Vector{Int64}}
L factor:
2×2 Matrix{Float64}:
1.0 0.0
0.666667 1.0
U factor:
2×2 Matrix{Float64}:
6.0 3.0
0.0 1.0
julia> F.L * F.U == A[F.p, :]
true
julia> l, u, p = lu(A); # desestructuración a través de la iteración
julia> l == F.L && u == F.U && p == F.p
true
julia> lu([1 2; 1 2], allowsingular = true)
LU{Float64, Matrix{Float64}, Vector{Int64}}
L factor:
2×2 Matrix{Float64}:
1.0 0.0
1.0 1.0
U factor (deficiente en rango):
2×2 Matrix{Float64}:
1.0 2.0
0.0 0.0LinearAlgebra.qr — Functionqr(A::SparseMatrixCSC; tol=_default_tol(A), ordering=ORDERING_DEFAULT) -> QRSparseCalcula la factorización QR de una matriz dispersa A. Se utilizan permutaciones de filas y columnas que reducen el llenado de manera que F.R = F.Q'*A[F.prow,F.pcol]. La aplicación principal de este tipo es resolver problemas de mínimos cuadrados o subdeterminado con \. La función llama a la biblioteca C SPQR[ACM933].
qr(A::SparseMatrixCSC) utiliza la biblioteca SPQR que es parte de SuiteSparse. Dado que esta biblioteca solo admite matrices dispersas con elementos de tipo Float64 o ComplexF64, a partir de Julia v1.4 qr convierte A en una copia que es de tipo SparseMatrixCSC{Float64} o SparseMatrixCSC{ComplexF64} según corresponda.
Ejemplos
julia> A = sparse([1,2,3,4], [1,1,2,2], [1.0,1.0,1.0,1.0])
4×2 SparseMatrixCSC{Float64, Int64} con 4 entradas almacenadas:
1.0 ⋅
1.0 ⋅
⋅ 1.0
⋅ 1.0
julia> qr(A)
SparseArrays.SPQR.QRSparse{Float64, Int64}
Factor Q:
4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64}
Factor R:
2×2 SparseMatrixCSC{Float64, Int64} con 2 entradas almacenadas:
-1.41421 ⋅
⋅ -1.41421
Permutación de filas:
Vector de 4 elementos{Int64}:
1
3
4
2
Permutación de columnas:
Vector de 2 elementos{Int64}:
1
2qr(A, pivot = NoPivot(); blocksize) -> FCalcula la factorización QR de la matriz A: una matriz ortogonal (o unitaria si A es de valor complejo) Q, y una matriz triangular superior R tal que
\[A = Q R\]
El objeto devuelto F almacena la factorización en un formato empaquetado:
- si
pivot == ColumnNorm()entoncesFes un objetoQRPivoted, - de lo contrario, si el tipo de elemento de
Aes un tipo BLAS (Float32,Float64,ComplexF32oComplexF64), entoncesFes un objetoQRCompactWY, - de lo contrario,
Fes un objetoQR.
Los componentes individuales de la descomposición F se pueden recuperar a través de accesores de propiedades:
F.Q: la matriz ortogonal/unitariaQF.R: la matriz triangular superiorRF.p: el vector de permutación del pivote (QRPivotedsolo)F.P: la matriz de permutación del pivote (QRPivotedsolo)
Cada referencia al factor triangular superior a través de F.R asigna un nuevo arreglo. Por lo tanto, es aconsejable almacenar ese arreglo, digamos, con R = F.R y continuar trabajando con R.
Iterar la descomposición produce los componentes Q, R, y si existe p.
Las siguientes funciones están disponibles para los objetos QR: inv, size, y \. Cuando A es rectangular, \ devolverá una solución de mínimos cuadrados y si la solución no es única, se devuelve la que tiene la norma más pequeña. Cuando A no tiene rango completo, se requiere la factorización con pivoteo (por columna) para obtener una solución de norma mínima.
Se permite la multiplicación con respecto a Q completo/cuadrado o no completo/cuadrado, es decir, tanto F.Q*F.R como F.Q*A son compatibles. Una matriz Q se puede convertir en una matriz regular con Matrix. Esta operación devuelve el factor Q "delgado", es decir, si A es m×n con m>=n, entonces Matrix(F.Q) produce una matriz m×n con columnas ortonormales. Para recuperar el factor Q "completo", una matriz ortogonal m×m, usa F.Q*I o collect(F.Q). Si m<=n, entonces Matrix(F.Q) produce una matriz ortogonal m×m.
El tamaño del bloque para la descomposición QR se puede especificar mediante el argumento de palabra clave blocksize :: Integer cuando pivot == NoPivot() y A isa StridedMatrix{<:BlasFloat}. Se ignora cuando blocksize > minimum(size(A)). Ver QRCompactWY.
El argumento de palabra clave blocksize requiere Julia 1.4 o posterior.
Ejemplos
julia> A = [3.0 -6.0; 4.0 -8.0; 0.0 1.0]
3×2 Matrix{Float64}:
3.0 -6.0
4.0 -8.0
0.0 1.0
julia> F = qr(A)
LinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}
Factor Q: 3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}
Factor R:
2×2 Matrix{Float64}:
-5.0 10.0
0.0 -1.0
julia> F.Q * F.R == A
trueqr devuelve múltiples tipos porque LAPACK utiliza varias representaciones que minimizan los requisitos de almacenamiento de memoria de los productos de reflectores elementales de Householder, de modo que las matrices Q y R se pueden almacenar de manera compacta en lugar de como dos matrices densas separadas.
Noteworthy External Sparse Packages
Varios otros paquetes de Julia proporcionan implementaciones de matrices dispersas que deben ser mencionadas:
- SuiteSparseGraphBLAS.jl es un envoltorio sobre la rápida biblioteca C SuiteSparse:GraphBLAS multihilo. En CPU, esta es típicamente la opción más rápida, a menudo superando significativamente a MKLSparse.
- CUDA.jl expone la biblioteca CUSPARSE para operaciones de matrices dispersas en GPU.
- SparseMatricesCSR.jl proporciona una implementación nativa en Julia del formato de Filas Escasas Comprimidas (CSR).
- MKLSparse.jl acelera las operaciones de matrices dispersas-densas de SparseArrays utilizando la biblioteca MKL de Intel.
- SparseArrayKit.jl disponible para arreglos dispersos multidimensionales.
- LuxurySparse.jl proporciona formatos de arreglos dispersos estáticos, así como un formato de coordenadas.
- ExtendableSparse.jl permite una inserción rápida en matrices dispersas utilizando un enfoque perezoso para nuevos índices almacenados.
- Finch.jl admite formatos y operaciones de arreglos dispersos multidimensionales extensos a través de un mini lenguaje de tensores y compilador, todo en Julia nativa. Soporte para COO, CSF, CSR, CSC y más, así como operaciones como difusión, reducción, etc. y operaciones personalizadas.
Paquetes externos que proporcionan solucionadores directos dispersos:
Paquetes externos que proporcionan solucionadores para la solución iterativa de sistemas de eigenvalores y descomposiciones en valores singulares:
Paquetes externos para trabajar con gráficos:
- ACM887Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008). Algoritmo 887: CHOLMOD, Factorización de Cholesky dispersa supernodal y actualización/bajada. ACM Trans. Math. Softw., 35(3). doi:10.1145/1391989.1391995
- DavisHager2009Davis, Timothy A., & Hager, W. W. (2009). Supernodos dinámicos en la actualización/bajada de Cholesky dispersa y soluciones triangulares. ACM Trans. Math. Softw., 35(4). doi:10.1145/1462173.1462176
- ACM832Davis, Timothy A. (2004b). Algorithm 832: UMFPACK V4.3–-an Unsymmetric-Pattern Multifrontal Method. ACM Trans. Math. Softw., 30(2), 196–199. doi:10.1145/992200.992206
- ACM933Foster, L. V., & Davis, T. A. (2013). Algoritmo 933: Cálculo confiable de rango numérico, bases de espacio nulo, soluciones de pseudoinversa y soluciones básicas utilizando SuitesparseQR. ACM Trans. Math. Softw., 40(1). doi:10.1145/2513109.2513116