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
end
El 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
end
En 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 entries
La 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] = 3
La 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
5
Otra 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.0
Puedes 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))
true
Sparse 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.0
sparse(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 ⋅
⋅ ⋅ 3
SparseArrays.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 SparseMatrixCSC
s 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]) -> SparseMatrixCSC
Variante 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] = 1
sparsevec(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] = 2
sparsevec(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.0
Base.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))
false
SparseArrays.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)
3
SparseArrays.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 almacenadas
spzeros([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 ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ 3
SparseArrays.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 ⋅
⋅ ⋅ ⋅ ⋅ 4
SparseArrays.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.49425
SparseArrays.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.234641
SparseArrays.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
2
SparseArrays.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
3
SparseArrays.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
end
Agregar 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.0
dropzeros(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.0
SparseArrays.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 SparseMatrixCSC
s. 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) -> Cholesky
Calcula 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
true
cholesky(A, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted
Calcula 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
true
cholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.Factor
Calcula 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
true
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.cholesky!
— Functioncholesky!(A::AbstractMatrix, NoPivot(); check = true) -> Cholesky
Lo 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) -> CholeskyPivoted
Lo 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.Factor
Calcula 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::Cholesky
Actualiza 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.Factor
Obtiene 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::Cholesky
Actualiza 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::Cholesky
Actualiza 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.Factor
Obtiene 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::Cholesky
Realiza 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) -> LDLt
Calcula 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.3488372093023255
ldlt(A::SparseMatrixCSC; shift = 0.0, check = true, perm=nothing) -> CHOLMOD.Factor
Calcula 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::UmfpackLU
Calcula 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 UMFPACK
Los 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::LU
Calcula 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 soporteabs
y<
. (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 soportaniszero
pero noabs
o<
.)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.0
LinearAlgebra.qr
— Functionqr(A::SparseMatrixCSC; tol=_default_tol(A), ordering=ORDERING_DEFAULT) -> QRSparse
Calcula 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
2
qr(A, pivot = NoPivot(); blocksize) -> F
Calcula 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()
entoncesF
es un objetoQRPivoted
, - de lo contrario, si el tipo de elemento de
A
es un tipo BLAS (Float32
,Float64
,ComplexF32
oComplexF64
), entoncesF
es un objetoQRCompactWY
, - de lo contrario,
F
es 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/unitariaQ
F.R
: la matriz triangular superiorR
F.p
: el vector de permutación del pivote (QRPivoted
solo)F.P
: la matriz de permutación del pivote (QRPivoted
solo)
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
true
qr
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